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 {
46 LocationPosition *pos;
47 LocationVelocity *vel;
48 LocationAccuracy *acc;
50 ZoneStatus zone_status;
59 PROP_REMOVAL_BOUNDARY,
63 static guint32 signals[LAST_SIGNAL] = {0, };
64 static GParamSpec *properties[PROP_MAX] = {NULL, };
66 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_WPS, LocationWpsPrivate))
68 static void location_ielement_interface_init (LocationIElementInterface *iface);
70 G_DEFINE_TYPE_WITH_CODE (LocationWps, location_wps, G_TYPE_OBJECT,
71 G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
72 location_ielement_interface_init));
75 wps_status_cb (gboolean enabled,
76 LocationStatus status,
79 LOCATION_LOGD("wps_status_cb");
80 g_return_if_fail(self);
81 LocationWpsPrivate* priv = GET_PRIVATE(self);
82 enable_signaling(self, signals, &(priv->enabled), enabled, status);
86 wps_position_cb (gboolean enabled,
87 LocationPosition *pos,
88 LocationAccuracy *acc,
91 LOCATION_LOGD("wps_position_cb");
92 g_return_if_fail(self);
93 g_return_if_fail(pos);
94 g_return_if_fail(acc);
95 LocationWpsPrivate* priv = GET_PRIVATE(self);
96 enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
97 position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), enabled, pos, acc);
101 wps_velocity_cb(gboolean enabled,
102 LocationVelocity *vel,
103 LocationAccuracy *acc,
106 LOCATION_LOGD("wps_velocity_cb");
107 g_return_if_fail(self);
108 LocationWpsPrivate* priv = GET_PRIVATE(self);
109 velocity_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->vel), enabled, vel, acc);
113 location_setting_wps_cb(keynode_t *key,
116 LOCATION_LOGD("location_setting_wps_cb");
117 g_return_if_fail(key);
118 g_return_if_fail(self);
119 LocationWpsPrivate* priv = GET_PRIVATE(self);
120 g_return_if_fail (priv->mod);
121 g_return_if_fail (priv->mod->handler);
123 int ret = LOCATION_ERROR_NONE;
125 if (location_setting_get_key_val(key) == 0) {
126 if (priv->mod->ops.stop && priv->is_started) {
127 ret = priv->mod->ops.stop(priv->mod->handler);
128 if (ret == LOCATION_ERROR_NONE) priv->is_started = FALSE;
132 if (1 == location_setting_get_int(NETWORK_ENABLED) && priv->mod->ops.start && !priv->is_started) {
133 LOCATION_LOGD("location resumed by setting");
134 ret = priv->mod->ops.start (priv->mod->handler, wps_status_cb, wps_position_cb, wps_velocity_cb, NULL, self);
135 if (ret == LOCATION_ERROR_NONE) priv->is_started = TRUE;
142 location_wps_start (LocationWps *self)
144 LOCATION_LOGD("location_wps_start");
145 LocationWpsPrivate* priv = GET_PRIVATE(self);
146 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
147 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
148 g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
150 if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
152 int ret = LOCATION_ERROR_NONE;
155 if (!location_setting_get_int(GPS_ENABLED) || !location_setting_get_int(NETWORK_ENABLED)) {
156 ret = LOCATION_ERROR_NOT_ALLOWED;
159 ret = priv->mod->ops.start (priv->mod->handler, wps_status_cb, wps_position_cb, wps_velocity_cb, NULL, self);
160 if (ret == LOCATION_ERROR_NONE) {
161 priv->is_started = TRUE;
168 if (priv->set_noti == FALSE) {
169 noti_err = location_setting_add_notify (GPS_ENABLED, location_setting_wps_cb, self);
171 return LOCATION_ERROR_UNKNOWN;
173 noti_err = location_setting_add_notify (NETWORK_ENABLED, location_setting_wps_cb, self);
175 return LOCATION_ERROR_UNKNOWN;
177 priv->set_noti = TRUE;
184 location_wps_stop (LocationWps *self)
186 LOCATION_LOGD("location_wps_stop");
187 LocationWpsPrivate* priv = GET_PRIVATE(self);
188 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
189 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
190 g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
192 int ret = LOCATION_ERROR_NONE;
195 if (priv->is_started == TRUE) {
196 ret = priv->mod->ops.stop (priv->mod->handler);
197 if (ret == LOCATION_ERROR_NONE) {
198 priv->is_started = FALSE;
205 if (priv->set_noti == TRUE) {
206 noti_err = location_setting_ignore_notify (GPS_ENABLED, location_setting_wps_cb);
208 return LOCATION_ERROR_UNKNOWN;
210 noti_err = location_setting_ignore_notify (NETWORK_ENABLED, location_setting_wps_cb);
212 return LOCATION_ERROR_UNKNOWN;
214 priv->set_noti = FALSE;
221 location_wps_dispose (GObject *gobject)
223 LOCATION_LOGD("location_wps_dispose");
224 G_OBJECT_CLASS (location_wps_parent_class)->dispose (gobject);
228 location_wps_finalize (GObject *gobject)
230 LOCATION_LOGD("location_wps_finalize");
231 LocationWpsPrivate* priv = GET_PRIVATE(gobject);
232 module_free(priv->mod, "wps");
233 G_OBJECT_CLASS (location_wps_parent_class)->finalize (gobject);
237 location_wps_set_property (GObject *object,
242 LocationWpsPrivate* priv = GET_PRIVATE(object);
245 switch (property_id){
247 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
248 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
249 if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
252 case PROP_REMOVAL_BOUNDARY: {
253 LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
254 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
255 if(ret != 0) LOCATION_LOGD("Set removal boundary. Error[%d]", ret);
258 case PROP_UPDATE_INTERVAL: {
259 guint interval = g_value_get_uint(value);
261 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
262 priv->interval = interval;
264 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
267 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
271 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
277 location_wps_get_property (GObject *object,
282 LocationWpsPrivate *priv = GET_PRIVATE (object);
284 switch (property_id){
285 case PROP_METHOD_TYPE:
286 g_value_set_int(value, LOCATION_METHOD_WPS);
288 case PROP_LAST_POSITION:
289 g_value_set_boxed (value, priv->pos);
292 g_value_set_pointer(value, g_list_first(priv->boundary_list));
294 case PROP_UPDATE_INTERVAL:
295 g_value_set_uint(value, priv->interval);
298 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
304 location_wps_get_position (LocationWps *self,
305 LocationPosition **position,
306 LocationAccuracy **accuracy)
308 LOCATION_LOGD("location_wps_get_position");
310 LocationWpsPrivate *priv = GET_PRIVATE (self);
311 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
312 setting_retval_if_fail(GPS_ENABLED);
313 setting_retval_if_fail(NETWORK_ENABLED);
315 LocModWpsOps ops = priv->mod->ops;
316 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
317 g_return_val_if_fail (ops.get_position, LOCATION_ERROR_NOT_AVAILABLE);
318 return ops.get_position(priv->mod->handler, position, accuracy);
322 location_wps_get_last_position (LocationWps *self,
323 LocationPosition **position,
324 LocationAccuracy **accuracy)
326 LOCATION_LOGD("location_wps_get_last_position");
328 /* Do not need to check GPS_ENABLED and NETWORK_ENABLED */
330 LocationWpsPrivate *priv = GET_PRIVATE (self);
331 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
333 LocModWpsOps ops = priv->mod->ops;
334 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
335 g_return_val_if_fail (ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
337 return ops.get_last_position(priv->mod->handler, position, accuracy);
342 location_wps_get_velocity (LocationWps *self,
343 LocationVelocity **velocity,
344 LocationAccuracy **accuracy)
346 LOCATION_LOGD("location_wps_get_velocity");
348 LocationWpsPrivate *priv = GET_PRIVATE (self);
349 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
350 setting_retval_if_fail(GPS_ENABLED);
351 setting_retval_if_fail(NETWORK_ENABLED);
353 LocModWpsOps ops = priv->mod->ops;
354 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
355 g_return_val_if_fail (ops.get_velocity, LOCATION_ERROR_NOT_AVAILABLE);
356 return ops.get_velocity(priv->mod->handler, velocity, accuracy);
360 location_wps_get_last_velocity (LocationWps *self,
361 LocationVelocity **velocity,
362 LocationAccuracy **accuracy)
364 LOCATION_LOGD("location_wps_get_last_velocity");
366 /* Do not need to check GPS_ENABLED and NETWORK_ENABLED */
368 LocationWpsPrivate *priv = GET_PRIVATE (self);
369 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
371 LocModWpsOps ops = priv->mod->ops;
372 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
373 g_return_val_if_fail (ops.get_last_velocity, LOCATION_ERROR_NOT_AVAILABLE);
374 return ops.get_last_velocity(priv->mod->handler, velocity, accuracy);
379 location_wps_get_satellite (LocationWps *self,
380 LocationSatellite **satellite)
382 LOCATION_LOGD("location_wps_get_satellite");
383 return LOCATION_ERROR_NOT_SUPPORTED;
387 location_wps_get_last_satellite (LocationWps *self,
388 LocationSatellite **satellite)
390 LOCATION_LOGD("location_wps_get_last_satellite");
391 return LOCATION_ERROR_NOT_SUPPORTED;
395 location_ielement_interface_init (LocationIElementInterface *iface)
397 iface->start = (TYPE_START_FUNC)location_wps_start;
398 iface->stop = (TYPE_STOP_FUNC)location_wps_stop;
399 iface->get_position = (TYPE_GET_POSITION)location_wps_get_position;
400 iface->get_last_position = (TYPE_GET_POSITION)location_wps_get_last_position;
401 iface->get_velocity = (TYPE_GET_VELOCITY)location_wps_get_velocity;
402 iface->get_last_velocity = (TYPE_GET_VELOCITY)location_wps_get_last_velocity;
403 iface->get_satellite = (TYPE_GET_SATELLITE)location_wps_get_satellite;
404 iface->get_last_satellite = (TYPE_GET_SATELLITE)location_wps_get_last_satellite;
408 location_wps_init (LocationWps *self)
410 LOCATION_LOGD("location_wps_init");
411 LocationWpsPrivate* priv = GET_PRIVATE(self);
413 priv->mod = (LocationWpsMod*)module_new("wps");
414 if(!priv->mod) LOCATION_LOGW("module loading failed");
416 priv->is_started = FALSE;
417 priv->set_noti = FALSE;
418 priv->enabled= FALSE;
419 priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
424 priv->zone_status = ZONE_STATUS_NONE;
425 priv->boundary_list = NULL;
429 location_wps_class_init (LocationWpsClass *klass)
431 LOCATION_LOGD("location_wps_class_init");
432 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
434 gobject_class->set_property = location_wps_set_property;
435 gobject_class->get_property = location_wps_get_property;
437 gobject_class->dispose = location_wps_dispose;
438 gobject_class->finalize = location_wps_finalize;
440 g_type_class_add_private (klass, sizeof (LocationWpsPrivate));
442 signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
443 G_TYPE_FROM_CLASS (klass),
446 G_STRUCT_OFFSET (LocationWpsClass, enabled),
452 signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
453 G_TYPE_FROM_CLASS (klass),
456 G_STRUCT_OFFSET (LocationWpsClass, disabled),
462 signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
463 G_TYPE_FROM_CLASS (klass),
466 G_STRUCT_OFFSET (LocationWpsClass, updated),
468 location_VOID__UINT_POINTER_POINTER,
474 signals[ZONE_IN] = g_signal_new ("zone-in",
475 G_TYPE_FROM_CLASS (klass),
478 G_STRUCT_OFFSET (LocationWpsClass, zone_in),
480 location_VOID__UINT_POINTER_POINTER,
486 signals[ZONE_OUT] = g_signal_new ("zone-out",
487 G_TYPE_FROM_CLASS (klass),
490 G_STRUCT_OFFSET (LocationWpsClass, zone_out),
492 location_VOID__UINT_POINTER_POINTER,
498 properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
500 "location method type name",
506 properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
507 "wps last position prop",
508 "wps last position data",
509 LOCATION_TYPE_POSITION,
512 properties[PROP_UPDATE_INTERVAL] = g_param_spec_uint ("update-interval",
513 "wps update interval prop",
514 "wps update interval data",
515 LOCATION_UPDATE_INTERVAL_MIN,
516 LOCATION_UPDATE_INTERVAL_MAX,
517 LOCATION_UPDATE_INTERVAL_DEFAULT,
520 properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
525 properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
526 "wps removal boundary prop",
527 "wps removal boundary data",
528 LOCATION_TYPE_BOUNDARY,
531 g_object_class_install_properties (gobject_class,