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-sps.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
37 typedef struct _LocationSpsPrivate {
43 LocationPosition *pos;
44 LocationVelocity *vel;
45 LocationAccuracy *acc;
47 ZoneStatus zone_status;
48 LocationPosition *pos_base;
49 LocationVelocity *vel_base;
50 LocationAccuracy *acc_info;
51 LocationSatellite *sat_info;
60 PROP_REMOVAL_BOUNDARY,
68 static guint32 signals[LAST_SIGNAL] = {0, };
69 static GParamSpec *properties[PROP_MAX] = {NULL, };
71 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_SPS, LocationSpsPrivate))
73 static void location_ielement_interface_init (LocationIElementInterface *iface);
75 G_DEFINE_TYPE_WITH_CODE (LocationSps, location_sps, G_TYPE_OBJECT,
76 G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
77 location_ielement_interface_init));
80 sps_status_cb (gboolean enabled,
81 LocationStatus status,
84 LOCATION_LOGD("sps_status_cb");
85 g_return_if_fail(self);
86 LocationSpsPrivate* priv = GET_PRIVATE(self);
87 enable_signaling(self, signals, &(priv->enabled), enabled, status);
91 sps_position_cb (gboolean enabled,
92 LocationPosition *pos,
93 LocationAccuracy *acc,
96 LOCATION_LOGD("sps_position_cb");
97 g_return_if_fail(self);
98 g_return_if_fail(pos);
99 g_return_if_fail(acc);
100 LocationSpsPrivate* priv = GET_PRIVATE(self);
101 enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
103 position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), enabled, pos, acc);
107 sps_velocity_cb (gboolean enabled,
108 LocationVelocity *vel,
109 LocationAccuracy *acc,
112 LOCATION_LOGD("sps_velocity_cb");
113 g_return_if_fail(self);
114 LocationSpsPrivate* priv = GET_PRIVATE(self);
115 velocity_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->vel), enabled, vel, acc);
119 location_setting_sps_cb(keynode_t *key,
122 LOCATION_LOGD("location_setting_sps_cb");
123 g_return_if_fail(key);
124 g_return_if_fail(self);
125 LocationSpsPrivate* priv = GET_PRIVATE(self);
126 g_return_if_fail (priv->mod);
127 g_return_if_fail (priv->mod->handler);
129 int ret = LOCATION_ERROR_NONE;
131 if (location_setting_get_key_val(key) == 0) {
132 if (priv->mod->ops.stop && priv->is_started) {
133 ret = priv->mod->ops.stop(priv->mod->handler);
134 if (ret == LOCATION_ERROR_NONE) priv->is_started = FALSE;
138 if (location_setting_get_int(SENSOR_ENABLED) &&
139 priv->mod->ops.start && !priv->is_started) {
140 LOCATION_LOGD("location resumed by setting");
141 ret = priv->mod->ops.start (priv->mod->handler, sps_status_cb, sps_position_cb, sps_velocity_cb, self);
142 if (ret == LOCATION_ERROR_NONE) priv->is_started = TRUE;
149 location_sps_start (LocationSps *self)
151 LOCATION_LOGD("location_sps_start");
152 LocationSpsPrivate* priv = GET_PRIVATE(self);
153 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
154 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
155 g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
156 g_return_val_if_fail (priv->mod->ops.update_data, LOCATION_ERROR_NOT_AVAILABLE);
158 if( priv->is_started == TRUE) return LOCATION_ERROR_NONE;
160 int ret = LOCATION_ERROR_NONE;
163 if (!location_setting_get_int(GPS_ENABLED) || !location_setting_get_int(SENSOR_ENABLED)) {
164 ret = LOCATION_ERROR_NOT_ALLOWED;
167 ret = priv->mod->ops.start(priv->mod->handler, sps_status_cb, sps_position_cb, sps_velocity_cb, self);
168 if (ret == LOCATION_ERROR_NONE) {
169 priv->is_started = TRUE;
175 priv->mod->ops.update_data(priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
178 if (priv->set_noti == FALSE) {
179 noti_err = location_setting_add_notify (GPS_ENABLED, location_setting_sps_cb, self);
181 return LOCATION_ERROR_UNKNOWN;
183 noti_err = location_setting_add_notify (SENSOR_ENABLED, location_setting_sps_cb, self);
185 return LOCATION_ERROR_UNKNOWN;
187 priv->set_noti = TRUE;
194 location_sps_stop (LocationSps *self)
196 LOCATION_LOGD("location_sps_stop");
197 LocationSpsPrivate* priv = GET_PRIVATE(self);
198 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
199 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
200 g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
202 int ret = LOCATION_ERROR_NONE;
205 if (priv->is_started == TRUE) {
206 ret = priv->mod->ops.stop (priv->mod->handler);
207 if (ret == LOCATION_ERROR_NONE) {
208 priv->is_started = FALSE;
215 if (priv->set_noti == TRUE) {
216 noti_err = location_setting_ignore_notify (GPS_ENABLED, location_setting_sps_cb);
218 return LOCATION_ERROR_UNKNOWN;
220 noti_err = location_setting_ignore_notify (SENSOR_ENABLED, location_setting_sps_cb);
222 return LOCATION_ERROR_UNKNOWN;
224 priv->set_noti = FALSE;
231 location_sps_dispose (GObject *gobject)
233 LOCATION_LOGD("location_sps_dispose");
234 G_OBJECT_CLASS (location_sps_parent_class)->dispose (gobject);
238 location_sps_finalize (GObject *gobject)
240 LOCATION_LOGD("location_sps_finalize");
241 LocationSpsPrivate* priv = GET_PRIVATE(gobject);
242 module_free(priv->mod, "sps");
244 G_OBJECT_CLASS (location_sps_parent_class)->finalize (gobject);
248 location_sps_set_property (GObject *object,
253 LocationSpsPrivate* priv = GET_PRIVATE(object);
255 g_return_if_fail (priv->mod);
256 g_return_if_fail (priv->mod->handler);
257 LocModSpsOps ops = priv->mod->ops;
258 g_return_if_fail (ops.update_data);
261 switch (property_id){
263 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
264 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
265 if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
268 case PROP_REMOVAL_BOUNDARY: {
269 LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
270 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
271 if(ret != 0) LOCATION_LOGD("Removal boundary. Error[%d]", ret);
274 case PROP_POSITION_BASE:{
275 if(priv->pos_base) location_position_free(priv->pos_base);
276 priv->pos_base = (LocationPosition*) g_value_dup_boxed (value);
277 LOCATION_LOGD("Set prop>> base position: \t%lf, %lf, %lf, time: %d", priv->pos_base->latitude, priv->pos_base->longitude, priv->pos_base->altitude, priv->pos_base->timestamp);
278 if (priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
281 case PROP_VELOCITY_BASE:{
282 if(priv->vel_base) location_velocity_free(priv->vel_base);
283 priv->vel_base = (LocationVelocity*) g_value_dup_boxed (value);
284 LOCATION_LOGD("Set prop>> base velocity: \t%lf, %lf, %lf, time: %d", priv->vel_base->speed, priv->vel_base->direction, priv->vel_base->climb, priv->vel_base->timestamp);
285 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
288 case PROP_ACCURACY_INFO:{
289 if(priv->acc_info) location_accuracy_free(priv->acc_info);
290 priv->acc_info = (LocationAccuracy*) g_value_dup_boxed (value);
291 LOCATION_LOGD("Set prop>> accuracy information: \t%d, %lf, %lf", priv->acc_info->level, priv->acc_info->horizontal_accuracy, priv->acc_info->vertical_accuracy);
292 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
295 case PROP_SATELLITE_INFO:{
296 if(priv->sat_info) location_satellite_free(priv->sat_info);
297 priv->sat_info = (LocationSatellite*) g_value_dup_boxed (value);
298 LOCATION_LOGD("Set prop>> satellite information: \tNofView:%d, NofUsed:%d", priv->sat_info->num_of_sat_inview, priv->sat_info->num_of_sat_used);
299 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
302 case PROP_UPDATE_INTERVAL: {
303 guint interval = g_value_get_uint(value);
305 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
306 priv->interval = interval;
308 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
312 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
316 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
322 location_sps_get_property (GObject *object,
327 LocationSpsPrivate *priv = GET_PRIVATE (object);
329 switch (property_id){
330 case PROP_METHOD_TYPE:
331 g_value_set_int(value, LOCATION_METHOD_SPS);
333 case PROP_LAST_POSITION:
334 g_value_set_boxed (value, priv->pos);
337 g_value_set_pointer(value, g_list_first(priv->boundary_list));
339 case PROP_POSITION_BASE:
340 g_value_set_boxed (value, priv->pos_base);
342 case PROP_VELOCITY_BASE:
343 g_value_set_boxed (value, priv->vel_base);
345 case PROP_ACCURACY_INFO:
346 g_value_set_boxed (value, priv->acc_info);
348 case PROP_SATELLITE_INFO:
349 g_value_set_boxed (value, priv->sat_info);
351 case PROP_UPDATE_INTERVAL:
352 g_value_set_uint(value, priv->interval);
355 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
361 location_sps_get_position (LocationSps *self,
362 LocationPosition **position,
363 LocationAccuracy **accuracy)
365 LOCATION_LOGD("location_sps_get_position");
367 LocationSpsPrivate *priv = GET_PRIVATE (self);
368 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
369 setting_retval_if_fail(GPS_ENABLED);
370 setting_retval_if_fail(SENSOR_ENABLED);
372 LocModSpsOps ops = priv->mod->ops;
373 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
374 g_return_val_if_fail (ops.get_position, LOCATION_ERROR_NOT_AVAILABLE);
375 return ops.get_position(priv->mod->handler, position, accuracy);
379 location_sps_get_last_position (LocationSps *self,
380 LocationPosition **position,
381 LocationAccuracy **accuracy)
383 LOCATION_LOGD("location_sps_get_last_position");
384 return LOCATION_ERROR_NOT_SUPPORTED;
388 location_sps_get_velocity (LocationSps *self,
389 LocationVelocity **velocity,
390 LocationAccuracy **accuracy)
392 LOCATION_LOGD("location_sps_get_velocity");
394 LocationSpsPrivate *priv = GET_PRIVATE (self);
395 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
396 setting_retval_if_fail(GPS_ENABLED);
397 setting_retval_if_fail(SENSOR_ENABLED);
399 LocModSpsOps ops = priv->mod->ops;
400 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
401 g_return_val_if_fail (ops.get_velocity, LOCATION_ERROR_NOT_AVAILABLE);
402 return ops.get_velocity(priv->mod->handler, velocity, accuracy);
406 location_sps_get_last_velocity (LocationSps *self,
407 LocationVelocity **velocity,
408 LocationAccuracy **accuracy)
410 LOCATION_LOGD("location_sps_get_last_velocity");
411 return LOCATION_ERROR_NOT_SUPPORTED;
415 location_sps_get_satellite (LocationSps *self,
416 LocationSatellite **satellite)
418 LOCATION_LOGD("location_sps_get_satellite");
419 return LOCATION_ERROR_NOT_SUPPORTED;
423 location_sps_get_last_satellite (LocationSps *self,
424 LocationSatellite **satellite)
426 LOCATION_LOGD("location_sps_get_last_satellite");
427 return LOCATION_ERROR_NOT_SUPPORTED;
431 location_ielement_interface_init (LocationIElementInterface *iface)
433 iface->start = (TYPE_START_FUNC)location_sps_start;
434 iface->stop = (TYPE_STOP_FUNC)location_sps_stop;
435 iface->get_position = (TYPE_GET_POSITION)location_sps_get_position;
436 iface->get_last_position = (TYPE_GET_POSITION)location_sps_get_last_position;
437 iface->get_velocity = (TYPE_GET_VELOCITY)location_sps_get_velocity;
438 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_sps_get_last_velocity;
439 iface->get_satellite = (TYPE_GET_SATELLITE)location_sps_get_satellite;
440 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_sps_get_last_satellite;
444 location_sps_init (LocationSps *self)
446 LOCATION_LOGD("location_sps_init");
447 LocationSpsPrivate* priv = GET_PRIVATE(self);
449 priv->mod = (LocationSpsMod*)module_new("sps");
451 LOCATION_LOGW("module loading failed");
453 priv->is_started = FALSE;
454 priv->enabled= FALSE;
455 priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
459 priv->zone_status = ZONE_STATUS_NONE;
460 priv->boundary_list = NULL;
462 priv->pos_base = NULL;
463 priv->vel_base = NULL;
464 priv->acc_info = NULL;
465 priv->sat_info = NULL;
469 location_sps_class_init (LocationSpsClass *klass)
471 LOCATION_LOGD("location_sps_class_init");
472 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
474 gobject_class->set_property = location_sps_set_property;
475 gobject_class->get_property = location_sps_get_property;
477 gobject_class->dispose = location_sps_dispose;
478 gobject_class->finalize = location_sps_finalize;
480 g_type_class_add_private (klass, sizeof (LocationSpsPrivate));
482 signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
483 G_TYPE_FROM_CLASS (klass),
486 G_STRUCT_OFFSET (LocationSpsClass, enabled),
492 signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
493 G_TYPE_FROM_CLASS (klass),
496 G_STRUCT_OFFSET (LocationSpsClass, disabled),
502 signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
503 G_TYPE_FROM_CLASS (klass),
506 G_STRUCT_OFFSET (LocationSpsClass, updated),
508 location_VOID__UINT_POINTER_POINTER,
514 signals[ZONE_IN] = g_signal_new ("zone-in",
515 G_TYPE_FROM_CLASS (klass),
518 G_STRUCT_OFFSET (LocationSpsClass, zone_in),
520 location_VOID__UINT_POINTER_POINTER,
526 signals[ZONE_OUT] = g_signal_new ("zone-out",
527 G_TYPE_FROM_CLASS (klass),
530 G_STRUCT_OFFSET (LocationSpsClass, zone_out),
532 location_VOID__UINT_POINTER_POINTER,
538 properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
540 "location method type name",
546 properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
547 "sps last position prop",
548 "sps last position data",
549 LOCATION_TYPE_POSITION,
552 properties[PROP_UPDATE_INTERVAL] = g_param_spec_uint ("update-interval",
553 "sps update interval prop",
554 "sps update interval data",
555 LOCATION_UPDATE_INTERVAL_MIN,
556 LOCATION_UPDATE_INTERVAL_MAX,
557 LOCATION_UPDATE_INTERVAL_DEFAULT,
560 properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
565 properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
566 "sps removal boundary prop",
567 "sps removal boundary data",
568 LOCATION_TYPE_BOUNDARY,
571 properties[PROP_POSITION_BASE] = g_param_spec_boxed ("position-base",
572 "sps position base prop",
573 "sps position base data",
574 LOCATION_TYPE_POSITION,
577 properties[PROP_VELOCITY_BASE] = g_param_spec_boxed ("velocity-base",
578 "sps velocity base prop",
579 "sps velocity base data",
580 LOCATION_TYPE_VELOCITY,
583 properties[PROP_ACCURACY_INFO] = g_param_spec_boxed ("accuracy-info",
584 "sps accuracy information prop",
585 "sps accuracy information data",
586 LOCATION_TYPE_ACCURACY,
589 properties[PROP_SATELLITE_INFO] = g_param_spec_boxed ("satellite-info",
590 "sps satellite information prop",
591 "sps satellite information data",
592 LOCATION_TYPE_SATELLITE,
595 g_object_class_install_properties (gobject_class,