Use 'static' to local function which is limited to the current source file.
[framework/api/location-manager.git] / src / locations.c
1 /*
2 * Copyright (c) 2011 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 <dlog.h>
22
23 #ifdef LOG_TAG
24 #undef LOG_TAG
25 #endif
26 #define LOG_TAG "TIZEN_N_LOCATION_MANAGER"
27
28 /*
29 * Internal Macros
30 */
31 #define LOCATIONS_CHECK_CONDITION(condition,error,msg)  \
32                 if(condition) {} else \
33                 { LOGE("[%s] %s(0x%08x)",__FUNCTION__, msg,error); return error;}; \
34
35 #define LOCATIONS_NULL_ARG_CHECK(arg)   \
36         LOCATIONS_CHECK_CONDITION(arg != NULL,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER")
37
38
39 /*
40 * Internal Implementation
41 */
42
43 static int __convert_error_code(int code,char *func_name)
44 {
45         int ret;
46         char* msg = "LOCATIONS_ERROR_NONE";
47         switch(code)
48         {
49                 case LOCATION_ERROR_NONE:
50                         ret = LOCATIONS_ERROR_NONE;
51                         msg = "LOCATIONS_ERROR_NONE";
52                         break;
53                 case LOCATION_ERROR_NETWORK_FAILED:
54                 case LOCATION_ERROR_NETWORK_NOT_CONNECTED:
55                         ret = LOCATIONS_ERROR_NETWORK_FAILED;
56                         msg = "LOCATIONS_ERROR_NETWORK_FAILED";
57                         break;
58                 case LOCATION_ERROR_NOT_ALLOWED:
59                         ret = LOCATIONS_ERROR_GPS_SETTING_OFF;
60                         msg = "LOCATIONS_ERROR_GPS_SETTING_OFF";
61                         break;
62                 case  LOCATION_ERROR_NOT_AVAILABLE:
63                 case LOCATION_ERROR_CONFIGURATION:
64                 case LOCATION_ERROR_PARAMETER:
65                 case  LOCATION_ERROR_UNKNOWN:
66                 default:
67                         msg = "LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE";
68                         ret = LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;    
69         }
70         LOGE("[%s] %s(0x%08x) : core fw error(0x%x)",func_name,msg, ret, code);
71         return ret;     
72 }
73
74 static void __cb_service_updated (GObject *self,  guint type, gpointer data, gpointer accuracy, gpointer userdata)
75 {
76         LOGI("[%s] Callback function has been invoked. ",__FUNCTION__);
77         location_manager_s * handle = (location_manager_s*)userdata;
78         if( type == VELOCITY_UPDATED && handle->user_cb[_LOCATIONS_EVENT_TYPE_VELOCITY])
79         {
80                 LocationVelocity *vel = (LocationVelocity*) data;
81                 LOGI("[%s] Current velocity: timestamp : %d, speed: %f, direction : %f, climb : %f",  __FUNCTION__ ,    vel->timestamp, vel->speed,     vel->direction, vel->climb);
82                 ((location_velocity_updated_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_VELOCITY])(vel->speed, vel->direction,vel->climb, vel->timestamp ,handle->user_data[_LOCATIONS_EVENT_TYPE_VELOCITY]);
83         }
84         if( type == POSITION_UPDATED && handle->user_cb[_LOCATIONS_EVENT_TYPE_POSITION])
85         {
86                 LocationPosition *pos = (LocationPosition*) data;
87                 LOGI("[%s] Current position: timestamp : %d, latitude : %f, altitude: %f, longitude: %f",  __FUNCTION__ ,        pos->timestamp, pos->latitude, pos->altitude,  pos->longitude);
88                 ((location_position_updated_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_POSITION])(pos->latitude, pos->longitude,pos->altitude, pos->timestamp ,handle->user_data[_LOCATIONS_EVENT_TYPE_POSITION]);
89         }
90 }
91
92 static void __cb_service_enabled (GObject *self, guint status, gpointer userdata)
93 {
94         LOGI("[%s] Callback function has been invoked. ",__FUNCTION__);
95         location_manager_s * handle = (location_manager_s*)userdata;
96         if(handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE])
97         {
98                 ((location_service_state_changed_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE])(LOCATIONS_SERVICE_ENABLED,handle->user_data[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]);
99         }
100 }
101
102 static void __cb_service_disabled (GObject *self, guint status, gpointer userdata)
103 {
104         LOGI("[%s] Callback function has been invoked. ",__FUNCTION__);
105         location_manager_s * handle = (location_manager_s*)userdata;
106         if( handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE] )
107                 ((location_service_state_changed_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_SERVICE_STATE])(LOCATIONS_SERVICE_DISABLED,handle->user_data[_LOCATIONS_EVENT_TYPE_SERVICE_STATE]);
108 }
109
110 static void __cb_zone_in (GObject *self, guint type, gpointer position, gpointer accuracy, gpointer userdata)
111 {
112         location_manager_s * handle = (location_manager_s*)userdata;
113         if( handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY] )
114         {
115                 LocationPosition *pos = (LocationPosition*) position;
116                 ((location_zone_changed_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY])(LOCATIONS_BOUNDARY_IN,      pos->latitude,pos->longitude,pos->altitude, pos->timestamp ,handle->user_data[_LOCATIONS_EVENT_TYPE_BOUNDARY]); 
117         }
118 }
119
120 static void __cb_zone_out (GObject *self, guint type, gpointer position, gpointer accuracy, gpointer userdata)
121 {
122         location_manager_s * handle = (location_manager_s*)userdata;
123         if( handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY] )
124         {
125                 LocationPosition *pos = (LocationPosition*) position;
126                 ((location_zone_changed_cb)handle->user_cb[_LOCATIONS_EVENT_TYPE_BOUNDARY])(LOCATIONS_BOUNDARY_OUT,     pos->latitude,pos->longitude,pos->altitude, pos->timestamp ,handle->user_data[_LOCATIONS_EVENT_TYPE_BOUNDARY]); 
127         }
128 }
129
130 static int __set_callback(_location_event_e type, location_manager_h manager, void* callback, void *user_data)
131 {
132         LOCATIONS_NULL_ARG_CHECK(manager);
133         LOCATIONS_NULL_ARG_CHECK(callback);
134         location_manager_s * handle = (location_manager_s *) manager; 
135         handle->user_cb[type] = callback;
136         handle->user_data[type] = user_data;
137         LOGI("[%s] event type : %d. ",__FUNCTION__, type);
138         return LOCATIONS_ERROR_NONE; 
139 }
140
141 static int __unset_callback(_location_event_e type, location_manager_h manager)
142 {
143         LOCATIONS_NULL_ARG_CHECK(manager);
144         location_manager_s * handle = (location_manager_s *) manager; 
145         handle->user_cb[type] = NULL;
146         handle->user_data[type] = NULL;
147         LOGI("[%s] event type : %d. ",__FUNCTION__, type);
148         return LOCATIONS_ERROR_NONE; 
149 }
150
151 static void  __remove_boundary(LocationBoundary *boundary, void *user_data)
152 {
153         LocationObject* loc = (LocationObject*) user_data;
154         if (loc != NULL && boundary != NULL) 
155         {
156                 int ret = location_boundary_remove(loc, boundary);
157                 if(ret != LOCATION_ERROR_NONE)
158                 {
159                         LOGI("[%s] Failed to remove boundary : 0x%x. ",__FUNCTION__, ret);
160                 }
161                 else
162                 {
163                         LOGI("[%s] Delete previous boundary - type : %d ",__FUNCTION__, boundary->type);
164                 }
165         }
166 }
167
168 /////////////////////////////////////////
169 // Location Manager
170 ////////////////////////////////////////
171
172 /*
173 * Public Implementation
174 */
175
176 bool location_manager_is_supported_method(location_method_e method)
177 {
178         LocationMethod _method = LOCATION_METHOD_NONE;
179         switch(method)
180         {
181                 case LOCATIONS_METHOD_HYBRID :
182                         _method = LOCATION_METHOD_HYBRID;
183                         break;
184                 case LOCATIONS_METHOD_GPS:
185                         _method = LOCATION_METHOD_GPS;
186                         break;
187                 case LOCATIONS_METHOD_WPS :
188                         _method = LOCATION_METHOD_WPS;
189                         break;
190                 case LOCATIONS_METHOD_SPS :
191                         _method = LOCATION_METHOD_SPS;
192                         break;
193                 default :
194                         _method = LOCATION_METHOD_NONE;
195                         break;
196                 }
197         return location_is_supported_method(_method);
198 }
199
200 int     location_manager_create(location_method_e method, location_manager_h* manager)
201 {
202         LOCATIONS_NULL_ARG_CHECK(manager);
203         if(location_init()!=LOCATION_ERROR_NONE)
204                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
205
206         LocationMethod _method = LOCATION_METHOD_NONE;
207         switch(method)
208         {
209                 case LOCATIONS_METHOD_NONE :
210                         _method = LOCATION_METHOD_NONE;
211                         break;
212                 case LOCATIONS_METHOD_HYBRID :
213                         _method = LOCATION_METHOD_HYBRID;
214                         break;
215                 case LOCATIONS_METHOD_GPS:
216                         _method = LOCATION_METHOD_GPS;
217                         break;
218                 case LOCATIONS_METHOD_WPS :
219                         _method = LOCATION_METHOD_WPS;
220                         break;
221                 case LOCATIONS_METHOD_SPS :
222                         _method = LOCATION_METHOD_SPS;
223                         break;
224                 default :
225                 {
226                         LOGE("[%s] LOCATIONS_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (location_method_e) - method : %d ",__FUNCTION__,LOCATIONS_ERROR_INVALID_PARAMETER, method);
227                         return LOCATIONS_ERROR_INVALID_PARAMETER;
228                 }
229         }
230
231         location_manager_s *handle = (location_manager_s*)malloc(sizeof(location_manager_s));
232         if(handle==NULL)
233         {
234                 LOGE("[%s] OUT_OF_MEMORY(0x%08x)", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
235                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
236         }
237
238         memset(handle, 0 , sizeof(location_manager_s));
239         
240         handle->object = location_new(_method);
241         if(handle->object  == NULL)
242         {
243                 LOGE("[%s] LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : fail to location_new", __FUNCTION__, LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
244                 free(handle);
245                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
246         }
247         handle->method = method;
248         handle->boundary= NULL;
249         *manager = (location_manager_h)handle;
250         return LOCATIONS_ERROR_NONE;
251 }
252
253 int     location_manager_destroy(location_manager_h manager)
254 {
255         LOCATIONS_NULL_ARG_CHECK(manager);
256         location_manager_s *handle = (location_manager_s*)manager;
257
258         if(handle->boundary)
259         {
260                 location_boundary_free(handle->boundary);
261         }
262                 
263         int ret = location_free(handle->object);
264         if(ret!=LOCATIONS_ERROR_NONE)
265         {
266                 return __convert_error_code(ret,(char*)__FUNCTION__);
267         }
268         free(handle);
269         return LOCATIONS_ERROR_NONE;
270 }
271
272 int     location_manager_start(location_manager_h manager)
273 {
274         LOCATIONS_NULL_ARG_CHECK(manager);
275         location_manager_s *handle = (location_manager_s*)manager;
276                 
277         g_signal_connect (handle->object, "service-enabled", G_CALLBACK(__cb_service_enabled), handle);
278         g_signal_connect (handle->object, "service-disabled", G_CALLBACK(__cb_service_disabled), handle);
279         g_signal_connect (handle->object, "service-updated", G_CALLBACK(__cb_service_updated), handle);
280         g_signal_connect (handle->object, "zone-in", G_CALLBACK(__cb_zone_in), handle);
281         g_signal_connect (handle->object, "zone-out", G_CALLBACK(__cb_zone_out), handle);
282         
283         int ret = location_start (handle->object);
284         if( ret != LOCATION_ERROR_NONE)
285         {
286                 return __convert_error_code(ret,(char*)__FUNCTION__);
287         }
288         return LOCATIONS_ERROR_NONE;
289 }
290
291 int     location_manager_stop(location_manager_h manager)
292 {
293         LOCATIONS_NULL_ARG_CHECK(manager);
294         location_manager_s *handle = (location_manager_s*)manager;
295                 
296         int ret = location_stop (handle->object);
297         if( ret != LOCATION_ERROR_NONE)
298         {
299                 return __convert_error_code(ret,(char*)__FUNCTION__);
300         }
301         return LOCATIONS_ERROR_NONE;
302 }
303
304 int     location_manager_set_boundary_rect(location_manager_h manager, double top_left_latitude,double top_left_longitude,double bottom_right_latitude,double bottom_right_longitude)
305 {
306         LOCATIONS_NULL_ARG_CHECK(manager);
307         LOCATIONS_CHECK_CONDITION(top_left_latitude>=-90 && top_left_latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
308         LOCATIONS_CHECK_CONDITION(top_left_longitude>=-180 && bottom_right_longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
309         LOCATIONS_CHECK_CONDITION(bottom_right_latitude>=-90 && bottom_right_latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
310         LOCATIONS_CHECK_CONDITION(bottom_right_longitude>=-180 && bottom_right_longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER, "LOCATIONS_ERROR_INVALID_PARAMETER");
311
312         location_manager_s *handle = (location_manager_s*)manager;
313
314         int ret;
315         ret = location_boundary_foreach(handle->object, __remove_boundary,handle->object );
316         if(ret != LOCATION_ERROR_NONE)
317         {
318                 LOGI("[%s] Failed to foreach boundary : 0x%x. ",__FUNCTION__, ret);
319         }
320
321         LocationPosition *rb = location_position_new(0, bottom_right_latitude, bottom_right_longitude, 0, LOCATION_STATUS_2D_FIX);
322         if (rb ==NULL)
323         {
324                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
325                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
326         }
327         LocationPosition *lt = location_position_new(0, top_left_latitude, top_left_longitude, 0, LOCATION_STATUS_2D_FIX);
328         if (lt ==NULL)
329         {
330                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
331                 location_position_free (rb);
332                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
333         }
334
335         LocationBoundary* bound = NULL;
336         bound = location_boundary_new_for_rect(lt, rb);
337         location_position_free (rb);
338         location_position_free (lt);
339         
340         if(bound)
341         {
342                 ret = location_boundary_add(handle->object, bound);
343                 if(handle->boundary)
344                 {
345                         location_boundary_free(handle->boundary);
346                         handle->boundary = NULL;
347                 }
348                 handle->boundary = location_boundary_copy(bound);
349                 location_boundary_free(bound);
350                 if( ret != LOCATION_ERROR_NONE)
351                 {
352                         return __convert_error_code(ret,(char*)__FUNCTION__);
353                 }
354         }
355         else
356         {
357                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_rect", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
358                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
359         }
360         return LOCATIONS_ERROR_NONE;
361 }
362
363 int     location_manager_set_boundary_circle(location_manager_h manager, double center_latitude,double center_longitude, double radius)
364 {
365         LOCATIONS_NULL_ARG_CHECK(manager);
366         
367         LOCATIONS_CHECK_CONDITION(center_latitude>=-90 && center_latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
368         LOCATIONS_CHECK_CONDITION(center_longitude>=-180 && center_longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
369         LOCATIONS_CHECK_CONDITION(radius>=0,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
370
371         location_manager_s *handle = (location_manager_s*)manager;      
372
373         int ret;
374         ret = location_boundary_foreach(handle->object, __remove_boundary, handle->object);
375         if(ret != LOCATION_ERROR_NONE)
376         {
377                 LOGI("[%s] Failed to foreach boundary : 0x%x. ",__FUNCTION__, ret);
378         }
379
380         LocationPosition *center = location_position_new(0, center_latitude, center_longitude, 0, LOCATION_STATUS_2D_FIX);
381         if (center ==NULL)
382         {
383                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
384                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
385         }
386
387         LocationBoundary* bound = NULL;
388         bound = location_boundary_new_for_circle(center,radius);
389         location_position_free (center);
390         if(bound)
391         {
392                 ret = location_boundary_add(handle->object, bound);
393                 if(handle->boundary)
394                 {
395                         location_boundary_free(handle->boundary);
396                         handle->boundary = NULL;
397                 }
398                 handle->boundary = location_boundary_copy(bound);
399                 location_boundary_free(bound);
400                 if( ret != LOCATION_ERROR_NONE)
401                 {
402                         return __convert_error_code(ret,(char*)__FUNCTION__);
403                 }
404         }
405         else
406         {
407                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_circle", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
408                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
409         }
410         return LOCATIONS_ERROR_NONE;
411 }
412
413 int location_manager_is_boundary_contains_coordinate(location_manager_h manager, double latitude, double longitude, bool *contained)
414 {
415         LOCATIONS_NULL_ARG_CHECK(manager);
416         LOCATIONS_NULL_ARG_CHECK(contained);
417         
418         LOCATIONS_CHECK_CONDITION(latitude>=-90 && latitude<=90,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
419         LOCATIONS_CHECK_CONDITION(longitude>=-180 && longitude<=180,LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
420
421         location_manager_s *handle = (location_manager_s*)manager;      
422
423         if(handle->boundary==NULL)
424         {
425                 LOGI("[%s] There is no boundary ",__FUNCTION__);
426                 *contained = FALSE;
427                 return LOCATIONS_ERROR_NONE;
428         }
429
430         LocationPosition *pos = location_position_new(0, latitude, longitude, 0, LOCATION_STATUS_2D_FIX);
431         if (pos ==NULL)
432         {
433                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", __FUNCTION__, LOCATIONS_ERROR_OUT_OF_MEMORY);
434                 *contained = FALSE;
435                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
436         }
437         gboolean is_inside = location_boundary_if_inside(handle->boundary, pos);
438         
439         if(is_inside)
440         {
441                 *contained = TRUE;
442         }
443         else
444         {
445                 *contained = FALSE;
446         }
447         location_position_free (pos);
448         return LOCATIONS_ERROR_NONE;
449 }
450
451 int     location_manager_get_method(location_manager_h manager, location_method_e* method)
452 {
453         LOCATIONS_NULL_ARG_CHECK(manager);
454         LOCATIONS_NULL_ARG_CHECK(method);
455         location_manager_s *handle = (location_manager_s*)manager;
456         LocationMethod _method = LOCATION_METHOD_NONE;  
457         g_object_get(handle->object, "method", &_method, NULL);
458         switch(_method)
459         {
460                 case LOCATION_METHOD_NONE :
461                         *method = LOCATIONS_METHOD_NONE;
462                         break;
463                 case LOCATION_METHOD_HYBRID :
464                 case LOCATION_METHOD_CPS:
465                 case LOCATION_METHOD_IPS :
466                         *method = LOCATIONS_METHOD_HYBRID;
467                         break;
468                 case LOCATION_METHOD_GPS:
469                         *method = LOCATIONS_METHOD_GPS;
470                         break;
471                 case LOCATION_METHOD_WPS :
472                         *method = LOCATIONS_METHOD_WPS;
473                         break;
474                 case LOCATION_METHOD_SPS :
475                         *method = LOCATIONS_METHOD_SPS;
476                         break;
477                 default :
478                 {
479                         LOGE("[%s] LOCATIONS_ERROR_INVALID_PARAMETER(0x%08x) : Out of range (location_method_e) - method : %d ",__FUNCTION__,LOCATIONS_ERROR_INVALID_PARAMETER, method);
480                         return LOCATIONS_ERROR_INVALID_PARAMETER;
481                 }
482         }
483         //*method = handle->method;
484         return LOCATIONS_ERROR_NONE;
485 }
486
487
488 int     location_manager_get_position(location_manager_h manager, double *altitude, double *latitude, double *longitude, time_t *timestamp)
489 {
490         LOCATIONS_NULL_ARG_CHECK(manager);
491         LOCATIONS_NULL_ARG_CHECK(altitude);
492         LOCATIONS_NULL_ARG_CHECK(latitude);
493         LOCATIONS_NULL_ARG_CHECK(longitude);
494         LOCATIONS_NULL_ARG_CHECK(timestamp);
495
496         location_manager_s *handle = (location_manager_s*)manager;
497         int ret;
498         LocationPosition *pos = NULL;
499         LocationAccuracy *acc = NULL;
500         ret = location_get_position(handle->object, &pos, &acc);
501         if( ret != LOCATION_ERROR_NONE)
502         {
503                 return __convert_error_code(ret,(char*)__FUNCTION__);
504         }
505
506         if(pos->status == LOCATION_STATUS_NO_FIX)
507         {
508                 *altitude = -1;
509                 *latitude = -1;
510                 *longitude =-1;
511         }
512         else
513         {
514                 if(pos->status == LOCATION_STATUS_3D_FIX)
515                 {
516                         *altitude = pos->altitude;
517                 }
518                 else
519                 {
520                         *altitude = -1;
521                 }
522                 *latitude = pos->latitude;
523                 *longitude = pos->longitude;
524         }
525         *timestamp = pos->timestamp;
526         location_position_free (pos);
527         location_accuracy_free (acc);
528         return LOCATIONS_ERROR_NONE;
529 }
530
531 int     location_manager_get_velocity(location_manager_h manager, int *climb, int *direction, int *speed, time_t *timestamp)
532 {
533         LOCATIONS_NULL_ARG_CHECK(manager);
534         LOCATIONS_NULL_ARG_CHECK(climb);
535         LOCATIONS_NULL_ARG_CHECK(direction);
536         LOCATIONS_NULL_ARG_CHECK(speed);
537         LOCATIONS_NULL_ARG_CHECK(timestamp);
538
539         location_manager_s *handle = (location_manager_s*)manager;
540         int ret;
541         LocationVelocity *vel = NULL;
542         LocationAccuracy *acc = NULL;
543         ret = location_get_velocity(handle->object, &vel, &acc);
544         if( ret != LOCATION_ERROR_NONE)
545         {
546                 return __convert_error_code(ret,(char*)__FUNCTION__);
547         }
548
549         *climb = vel->climb;
550         *direction = vel->direction;
551         *speed = vel->speed;
552         *timestamp = vel->timestamp;
553         location_velocity_free(vel);
554         location_accuracy_free(acc);
555         return LOCATIONS_ERROR_NONE;
556 }
557
558 int     location_manager_get_accuracy(location_manager_h manager, location_accuracy_level_e *level, double *horizontal, double *vertical)
559 {
560         LOCATIONS_NULL_ARG_CHECK(manager);
561         LOCATIONS_NULL_ARG_CHECK(level);
562         LOCATIONS_NULL_ARG_CHECK(horizontal);
563         LOCATIONS_NULL_ARG_CHECK(vertical);
564         location_manager_s *handle = (location_manager_s*)manager;
565
566         int ret;
567         LocationPosition *pos = NULL;
568         LocationAccuracy *acc = NULL;
569         ret = location_get_position(handle->object, &pos, &acc);
570         if( ret != LOCATION_ERROR_NONE)
571         {
572                 return __convert_error_code(ret,(char*)__FUNCTION__);
573         }
574         
575         *level = acc->level;
576         *horizontal = acc->horizontal_accuracy; 
577         *vertical = acc->vertical_accuracy;
578         location_position_free(pos);
579         location_accuracy_free(acc);
580         return LOCATIONS_ERROR_NONE;                    
581 }
582
583 int location_manager_get_last_known_position(location_manager_h manager, double *altitude, double *latitude, double *longitude, time_t *timestamp)
584 {
585         LOCATIONS_NULL_ARG_CHECK(manager);
586         LOCATIONS_NULL_ARG_CHECK(altitude);
587         LOCATIONS_NULL_ARG_CHECK(latitude);
588         LOCATIONS_NULL_ARG_CHECK(longitude);
589         LOCATIONS_NULL_ARG_CHECK(timestamp);
590
591         location_manager_s *handle = (location_manager_s*)manager;
592
593         LocationMethod _method = LOCATION_METHOD_NONE;  
594         g_object_get(handle->object, "method", &_method, NULL);
595         
596         int ret;
597         LocationPosition *pos = NULL;
598         LocationAccuracy *acc = NULL;
599         ret = location_get_last_position(handle->object, _method, &pos,&acc);
600         if (ret == LOCATION_ERROR_UNKNOWN)
601         {
602                 *altitude = 0;
603                 *latitude = 0;
604                 *longitude =0;
605                 *timestamp = 0;
606                 LOGI("[%s] There is no record of any previous position information. ",__FUNCTION__);
607                 return LOCATIONS_ERROR_NONE;
608         }       
609         else if( ret != LOCATION_ERROR_NONE)
610         {
611                 return __convert_error_code(ret,(char*)__FUNCTION__);
612         }
613         
614         *altitude = pos->altitude;
615         *latitude = pos->latitude;
616         *longitude = pos->longitude;
617         *timestamp = pos->timestamp;
618         location_position_free(pos);
619         location_accuracy_free(acc);
620         return LOCATIONS_ERROR_NONE;
621 }
622
623 int     location_manager_set_position_updated_cb(location_manager_h manager, location_position_updated_cb callback, int interval, void *user_data)
624 {
625         LOCATIONS_CHECK_CONDITION(interval>=1 && interval<=120, LOCATIONS_ERROR_INVALID_PARAMETER,"LOCATIONS_ERROR_INVALID_PARAMETER");
626         LOCATIONS_NULL_ARG_CHECK(manager);
627         location_manager_s *handle = (location_manager_s*)manager;
628         g_object_set(handle->object, "update-interval", interval, NULL);
629         return __set_callback(_LOCATIONS_EVENT_TYPE_POSITION,manager,callback,user_data);
630 }
631
632 int     location_manager_unset_position_updated_cb(location_manager_h manager)
633 {
634         return __unset_callback(_LOCATIONS_EVENT_TYPE_POSITION,manager);
635 }
636
637 int     location_manager_set_velocity_updated_cb(location_manager_h manager, location_velocity_updated_cb callback, void *user_data)
638 {
639         return __set_callback(_LOCATIONS_EVENT_TYPE_VELOCITY,manager,callback,user_data);
640 }
641
642 int     location_manager_unset_velocity_updated_cb(location_manager_h manager)
643 {
644         return __unset_callback(_LOCATIONS_EVENT_TYPE_VELOCITY,manager);
645 }
646
647 int     location_manager_set_service_state_changed_cb(location_manager_h manager, location_service_state_changed_cb callback, void *user_data)
648 {
649         return __set_callback(_LOCATIONS_EVENT_TYPE_SERVICE_STATE,manager,callback,user_data);
650 }
651
652 int     location_manager_unset_service_state_changed_cb(location_manager_h manager)
653 {
654         return __unset_callback(_LOCATIONS_EVENT_TYPE_SERVICE_STATE,manager);
655 }
656
657 int     location_manager_set_zone_changed_cb(location_manager_h manager, location_zone_changed_cb callback, void *user_data)
658 {
659         return __set_callback(_LOCATIONS_EVENT_TYPE_BOUNDARY,manager,callback,user_data);
660 }
661
662 int     location_manager_unset_zone_changed_cb(location_manager_h manager)
663 {
664         return __unset_callback(_LOCATIONS_EVENT_TYPE_BOUNDARY,manager);
665 }
666
667 /////////////////////////////////////////
668 // GPS Status & Satellites
669 ////////////////////////////////////////
670
671 int     gps_status_get_nmea(location_manager_h manager, char** nmea)
672 {
673         LOCATIONS_NULL_ARG_CHECK(manager);
674         LOCATIONS_NULL_ARG_CHECK(nmea);
675         location_manager_s *handle = (location_manager_s*)manager;
676
677         if(handle->method == LOCATIONS_METHOD_HYBRID)
678         {
679                 LocationMethod _method = LOCATION_METHOD_NONE;  
680                 g_object_get(handle->object, "method", &_method, NULL);
681                 if(_method!=LOCATION_METHOD_GPS)
682                 {
683                         LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
684                         return LOCATIONS_ERROR_INCORRECT_METHOD;
685                 }       
686         }
687         else if(handle->method != LOCATIONS_METHOD_GPS)
688         {
689                 LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
690                 return LOCATIONS_ERROR_INCORRECT_METHOD;
691         }
692         gchar* nmea_data = NULL;
693         g_object_get(handle->object, "nmea", &nmea_data, NULL); 
694         if(nmea_data == NULL)
695         {
696                 LOGE("[%s] LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : nmea data is NULL ",__FUNCTION__,LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
697                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
698         }       
699         *nmea = NULL;
700         *nmea = strdup(nmea_data);
701         if(*nmea == NULL)
702         {
703                 LOGE("[%s] LOCATIONS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to strdup ",__FUNCTION__,LOCATIONS_ERROR_OUT_OF_MEMORY);
704                 return LOCATIONS_ERROR_OUT_OF_MEMORY;
705         }
706         g_free(nmea_data);
707         return LOCATIONS_ERROR_NONE;
708 }
709
710 int  gps_status_get_satellite_count_in_view(location_manager_h manager, int *count)
711 {
712         LOCATIONS_NULL_ARG_CHECK(manager);
713         LOCATIONS_NULL_ARG_CHECK(count);
714         location_manager_s *handle = (location_manager_s*)manager;
715         if(handle->method == LOCATIONS_METHOD_HYBRID)
716         {
717                 LocationMethod _method = LOCATION_METHOD_NONE;  
718                 g_object_get(handle->object, "method", &_method, NULL);
719                 if(_method!=LOCATION_METHOD_GPS)
720                 {
721                         LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
722                         return LOCATIONS_ERROR_INCORRECT_METHOD;
723                 }       
724         }
725         else if(handle->method != LOCATIONS_METHOD_GPS)
726         {
727                 LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
728                 return LOCATIONS_ERROR_INCORRECT_METHOD;
729         }
730         
731         LocationSatellite *sat = NULL;
732         g_object_get (handle->object, "satellite", &sat, NULL);
733         if (sat == NULL) 
734         {
735                 LOGE("[%s] LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",__FUNCTION__,LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
736                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
737         }
738         *count = sat->num_of_sat_inview;
739         location_satellite_free (sat);
740         sat = NULL;
741         return LOCATIONS_ERROR_NONE;
742 }
743
744 int  gps_status_foreach_satellites_in_view (location_manager_h manager, gps_status_get_satellites_cb callback, void *user_data)
745 {
746         LOCATIONS_NULL_ARG_CHECK(manager);
747         LOCATIONS_NULL_ARG_CHECK(callback);
748         location_manager_s *handle = (location_manager_s*)manager;
749         if(handle->method == LOCATIONS_METHOD_HYBRID)
750         {
751                 LocationMethod _method = LOCATION_METHOD_NONE;  
752                 g_object_get(handle->object, "method", &_method, NULL);
753                 if(_method!=LOCATION_METHOD_GPS)
754                 {
755                         LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
756                         return LOCATIONS_ERROR_INCORRECT_METHOD;
757                 }       
758         }
759         else if(handle->method != LOCATIONS_METHOD_GPS)
760         {
761                 LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
762                 return LOCATIONS_ERROR_INCORRECT_METHOD;
763         }
764         
765         LocationSatellite *sat = NULL;
766         g_object_get (handle->object, "satellite", &sat, NULL);
767         if (sat == NULL) 
768         {
769                 LOGE("[%s] LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",__FUNCTION__,LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
770                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
771         }
772
773         int i;
774         for (i=0; i<sat->num_of_sat_inview; i++) 
775         {
776                 guint prn;
777                 gboolean used;
778                 guint elevation;
779                 guint azimuth;
780                 gint snr;
781                 location_satellite_get_satellite_details(sat, i, &prn, &used, &elevation, &azimuth, &snr);
782                 if ( callback(azimuth, elevation, prn, snr, used, user_data) != TRUE )
783                         break;
784         }
785         location_satellite_free (sat);  
786         sat = NULL;
787         return LOCATIONS_ERROR_NONE;
788 }
789
790 int  gps_status_get_active_satellite_count(location_manager_h manager, int *count)
791 {
792         LOCATIONS_NULL_ARG_CHECK(manager);
793         LOCATIONS_NULL_ARG_CHECK(count);
794         location_manager_s *handle = (location_manager_s*)manager;
795         if(handle->method == LOCATIONS_METHOD_HYBRID)
796         {
797                 LocationMethod _method = LOCATION_METHOD_NONE;  
798                 g_object_get(handle->object, "method", &_method, NULL);
799                 if(_method!=LOCATION_METHOD_GPS)
800                 {
801                         LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
802                         return LOCATIONS_ERROR_INCORRECT_METHOD;
803                 }       
804         }
805         else if(handle->method != LOCATIONS_METHOD_GPS)
806         {
807                 LOGE("[%s] LOCATIONS_ERROR_INCORRECT_METHOD(0x%08x) : method - %d", __FUNCTION__, LOCATIONS_ERROR_INCORRECT_METHOD, handle->method);
808                 return LOCATIONS_ERROR_INCORRECT_METHOD;
809         }
810         
811         LocationSatellite *sat = NULL;
812         g_object_get (handle->object, "satellite", &sat, NULL);
813         if (sat == NULL) 
814         {
815                 LOGE("[%s] LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE(0x%08x) : satellite is NULL ",__FUNCTION__,LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE);
816                 return LOCATIONS_ERROR_SERVICE_NOT_AVAILABLE;
817         }
818         *count = sat->num_of_sat_used;
819         location_satellite_free (sat);
820         sat = NULL;
821         return LOCATIONS_ERROR_NONE;
822 }