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/location-setting.h"
27 #include "location/location-log.h"
29 #include "location/location-module-internal.h"
31 #include "location/location-sps.h"
32 #include "location/location-marshal.h"
33 #include "location/location-ielement.h"
34 #include "location/location-signaling-util.h"
35 #include "location/location-common-util.h"
37 typedef struct _LocationSpsPrivate {
42 LocationPosition *pos;
43 LocationVelocity *vel;
44 LocationAccuracy *acc;
46 ZoneStatus zone_status;
47 LocationPosition *pos_base;
48 LocationVelocity *vel_base;
49 LocationAccuracy *acc_info;
50 LocationSatellite *sat_info;
59 PROP_REMOVAL_BOUNDARY,
67 static guint32 signals[LAST_SIGNAL] = {0, };
68 static GParamSpec *properties[PROP_MAX] = {NULL, };
70 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_SPS, LocationSpsPrivate))
72 static void location_ielement_interface_init (LocationIElementInterface *iface);
74 G_DEFINE_TYPE_WITH_CODE (LocationSps, location_sps, G_TYPE_OBJECT,
75 G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
76 location_ielement_interface_init));
79 sps_status_cb (gboolean enabled,
80 LocationStatus status,
83 LOCATION_LOGD("sps_status_cb");
84 g_return_if_fail(self);
85 LocationSpsPrivate* priv = GET_PRIVATE(self);
86 enable_signaling(self, signals, &(priv->enabled), enabled, status);
90 sps_position_cb (gboolean enabled,
91 LocationPosition *pos,
92 LocationAccuracy *acc,
95 LOCATION_LOGD("sps_position_cb");
96 g_return_if_fail(self);
97 g_return_if_fail(pos);
98 g_return_if_fail(acc);
99 LocationSpsPrivate* priv = GET_PRIVATE(self);
100 enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
102 position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), enabled, pos, acc);
106 sps_velocity_cb (gboolean enabled,
107 LocationVelocity *vel,
108 LocationAccuracy *acc,
111 LOCATION_LOGD("sps_velocity_cb");
112 g_return_if_fail(self);
113 LocationSpsPrivate* priv = GET_PRIVATE(self);
114 velocity_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->vel), enabled, vel, acc);
118 location_setting_sps_cb(keynode_t *key,
121 LOCATION_LOGD("location_setting_sps_cb");
122 g_return_if_fail(key);
123 g_return_if_fail(self);
124 LocationSpsPrivate* priv = GET_PRIVATE(self);
125 g_return_if_fail (priv->mod);
126 g_return_if_fail (priv->mod->handler);
127 if (0 == location_setting_get_key_val(key) && priv->mod->ops.stop) {
128 LOCATION_LOGD("location stopped by setting");
129 priv->mod->ops.stop(priv->mod->handler);
131 else if (1 == location_setting_get_key_val(key) && priv->mod->ops.start) {
132 LOCATION_LOGD("location resumed by setting");
133 priv->mod->ops.start (priv->mod->handler, sps_status_cb, sps_position_cb, sps_velocity_cb, self);
138 location_sps_start (LocationSps *self)
140 LOCATION_LOGD("location_sps_start");
141 LocationSpsPrivate* priv = GET_PRIVATE(self);
142 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
143 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
144 g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
145 g_return_val_if_fail (priv->mod->ops.update_data, LOCATION_ERROR_NOT_AVAILABLE);
146 setting_retval_if_fail(GPS_ENABLED);
147 setting_retval_if_fail(SENSOR_ENABLED);
148 if( priv->is_started == TRUE) return LOCATION_ERROR_NONE;
150 int ret = priv->mod->ops.start(priv->mod->handler, sps_status_cb, sps_position_cb, sps_velocity_cb, self);
151 if(ret == LOCATION_ERROR_NONE){
152 priv->is_started = TRUE;
153 location_setting_add_notify (GPS_ENABLED, location_setting_sps_cb, self);
154 location_setting_add_notify (SENSOR_ENABLED, location_setting_sps_cb, self);
155 priv->mod->ops.update_data(priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
161 location_sps_stop (LocationSps *self)
163 LOCATION_LOGD("location_sps_stop");
164 LocationSpsPrivate* priv = GET_PRIVATE(self);
165 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
166 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
167 g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
168 if (priv->is_started == FALSE) return LOCATION_ERROR_NONE;
170 int ret = priv->mod->ops.stop (priv->mod->handler);
171 if (ret == LOCATION_ERROR_NONE){
172 priv->is_started = FALSE;
173 location_setting_ignore_notify (GPS_ENABLED, location_setting_sps_cb);
174 location_setting_ignore_notify (SENSOR_ENABLED, location_setting_sps_cb);
180 location_sps_dispose (GObject *gobject)
182 LOCATION_LOGD("location_sps_dispose");
183 G_OBJECT_CLASS (location_sps_parent_class)->dispose (gobject);
187 location_sps_finalize (GObject *gobject)
189 LOCATION_LOGD("location_sps_finalize");
190 LocationSpsPrivate* priv = GET_PRIVATE(gobject);
191 module_free(priv->mod, "sps");
193 G_OBJECT_CLASS (location_sps_parent_class)->finalize (gobject);
197 location_sps_set_property (GObject *object,
202 LocationSpsPrivate* priv = GET_PRIVATE(object);
204 g_return_if_fail (priv->mod);
205 g_return_if_fail (priv->mod->handler);
206 LocModSpsOps ops = priv->mod->ops;
207 g_return_if_fail (ops.update_data);
210 switch (property_id){
212 GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
213 ret = set_prop_boundary(&priv->boundary_list, boundary_list);
214 if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
217 case PROP_REMOVAL_BOUNDARY: {
218 LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
219 ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
220 if(ret != 0) LOCATION_LOGD("Removal boundary. Error[%d]", ret);
223 case PROP_POSITION_BASE:{
224 if(priv->pos_base) location_position_free(priv->pos_base);
225 priv->pos_base = (LocationPosition*) g_value_dup_boxed (value);
226 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);
227 if (priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
230 case PROP_VELOCITY_BASE:{
231 if(priv->vel_base) location_velocity_free(priv->vel_base);
232 priv->vel_base = (LocationVelocity*) g_value_dup_boxed (value);
233 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);
234 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
237 case PROP_ACCURACY_INFO:{
238 if(priv->acc_info) location_accuracy_free(priv->acc_info);
239 priv->acc_info = (LocationAccuracy*) g_value_dup_boxed (value);
240 LOCATION_LOGD("Set prop>> accuracy information: \t%d, %lf, %lf", priv->acc_info->level, priv->acc_info->horizontal_accuracy, priv->acc_info->vertical_accuracy);
241 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
244 case PROP_SATELLITE_INFO:{
245 if(priv->sat_info) location_satellite_free(priv->sat_info);
246 priv->sat_info = (LocationSatellite*) g_value_dup_boxed (value);
247 LOCATION_LOGD("Set prop>> satellite information: \tNofView:%d, NofUsed:%d", priv->sat_info->num_of_sat_inview, priv->sat_info->num_of_sat_used);
248 if(priv->is_started) ops.update_data (priv->mod->handler, priv->pos_base, priv->vel_base, priv->acc_info, priv->sat_info);
251 case PROP_UPDATE_INTERVAL: {
252 guint interval = g_value_get_uint(value);
254 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
255 priv->interval = interval;
257 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
261 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
265 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
271 location_sps_get_property (GObject *object,
276 LocationSpsPrivate *priv = GET_PRIVATE (object);
278 switch (property_id){
279 case PROP_METHOD_TYPE:
280 g_value_set_int(value, LOCATION_METHOD_SPS);
282 case PROP_LAST_POSITION:
283 g_value_set_boxed (value, priv->pos);
286 g_value_set_pointer(value, g_list_first(priv->boundary_list));
288 case PROP_POSITION_BASE:
289 g_value_set_boxed (value, priv->pos_base);
291 case PROP_VELOCITY_BASE:
292 g_value_set_boxed (value, priv->vel_base);
294 case PROP_ACCURACY_INFO:
295 g_value_set_boxed (value, priv->acc_info);
297 case PROP_SATELLITE_INFO:
298 g_value_set_boxed (value, priv->sat_info);
300 case PROP_UPDATE_INTERVAL:
301 g_value_set_uint(value, priv->interval);
304 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
310 location_sps_get_position (LocationSps *self,
311 LocationPosition **position,
312 LocationAccuracy **accuracy)
314 LOCATION_LOGD("location_sps_get_position");
316 LocationSpsPrivate *priv = GET_PRIVATE (self);
317 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
318 setting_retval_if_fail(GPS_ENABLED);
319 setting_retval_if_fail(SENSOR_ENABLED);
321 LocModSpsOps ops = priv->mod->ops;
322 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
323 g_return_val_if_fail (ops.get_position, LOCATION_ERROR_NOT_AVAILABLE);
324 return ops.get_position(priv->mod->handler, position, accuracy);
328 location_sps_get_velocity (LocationSps *self,
329 LocationVelocity **velocity,
330 LocationAccuracy **accuracy)
332 LOCATION_LOGD("location_sps_get_velocity");
334 LocationSpsPrivate *priv = GET_PRIVATE (self);
335 g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
336 setting_retval_if_fail(GPS_ENABLED);
337 setting_retval_if_fail(SENSOR_ENABLED);
339 LocModSpsOps ops = priv->mod->ops;
340 g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
341 g_return_val_if_fail (ops.get_velocity, LOCATION_ERROR_NOT_AVAILABLE);
342 return ops.get_velocity(priv->mod->handler, velocity, accuracy);
346 location_ielement_interface_init (LocationIElementInterface *iface)
348 iface->start = (TYPE_START_FUNC)location_sps_start;
349 iface->stop = (TYPE_STOP_FUNC)location_sps_stop;
350 iface->get_position = (TYPE_GET_POSITION)location_sps_get_position;
351 iface->get_velocity = (TYPE_GET_VELOCITY)location_sps_get_velocity;
355 location_sps_init (LocationSps *self)
357 LOCATION_LOGD("location_sps_init");
358 LocationSpsPrivate* priv = GET_PRIVATE(self);
360 priv->mod = (LocationSpsMod*)module_new("sps");
362 LOCATION_LOGW("module loading failed");
364 priv->is_started = FALSE;
365 priv->enabled= FALSE;
366 priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
370 priv->zone_status = ZONE_STATUS_NONE;
371 priv->boundary_list = NULL;
373 priv->pos_base = NULL;
374 priv->vel_base = NULL;
375 priv->acc_info = NULL;
376 priv->sat_info = NULL;
380 location_sps_class_init (LocationSpsClass *klass)
382 LOCATION_LOGD("location_sps_class_init");
383 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
385 gobject_class->set_property = location_sps_set_property;
386 gobject_class->get_property = location_sps_get_property;
388 gobject_class->dispose = location_sps_dispose;
389 gobject_class->finalize = location_sps_finalize;
391 g_type_class_add_private (klass, sizeof (LocationSpsPrivate));
393 signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
394 G_TYPE_FROM_CLASS (klass),
397 G_STRUCT_OFFSET (LocationSpsClass, enabled),
403 signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
404 G_TYPE_FROM_CLASS (klass),
407 G_STRUCT_OFFSET (LocationSpsClass, disabled),
413 signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
414 G_TYPE_FROM_CLASS (klass),
417 G_STRUCT_OFFSET (LocationSpsClass, updated),
419 location_VOID__UINT_POINTER_POINTER,
425 signals[ZONE_IN] = g_signal_new ("zone-in",
426 G_TYPE_FROM_CLASS (klass),
429 G_STRUCT_OFFSET (LocationSpsClass, zone_in),
431 location_VOID__UINT_POINTER_POINTER,
437 signals[ZONE_OUT] = g_signal_new ("zone-out",
438 G_TYPE_FROM_CLASS (klass),
441 G_STRUCT_OFFSET (LocationSpsClass, zone_out),
443 location_VOID__UINT_POINTER_POINTER,
449 properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
451 "location method type name",
457 properties[PROP_LAST_POSITION] = g_param_spec_boxed ("last-position",
458 "sps last position prop",
459 "sps last position data",
460 LOCATION_TYPE_POSITION,
463 properties[PROP_UPDATE_INTERVAL] = g_param_spec_uint ("update-interval",
464 "sps update interval prop",
465 "sps update interval data",
466 LOCATION_UPDATE_INTERVAL_MIN,
467 LOCATION_UPDATE_INTERVAL_MAX,
468 LOCATION_UPDATE_INTERVAL_DEFAULT,
471 properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
476 properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
477 "sps removal boundary prop",
478 "sps removal boundary data",
479 LOCATION_TYPE_BOUNDARY,
482 properties[PROP_POSITION_BASE] = g_param_spec_boxed ("position-base",
483 "sps position base prop",
484 "sps position base data",
485 LOCATION_TYPE_POSITION,
488 properties[PROP_VELOCITY_BASE] = g_param_spec_boxed ("velocity-base",
489 "sps velocity base prop",
490 "sps velocity base data",
491 LOCATION_TYPE_VELOCITY,
494 properties[PROP_ACCURACY_INFO] = g_param_spec_boxed ("accuracy-info",
495 "sps accuracy information prop",
496 "sps accuracy information data",
497 LOCATION_TYPE_ACCURACY,
500 properties[PROP_SATELLITE_INFO] = g_param_spec_boxed ("satellite-info",
501 "sps satellite information prop",
502 "sps satellite information data",
503 LOCATION_TYPE_SATELLITE,
506 g_object_class_install_properties (gobject_class,