12fee81244a51af633c3b6c9d8b1eccc54e70d3f
[framework/location/libslp-location.git] / location / manager / location-gps.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "location-setting.h"
27 #include "location-log.h"
28
29 #include "module-internal.h"
30
31 #include "location-gps.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
36
37 #include <vconf-internal-location-keys.h>
38
39 typedef struct _LocationGpsPrivate {
40         LocationGpsMod*         mod;
41         gboolean                is_started;
42         gboolean                set_noti;
43         gboolean                enabled;
44         guint                   pos_updated_timestamp;
45         guint                   pos_interval;
46         guint                   vel_updated_timestamp;
47         guint                   vel_interval;
48         guint                   sat_updated_timestamp;
49         guint                   sat_interval;
50         LocationPosition*       pos;
51         LocationVelocity*       vel;
52         LocationAccuracy*       acc;
53         GList*                  boundary_list;
54         ZoneStatus              zone_status;
55         LocationSatellite*      sat;
56
57         guint                   pos_timer;
58         guint                   vel_timer;
59
60 } LocationGpsPrivate;
61
62 enum {
63         PROP_0,
64         PROP_DEV_NAME,
65         PROP_METHOD_TYPE,
66         PROP_LAST_POSITION,
67         PROP_POS_INTERVAL,
68         PROP_VEL_INTERVAL,
69         PROP_SAT_INTERVAL,
70         PROP_BOUNDARY,
71         PROP_REMOVAL_BOUNDARY,
72         PROP_NMEA,
73         PROP_SATELLITE,
74         PROP_MAX
75 };
76
77 static guint32 signals[LAST_SIGNAL] = {0, };
78 static GParamSpec *properties[PROP_MAX] = {NULL, };
79
80 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_GPS, LocationGpsPrivate))
81
82 static void location_ielement_interface_init (LocationIElementInterface *iface);
83
84 G_DEFINE_TYPE_WITH_CODE (LocationGps, location_gps, G_TYPE_OBJECT,
85                          G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
86                          location_ielement_interface_init));
87
88 static gboolean
89 _position_timeout_cb (gpointer data)
90 {
91         GObject *object = (GObject *)data;
92         LocationGpsPrivate *priv = GET_PRIVATE(object);
93         if (!priv) return FALSE;
94
95         LocationPosition *pos = NULL;
96         LocationAccuracy *acc = NULL;
97
98         if (priv->pos) {
99                 pos = location_position_copy(priv->pos);
100         }
101         else {
102                 pos = location_position_new (0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
103         }
104
105         if (priv->acc) {
106                 acc = location_accuracy_copy (priv->acc);
107         }
108         else {
109                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
110         }
111
112         LOCATION_LOGD("POSITION SERVICE_UPDATED");
113         g_signal_emit(object, signals[SERVICE_UPDATED], 0, POSITION_UPDATED, pos, acc);
114
115         location_position_free (pos);
116         location_accuracy_free (acc);
117
118         return TRUE;
119 }
120
121 static gboolean
122 _velocity_timeout_cb (gpointer data)
123 {
124         GObject *object = (GObject *)data;
125         LocationGpsPrivate *priv = GET_PRIVATE(object);
126         if (!priv) return FALSE;
127
128         LocationVelocity *vel = NULL;
129         LocationAccuracy *acc = NULL;
130
131         if (priv->vel) {
132                 vel = location_velocity_copy(priv->vel);
133         }
134         else {
135                 vel = location_velocity_new (0, 0.0, 0.0, 0.0);
136         }
137
138         if (priv->acc) {
139                 acc = location_accuracy_copy (priv->acc);
140         }
141         else {
142                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
143         }
144
145         LOCATION_LOGD("VELOCITY SERVICE_UPDATED");
146         g_signal_emit(object, signals[SERVICE_UPDATED], 0, VELOCITY_UPDATED, vel, acc);
147
148         location_velocity_free (vel);
149         location_accuracy_free (acc);
150
151         return TRUE;
152 }
153
154 static void
155 gps_status_cb (gboolean enabled,
156         LocationStatus status,
157         gpointer self)
158 {
159         LOCATION_LOGD("gps_status_cb");
160         g_return_if_fail(self);
161         LocationGpsPrivate* priv = GET_PRIVATE(self);
162         enable_signaling(self, signals, &(priv->enabled), enabled, status);
163
164         if (!priv->enabled) {
165                 if (priv->pos_timer) g_source_remove (priv->pos_timer);
166                 if (priv->vel_timer) g_source_remove (priv->vel_timer);
167                 priv->pos_timer = 0;
168                 priv->vel_timer = 0;
169         }
170 }
171
172 static void
173 gps_position_cb (gboolean enabled,
174         LocationPosition *pos,
175         LocationAccuracy *acc,
176         gpointer self)
177 {
178         LOCATION_LOGD("gps_position_cb");
179         g_return_if_fail(self);
180         g_return_if_fail(pos);
181         g_return_if_fail(acc);
182         LocationGpsPrivate* priv = GET_PRIVATE(self);
183
184         enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
185         position_signaling(self, signals, &(priv->enabled), priv->pos_interval, TRUE, &(priv->pos_updated_timestamp), &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), pos, acc);
186
187 }
188
189 static void
190 gps_velocity_cb (gboolean enabled,
191         LocationVelocity *vel,
192         LocationAccuracy *acc,
193         gpointer self)
194 {
195         LOCATION_LOGD("gps_velocity_cb");
196         g_return_if_fail(self);
197         LocationGpsPrivate* priv = GET_PRIVATE(self);
198         velocity_signaling(self, signals, &(priv->enabled), priv->vel_interval, TRUE, &(priv->vel_updated_timestamp), &(priv->vel), vel, acc);
199 }
200
201 static void
202 gps_satellite_cb (gboolean enabled,
203                 LocationSatellite *sat,
204                 gpointer self)
205 {
206         LOCATION_LOGD("gps_satellite_cb");
207         g_return_if_fail(self);
208         LocationGpsPrivate* priv = GET_PRIVATE(self);
209         satellite_signaling(self, signals, &(priv->enabled), priv->sat_interval, TRUE, &(priv->sat_updated_timestamp), &(priv->sat), sat);
210 }
211
212 static void
213 location_setting_search_cb (keynode_t *key, gpointer self)
214 {
215         LOCATION_LOGD("location_setting_search_cb");
216         g_return_if_fail(key);
217         g_return_if_fail(self);
218         LocationGpsPrivate* priv = GET_PRIVATE(self);
219         g_return_if_fail (priv->mod);
220         g_return_if_fail (priv->mod->handler);
221
222         if (location_setting_get_key_val(key) == VCONFKEY_LOCATION_GPS_SEARCHING) {
223                 if (!priv->pos_timer) priv->pos_timer = g_timeout_add (priv->pos_interval * 1000, _position_timeout_cb, self);
224                 if (!priv->vel_timer) priv->vel_timer = g_timeout_add (priv->vel_interval * 1000, _velocity_timeout_cb, self);
225         }
226         else {
227                 if (priv->pos_timer) g_source_remove (priv->pos_timer);
228                 if (priv->vel_timer) g_source_remove (priv->vel_timer);
229                 priv->pos_timer = 0;
230                 priv->vel_timer = 0;
231         }
232 }
233
234 static void
235 location_setting_gps_cb (keynode_t *key,
236         gpointer self)
237 {
238         LOCATION_LOGD("location_setting_gps_cb");
239         g_return_if_fail(key);
240         g_return_if_fail(self);
241         LocationGpsPrivate* priv = GET_PRIVATE(self);
242         g_return_if_fail (priv->mod);
243         g_return_if_fail (priv->mod->handler);
244
245         int ret = LOCATION_ERROR_NONE;
246
247         if (0 == location_setting_get_key_val(key) && priv->mod->ops.stop && priv->is_started) {
248                 LOCATION_LOGD("location stopped by setting");
249                 ret = priv->mod->ops.stop(priv->mod->handler);
250                 if (ret == LOCATION_ERROR_NONE) {
251                         priv->is_started = FALSE;
252                 }
253         }
254         else if (1 == location_setting_get_key_val(key) && priv->mod->ops.start && !priv->is_started) {
255                 LOCATION_LOGD("location resumed by setting");
256                 ret = priv->mod->ops.start (priv->mod->handler, gps_status_cb, gps_position_cb, gps_velocity_cb, gps_satellite_cb, self);
257                 if (ret == LOCATION_ERROR_NONE) {
258                         priv->is_started = TRUE;
259                 }
260         }
261 }
262
263 static int
264 location_gps_start (LocationGps *self)
265 {
266         LOCATION_LOGD("location_gps_start");
267         LocationGpsPrivate* priv = GET_PRIVATE(self);
268         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
269         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
270         g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
271
272         if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
273
274         int ret = LOCATION_ERROR_NONE;
275
276         if (!location_setting_get_int(VCONFKEY_LOCATION_ENABLED)) {
277                 ret = LOCATION_ERROR_NOT_ALLOWED;
278         }
279         else {
280                 ret = priv->mod->ops.start (priv->mod->handler, gps_status_cb, gps_position_cb, gps_velocity_cb, gps_satellite_cb, self);
281                 if (ret == LOCATION_ERROR_NONE) {
282                         priv->is_started = TRUE;
283                 }
284                 else {
285                         return ret;
286                 }
287         }
288
289         if(priv->set_noti == FALSE) {
290                 location_setting_add_notify (VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb, self);
291                 location_setting_add_notify (VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb, self);
292                 priv->set_noti = TRUE;
293         }
294
295         return ret;
296 }
297
298 static int
299 location_gps_stop (LocationGps *self)
300 {
301         LOCATION_LOGD("location_gps_stop");
302         LocationGpsPrivate* priv = GET_PRIVATE(self);
303         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
304         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
305         g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
306
307         int ret = LOCATION_ERROR_NONE;
308
309         if ( priv->is_started == TRUE) {
310                 ret = priv->mod->ops.stop (priv->mod->handler);
311                 if (ret == LOCATION_ERROR_NONE) {
312                         priv->is_started = FALSE;
313                 }
314                 else {
315                         return ret;
316                 }
317         }
318
319         if (priv->pos_timer ) g_source_remove (priv->pos_timer);
320         if (priv->vel_timer ) g_source_remove (priv->vel_timer);
321         priv->pos_timer = 0;
322         priv->vel_timer = 0;
323
324         if(priv->set_noti == TRUE) {
325                 location_setting_ignore_notify (VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb);
326                 location_setting_ignore_notify (VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb);
327                 priv->set_noti = FALSE;
328         }
329
330         return ret;
331 }
332
333 static void
334 location_gps_dispose (GObject *gobject)
335 {
336         LOCATION_LOGD("location_gps_dispose");
337
338         LocationGpsPrivate* priv = GET_PRIVATE(gobject);
339
340         if (priv->pos_timer) g_source_remove (priv->pos_timer);
341         if (priv->vel_timer) g_source_remove (priv->vel_timer);
342         priv->pos_timer = 0;
343         priv->vel_timer = 0;
344
345         if(priv->set_noti == TRUE) {
346                 location_setting_ignore_notify (VCONFKEY_LOCATION_ENABLED, location_setting_gps_cb);
347                 location_setting_ignore_notify (VCONFKEY_LOCATION_GPS_STATE, location_setting_search_cb);
348                 priv->set_noti = FALSE;
349         }
350
351 }
352
353 static void
354 location_gps_finalize (GObject *gobject)
355 {
356         LOCATION_LOGD("location_gps_finalize");
357         LocationGpsPrivate* priv = GET_PRIVATE(gobject);
358
359         module_free(priv->mod, "gps");
360         priv->mod = NULL;
361
362         if (priv->boundary_list) {
363                 g_list_free_full (priv->boundary_list, free_boundary_list);
364                 priv->boundary_list = NULL;
365         }
366
367         if (priv->pos) {
368                 location_position_free(priv->pos);
369                 priv->pos = NULL;
370         }
371
372         if (priv->vel) {
373                 location_velocity_free(priv->vel);
374                 priv->vel = NULL;
375         }
376
377         if (priv->acc) {
378                 location_accuracy_free(priv->acc);
379                 priv->acc = NULL;
380         }
381
382         if (priv->sat) {
383                 location_satellite_free(priv->sat);
384                 priv->sat = NULL;
385         }
386         G_OBJECT_CLASS (location_gps_parent_class)->finalize (gobject);
387 }
388
389 static void
390 location_gps_set_property (GObject *object,
391         guint property_id,
392         const GValue *value,
393         GParamSpec *pspec)
394 {
395         LocationGpsPrivate* priv = GET_PRIVATE(object);
396
397         g_return_if_fail (priv->mod);
398         g_return_if_fail (priv->mod->handler);
399         LocModGpsOps ops = priv->mod->ops;
400
401         int ret = 0;
402         switch (property_id){
403                 case PROP_DEV_NAME: {
404                         char* devname = g_value_dup_string(value);
405                         LOCATION_LOGD("Set prop>> device_name: %s", devname);
406                         if(ops.set_devname)
407                                 ops.set_devname(priv->mod->handler, devname);
408                         g_free(devname);
409                         break;
410                 }
411                 case PROP_BOUNDARY: {
412                         GList *boundary_list = g_list_copy(g_value_get_pointer(value));
413                         ret = set_prop_boundary(&priv->boundary_list, boundary_list);
414                         if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
415                         break;
416                 }
417                 case PROP_REMOVAL_BOUNDARY: {
418                         LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
419                         ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
420                         if(ret != 0) LOCATION_LOGD("Removal boundary. Error[%d]", ret);
421                         break;
422                 }
423                 case PROP_POS_INTERVAL: {
424                         guint interval = g_value_get_uint(value);
425                         LOCATION_LOGD("Set prop>> update-interval: %u", interval);
426                         if(interval > 0) {
427                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
428                                         priv->pos_interval = interval;
429                                 else
430                                         priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
431                         }
432                         else
433                                 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
434
435                         if (priv->pos_timer) {
436                                 g_source_remove (priv->pos_timer);
437                                 priv->pos_timer = g_timeout_add (priv->pos_interval * 1000, _position_timeout_cb, object);
438                         }
439
440                         break;
441                 }
442                 case PROP_VEL_INTERVAL: {
443                         guint interval = g_value_get_uint(value);
444                         LOCATION_LOGD("Set prop>> update-interval: %u", interval);
445                         if(interval > 0) {
446                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
447                                         priv->vel_interval = interval;
448                                 else
449                                         priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
450                         }
451                         else
452                                 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
453
454                         if (priv->vel_timer) {
455                                 g_source_remove (priv->vel_timer);
456                                 priv->vel_timer = g_timeout_add (priv->vel_interval * 1000, _velocity_timeout_cb, object);
457                         }
458
459                         break;
460                 }
461                 case PROP_SAT_INTERVAL: {
462                         guint interval = g_value_get_uint(value);
463                         LOCATION_LOGD("Set prop>> update-interval: %u", interval);
464                         if(interval > 0) {
465                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
466                                         priv->sat_interval = interval;
467                                 else
468                                         priv->sat_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
469                         }
470                         else
471                                 priv->sat_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
472
473                         break;
474                 }
475                 default:
476                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
477                         break;
478         }
479 }
480
481 static void
482 location_gps_get_property (GObject *object,
483         guint property_id,
484         GValue *value,
485         GParamSpec *pspec)
486 {
487         LocationGpsPrivate *priv = GET_PRIVATE (object);
488
489         g_return_if_fail (priv->mod);
490         g_return_if_fail (priv->mod->handler);
491         LocModGpsOps ops = priv->mod->ops;
492         switch (property_id) {
493                 case PROP_DEV_NAME: {
494                         char* devname = NULL;
495                         if(ops.get_devname)
496                                 ops.get_devname(priv->mod->handler, &devname);
497                         LOCATION_LOGD ("Get prop>> device_name: %s", devname);
498                         g_value_set_string (value, devname);
499                         g_free(devname);
500                         break;
501                 }
502                 case PROP_METHOD_TYPE:
503                         g_value_set_int(value, LOCATION_METHOD_GPS);
504                         break;
505                 case PROP_LAST_POSITION:
506                         g_value_set_boxed (value, priv->pos);
507                         break;
508                 case PROP_POS_INTERVAL:
509                         g_value_set_uint(value, priv->pos_interval);
510                         break;
511                 case PROP_VEL_INTERVAL:
512                         g_value_set_uint(value, priv->vel_interval);
513                         break;
514                 case PROP_SAT_INTERVAL:
515                         g_value_set_uint(value, priv->sat_interval);
516                         break;
517                 case PROP_BOUNDARY:
518                         g_value_set_pointer(value, g_list_first(priv->boundary_list));
519                         break;
520                 case PROP_NMEA: {
521                         char *nmea_data = NULL;
522                         if (ops.get_nmea &&  LOCATION_ERROR_NONE == ops.get_nmea(priv->mod->handler, &nmea_data) && nmea_data) {
523                                 LOCATION_LOGD("Get prop>> Lastest nmea: \n%s", nmea_data);
524                                 g_value_set_string(value, nmea_data);
525                                 g_free(nmea_data);
526                         } else {
527                                 LOCATION_LOGW("Get prop>> Lastest nmea: failed");
528                                 g_value_set_string(value, NULL);
529                         }
530                         break;
531                 }
532                 case PROP_SATELLITE: {
533                         LocationSatellite *satellite = NULL;
534                         if (ops.get_satellite && priv->mod->handler && LOCATION_ERROR_NONE == ops.get_satellite(priv->mod->handler, &satellite) && satellite){
535                                 LOCATION_LOGD("Get prop>> Last sat: num_used(%d) num_view(%d)", satellite->num_of_sat_used, satellite->num_of_sat_inview);
536                                 g_value_set_boxed (value, satellite);
537                                 location_satellite_free(satellite);
538                         } else {
539                                 LOCATION_LOGW("Get prop>> Last sat: failed");
540                                 g_value_set_boxed (value, NULL);
541                         }
542                         break;
543                 }
544                 default:
545                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
546                         break;
547         }
548 }
549
550 static int
551 location_gps_get_position (LocationGps *self,
552         LocationPosition **position,
553         LocationAccuracy **accuracy)
554 {
555         int ret = LOCATION_ERROR_NOT_AVAILABLE;
556         LOCATION_LOGD("location_gps_get_position");
557
558         LocationGpsPrivate *priv = GET_PRIVATE (self);
559         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
560         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
561
562         LocModGpsOps ops = priv->mod->ops;
563         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
564         g_return_val_if_fail (ops.get_position, LOCATION_ERROR_NOT_AVAILABLE);
565
566         if (priv->pos) {
567                 *position = location_position_copy (priv->pos);
568                 ret = LOCATION_ERROR_NONE;
569         }
570
571         if (priv->acc) {
572                 *accuracy = location_accuracy_copy (priv->acc);
573         }
574
575         return ret;
576 }
577
578 static int
579 location_gps_get_last_position (LocationGps *self,
580         LocationPosition **position,
581         LocationAccuracy **accuracy)
582 {
583         LOCATION_LOGD("location_gps_get_last_position");
584         // Enable to get a last position even though GPS_ENABLE dose not set on
585
586         LocationGpsPrivate *priv = GET_PRIVATE (self);
587         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
588
589         LocModGpsOps ops = priv->mod->ops;
590         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
591         g_return_val_if_fail (ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
592         return ops.get_last_position(priv->mod->handler, position, accuracy);
593
594 }
595
596 static int
597 location_gps_get_velocity (LocationGps *self,
598         LocationVelocity **velocity,
599         LocationAccuracy **accuracy)
600 {
601         LOCATION_LOGD("location_gps_get_velocity");
602
603         int ret = LOCATION_ERROR_NOT_AVAILABLE;
604
605         LocationGpsPrivate *priv = GET_PRIVATE (self);
606         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
607         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
608
609         LocModGpsOps ops = priv->mod->ops;
610         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
611         g_return_val_if_fail (ops.get_velocity, LOCATION_ERROR_NOT_AVAILABLE);
612         
613         if (priv->vel) {
614                 *velocity = location_velocity_copy (priv->vel);
615                 ret = LOCATION_ERROR_NONE;
616         }
617
618         if (priv->acc) {
619                 *accuracy = location_accuracy_copy (priv->acc);
620         }
621
622         return ret;
623 }
624
625 static int
626 location_gps_get_last_velocity (LocationGps *self,
627         LocationVelocity **velocity,
628         LocationAccuracy **accuracy)
629 {
630         LOCATION_LOGD("location_gps_get_last_velocity");
631
632         LocationGpsPrivate *priv = GET_PRIVATE (self);
633         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
634         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
635
636         LocModGpsOps ops = priv->mod->ops;
637         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
638         g_return_val_if_fail (ops.get_last_velocity, LOCATION_ERROR_NOT_AVAILABLE);
639         return ops.get_last_velocity(priv->mod->handler, velocity, accuracy);
640
641 }
642
643 static int
644 location_gps_get_satellite (LocationGps *self,
645         LocationSatellite **satellite)
646 {
647         int ret = LOCATION_ERROR_NOT_AVAILABLE;
648         LOCATION_LOGD("location_gps_get_satellite");
649
650         LocationGpsPrivate *priv = GET_PRIVATE (self);
651         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
652         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
653
654         if (priv->sat) {
655                 *satellite = location_satellite_copy (priv->sat);
656                 ret = LOCATION_ERROR_NONE;
657         }
658         
659         return ret;
660 }
661
662 static int
663 location_gps_get_last_satellite (LocationGps *self,
664         LocationSatellite **satellite)
665 {
666         LOCATION_LOGD("location_gps_get_last_satellite");
667
668         LocationGpsPrivate *priv = GET_PRIVATE (self);
669         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
670         setting_retval_if_fail(VCONFKEY_LOCATION_ENABLED);
671
672         LocModGpsOps ops = priv->mod->ops;
673         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
674         g_return_val_if_fail (ops.get_last_satellite, LOCATION_ERROR_NOT_AVAILABLE);
675         return ops.get_last_satellite(priv->mod->handler, satellite);
676 }
677
678 static void
679 location_ielement_interface_init (LocationIElementInterface *iface)
680 {
681         iface->start = (TYPE_START_FUNC)location_gps_start;
682         iface->stop = (TYPE_STOP_FUNC)location_gps_stop;
683         iface->get_position = (TYPE_GET_POSITION)location_gps_get_position;
684         iface->get_last_position = (TYPE_GET_POSITION)location_gps_get_last_position;
685         iface->get_velocity = (TYPE_GET_VELOCITY)location_gps_get_velocity;
686         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_gps_get_last_velocity;
687         iface->get_satellite = (TYPE_GET_SATELLITE)location_gps_get_satellite;
688         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_gps_get_last_satellite;
689 }
690
691 static void
692 location_gps_init (LocationGps *self)
693 {
694         LOCATION_LOGD("location_gps_init");
695         LocationGpsPrivate* priv = GET_PRIVATE(self);
696
697         priv->mod = (LocationGpsMod*)module_new("gps");
698         if(!priv->mod) LOCATION_LOGW("module loading failed");
699
700         priv->is_started = FALSE;
701         priv->set_noti = FALSE;
702         priv->enabled= FALSE;
703
704         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
705         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
706         priv->sat_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
707
708         priv->pos_updated_timestamp = 0;
709         priv->vel_updated_timestamp = 0;
710         priv->sat_updated_timestamp = 0;
711
712         priv->pos = NULL;
713         priv->vel = NULL;
714         priv->acc = NULL;
715         priv->sat = NULL;
716         priv->zone_status = ZONE_STATUS_NONE;
717         priv->boundary_list = NULL;
718
719         priv->pos_timer = 0;
720         priv->vel_timer = 0;
721
722 }
723
724 static void
725 location_gps_class_init (LocationGpsClass *klass)
726 {
727         LOCATION_LOGD("location_gps_class_init");
728         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
729
730         gobject_class->set_property = location_gps_set_property;
731         gobject_class->get_property = location_gps_get_property;
732
733         gobject_class->dispose = location_gps_dispose;
734         gobject_class->finalize = location_gps_finalize;
735
736         g_type_class_add_private (klass, sizeof (LocationGpsPrivate));
737
738         signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
739                         G_TYPE_FROM_CLASS (klass),
740                         G_SIGNAL_RUN_FIRST |
741                         G_SIGNAL_NO_RECURSE,
742                         G_STRUCT_OFFSET (LocationGpsClass, enabled),
743                         NULL, NULL,
744                         location_VOID__UINT,
745                         G_TYPE_NONE, 1,
746                         G_TYPE_UINT);
747
748         signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
749                         G_TYPE_FROM_CLASS (klass),
750                         G_SIGNAL_RUN_FIRST |
751                         G_SIGNAL_NO_RECURSE,
752                         G_STRUCT_OFFSET (LocationGpsClass, disabled),
753                         NULL, NULL,
754                         location_VOID__UINT,
755                         G_TYPE_NONE, 1,
756                         G_TYPE_UINT);
757
758         signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
759                         G_TYPE_FROM_CLASS (klass),
760                         G_SIGNAL_RUN_FIRST |
761                         G_SIGNAL_NO_RECURSE,
762                         G_STRUCT_OFFSET (LocationGpsClass, updated),
763                         NULL, NULL,
764                         location_VOID__UINT_POINTER_POINTER,
765                         G_TYPE_NONE, 3,
766                         G_TYPE_UINT,
767                         G_TYPE_POINTER,
768                         G_TYPE_POINTER);
769
770         signals[ZONE_IN] = g_signal_new ("zone-in",
771                         G_TYPE_FROM_CLASS (klass),
772                         G_SIGNAL_RUN_FIRST |
773                         G_SIGNAL_NO_RECURSE,
774                         G_STRUCT_OFFSET (LocationGpsClass, zone_in),
775                         NULL, NULL,
776                         location_VOID__UINT_POINTER_POINTER,
777                         G_TYPE_NONE, 3,
778                         G_TYPE_UINT,
779                         G_TYPE_POINTER,
780                         G_TYPE_POINTER);
781
782         signals[ZONE_OUT] = g_signal_new ("zone-out",
783                         G_TYPE_FROM_CLASS (klass),
784                         G_SIGNAL_RUN_FIRST |
785                         G_SIGNAL_NO_RECURSE,
786                         G_STRUCT_OFFSET (LocationGpsClass, zone_out),
787                         NULL, NULL,
788                         location_VOID__UINT_POINTER_POINTER,
789                         G_TYPE_NONE, 3,
790                         G_TYPE_UINT,
791                         G_TYPE_POINTER,
792                         G_TYPE_POINTER);
793
794         properties[PROP_DEV_NAME] = g_param_spec_string ("dev-name",
795                         "gps device name prop",
796                         "gps device name",
797                         "/dev/rfcomm0",
798                         G_PARAM_READWRITE);
799
800         properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
801                         "method type",
802                         "location method type name",
803                         LOCATION_METHOD_GPS,
804                         LOCATION_METHOD_GPS,
805                         LOCATION_METHOD_GPS,
806                         G_PARAM_READABLE);
807
808         properties[PROP_LAST_POSITION]  = g_param_spec_boxed ("last-position",
809                         "gps last position prop",
810                         "gps last position data",
811                         LOCATION_TYPE_POSITION,
812                         G_PARAM_READABLE);
813
814         properties[PROP_POS_INTERVAL] = g_param_spec_uint ("pos-interval",
815                         "gps position interval prop",
816                         "gps position interval data",
817                         LOCATION_UPDATE_INTERVAL_MIN,
818                         LOCATION_UPDATE_INTERVAL_MAX,
819                         LOCATION_UPDATE_INTERVAL_DEFAULT,
820                         G_PARAM_READWRITE);
821
822         properties[PROP_VEL_INTERVAL] = g_param_spec_uint ("vel-interval",
823                         "gps velocity interval prop",
824                         "gps velocity interval data",
825                         LOCATION_UPDATE_INTERVAL_MIN,
826                         LOCATION_UPDATE_INTERVAL_MAX,
827                         LOCATION_UPDATE_INTERVAL_DEFAULT,
828                         G_PARAM_READWRITE);
829
830         properties[PROP_SAT_INTERVAL] = g_param_spec_uint ("sat-interval",
831                         "gps satellite interval prop",
832                         "gps satellite interval data",
833                         LOCATION_UPDATE_INTERVAL_MIN,
834                         LOCATION_UPDATE_INTERVAL_MAX,
835                         LOCATION_UPDATE_INTERVAL_DEFAULT,
836                         G_PARAM_READWRITE);
837                 ;
838         properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
839                         "gps boundary prop",
840                         "gps boundary data",
841                         G_PARAM_READWRITE);
842
843         properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
844                         "gps removal boundary prop",
845                         "gps removal boundary data",
846                         LOCATION_TYPE_BOUNDARY,
847                         G_PARAM_READWRITE);
848
849
850         properties[PROP_NMEA] = g_param_spec_string ("nmea",
851                         "gps NMEA name prop",
852                         "gps NMEA",
853                         NULL,
854                         G_PARAM_READABLE);
855
856         properties[PROP_SATELLITE] = g_param_spec_boxed ("satellite",
857                         "gps satellite prop",
858                         "gps satellite data",
859                         LOCATION_TYPE_SATELLITE,
860                         G_PARAM_READABLE);
861
862         g_object_class_install_properties (gobject_class,
863                         PROP_MAX,
864                         properties);
865
866 }