4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
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>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
26 #include "location-setting.h"
27 #include "location-log.h"
29 #include "module-internal.h"
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"
38 typedef struct _LocationGpsPrivate {
44 LocationPosition* pos;
45 LocationVelocity* vel;
46 LocationAccuracy* acc;
48 ZoneStatus zone_status;
50 LocationSatellite* sat;
60 PROP_REMOVAL_BOUNDARY,
66 static guint32 signals[LAST_SIGNAL] = {0, };
67 static GParamSpec *properties[PROP_MAX] = {NULL, };
69 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_GPS, LocationGpsPrivate))
71 static void location_ielement_interface_init (LocationIElementInterface *iface);
73 G_DEFINE_TYPE_WITH_CODE (LocationGps, location_gps, G_TYPE_OBJECT,
74 G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
75 location_ielement_interface_init));
78 gps_status_cb (gboolean enabled,
79 LocationStatus status,
82 LOCATION_LOGD("gps_status_cb");
83 g_return_if_fail(self);
84 LocationGpsPrivate* priv = GET_PRIVATE(self);
85 enable_signaling(self, signals, &(priv->enabled), enabled, status);
89 gps_position_cb (gboolean enabled,
90 LocationPosition *pos,
91 LocationAccuracy *acc,
94 LOCATION_LOGD("gps_position_cb");
95 g_return_if_fail(self);
96 g_return_if_fail(pos);
97 g_return_if_fail(acc);
98 LocationGpsPrivate* priv = GET_PRIVATE(self);
99 enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
100 position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), enabled, pos, acc);
104 gps_velocity_cb (gboolean enabled,
105 LocationVelocity *vel,
106 LocationAccuracy *acc,
109 LOCATION_LOGD("gps_velocity_cb");
110 g_return_if_fail(self);
111 LocationGpsPrivate* priv = GET_PRIVATE(self);
112 velocity_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->vel), enabled, vel, acc);
116 gps_satellite_cb (gboolean enabled,
117 LocationSatellite *sat,
120 LOCATION_LOGD("gps_satellite_cb");
121 g_return_if_fail(self);
122 LocationGpsPrivate* priv = GET_PRIVATE(self);
123 satellite_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->sat_timestamp), &(priv->sat), enabled, sat);
127 location_setting_gps_cb (keynode_t *key,
130 LOCATION_LOGD("location_setting_gps_cb");
131 g_return_if_fail(key);
132 g_return_if_fail(self);
133 LocationGpsPrivate* priv = GET_PRIVATE(self);
134 g_return_if_fail (priv->mod);
135 g_return_if_fail (priv->mod->handler);
137 int ret = LOCATION_ERROR_NONE;
139 if (0 == location_setting_get_key_val(key) && priv->mod->ops.stop && priv->is_started) {
140 LOCATION_LOGD("location stopped by setting");
141 ret = priv->mod->ops.stop(priv->mod->handler);
142 if (ret == LOCATION_ERROR_NONE) priv->is_started = FALSE;
144 else if (1 == location_setting_get_key_val(key) && priv->mod->ops.start && !priv->is_started) {
145 LOCATION_LOGD("location resumed by setting");
146 ret = priv->mod->ops.start (priv->mod->handler, gps_status_cb, gps_position_cb, gps_velocity_cb, gps_satellite_cb, self);
147 if (ret == LOCATION_ERROR_NONE) priv->is_started = TRUE;
152 location_gps_start (LocationGps *self)
154 LOCATION_LOGD("location_gps_start");
155 LocationGpsPrivate* priv = GET_PRIVATE(self);
156 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
157 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
158 g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
160 if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
162 int ret = LOCATION_ERROR_NONE;
165 if (!location_setting_get_int(GPS_ENABLED)) {
166 ret = LOCATION_ERROR_NOT_ALLOWED;
169 ret = priv->mod->ops.start (priv->mod->handler, gps_status_cb, gps_position_cb, gps_velocity_cb, gps_satellite_cb, self);
170 if (ret == LOCATION_ERROR_NONE) {
171 priv->is_started = TRUE;
178 if(priv->set_noti == FALSE) {
179 noti_err = location_setting_add_notify (GPS_ENABLED, location_setting_gps_cb, self);
181 return LOCATION_ERROR_UNKNOWN;
183 priv->set_noti = TRUE;
190 location_gps_stop (LocationGps *self)
192 LOCATION_LOGD("location_gps_stop");
193 LocationGpsPrivate* priv = GET_PRIVATE(self);
194 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
195 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
196 g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
198 int ret = LOCATION_ERROR_NONE;
201 if ( priv->is_started == TRUE) {
202 ret = priv->mod->ops.stop (priv->mod->handler);
203 if (ret == LOCATION_ERROR_NONE) {
204 priv->is_started = FALSE;
211 if(priv->set_noti == TRUE) {
212 noti_err = location_setting_ignore_notify (GPS_ENABLED, location_setting_gps_cb);
214 return LOCATION_ERROR_UNKNOWN;
216 priv->set_noti = FALSE;
223 location_gps_dispose (GObject *gobject)
225 LOCATION_LOGD("location_gps_dispose");
226 G_OBJECT_CLASS (location_gps_parent_class)->dispose (gobject);
230 location_gps_finalize (GObject *gobject)
232 LOCATION_LOGD("location_gps_finalize");
233 LocationGpsPrivate* priv = GET_PRIVATE(gobject);
234 module_free(priv->mod, "gps");
236 G_OBJECT_CLASS (location_gps_parent_class)->finalize (gobject);
240 location_gps_set_property (GObject *object,
245 LocationGpsPrivate* priv = GET_PRIVATE(object);
247 g_return_if_fail (priv->mod);
248 g_return_if_fail (priv->mod->handler);
249 LocModGpsOps ops = priv->mod->ops;
252 switch (property_id){
253 case PROP_DEV_NAME: {
254 char* devname = g_value_dup_string(value);
255 LOCATION_LOGD("Set prop>> device_name: %s", devname);
257 ops.set_devname(priv->mod->handler, devname);
261 case PROP_BOUNDARY: {
262 GList *boundary_list = g_list_copy(g_value_get_pointer(value));
263 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
264 if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
267 case PROP_REMOVAL_BOUNDARY: {
268 LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
269 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
270 if(ret != 0) LOCATION_LOGD("Removal boundary. Error[%d]", ret);
273 case PROP_UPDATE_INTERVAL: {
274 guint interval = g_value_get_uint(value);
275 LOCATION_LOGD("Set prop>> update-interval: %u", interval);
277 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
278 priv->interval = interval;
280 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
283 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
287 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
293 location_gps_get_property (GObject *object,
298 LocationGpsPrivate *priv = GET_PRIVATE (object);
300 g_return_if_fail (priv->mod);
301 g_return_if_fail (priv->mod->handler);
302 LocModGpsOps ops = priv->mod->ops;
303 switch (property_id) {
304 case PROP_DEV_NAME: {
305 char* devname = NULL;
307 ops.get_devname(priv->mod->handler, &devname);
308 LOCATION_LOGD ("Get prop>> device_name: %s", devname);
309 g_value_set_string (value, devname);
313 case PROP_METHOD_TYPE:
314 g_value_set_int(value, LOCATION_METHOD_GPS);
316 case PROP_LAST_POSITION:
317 g_value_set_boxed (value, priv->pos);
319 case PROP_UPDATE_INTERVAL:
320 g_value_set_uint(value, priv->interval);
323 g_value_set_pointer(value, g_list_first(priv->boundary_list));
326 char *nmea_data = NULL;
327 if (ops.get_nmea && LOCATION_ERROR_NONE == ops.get_nmea(priv->mod->handler, &nmea_data) && nmea_data) {
328 LOCATION_LOGD("Get prop>> Lastest nmea: \n%s", nmea_data);
329 g_value_set_string(value, nmea_data);
332 LOCATION_LOGW("Get prop>> Lastest nmea: failed");
333 g_value_set_string(value, NULL);
337 case PROP_SATELLITE: {
338 LocationSatellite *satellite = NULL;
339 if (ops.get_satellite && priv->mod->handler && LOCATION_ERROR_NONE == ops.get_satellite(priv->mod->handler, &satellite) && satellite){
340 LOCATION_LOGD("Get prop>> Last sat: num_used(%d) num_view(%d)", satellite->num_of_sat_used, satellite->num_of_sat_inview);
341 g_value_set_boxed (value, satellite);
342 location_satellite_free(satellite);
344 LOCATION_LOGW("Get prop>> Last sat: failed");
345 g_value_set_boxed (value, NULL);
350 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
356 location_gps_get_position (LocationGps *self,
357 LocationPosition **position,
358 LocationAccuracy **accuracy)
360 LOCATION_LOGD("location_gps_get_position");
362 LocationGpsPrivate *priv = GET_PRIVATE (self);
363 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
364 setting_retval_if_fail(GPS_ENABLED);
366 LocModGpsOps ops = priv->mod->ops;
367 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
368 g_return_val_if_fail (ops.get_position, LOCATION_ERROR_NOT_AVAILABLE);
369 return ops.get_position(priv->mod->handler, position, accuracy);
373 location_gps_get_last_position (LocationGps *self,
374 LocationPosition **position,
375 LocationAccuracy **accuracy)
377 LOCATION_LOGD("location_gps_get_position");
378 // Enable to get a last position even though GPS_ENABLE dose not set on
380 LocationGpsPrivate *priv = GET_PRIVATE (self);
381 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
383 LocModGpsOps ops = priv->mod->ops;
384 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
385 g_return_val_if_fail (ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
386 return ops.get_last_position(priv->mod->handler, position, accuracy);
391 location_gps_get_velocity (LocationGps *self,
392 LocationVelocity **velocity,
393 LocationAccuracy **accuracy)
395 LOCATION_LOGD("location_gps_get_velocity");
397 LocationGpsPrivate *priv = GET_PRIVATE (self);
398 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
399 setting_retval_if_fail(GPS_ENABLED);
401 LocModGpsOps ops = priv->mod->ops;
402 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
403 g_return_val_if_fail (ops.get_velocity, LOCATION_ERROR_NOT_AVAILABLE);
404 return ops.get_velocity(priv->mod->handler, velocity, accuracy);
408 location_gps_get_last_velocity (LocationGps *self,
409 LocationVelocity **velocity,
410 LocationAccuracy **accuracy)
412 LOCATION_LOGD("location_gps_get_last_velocity");
414 LocationGpsPrivate *priv = GET_PRIVATE (self);
415 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
416 setting_retval_if_fail(GPS_ENABLED);
418 LocModGpsOps ops = priv->mod->ops;
419 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
420 g_return_val_if_fail (ops.get_last_velocity, LOCATION_ERROR_NOT_AVAILABLE);
421 return ops.get_last_velocity(priv->mod->handler, velocity, accuracy);
426 location_gps_get_satellite (LocationGps *self,
427 LocationSatellite **satellite)
429 LOCATION_LOGD("location_gps_get_satellite");
431 LocationGpsPrivate *priv = GET_PRIVATE (self);
432 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
433 setting_retval_if_fail(GPS_ENABLED);
435 LocModGpsOps ops = priv->mod->ops;
436 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
437 g_return_val_if_fail (ops.get_satellite, LOCATION_ERROR_NOT_AVAILABLE);
438 return ops.get_satellite(priv->mod->handler, satellite);
442 location_gps_get_last_satellite (LocationGps *self,
443 LocationSatellite **satellite)
445 LOCATION_LOGD("location_gps_get_last_satellite");
447 LocationGpsPrivate *priv = GET_PRIVATE (self);
448 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
449 setting_retval_if_fail(GPS_ENABLED);
451 LocModGpsOps ops = priv->mod->ops;
452 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
453 g_return_val_if_fail (ops.get_last_satellite, LOCATION_ERROR_NOT_AVAILABLE);
454 return ops.get_last_satellite(priv->mod->handler, satellite);
458 location_ielement_interface_init (LocationIElementInterface *iface)
460 iface->start = (TYPE_START_FUNC)location_gps_start;
461 iface->stop = (TYPE_STOP_FUNC)location_gps_stop;
462 iface->get_position = (TYPE_GET_POSITION)location_gps_get_position;
463 iface->get_last_position = (TYPE_GET_POSITION)location_gps_get_last_position;
464 iface->get_velocity = (TYPE_GET_VELOCITY)location_gps_get_velocity;
465 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_gps_get_last_velocity;
466 iface->get_satellite = (TYPE_GET_SATELLITE)location_gps_get_satellite;
467 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_gps_get_last_satellite;
471 location_gps_init (LocationGps *self)
473 LOCATION_LOGD("location_gps_init");
474 LocationGpsPrivate* priv = GET_PRIVATE(self);
476 priv->mod = (LocationGpsMod*)module_new("gps");
477 if(!priv->mod) LOCATION_LOGW("module loading failed");
479 priv->is_started = FALSE;
480 priv->set_noti = FALSE;
481 priv->enabled= FALSE;
482 priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
487 priv->zone_status = ZONE_STATUS_NONE;
488 priv->boundary_list = NULL;
492 location_gps_class_init (LocationGpsClass *klass)
494 LOCATION_LOGD("location_gps_class_init");
495 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
497 gobject_class->set_property = location_gps_set_property;
498 gobject_class->get_property = location_gps_get_property;
500 gobject_class->dispose = location_gps_dispose;
501 gobject_class->finalize = location_gps_finalize;
503 g_type_class_add_private (klass, sizeof (LocationGpsPrivate));
505 signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
506 G_TYPE_FROM_CLASS (klass),
509 G_STRUCT_OFFSET (LocationGpsClass, enabled),
515 signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
516 G_TYPE_FROM_CLASS (klass),
519 G_STRUCT_OFFSET (LocationGpsClass, disabled),
525 signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
526 G_TYPE_FROM_CLASS (klass),
529 G_STRUCT_OFFSET (LocationGpsClass, updated),
531 location_VOID__UINT_POINTER_POINTER,
537 signals[ZONE_IN] = g_signal_new ("zone-in",
538 G_TYPE_FROM_CLASS (klass),
541 G_STRUCT_OFFSET (LocationGpsClass, zone_in),
543 location_VOID__UINT_POINTER_POINTER,
549 signals[ZONE_OUT] = g_signal_new ("zone-out",
550 G_TYPE_FROM_CLASS (klass),
553 G_STRUCT_OFFSET (LocationGpsClass, zone_out),
555 location_VOID__UINT_POINTER_POINTER,
561 properties[PROP_DEV_NAME] = g_param_spec_string ("dev-name",
562 "gps device name prop",
567 properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
569 "location method type name",
575 properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
576 "gps last position prop",
577 "gps last position data",
578 LOCATION_TYPE_POSITION,
581 properties[PROP_UPDATE_INTERVAL] = g_param_spec_uint ("update-interval",
582 "gps update interval prop",
583 "gps update interval data",
584 LOCATION_UPDATE_INTERVAL_MIN,
585 LOCATION_UPDATE_INTERVAL_MAX,
586 LOCATION_UPDATE_INTERVAL_DEFAULT,
589 properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
594 properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
595 "gps removal boundary prop",
596 "gps removal boundary data",
597 LOCATION_TYPE_BOUNDARY,
601 properties[PROP_NMEA] = g_param_spec_string ("nmea",
602 "gps NMEA name prop",
607 properties[PROP_SATELLITE] = g_param_spec_boxed ("satellite",
608 "gps satellite prop",
609 "gps satellite data",
610 LOCATION_TYPE_SATELLITE,
613 g_object_class_install_properties (gobject_class,