sync PRIVATE and RSA for tizen2.1
[platform/core/api/location-manager.git] / src / locations.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <locations_private.h>
21 #include <location_bounds.h>
22
23
24 #define LOCATIONS_NULL_ARG_CHECK(arg)   \
25         LOCATIONS_CHECK_CONDITION((arg != NULL),LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER") \
26
27 /*
28 * Internal Implementation
29 */
30
31 static int __convert_error_code(int code)
32 {
33         int ret;
34         char *msg = "LOCATIONS_ERROR_NONE";
35         switch (code) {
36         case LOCATION_ERROR_NONE:
37                 ret = LOCATIONS_ERROR_NONE;
38                 msg = "LOCATIONS_ERROR_NONE";
39                 break;
40         case LOCATION_ERROR_NETWORK_FAILED:
41         case LOCATION_ERROR_NETWORK_NOT_CONNECTED:
42                 ret = LOCATIONS_ERROR_NETWORK_FAILED;
43                 msg = "LOCATIONS_ERROR_NETWORK_FAILED";
44                 break;
45         case LOCATION_ERROR_NOT_ALLOWED:
46                 ret = LOCATIONS_ERROR_ACCESSIBILITY_NOT_ALLOWED;
47                 msg = "LOCATIONS_ERROR_ACCESSIBILITY_NOT_ALLOWED";
48                 break;
49         case LOCATION_ERROR_SETTING_OFF:
50                 ret = LOCATIONS_ERROR_GPS_SETTING_OFF;
51                 msg = "LOCATIONS_ERROR_GPS_SETTING_OFF";
52                 break;
53         case LOCATION_ERROR_SECURITY_DENIED:
54                 ret = LOCATIONS_ERROR_SECURITY_RESTRICTED;
55                 msg = "LOCATIONS_ERROR_SECURITY_RESTRICTED";
56                 break;
57         case LOCATION_ERROR_NOT_AVAILABLE:
58         case LOCATION_ERROR_CONFIGURATION:
59         case LOCATION_ERROR_PARAMETER:
60         case LOCATION_ERROR_UNKNOWN:
61         default:
62                 msg = "LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE";
63                 ret = LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
64         }
65         LOCATIONS_LOGE("%s(0x%08x) : core fw error(0x%x)", msg, ret, code);
66         return ret;
67 }
68
69 static void __cb_service_updated(GObject * self, guint type, gpointer data, gpointer accuracy, gpointer userdata)
70 {
71         LOCATIONS_LOGI("Callback function has been invoked. ");
72         location_manager_s *handle = (location_manager_s *) userdata;
73         if (type == VELOCITY_UPDATED && handle->user_cb[_LOCATIONS_EVENT_TYPE_VELOCITY]) {
74                 LocationVelocity *vel = (LocationVelocity *) data;
75                 LOCATIONS_LOGI("Current velocity: timestamp : %d", vel->timestamp);
76                 ((location_velocity_updated_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_VELOCITY]) (vel->speed, vel->direction,
77                                                                                                   vel->climb, vel->timestamp,
78                                                                                                   handle->user_data
79                                                                                                   [_LOCATIONS_EVENT_TYPE_VELOCITY]);
80         }
81         else if (type == POSITION_UPDATED && handle->user_cb[_LOCATIONS_EVENT_TYPE_POSITION]) {
82                 LocationPosition *pos = (LocationPosition *) data;
83                 LOCATIONS_LOGI("Current position: timestamp : %d", pos->timestamp);
84                 ((location_position_updated_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_POSITION]) (pos->latitude, pos->longitude,
85                                                                                                   pos->altitude, pos->timestamp,
86                                                                                                   handle->user_data
87                                                                                                   [_LOCATIONS_EVENT_TYPE_POSITION]);
88         }
89         else if (type == SATELLITE_UPDATED && handle->user_cb[_LOCATIONS_EVENT_TYPE_SATELLITE]) {
90                 LocationSatellite *sat = (LocationSatellite *)data;
91                 LOCATIONS_LOGI("Current satellite information: timestamp : %d, number of active : %d, number of inview : %d",
92                      sat->timestamp, sat->num_of_sat_used, sat->num_of_sat_inview);
93                 ((gps_status_satellite_updated_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_SATELLITE]) (sat->num_of_sat_used, sat->num_of_sat_inview,
94                                                                                                  sat->timestamp, handle->user_data[_LOCATIONS_EVENT_TYPE_SATELLITE]);
95         }
96 }
97
98 static void __cb_service_enabled(GObject * self, guint status, gpointer userdata)
99 {
100         LOCATIONS_LOGI("Callback function has been invoked. ");
101         location_manager_s *handle = (location_manager_s *) userdata;
102         if (handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]) {
103                 ((location_service_state_changed_cb)
104                  handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]) (LOCATIONS_SERVICE_ENABLED,
105                                                                         handle->user_data[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]);
106         }
107 }
108
109 static void __cb_service_disabled(GObject * self, guint status, gpointer userdata)
110 {
111         LOCATIONS_LOGI("Callback function has been invoked. ");
112         location_manager_s *handle = (location_manager_s *) userdata;
113         if (handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE])
114                 ((location_service_state_changed_cb)
115                  handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]) (LOCATIONS_SERVICE_DISABLED,
116                                                                         handle->user_data[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]);
117 }
118
119 static int __compare_position (gconstpointer a, gconstpointer b)
120 {
121         if(location_position_equal((LocationPosition*) a, (LocationPosition *)b) == TRUE) {
122                 return 0;
123         }
124
125         return -1;
126 }
127
128 static int __boundary_compare(LocationBoundary * bound1, LocationBoundary * bound2)
129 {
130         int ret = -1;
131
132         if (bound1->type == bound2->type) {
133                 switch (bound1->type) {
134                 case LOCATION_BOUNDARY_CIRCLE:
135                         if (location_position_equal(bound1->circle.center, bound2->circle.center) && bound1->circle.radius == bound2->circle.radius) {
136                                 ret = 0;
137                         }
138                         break;
139                 case LOCATION_BOUNDARY_RECT:
140                         if (location_position_equal(bound1->rect.left_top, bound2->rect.left_top) && location_position_equal(bound1->rect.right_bottom, bound2->rect.right_bottom)) {
141                                 ret = 0;
142                         }
143                         break;
144                 case LOCATION_BOUNDARY_POLYGON: {
145                         GList *boundary1_next = NULL;
146                         GList *boundary2_start = NULL, *boundary2_prev = NULL, *boundary2_next = NULL;
147                         if (g_list_length(bound1->polygon.position_list) != g_list_length(bound2->polygon.position_list)) {
148                                 return -1;
149                         }
150
151                         boundary2_start = g_list_find_custom(bound2->polygon.position_list, g_list_nth_data(bound1->polygon.position_list, 0), (GCompareFunc) __compare_position);
152                         if (boundary2_start == NULL) return -1;
153
154                         boundary2_prev = g_list_previous(boundary2_start);
155                         boundary2_next = g_list_next(boundary2_start);
156
157                         if (boundary2_prev == NULL) boundary2_prev = g_list_last(bound2->polygon.position_list);
158                         if (boundary2_next == NULL) boundary2_next = g_list_first(bound2->polygon.position_list);
159
160                         boundary1_next = g_list_next(bound1->polygon.position_list);
161                         if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_prev->data) == TRUE) {
162                                 boundary1_next = g_list_next(boundary1_next);
163                                 while (boundary1_next) {
164                                         boundary2_prev = g_list_previous(boundary2_prev);
165                                         if (boundary2_prev == NULL) boundary2_prev = g_list_last(bound2->polygon.position_list);
166                                         if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_prev->data) == FALSE) {
167                                                 return -1;
168                                         }
169                                         boundary1_next = g_list_next(boundary1_next);
170                                 }
171                                 ret = 0;
172                         } else if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_next->data) == TRUE) {
173                                 boundary1_next = g_list_next(boundary1_next);
174                                 while(boundary1_next) {
175                                         boundary2_next = g_list_next(boundary2_next);
176                                         if (boundary2_next == NULL) boundary2_next = g_list_first(bound2->polygon.position_list);
177                                         if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_next->data) == FALSE) {
178                                                 return -1;
179                                         }
180                                         boundary1_next = g_list_next(boundary1_next);
181                                 }
182                                 ret = 0;
183                         } else {
184                                 return -1;
185                         }
186                         break;
187                 }
188                 default:
189                         break;
190                 }
191         }
192         return ret;
193 }
194
195 static void __cb_zone_in(GObject * self, gpointer boundary, gpointer position, gpointer accuracy, gpointer userdata)
196 {
197         LOCATIONS_LOGI("Callback function has been invoked.");
198         location_manager_s *handle = (location_manager_s *) userdata;
199         if (handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY]) {
200                 LocationPosition *pos = (LocationPosition *) position;
201                 ((location_zone_changed_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY]) (LOCATIONS_BOUNDARY_IN,
202                                                                                               pos->latitude, pos->longitude,
203                                                                                               pos->altitude, pos->timestamp,
204                                                                                               handle->user_data
205                                                                                               [_LOCATIONS_EVENT_TYPE_BOUNDARY]);
206         }
207
208         location_bounds_s *bounds;
209         GList *bounds_list = g_list_first(handle->bounds_list);
210         while (bounds_list) {
211                 bounds = (location_bounds_s *)bounds_list->data;
212                 if (__boundary_compare(boundary, bounds->boundary) == 0) {
213                         LOCATIONS_LOGI("Find zone in boundary");
214                         ((location_bounds_state_changed_cb) bounds->user_cb) (LOCATIONS_BOUNDARY_IN, bounds->user_data);
215                         break;
216                 }
217                 bounds_list = g_list_next(bounds_list);
218         }
219 }
220
221 static void __cb_zone_out(GObject * self, gpointer boundary, gpointer position, gpointer accuracy, gpointer userdata)
222 {
223         LOCATIONS_LOGI("Callback function has been invoked.");
224         location_manager_s *handle = (location_manager_s *) userdata;
225         if (handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY]) {
226                 LocationPosition *pos = (LocationPosition *) position;
227                 ((location_zone_changed_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY]) (LOCATIONS_BOUNDARY_OUT,
228                                                                                               pos->latitude, pos->longitude,
229                                                                                               pos->altitude, pos->timestamp,
230                                                                                               handle->user_data
231                                                                                               [_LOCATIONS_EVENT_TYPE_BOUNDARY]);
232         }
233
234         location_bounds_s *bounds;
235         GList *bounds_list = g_list_first(handle->bounds_list);
236         while (bounds_list) {
237                 bounds = (location_bounds_s *)bounds_list->data;
238                 if (__boundary_compare(boundary, bounds->boundary) == 0) {
239                         LOCATIONS_LOGI("Find zone out boundary");
240                         ((location_bounds_state_changed_cb) bounds->user_cb) (LOCATIONS_BOUNDARY_OUT, bounds->user_data);
241                         break;
242                 }
243                 bounds_list = g_list_next(bounds_list);
244         }
245 }
246
247 static int __set_callback(_location_event_e type, location_manager_h manager, void *callback, void *user_data)
248 {
249         LOCATIONS_NULL_ARG_CHECK(manager);
250         LOCATIONS_NULL_ARG_CHECK(callback);
251         location_manager_s *handle = (location_manager_s *) manager;
252         handle->user_cb[type] = callback;
253         handle->user_data[type] = user_data;
254         LOCATIONS_LOGI("event type : %d. ", type);
255         return LOCATIONS_ERROR_NONE;
256 }
257
258 static int __unset_callback(_location_event_e type, location_manager_h manager)
259 {
260         LOCATIONS_NULL_ARG_CHECK(manager);
261         location_manager_s *handle = (location_manager_s *) manager;
262         handle->user_cb[type] = NULL;
263         handle->user_data[type] = NULL;
264         LOCATIONS_LOGI("event type : %d. ", type);
265         return LOCATIONS_ERROR_NONE;
266 }
267
268 static void __foreach_boundary(LocationBoundary * boundary, void *user_data)
269 {
270         location_manager_s *handle = (location_manager_s *) user_data;
271
272         if (handle != NULL && boundary != NULL) {
273                 int ret = -1;
274                 location_bounds_h bounds;
275                 if (boundary->type == LOCATION_BOUNDARY_CIRCLE) {
276                         location_coords_s center;
277                         center.latitude = boundary->circle.center->latitude;
278                         center.longitude = boundary->circle.center->longitude;
279                         ret = location_bounds_create_circle(center, boundary->circle.radius, &bounds);
280                 } else if (boundary->type == LOCATION_BOUNDARY_RECT) {
281                         location_coords_s left_top;
282                         location_coords_s right_bottom;
283                         left_top.latitude = boundary->rect.left_top->latitude;
284                         left_top.longitude = boundary->rect.left_top->longitude;
285                         right_bottom.latitude = boundary->rect.right_bottom->latitude;
286                         right_bottom.longitude = boundary->rect.right_bottom->longitude;
287                         ret = location_bounds_create_rect(left_top, right_bottom, &bounds);
288                 } else if (boundary->type == LOCATION_BOUNDARY_POLYGON) {
289                         GList *list = boundary->polygon.position_list;
290                         int size = g_list_length(list);
291                         if (size > 0) {
292                                 location_coords_s coords[size];
293                                 int cnt = 0;
294                                 while (list) {
295                                         LocationPosition *pos = list->data;
296                                         coords[cnt].latitude = pos->latitude;
297                                         coords[cnt].longitude = pos->longitude;
298                                         list = g_list_next(list);
299                                         cnt++;
300                                 }
301                                 ret = location_bounds_create_polygon(coords, size, &bounds);
302                         }
303                 } else {
304                         LOCATIONS_LOGI("Invalid boundary type : %d", boundary->type);
305                 }
306
307                 if (ret != LOCATIONS_ERROR_NONE) {
308                         LOCATIONS_LOGI("Failed to create location_bounds : (0x%08x) ", ret);
309                 } else {
310                         if (handle->is_continue_foreach_bounds) {
311                                 handle->is_continue_foreach_bounds =
312                                     ((location_bounds_cb) handle->user_cb[_LOCATIONS_EVENT_TYPE_FOREACH_BOUNDS]) (bounds,
313                                                                                                                   handle->
314                                                                                                                   user_data
315                                                                                                                   [_LOCATIONS_EVENT_TYPE_FOREACH_BOUNDS]);
316                         }
317                         location_bounds_destroy(bounds);
318                 }
319         } else {
320                 LOCATIONS_LOGI("__foreach_boundary() has been failed");
321         }
322 }
323
324 /////////////////////////////////////////
325 // Location Manager
326 ////////////////////////////////////////
327
328 /*
329 * Public Implementation
330 */
331
332 EXPORT_API bool location_manager_is_supported_method(location_method_e method)
333 {
334         LocationMethod _method = LOCATION_METHOD_NONE;
335         switch (method) {
336         case LOCATIONS_METHOD_HYBRID:
337                 _method = LOCATION_METHOD_HYBRID;
338                 break;
339         case LOCATIONS_METHOD_GPS:
340                 _method = LOCATION_METHOD_GPS;
341                 break;
342         case LOCATIONS_METHOD_WPS:
343                 _method = LOCATION_METHOD_WPS;
344                 break;
345         case LOCATIONS_METHOD_CPS:
346                 _method = LOCATION_METHOD_CPS;
347                 break;
348         default:
349                 _method = LOCATION_METHOD_NONE;
350                 break;
351         }
352         return location_is_supported_method(_method);
353 }
354
355 EXPORT_API int location_manager_create(location_method_e method, location_manager_h * manager)
356 {
357         LOCATIONS_NULL_ARG_CHECK(manager);
358         if (location_init() != LOCATION_ERROR_NONE)
359                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
360
361         LocationMethod _method = LOCATION_METHOD_NONE;
362         switch (method) {
363         case LOCATIONS_METHOD_HYBRID:
364                 _method = LOCATION_METHOD_HYBRID;
365                 break;
366         case LOCATIONS_METHOD_GPS:
367                 _method = LOCATION_METHOD_GPS;
368                 break;
369         case LOCATIONS_METHOD_WPS:
370                 _method = LOCATION_METHOD_WPS;
371                 break;
372         case LOCATIONS_METHOD_CPS:
373                 _method = LOCATION_METHOD_CPS;
374                 break;
375         case LOCATIONS_METHOD_NONE:
376                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
377         default:
378                 {
379                         LOCATIONS_LOGE("LOCATIONS_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (location_method_e) - method : %d ",
380                              LOCATIONS_ERROR_INVALID_PARAMETER, method);
381                         return LOCATIONS_ERROR_INVALID_PARAMETER;
382                 }
383         }
384
385         location_manager_s *handle = (location_manager_s *) malloc(sizeof(location_manager_s));
386         if (handle == NULL) {
387                 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATIONS_ERROR_OUT_OF_MEMORY);
388                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
389         }
390
391         memset(handle, 0, sizeof(location_manager_s));
392
393         handle->object = location_new(_method);
394         if (handle->object == NULL) {
395                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_new",
396                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
397                 free(handle);
398                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
399         }
400         handle->method = method;
401         handle->is_continue_foreach_bounds = TRUE;
402         handle->bounds_list = NULL;
403
404         handle->sig_id[_LOCATION_SIGNAL_SERVICE_ENABLED] = g_signal_connect(handle->object, "service-enabled", G_CALLBACK(__cb_service_enabled), handle);
405         handle->sig_id[_LOCATION_SIGNAL_SERVICE_DISABLED] = g_signal_connect(handle->object, "service-disabled", G_CALLBACK(__cb_service_disabled), handle);
406
407         *manager = (location_manager_h) handle;
408         return LOCATIONS_ERROR_NONE;
409 }
410
411 EXPORT_API int location_manager_destroy(location_manager_h manager)
412 {
413         LOCATIONS_NULL_ARG_CHECK(manager);
414         location_manager_s *handle = (location_manager_s *) manager;
415
416         g_signal_handler_disconnect(handle->object, handle->sig_id[_LOCATION_SIGNAL_SERVICE_ENABLED]);
417         g_signal_handler_disconnect(handle->object, handle->sig_id[_LOCATION_SIGNAL_SERVICE_DISABLED]);
418
419         int ret = location_free(handle->object);
420         if (ret != LOCATIONS_ERROR_NONE) {
421                 return __convert_error_code(ret);
422         }
423         free(handle);
424         return LOCATIONS_ERROR_NONE;
425 }
426
427 EXPORT_API int location_manager_start(location_manager_h manager)
428 {
429         LOCATIONS_NULL_ARG_CHECK(manager);
430         location_manager_s *handle = (location_manager_s *) manager;
431
432         handle->sig_id[_LOCATION_SIGNAL_SERVICE_UPDATED] = g_signal_connect(handle->object, "service-updated", G_CALLBACK(__cb_service_updated), handle);
433         handle->sig_id[_LOCATION_SIGNAL_ZONE_IN] = g_signal_connect(handle->object, "zone-in", G_CALLBACK(__cb_zone_in), handle);
434         handle->sig_id[_LOCATION_SIGNAL_ZONE_OUT] = g_signal_connect(handle->object, "zone-out", G_CALLBACK(__cb_zone_out), handle);
435
436         int ret = location_start(handle->object);
437         if (ret != LOCATION_ERROR_NONE) {
438                 return __convert_error_code(ret);
439         }
440         return LOCATIONS_ERROR_NONE;
441 }
442
443 EXPORT_API int location_manager_stop(location_manager_h manager)
444 {
445         LOCATIONS_NULL_ARG_CHECK(manager);
446         location_manager_s *handle = (location_manager_s *) manager;
447
448         g_signal_handler_disconnect(handle->object, handle->sig_id[_LOCATION_SIGNAL_SERVICE_UPDATED]);
449         g_signal_handler_disconnect(handle->object, handle->sig_id[_LOCATION_SIGNAL_ZONE_IN]);
450         g_signal_handler_disconnect(handle->object, handle->sig_id[_LOCATION_SIGNAL_ZONE_OUT]);
451
452         int ret = location_stop(handle->object);
453         if (ret != LOCATION_ERROR_NONE) {
454                 return __convert_error_code(ret);
455         }
456         return LOCATIONS_ERROR_NONE;
457 }
458
459 EXPORT_API int location_manager_add_boundary(location_manager_h manager, location_bounds_h bounds)
460 {
461         LOCATIONS_NULL_ARG_CHECK(manager);
462         LOCATIONS_NULL_ARG_CHECK(bounds);
463
464         location_manager_s *handle = (location_manager_s *) manager;
465         location_bounds_s *bound_handle = (location_bounds_s *) bounds;
466         int ret = location_boundary_add(handle->object, bound_handle->boundary);
467         if (ret != LOCATION_ERROR_NONE) {
468                 return __convert_error_code(ret);
469         }
470         bound_handle->is_added = TRUE;
471         handle->bounds_list = g_list_append(handle->bounds_list, bound_handle);
472         return LOCATIONS_ERROR_NONE;
473 }
474
475 EXPORT_API int location_manager_remove_boundary(location_manager_h manager, location_bounds_h bounds)
476 {
477         LOCATIONS_NULL_ARG_CHECK(manager);
478         LOCATIONS_NULL_ARG_CHECK(bounds);
479
480         location_manager_s *handle = (location_manager_s *) manager;
481         location_bounds_s *bound_handle = (location_bounds_s *) bounds;
482         int ret = location_boundary_remove(handle->object, bound_handle->boundary);
483         if (ret != LOCATION_ERROR_NONE) {
484                 return __convert_error_code(ret);
485         }
486         handle->bounds_list = g_list_remove(handle->bounds_list, bound_handle);
487         bound_handle->is_added = FALSE;
488         return LOCATIONS_ERROR_NONE;
489 }
490
491 EXPORT_API int location_manager_foreach_boundary(location_manager_h manager, location_bounds_cb callback, void *user_data)
492 {
493         LOCATIONS_NULL_ARG_CHECK(manager);
494         LOCATIONS_NULL_ARG_CHECK(callback);
495
496         location_manager_s *handle = (location_manager_s *) manager;
497         handle->user_cb[_LOCATIONS_EVENT_TYPE_FOREACH_BOUNDS] = callback;
498         handle->user_data[_LOCATIONS_EVENT_TYPE_FOREACH_BOUNDS] = user_data;
499         handle->is_continue_foreach_bounds = TRUE;
500         int ret = location_boundary_foreach(handle->object, __foreach_boundary, handle);
501         if (ret != LOCATION_ERROR_NONE) {
502                 return __convert_error_code(ret);
503         }
504         return LOCATIONS_ERROR_NONE;
505 }
506
507 EXPORT_API int location_manager_get_method(location_manager_h manager, location_method_e * method)
508 {
509         LOCATIONS_NULL_ARG_CHECK(manager);
510         LOCATIONS_NULL_ARG_CHECK(method);
511         location_manager_s *handle = (location_manager_s *) manager;
512         LocationMethod _method = LOCATION_METHOD_NONE;
513         g_object_get(handle->object, "method", &_method, NULL);
514         switch (_method) {
515         case LOCATION_METHOD_NONE:
516                 *method = LOCATIONS_METHOD_NONE;
517                 break;
518         case LOCATION_METHOD_HYBRID:
519                 *method = LOCATIONS_METHOD_HYBRID;
520                 break;
521         case LOCATION_METHOD_GPS:
522                 *method = LOCATIONS_METHOD_GPS;
523                 break;
524         case LOCATION_METHOD_WPS:
525                 *method = LOCATIONS_METHOD_WPS;
526                 break;
527         case LOCATION_METHOD_CPS:
528                 *method = LOCATIONS_METHOD_CPS;
529                 break;
530         default:
531                 {
532                         LOCATIONS_LOGE("LOCATIONS_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (location_method_e) - method : %d ",
533                              LOCATIONS_ERROR_INVALID_PARAMETER, method);
534                         return LOCATIONS_ERROR_INVALID_PARAMETER;
535                 }
536         }
537         //*method = handle->method;
538         return LOCATIONS_ERROR_NONE;
539 }
540
541 EXPORT_API int location_manager_get_position(location_manager_h manager, double *altitude, double *latitude, double *longitude,
542                                   time_t * timestamp)
543 {
544         LOCATIONS_NULL_ARG_CHECK(manager);
545         LOCATIONS_NULL_ARG_CHECK(altitude);
546         LOCATIONS_NULL_ARG_CHECK(latitude);
547         LOCATIONS_NULL_ARG_CHECK(longitude);
548         LOCATIONS_NULL_ARG_CHECK(timestamp);
549
550         location_manager_s *handle = (location_manager_s *) manager;
551         int ret;
552         LocationPosition *pos = NULL;
553         LocationAccuracy *acc = NULL;
554         ret = location_get_position(handle->object, &pos, &acc);
555         if (ret != LOCATION_ERROR_NONE) {
556                 return __convert_error_code(ret);
557         }
558
559         if (pos->status == LOCATION_STATUS_NO_FIX) {
560                 *altitude = -1;
561                 *latitude = -1;
562                 *longitude = -1;
563         } else {
564                 if (pos->status == LOCATION_STATUS_3D_FIX) {
565                         *altitude = pos->altitude;
566                 } else {
567                         *altitude = -1;
568                 }
569                 *latitude = pos->latitude;
570                 *longitude = pos->longitude;
571         }
572         *timestamp = pos->timestamp;
573         location_position_free(pos);
574         location_accuracy_free(acc);
575         return LOCATIONS_ERROR_NONE;
576 }
577
578 EXPORT_API int location_manager_get_location(location_manager_h manager, double *altitude, double *latitude, double *longitude, double *climb, double *direction, double *speed, location_accuracy_level_e *level, double *horizontal, double *vertical, time_t *timestamp)
579 {
580         LOCATIONS_NULL_ARG_CHECK(manager);
581         LOCATIONS_NULL_ARG_CHECK(altitude);
582         LOCATIONS_NULL_ARG_CHECK(latitude);
583         LOCATIONS_NULL_ARG_CHECK(longitude);
584         LOCATIONS_NULL_ARG_CHECK(climb);
585         LOCATIONS_NULL_ARG_CHECK(direction);
586         LOCATIONS_NULL_ARG_CHECK(speed);
587         LOCATIONS_NULL_ARG_CHECK(level);
588         LOCATIONS_NULL_ARG_CHECK(horizontal);
589         LOCATIONS_NULL_ARG_CHECK(vertical);
590         LOCATIONS_NULL_ARG_CHECK(timestamp);
591
592         location_manager_s *handle = (location_manager_s *) manager;
593         int ret;
594         LocationPosition *pos = NULL;
595         LocationVelocity *vel = NULL;
596         LocationAccuracy *acc = NULL;
597         ret = location_get_position_ext(handle->object, &pos, &vel, &acc);
598         if (ret != LOCATION_ERROR_NONE) {
599                 return __convert_error_code(ret);
600         }
601
602         if (pos->status == LOCATION_STATUS_NO_FIX) {
603                 *altitude = -1;
604                 *latitude = -1;
605                 *longitude = -1;
606         } else {
607                 if (pos->status == LOCATION_STATUS_3D_FIX) {
608                         *altitude = pos->altitude;
609                 } else {
610                         *altitude = -1;
611                 }
612                 *latitude = pos->latitude;
613                 *longitude = pos->longitude;
614         }
615         *timestamp = pos->timestamp;
616         *climb = vel->climb;
617         *direction = vel->direction;
618         *speed = vel->speed;
619         *level = acc->level;
620         *horizontal = acc->horizontal_accuracy;
621         *vertical = acc->vertical_accuracy;
622
623         location_position_free(pos);
624         location_velocity_free(vel);
625         location_accuracy_free(acc);
626         return LOCATIONS_ERROR_NONE;
627 }
628
629 EXPORT_API int location_manager_get_velocity(location_manager_h manager, double *climb, double *direction, double *speed, time_t * timestamp)
630 {
631         LOCATIONS_NULL_ARG_CHECK(manager);
632         LOCATIONS_NULL_ARG_CHECK(climb);
633         LOCATIONS_NULL_ARG_CHECK(direction);
634         LOCATIONS_NULL_ARG_CHECK(speed);
635         LOCATIONS_NULL_ARG_CHECK(timestamp);
636
637         location_manager_s *handle = (location_manager_s *) manager;
638         int ret;
639         LocationVelocity *vel = NULL;
640         LocationAccuracy *acc = NULL;
641         ret = location_get_velocity(handle->object, &vel, &acc);
642         if (ret != LOCATION_ERROR_NONE) {
643                 return __convert_error_code(ret);
644         }
645
646         *climb = vel->climb;
647         *direction = vel->direction;
648         *speed = vel->speed;
649         *timestamp = vel->timestamp;
650         location_velocity_free(vel);
651         location_accuracy_free(acc);
652         return LOCATIONS_ERROR_NONE;
653 }
654
655 EXPORT_API int location_manager_get_accuracy(location_manager_h manager, location_accuracy_level_e * level, double *horizontal,
656                                   double *vertical)
657 {
658         LOCATIONS_NULL_ARG_CHECK(manager);
659         LOCATIONS_NULL_ARG_CHECK(level);
660         LOCATIONS_NULL_ARG_CHECK(horizontal);
661         LOCATIONS_NULL_ARG_CHECK(vertical);
662         location_manager_s *handle = (location_manager_s *) manager;
663
664         int ret;
665         LocationPosition *pos = NULL;
666         LocationAccuracy *acc = NULL;
667         ret = location_get_position(handle->object, &pos, &acc);
668         if (ret != LOCATION_ERROR_NONE) {
669                 return __convert_error_code(ret);
670         }
671
672         if (acc == NULL) {
673                 return __convert_error_code(LOCATION_ERROR_NOT_AVAILABLE);
674         }
675
676         *level = acc->level;
677         *horizontal = acc->horizontal_accuracy;
678         *vertical = acc->vertical_accuracy;
679         location_position_free(pos);
680         location_accuracy_free(acc);
681         return LOCATIONS_ERROR_NONE;
682 }
683
684 EXPORT_API int location_manager_get_last_position(location_manager_h manager, double *altitude, double *latitude, double *longitude,
685                                        time_t * timestamp)
686 {
687         LOCATIONS_NULL_ARG_CHECK(manager);
688         LOCATIONS_NULL_ARG_CHECK(altitude);
689         LOCATIONS_NULL_ARG_CHECK(latitude);
690         LOCATIONS_NULL_ARG_CHECK(longitude);
691         LOCATIONS_NULL_ARG_CHECK(timestamp);
692
693         location_manager_s *handle = (location_manager_s *) manager;
694
695         int ret;
696         LocationPosition *last_pos = NULL;
697         LocationAccuracy *last_acc = NULL;
698         ret = location_get_last_position(handle->object, &last_pos, &last_acc);
699         if (ret != LOCATION_ERROR_NONE) {
700                 return __convert_error_code(ret);
701         }
702
703         if (last_pos->status == LOCATION_STATUS_NO_FIX) {
704                 *altitude = -1;
705                 *latitude = -1;
706                 *longitude = -1;
707         } else {
708                 if (last_pos->status == LOCATION_STATUS_3D_FIX) {
709                         *altitude = last_pos->altitude;
710                 } else {
711                         *altitude = -1;
712                 }
713                 *latitude = last_pos->latitude;
714                 *longitude = last_pos->longitude;
715         }
716         *timestamp = last_pos->timestamp;
717         location_position_free(last_pos);
718         location_accuracy_free(last_acc);
719         return LOCATIONS_ERROR_NONE;
720 }
721
722 EXPORT_API int location_manager_get_last_location(location_manager_h manager, double *altitude, double *latitude, double *longitude, double *climb, double *direction, double *speed, location_accuracy_level_e * level, double *horizontal, double *vertical, time_t * timestamp)
723 {
724         LOCATIONS_NULL_ARG_CHECK(manager);
725         LOCATIONS_NULL_ARG_CHECK(altitude);
726         LOCATIONS_NULL_ARG_CHECK(latitude);
727         LOCATIONS_NULL_ARG_CHECK(longitude);
728         LOCATIONS_NULL_ARG_CHECK(climb);
729         LOCATIONS_NULL_ARG_CHECK(direction);
730         LOCATIONS_NULL_ARG_CHECK(speed);
731         LOCATIONS_NULL_ARG_CHECK(level);
732         LOCATIONS_NULL_ARG_CHECK(horizontal);
733         LOCATIONS_NULL_ARG_CHECK(vertical);
734         LOCATIONS_NULL_ARG_CHECK(timestamp);
735
736         location_manager_s *handle = (location_manager_s *) manager;
737
738         int ret;
739         LocationPosition *last_pos = NULL;
740         LocationVelocity *last_vel = NULL;
741         LocationAccuracy *last_acc = NULL;
742         ret = location_get_last_position_ext(handle->object, &last_pos, &last_vel, &last_acc);
743         if (ret != LOCATION_ERROR_NONE) {
744                 return __convert_error_code(ret);
745         }
746
747         if (last_pos->status == LOCATION_STATUS_NO_FIX) {
748                 *altitude = -1;
749                 *latitude = -1;
750                 *longitude = -1;
751         } else {
752                 if (last_pos->status == LOCATION_STATUS_3D_FIX) {
753                         *altitude = last_pos->altitude;
754                 } else {
755                         *altitude = -1;
756                 }
757                 *latitude = last_pos->latitude;
758                 *longitude = last_pos->longitude;
759         }
760         *timestamp = last_pos->timestamp;
761         *climb = last_vel->climb;
762         *direction = last_vel->direction;
763         *speed = last_vel->speed;
764         *level = last_acc->level;
765         *horizontal = last_acc->horizontal_accuracy;
766         *vertical = last_acc->vertical_accuracy;
767         location_position_free(last_pos);
768         location_velocity_free(last_vel);
769         location_accuracy_free(last_acc);
770         return LOCATIONS_ERROR_NONE;
771 }
772
773 EXPORT_API int location_manager_get_last_velocity(location_manager_h manager, double *climb, double *direction, double *speed, time_t * timestamp)
774 {
775         LOCATIONS_NULL_ARG_CHECK(manager);
776         LOCATIONS_NULL_ARG_CHECK(climb);
777         LOCATIONS_NULL_ARG_CHECK(direction);
778         LOCATIONS_NULL_ARG_CHECK(speed);
779         LOCATIONS_NULL_ARG_CHECK(timestamp);
780
781         location_manager_s *handle = (location_manager_s *) manager;
782
783         int ret;
784         LocationVelocity *last_vel = NULL;
785         LocationAccuracy *last_acc = NULL;
786         ret = location_get_last_velocity(handle->object, &last_vel, &last_acc);
787         if (ret != LOCATION_ERROR_NONE) {
788                 return __convert_error_code(ret);
789         }
790
791         *climb = last_vel->climb;
792         *direction = last_vel->direction;
793         *speed = last_vel->speed;
794         *timestamp = last_vel->timestamp;
795         location_velocity_free(last_vel);
796         location_accuracy_free(last_acc);
797         return LOCATIONS_ERROR_NONE;
798 }
799
800 EXPORT_API int location_manager_get_last_accuracy(location_manager_h manager, location_accuracy_level_e * level, double *horizontal,
801                                        double *vertical)
802 {
803         LOCATIONS_NULL_ARG_CHECK(manager);
804         LOCATIONS_NULL_ARG_CHECK(level);
805         LOCATIONS_NULL_ARG_CHECK(horizontal);
806         LOCATIONS_NULL_ARG_CHECK(vertical);
807         location_manager_s *handle = (location_manager_s *) manager;
808
809         int ret;
810         LocationPosition *last_pos = NULL;
811         LocationAccuracy *last_acc = NULL;
812         ret = location_get_last_position(handle->object, &last_pos, &last_acc);
813         if (ret != LOCATION_ERROR_NONE) {
814                 return __convert_error_code(ret);
815         }
816
817         *level = last_acc->level;
818         *horizontal = last_acc->horizontal_accuracy;
819         *vertical = last_acc->vertical_accuracy;
820         location_position_free(last_pos);
821         location_accuracy_free(last_acc);
822         return LOCATIONS_ERROR_NONE;
823 }
824
825 EXPORT_API int location_manager_get_accessibility_state(location_accessibility_state_e* state)
826 {
827         LOCATIONS_NULL_ARG_CHECK(state);
828
829         int ret = LOCATION_ERROR_NONE;
830         LocationAccessState auth = LOCATION_ACCESS_NONE;
831         ret = location_get_accessibility_state (&auth);
832         if (ret != LOCATION_ERROR_NONE) {
833                 *state = LOCATIONS_ACCESS_STATE_NONE;
834                 return __convert_error_code(ret);
835         }
836
837         switch (auth) {
838                 case LOCATION_ACCESS_DENIED:
839                         *state = LOCATIONS_ACCESS_STATE_DENIED;
840                         break;
841                 case LOCATION_ACCESS_ALLOWED:
842                         *state = LOCATIONS_ACCESS_STATE_ALLOWED;
843                         break;
844                 case LOCATION_ACCESS_NONE:
845                 default:
846                         *state = LOCATIONS_ACCESS_STATE_NONE;
847                         break;
848         }
849
850         return LOCATIONS_ERROR_NONE;
851 }
852
853 EXPORT_API int location_manager_set_position_updated_cb(location_manager_h manager, location_position_updated_cb callback, int interval, void *user_data)
854 {
855         LOCATIONS_CHECK_CONDITION(interval >= 1
856                                   && interval <= 120, LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
857         LOCATIONS_NULL_ARG_CHECK(manager);
858         location_manager_s *handle = (location_manager_s *) manager;
859         g_object_set(handle->object, "pos-interval", interval, NULL);
860         return __set_callback(_LOCATIONS_EVENT_TYPE_POSITION, manager, callback, user_data);
861 }
862
863 EXPORT_API int location_manager_unset_position_updated_cb(location_manager_h manager)
864 {
865         return __unset_callback(_LOCATIONS_EVENT_TYPE_POSITION, manager);
866 }
867
868 EXPORT_API int location_manager_set_velocity_updated_cb(location_manager_h manager, location_velocity_updated_cb callback, int interval, void *user_data)
869 {
870         LOCATIONS_CHECK_CONDITION(interval >= 1
871                                   && interval <= 120, LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
872         LOCATIONS_NULL_ARG_CHECK(manager);
873         location_manager_s *handle = (location_manager_s *) manager;
874         g_object_set(handle->object, "vel-interval", interval, NULL);
875         return __set_callback(_LOCATIONS_EVENT_TYPE_VELOCITY, manager, callback, user_data);
876 }
877
878 EXPORT_API int location_manager_unset_velocity_updated_cb(location_manager_h manager)
879 {
880         return __unset_callback(_LOCATIONS_EVENT_TYPE_VELOCITY, manager);
881 }
882
883 EXPORT_API int location_manager_set_service_state_changed_cb(location_manager_h manager, location_service_state_changed_cb callback,
884                                                   void *user_data)
885 {
886         return __set_callback(_LOCATIONS_EVENT_TYPE_SERVICE_STATE, manager, callback, user_data);
887 }
888
889 EXPORT_API int location_manager_unset_service_state_changed_cb(location_manager_h manager)
890 {
891         return __unset_callback(_LOCATIONS_EVENT_TYPE_SERVICE_STATE, manager);
892 }
893
894 EXPORT_API int location_manager_set_zone_changed_cb(location_manager_h manager, location_zone_changed_cb callback, void *user_data)
895 {
896         return __set_callback(_LOCATIONS_EVENT_TYPE_BOUNDARY, manager, callback, user_data);
897 }
898
899 EXPORT_API int location_manager_unset_zone_changed_cb(location_manager_h manager)
900 {
901         return __unset_callback(_LOCATIONS_EVENT_TYPE_BOUNDARY, manager);
902 }
903
904 EXPORT_API int location_manager_get_distance(double start_latitude, double start_longitude, double end_latitude, double end_longitude, double *distance)
905 {
906         LOCATIONS_NULL_ARG_CHECK(distance);
907         LOCATIONS_CHECK_CONDITION(start_latitude>=-90 && start_latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
908         LOCATIONS_CHECK_CONDITION(start_longitude>=-180 && start_longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
909         LOCATIONS_CHECK_CONDITION(end_latitude>=-90 && end_latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
910         LOCATIONS_CHECK_CONDITION(end_longitude>=-180 && end_longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
911
912         int ret = LOCATION_ERROR_NONE;
913         ulong u_distance;
914
915         LocationPosition *start = location_position_new (0, start_latitude, start_longitude, 0, LOCATION_STATUS_2D_FIX);
916         LocationPosition *end = location_position_new (0, end_latitude, end_longitude, 0, LOCATION_STATUS_2D_FIX);
917
918         ret = location_get_distance (start, end, &u_distance);
919         if (ret != LOCATION_ERROR_NONE) {
920                 return __convert_error_code(ret);
921         }
922
923         *distance = (double)u_distance;
924
925         return LOCATIONS_ERROR_NONE;
926 }
927
928 EXPORT_API int location_manager_send_command(const char *cmd)
929 {
930         LOCATIONS_NULL_ARG_CHECK(cmd);
931
932         int ret;
933         ret = location_send_command(cmd);
934         if (ret != LOCATION_ERROR_NONE) {
935                 return __convert_error_code(ret);
936         }
937
938         return LOCATIONS_ERROR_NONE;
939 }
940
941 /////////////////////////////////////////
942 // GPS Status & Satellites
943 ////////////////////////////////////////
944
945 EXPORT_API int gps_status_get_nmea(location_manager_h manager, char **nmea)
946 {
947         LOCATIONS_NULL_ARG_CHECK(manager);
948         LOCATIONS_NULL_ARG_CHECK(nmea);
949         location_manager_s *handle = (location_manager_s *) manager;
950
951         if (handle->method == LOCATIONS_METHOD_HYBRID) {
952                 LocationMethod _method = LOCATION_METHOD_NONE;
953                 g_object_get(handle->object, "method", &_method, NULL);
954                 if (_method != LOCATION_METHOD_GPS) {
955                         LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
956                              LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
957                         return LOCATIONS_ERROR_INCORRECT_METHOD;
958                 }
959         } else if (handle->method != LOCATIONS_METHOD_GPS) {
960                 LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
961                      LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
962                 return LOCATIONS_ERROR_INCORRECT_METHOD;
963         }
964         gchar *nmea_data = NULL;
965         g_object_get(handle->object, "nmea", &nmea_data, NULL);
966         if (nmea_data == NULL) {
967                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : nmea data is NULL ",
968                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
969                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
970         }
971         *nmea = NULL;
972         *nmea = strdup(nmea_data);
973         if (*nmea == NULL) {
974                 LOCATIONS_LOGE("LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to strdup ",
975                      LOCATIONS_ERROR_OUT_OF_MEMORY);
976                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
977         }
978         g_free(nmea_data);
979         return LOCATIONS_ERROR_NONE;
980 }
981
982 EXPORT_API int gps_status_get_satellite(location_manager_h manager, int *num_of_active, int *num_of_inview, time_t *timestamp)
983 {
984         LOCATIONS_NULL_ARG_CHECK(manager);
985         LOCATIONS_NULL_ARG_CHECK(num_of_active);
986         LOCATIONS_NULL_ARG_CHECK(num_of_inview);
987         LOCATIONS_NULL_ARG_CHECK(timestamp);
988         location_manager_s *handle = (location_manager_s *) manager;
989         LocationSatellite *sat = NULL;
990         int ret = location_get_satellite (handle->object, &sat);
991         if (ret != LOCATION_ERROR_NONE || sat == NULL) {
992                 if (ret == LOCATION_ERROR_NOT_SUPPORTED) {
993                         LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
994                              LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
995                         return LOCATIONS_ERROR_INCORRECT_METHOD;
996                 }
997
998                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",
999                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
1000                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
1001         }
1002
1003         *num_of_active = sat->num_of_sat_used;
1004         *num_of_inview = sat->num_of_sat_inview;
1005         *timestamp = sat->timestamp;
1006         location_satellite_free(sat);
1007         sat = NULL;
1008         return LOCATIONS_ERROR_NONE;
1009 }
1010
1011 EXPORT_API int gps_status_set_satellite_updated_cb(location_manager_h manager, gps_status_satellite_updated_cb callback, int interval, void *user_data)
1012 {
1013         LOCATIONS_CHECK_CONDITION(interval >= 1
1014                                   && interval <= 120, LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
1015         LOCATIONS_NULL_ARG_CHECK(manager);
1016         location_manager_s *handle = (location_manager_s *) manager;
1017         g_object_set(handle->object, "sat-interval", interval, NULL);
1018         return __set_callback(_LOCATIONS_EVENT_TYPE_SATELLITE, manager, callback, user_data);
1019 }
1020
1021 EXPORT_API int gps_status_unset_satellite_updated_cb(location_manager_h manager)
1022 {
1023         return __unset_callback(_LOCATIONS_EVENT_TYPE_SATELLITE, manager);
1024 }
1025
1026
1027 EXPORT_API int gps_status_foreach_satellites_in_view(location_manager_h manager, gps_status_get_satellites_cb callback, void *user_data)
1028 {
1029         LOCATIONS_NULL_ARG_CHECK(manager);
1030         LOCATIONS_NULL_ARG_CHECK(callback);
1031         location_manager_s *handle = (location_manager_s *) manager;
1032         LocationSatellite *sat = NULL;
1033         int ret = location_get_satellite (handle->object, &sat);
1034         if (ret != LOCATION_ERROR_NONE || sat == NULL) {
1035                 if (ret == LOCATION_ERROR_NOT_SUPPORTED) {
1036                         LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
1037                              LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
1038                         return LOCATIONS_ERROR_INCORRECT_METHOD;
1039                 }
1040
1041                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",
1042                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
1043                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
1044         }
1045
1046         int i;
1047         for (i = 0; i < sat->num_of_sat_inview; i++) {
1048                 guint prn;
1049                 gboolean used;
1050                 guint elevation;
1051                 guint azimuth;
1052                 gint snr;
1053                 location_satellite_get_satellite_details(sat, i, &prn, &used, &elevation, &azimuth, &snr);
1054                 if (callback(azimuth, elevation, prn, snr, used, user_data) != TRUE)
1055                         break;
1056         }
1057         location_satellite_free(sat);
1058         sat = NULL;
1059         return LOCATIONS_ERROR_NONE;
1060 }
1061
1062 EXPORT_API int gps_status_get_last_satellite(location_manager_h manager, int *num_of_active, int *num_of_inview, time_t *timestamp)
1063 {
1064         LOCATIONS_NULL_ARG_CHECK(manager);
1065         LOCATIONS_NULL_ARG_CHECK(num_of_active);
1066         LOCATIONS_NULL_ARG_CHECK(num_of_inview);
1067         LOCATIONS_NULL_ARG_CHECK(timestamp);
1068         location_manager_s *handle = (location_manager_s *) manager;
1069         int ret = LOCATION_ERROR_NONE;
1070         LocationSatellite *last_sat = NULL;
1071         ret = location_get_last_satellite(handle->object, &last_sat);
1072         if (ret != LOCATION_ERROR_NONE || last_sat == NULL) {
1073                 if (ret == LOCATION_ERROR_NOT_SUPPORTED) {
1074                         LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
1075                              LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
1076                         return LOCATIONS_ERROR_INCORRECT_METHOD;
1077                 }
1078
1079                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",
1080                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
1081                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
1082         }
1083
1084         *num_of_active = last_sat->num_of_sat_used;
1085         *num_of_inview = last_sat->num_of_sat_inview;
1086         *timestamp = last_sat->timestamp;
1087         location_satellite_free(last_sat);
1088         return LOCATIONS_ERROR_NONE;
1089 }
1090
1091 EXPORT_API int gps_status_foreach_last_satellites_in_view(location_manager_h manager, gps_status_get_satellites_cb callback,
1092                                                void *user_data)
1093 {
1094         LOCATIONS_NULL_ARG_CHECK(manager);
1095         LOCATIONS_NULL_ARG_CHECK(callback);
1096         location_manager_s *handle = (location_manager_s *) manager;
1097         int ret;
1098         LocationSatellite *last_sat = NULL;
1099         ret = location_get_last_satellite(handle->object, &last_sat);
1100         if (ret != LOCATION_ERROR_NONE || last_sat == NULL) {
1101                 if (ret == LOCATION_ERROR_NOT_SUPPORTED) {
1102                         LOCATIONS_LOGE("LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d",
1103                              LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
1104                         return LOCATIONS_ERROR_INCORRECT_METHOD;
1105                 }
1106
1107                 LOCATIONS_LOGE("LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",
1108                      LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
1109                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
1110         }
1111
1112         int i;
1113         for (i = 0; i < last_sat->num_of_sat_inview; i++) {
1114                 guint prn;
1115                 gboolean used;
1116                 guint elevation;
1117                 guint azimuth;
1118                 gint snr;
1119                 location_satellite_get_satellite_details(last_sat, i, &prn, &used, &elevation, &azimuth, &snr);
1120                 if (callback(azimuth, elevation, prn, snr, used, user_data) != TRUE) {
1121                         break;
1122                 }
1123         }
1124         location_satellite_free(last_sat);
1125         return LOCATIONS_ERROR_NONE;
1126 }