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-wps.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
40 typedef struct _LocationWpsPrivate {
45 guint pos_updated_timestamp;
47 guint vel_updated_timestamp;
49 LocationPosition *pos;
50 LocationVelocity *vel;
51 LocationAccuracy *acc;
53 ZoneStatus zone_status;
66 PROP_REMOVAL_BOUNDARY,
70 static guint32 signals[LAST_SIGNAL] = {0, };
71 static GParamSpec *properties[PROP_MAX] = {NULL, };
73 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_WPS, LocationWpsPrivate))
75 static void location_ielement_interface_init (LocationIElementInterface *iface);
77 G_DEFINE_TYPE_WITH_CODE (LocationWps, location_wps, G_TYPE_OBJECT,
78 G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
79 location_ielement_interface_init));
82 _position_timeout_cb (gpointer data)
84 GObject *object = (GObject *)data;
85 LocationWpsPrivate *priv = GET_PRIVATE(object);
86 if (!priv) return FALSE;
88 LocationPosition *pos = NULL;
89 LocationAccuracy *acc = NULL;
92 pos = location_position_copy(priv->pos);
95 pos = location_position_new (0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
99 acc = location_accuracy_copy (priv->acc);
102 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
105 LOCATION_LOGD("POSITION SERVICE_UPDATED");
106 g_signal_emit(object, signals[SERVICE_UPDATED], 0, POSITION_UPDATED, pos, acc);
108 location_position_free (pos);
109 location_accuracy_free (acc);
115 _velocity_timeout_cb (gpointer data)
117 GObject *object = (GObject *)data;
118 LocationWpsPrivate *priv = GET_PRIVATE(object);
119 if (!priv) return FALSE;
121 LocationVelocity *vel = NULL;
122 LocationAccuracy *acc = NULL;
125 vel = location_velocity_copy(priv->vel);
128 vel = location_velocity_new (0, 0.0, 0.0, 0.0);
132 acc = location_accuracy_copy (priv->acc);
135 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
138 LOCATION_LOGD("POSITION SERVICE_UPDATED");
139 g_signal_emit(object, signals[SERVICE_UPDATED], 0, VELOCITY_UPDATED, vel, acc);
141 location_velocity_free (vel);
142 location_accuracy_free (acc);
148 wps_status_cb (gboolean enabled,
149 LocationStatus status,
152 LOCATION_LOGD("wps_status_cb");
153 g_return_if_fail(self);
154 LocationWpsPrivate* priv = GET_PRIVATE(self);
155 enable_signaling(self, signals, &(priv->enabled), enabled, status);
156 if (!priv->enabled) {
157 if (priv->pos_timer) {
158 g_source_remove (priv->pos_timer);
161 if (priv->vel_timer) {
162 g_source_remove (priv->vel_timer);
169 wps_position_cb (gboolean enabled,
170 LocationPosition *pos,
171 LocationAccuracy *acc,
174 LOCATION_LOGD("wps_position_cb");
175 g_return_if_fail(self);
176 g_return_if_fail(pos);
177 g_return_if_fail(acc);
178 LocationWpsPrivate* priv = GET_PRIVATE(self);
180 if (!priv->enabled && enabled) {
181 if (!priv->pos_timer) priv->pos_timer = g_timeout_add_seconds (priv->pos_interval, _position_timeout_cb, self);
182 if (!priv->vel_timer) priv->vel_timer = g_timeout_add_seconds (priv->vel_interval, _velocity_timeout_cb, self);
185 enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
186 position_signaling(self, signals, &(priv->enabled), priv->pos_interval, FALSE, &(priv->pos_updated_timestamp), &(priv->pos), priv->boundary_list, &(priv->zone_status), pos, acc);
190 wps_velocity_cb(gboolean enabled,
191 LocationVelocity *vel,
192 LocationAccuracy *acc,
195 LOCATION_LOGD("wps_velocity_cb");
196 g_return_if_fail(self);
197 LocationWpsPrivate* priv = GET_PRIVATE(self);
198 velocity_signaling(self, signals, &(priv->enabled), priv->vel_interval, FALSE, &(priv->vel_updated_timestamp), &(priv->vel), &(priv->acc), vel, acc);
202 location_setting_wps_cb(keynode_t *key,
205 LOCATION_LOGD("location_setting_wps_cb");
206 g_return_if_fail(key);
207 g_return_if_fail(self);
208 LocationWpsPrivate* priv = GET_PRIVATE(self);
209 g_return_if_fail (priv->mod);
210 g_return_if_fail (priv->mod->handler);
212 int ret = LOCATION_ERROR_NONE;
214 if (location_setting_get_key_val(key) == 0) {
215 if (priv->mod->ops.stop && priv->is_started) {
216 ret = priv->mod->ops.stop(priv->mod->handler);
217 if (ret == LOCATION_ERROR_NONE) {
218 priv->is_started = FALSE;
223 if (1 == location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED) && priv->mod->ops.start && !priv->is_started) {
224 LOCATION_LOGD("location resumed by setting");
225 ret = priv->mod->ops.start (priv->mod->handler, wps_status_cb, wps_position_cb, wps_velocity_cb, NULL, self);
226 if (ret == LOCATION_ERROR_NONE) {
227 priv->is_started = TRUE;
235 location_wps_start (LocationWps *self)
237 LOCATION_LOGD("location_wps_start");
238 LocationWpsPrivate* priv = GET_PRIVATE(self);
239 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
240 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
241 g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
243 if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
245 int ret = LOCATION_ERROR_NONE;
247 if (!location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
248 ret = LOCATION_ERROR_NOT_ALLOWED;
251 ret = priv->mod->ops.start (priv->mod->handler, wps_status_cb, wps_position_cb, wps_velocity_cb, NULL, self);
252 if (ret == LOCATION_ERROR_NONE) {
253 priv->is_started = TRUE;
260 if (priv->set_noti == FALSE) {
261 location_setting_add_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_wps_cb, self);
262 priv->set_noti = TRUE;
269 location_wps_stop (LocationWps *self)
271 LOCATION_LOGD("location_wps_stop");
272 LocationWpsPrivate* priv = GET_PRIVATE(self);
273 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
274 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
275 g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
277 int ret = LOCATION_ERROR_NONE;
279 if (priv->is_started == TRUE) {
280 ret = priv->mod->ops.stop (priv->mod->handler);
281 if (ret == LOCATION_ERROR_NONE) {
282 priv->is_started = FALSE;
289 if (priv->set_noti == TRUE) {
290 location_setting_ignore_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_wps_cb);
291 priv->set_noti = FALSE;
298 location_wps_dispose (GObject *gobject)
300 LOCATION_LOGD("location_wps_dispose");
302 LocationWpsPrivate* priv = GET_PRIVATE(gobject);
303 if (priv->set_noti == TRUE) {
304 location_setting_ignore_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_wps_cb);
305 priv->set_noti = FALSE;
307 if (priv->pos_timer) {
308 g_source_remove (priv->pos_timer);
311 if (priv->vel_timer) {
312 g_source_remove (priv->vel_timer);
318 G_OBJECT_CLASS (location_wps_parent_class)->dispose (gobject);
322 location_wps_finalize (GObject *gobject)
324 LOCATION_LOGD("location_wps_finalize");
325 LocationWpsPrivate* priv = GET_PRIVATE(gobject);
326 module_free(priv->mod, "wps");
328 if (priv->boundary_list) {
329 g_list_free_full (priv->boundary_list, free_boundary_list);
330 priv->boundary_list = NULL;
334 location_position_free(priv->pos);
339 location_velocity_free(priv->vel);
344 location_accuracy_free(priv->acc);
347 G_OBJECT_CLASS (location_wps_parent_class)->finalize (gobject);
351 location_wps_set_property (GObject *object,
356 LocationWpsPrivate* priv = GET_PRIVATE(object);
359 switch (property_id){
361 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
362 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
363 if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
366 case PROP_REMOVAL_BOUNDARY: {
367 LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
368 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
369 if(ret != 0) LOCATION_LOGD("Set removal boundary. Error[%d]", ret);
372 case PROP_POS_INTERVAL: {
373 guint interval = g_value_get_uint(value);
375 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
376 priv->pos_interval = interval;
378 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
381 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
383 if (priv->pos_timer) {
384 g_source_remove (priv->pos_timer);
385 priv->pos_timer = g_timeout_add_seconds (priv->pos_interval, _position_timeout_cb, object);
390 case PROP_VEL_INTERVAL: {
391 guint interval = g_value_get_uint(value);
393 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
394 priv->vel_interval = interval;
396 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
399 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
401 if (priv->vel_timer) {
402 g_source_remove (priv->vel_timer);
403 priv->vel_timer = g_timeout_add_seconds (priv->vel_interval, _velocity_timeout_cb, object);
409 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
415 location_wps_get_property (GObject *object,
420 LocationWpsPrivate *priv = GET_PRIVATE (object);
422 switch (property_id){
423 case PROP_METHOD_TYPE:
424 g_value_set_int(value, LOCATION_METHOD_WPS);
426 case PROP_LAST_POSITION:
427 g_value_set_boxed (value, priv->pos);
430 g_value_set_pointer(value, g_list_first(priv->boundary_list));
432 case PROP_POS_INTERVAL:
433 g_value_set_uint(value, priv->pos_interval);
435 case PROP_VEL_INTERVAL:
436 g_value_set_uint(value, priv->vel_interval);
439 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
445 location_wps_get_position (LocationWps *self,
446 LocationPosition **position,
447 LocationAccuracy **accuracy)
449 int ret = LOCATION_ERROR_NOT_AVAILABLE;
450 LOCATION_LOGD("location_wps_get_position");
452 LocationWpsPrivate *priv = GET_PRIVATE (self);
453 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
454 setting_retval_if_fail(VCONFKEY_LOCATION_NETWORK_ENABLED);
457 *position = location_position_copy (priv->pos);
458 ret = LOCATION_ERROR_NONE;
461 *accuracy = location_accuracy_copy (priv->acc);
468 location_wps_get_last_position (LocationWps *self,
469 LocationPosition **position,
470 LocationAccuracy **accuracy)
472 LOCATION_LOGD("location_wps_get_last_position");
474 /* Do not need to check VCONFKEY_LOCATION_ENABLED and VCONFKEY_LOCATION_NETWORK_ENABLED */
476 LocationWpsPrivate *priv = GET_PRIVATE (self);
477 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
479 LocModWpsOps ops = priv->mod->ops;
480 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
481 g_return_val_if_fail (ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
483 return ops.get_last_position(priv->mod->handler, position, accuracy);
488 location_wps_get_velocity (LocationWps *self,
489 LocationVelocity **velocity,
490 LocationAccuracy **accuracy)
492 int ret = LOCATION_ERROR_NOT_AVAILABLE;
493 LOCATION_LOGD("location_wps_get_velocity");
495 LocationWpsPrivate *priv = GET_PRIVATE (self);
496 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
497 setting_retval_if_fail(VCONFKEY_LOCATION_NETWORK_ENABLED);
500 *velocity = location_velocity_copy (priv->vel);
501 ret = LOCATION_ERROR_NONE;
505 *accuracy = location_accuracy_copy (priv->acc);
512 location_wps_get_last_velocity (LocationWps *self,
513 LocationVelocity **velocity,
514 LocationAccuracy **accuracy)
516 LOCATION_LOGD("location_wps_get_last_velocity");
518 /* Do not need to check VCONFKEY_LOCATION_ENABLED and VCONFKEY_LOCATION_NETWORK_ENABLED */
520 LocationWpsPrivate *priv = GET_PRIVATE (self);
521 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
523 LocModWpsOps ops = priv->mod->ops;
524 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
525 g_return_val_if_fail (ops.get_last_velocity, LOCATION_ERROR_NOT_AVAILABLE);
526 return ops.get_last_velocity(priv->mod->handler, velocity, accuracy);
531 location_wps_get_satellite (LocationWps *self,
532 LocationSatellite **satellite)
534 LOCATION_LOGD("location_wps_get_satellite");
535 return LOCATION_ERROR_NOT_SUPPORTED;
539 location_wps_get_last_satellite (LocationWps *self,
540 LocationSatellite **satellite)
542 LOCATION_LOGD("location_wps_get_last_satellite");
543 return LOCATION_ERROR_NOT_SUPPORTED;
547 location_ielement_interface_init (LocationIElementInterface *iface)
549 iface->start = (TYPE_START_FUNC)location_wps_start;
550 iface->stop = (TYPE_STOP_FUNC)location_wps_stop;
551 iface->get_position = (TYPE_GET_POSITION)location_wps_get_position;
552 iface->get_last_position = (TYPE_GET_POSITION)location_wps_get_last_position;
553 iface->get_velocity = (TYPE_GET_VELOCITY)location_wps_get_velocity;
554 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_wps_get_last_velocity;
555 iface->get_satellite = (TYPE_GET_SATELLITE)location_wps_get_satellite;
556 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_wps_get_last_satellite;
560 location_wps_init (LocationWps *self)
562 LOCATION_LOGD("location_wps_init");
563 LocationWpsPrivate* priv = GET_PRIVATE(self);
565 priv->mod = (LocationWpsMod*)module_new("wps");
566 if(!priv->mod) LOCATION_LOGW("module loading failed");
568 priv->is_started = FALSE;
569 priv->set_noti = FALSE;
570 priv->enabled= FALSE;
572 priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
573 priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
575 priv->pos_updated_timestamp = 0;
576 priv->vel_updated_timestamp = 0;
581 priv->zone_status = ZONE_STATUS_NONE;
582 priv->boundary_list = NULL;
589 location_wps_class_init (LocationWpsClass *klass)
591 LOCATION_LOGD("location_wps_class_init");
592 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
594 gobject_class->set_property = location_wps_set_property;
595 gobject_class->get_property = location_wps_get_property;
597 gobject_class->dispose = location_wps_dispose;
598 gobject_class->finalize = location_wps_finalize;
600 g_type_class_add_private (klass, sizeof (LocationWpsPrivate));
602 signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
603 G_TYPE_FROM_CLASS (klass),
606 G_STRUCT_OFFSET (LocationWpsClass, enabled),
612 signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
613 G_TYPE_FROM_CLASS (klass),
616 G_STRUCT_OFFSET (LocationWpsClass, disabled),
622 signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
623 G_TYPE_FROM_CLASS (klass),
626 G_STRUCT_OFFSET (LocationWpsClass, updated),
628 location_VOID__UINT_POINTER_POINTER,
634 signals[ZONE_IN] = g_signal_new ("zone-in",
635 G_TYPE_FROM_CLASS (klass),
638 G_STRUCT_OFFSET (LocationWpsClass, zone_in),
640 location_VOID__UINT_POINTER_POINTER,
646 signals[ZONE_OUT] = g_signal_new ("zone-out",
647 G_TYPE_FROM_CLASS (klass),
650 G_STRUCT_OFFSET (LocationWpsClass, zone_out),
652 location_VOID__UINT_POINTER_POINTER,
658 properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
660 "location method type name",
666 properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
667 "wps last position prop",
668 "wps last position data",
669 LOCATION_TYPE_POSITION,
672 properties[PROP_POS_INTERVAL] = g_param_spec_uint ("pos-interval",
673 "wps position interval prop",
674 "wps position interval data",
675 LOCATION_UPDATE_INTERVAL_MIN,
676 LOCATION_UPDATE_INTERVAL_MAX,
677 LOCATION_UPDATE_INTERVAL_DEFAULT,
680 properties[PROP_VEL_INTERVAL] = g_param_spec_uint ("vel-interval",
681 "wps velocity interval prop",
682 "wps velocity interval data",
683 LOCATION_UPDATE_INTERVAL_MIN,
684 LOCATION_UPDATE_INTERVAL_MAX,
685 LOCATION_UPDATE_INTERVAL_DEFAULT,
688 properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
693 properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
694 "wps removal boundary prop",
695 "wps removal boundary data",
696 LOCATION_TYPE_BOUNDARY,
699 g_object_class_install_properties (gobject_class,