Git init
[framework/location/libslp-location.git] / location / location-sps.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include "location/location-setting.h"
27 #include "location/location-log.h"
28
29 #include "location/location-module-internal.h"
30
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"
36
37 typedef struct _LocationSpsPrivate {
38         LocationSpsMod* mod;
39         gboolean is_started;
40         gboolean enabled;
41         guint    interval;
42         LocationPosition *pos;
43         LocationVelocity *vel;
44         LocationAccuracy *acc;
45         GList *boundary_list;
46         ZoneStatus zone_status;
47         LocationPosition *pos_base;
48         LocationVelocity *vel_base;
49         LocationAccuracy *acc_info;
50         LocationSatellite *sat_info;
51 } LocationSpsPrivate;
52
53 enum {
54         PROP_0,
55         PROP_METHOD_TYPE,
56         PROP_LAST_POSITION,
57         PROP_UPDATE_INTERVAL,
58         PROP_BOUNDARY,
59         PROP_REMOVAL_BOUNDARY,
60         PROP_POSITION_BASE,
61         PROP_VELOCITY_BASE,
62         PROP_ACCURACY_INFO,
63         PROP_SATELLITE_INFO,
64         PROP_MAX
65 };
66
67 static guint32 signals[LAST_SIGNAL] = {0, };
68 static GParamSpec *properties[PROP_MAX] = {NULL, };
69
70 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_SPS, LocationSpsPrivate))
71
72 static void location_ielement_interface_init (LocationIElementInterface *iface);
73
74 G_DEFINE_TYPE_WITH_CODE (LocationSps, location_sps, G_TYPE_OBJECT,
75                          G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
76                          location_ielement_interface_init));
77
78 static void
79 sps_status_cb (gboolean enabled,
80         LocationStatus status,
81         gpointer self)
82 {
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);
87 }
88
89 static void
90 sps_position_cb (gboolean enabled,
91         LocationPosition *pos,
92         LocationAccuracy *acc,
93         gpointer self)
94 {
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);
101
102         position_signaling(self, signals, &(priv->enabled), priv->interval, &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), enabled, pos, acc);
103 }
104
105 static void
106 sps_velocity_cb (gboolean enabled,
107         LocationVelocity *vel,
108         LocationAccuracy *acc,
109         gpointer self)
110 {
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);
115 }
116
117 static void
118 location_setting_sps_cb(keynode_t *key,
119         gpointer self)
120 {
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);
130         }
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);
134         }
135 }
136
137 static int
138 location_sps_start (LocationSps *self)
139 {
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;
149
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);
156         }
157         return ret;
158 }
159
160 static int
161 location_sps_stop (LocationSps *self)
162 {
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;
169
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);
175         }
176         return ret;
177 }
178
179 static void
180 location_sps_dispose (GObject *gobject)
181 {
182         LOCATION_LOGD("location_sps_dispose");
183         G_OBJECT_CLASS (location_sps_parent_class)->dispose (gobject);
184 }
185
186 static void
187 location_sps_finalize (GObject *gobject)
188 {
189         LOCATION_LOGD("location_sps_finalize");
190         LocationSpsPrivate* priv = GET_PRIVATE(gobject);
191         module_free(priv->mod, "sps");
192         priv->mod = NULL;
193         G_OBJECT_CLASS (location_sps_parent_class)->finalize (gobject);
194 }
195
196 static void
197 location_sps_set_property (GObject *object,
198         guint property_id,
199         const GValue *value,
200         GParamSpec *pspec)
201 {
202         LocationSpsPrivate* priv = GET_PRIVATE(object);
203
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);
208
209         int ret = 0;
210         switch (property_id){
211                 case PROP_BOUNDARY:{
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);
215          break;
216                 }
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);
221                         break;
222                 }
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);
228                         break;
229                 }
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);
235                         break;
236                 }
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);
242                         break;
243                 }
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);
249                         break;
250                 }
251                 case PROP_UPDATE_INTERVAL: {
252                         guint interval = g_value_get_uint(value);
253                         if(interval > 0) {
254                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
255                                         priv->interval = interval;
256                                 else
257                                         priv->interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
258
259                         }
260                         else
261                                 priv->interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
262                         break;
263                 }
264                 default:
265                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
266                         break;
267         }
268 }
269
270 static void
271 location_sps_get_property (GObject *object,
272                            guint property_id,
273                            GValue *value,
274                            GParamSpec *pspec)
275 {
276         LocationSpsPrivate *priv = GET_PRIVATE (object);
277
278         switch (property_id){
279                 case PROP_METHOD_TYPE:
280                         g_value_set_int(value, LOCATION_METHOD_SPS);
281                         break;
282                 case PROP_LAST_POSITION:
283                         g_value_set_boxed (value, priv->pos);
284                         break;
285                 case PROP_BOUNDARY:
286                         g_value_set_pointer(value, g_list_first(priv->boundary_list));
287                         break;
288                 case PROP_POSITION_BASE:
289                         g_value_set_boxed (value, priv->pos_base);
290                         break;
291                 case PROP_VELOCITY_BASE:
292                         g_value_set_boxed (value, priv->vel_base);
293                         break;
294                 case PROP_ACCURACY_INFO:
295                         g_value_set_boxed (value, priv->acc_info);
296                         break;
297                 case PROP_SATELLITE_INFO:
298                         g_value_set_boxed (value, priv->sat_info);
299                         break;
300                 case PROP_UPDATE_INTERVAL:
301                         g_value_set_uint(value, priv->interval);
302                         break;
303                 default:
304                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
305                         break;
306         }
307 }
308
309 static int
310 location_sps_get_position (LocationSps *self,
311         LocationPosition **position,
312         LocationAccuracy **accuracy)
313 {
314         LOCATION_LOGD("location_sps_get_position");
315
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);
320
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);
325 }
326
327 static int
328 location_sps_get_velocity (LocationSps *self,
329         LocationVelocity **velocity,
330         LocationAccuracy **accuracy)
331 {
332         LOCATION_LOGD("location_sps_get_velocity");
333
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);
338
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);
343 }
344
345 static void
346 location_ielement_interface_init (LocationIElementInterface *iface)
347 {
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;
352 }
353
354 static void
355 location_sps_init (LocationSps *self)
356 {
357         LOCATION_LOGD("location_sps_init");
358         LocationSpsPrivate* priv = GET_PRIVATE(self);
359
360         priv->mod = (LocationSpsMod*)module_new("sps");
361         if(!priv->mod)
362                 LOCATION_LOGW("module loading failed");
363
364         priv->is_started = FALSE;
365         priv->enabled= FALSE;
366         priv->interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
367         priv->pos = NULL;
368         priv->vel = NULL;
369         priv->acc = NULL;
370         priv->zone_status = ZONE_STATUS_NONE;
371         priv->boundary_list = NULL;
372
373         priv->pos_base = NULL;
374         priv->vel_base = NULL;
375         priv->acc_info = NULL;
376         priv->sat_info = NULL;
377 }
378
379 static void
380 location_sps_class_init (LocationSpsClass *klass)
381 {
382         LOCATION_LOGD("location_sps_class_init");
383         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
384
385         gobject_class->set_property = location_sps_set_property;
386         gobject_class->get_property = location_sps_get_property;
387
388         gobject_class->dispose = location_sps_dispose;
389         gobject_class->finalize = location_sps_finalize;
390
391         g_type_class_add_private (klass, sizeof (LocationSpsPrivate));
392
393         signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
394                         G_TYPE_FROM_CLASS (klass),
395                         G_SIGNAL_RUN_FIRST |
396                         G_SIGNAL_NO_RECURSE,
397                         G_STRUCT_OFFSET (LocationSpsClass, enabled),
398                         NULL, NULL,
399                         location_VOID__UINT,
400                         G_TYPE_NONE, 1,
401                         G_TYPE_UINT);
402
403         signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
404                         G_TYPE_FROM_CLASS (klass),
405                         G_SIGNAL_RUN_FIRST |
406                         G_SIGNAL_NO_RECURSE,
407                         G_STRUCT_OFFSET (LocationSpsClass, disabled),
408                         NULL, NULL,
409                         location_VOID__UINT,
410                         G_TYPE_NONE, 1,
411                         G_TYPE_UINT);
412
413         signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
414                         G_TYPE_FROM_CLASS (klass),
415                         G_SIGNAL_RUN_FIRST |
416                         G_SIGNAL_NO_RECURSE,
417                         G_STRUCT_OFFSET (LocationSpsClass, updated),
418                         NULL, NULL,
419                         location_VOID__UINT_POINTER_POINTER,
420                         G_TYPE_NONE, 3,
421                         G_TYPE_UINT,
422                         G_TYPE_POINTER,
423                         G_TYPE_POINTER);
424
425         signals[ZONE_IN] = g_signal_new ("zone-in",
426                         G_TYPE_FROM_CLASS (klass),
427                         G_SIGNAL_RUN_FIRST |
428                         G_SIGNAL_NO_RECURSE,
429                         G_STRUCT_OFFSET (LocationSpsClass, zone_in),
430                         NULL, NULL,
431                         location_VOID__UINT_POINTER_POINTER,
432                         G_TYPE_NONE, 3,
433                         G_TYPE_UINT,
434                         G_TYPE_POINTER,
435                         G_TYPE_POINTER);
436
437         signals[ZONE_OUT] = g_signal_new ("zone-out",
438                         G_TYPE_FROM_CLASS (klass),
439                         G_SIGNAL_RUN_FIRST |
440                         G_SIGNAL_NO_RECURSE,
441                         G_STRUCT_OFFSET (LocationSpsClass, zone_out),
442                         NULL, NULL,
443                         location_VOID__UINT_POINTER_POINTER,
444                         G_TYPE_NONE, 3,
445                         G_TYPE_UINT,
446                         G_TYPE_POINTER,
447                         G_TYPE_POINTER);
448
449         properties[PROP_METHOD_TYPE]  = g_param_spec_int ("method",
450                         "method type",
451                         "location method type name",
452                         LOCATION_METHOD_SPS,
453                         LOCATION_METHOD_SPS,
454                         LOCATION_METHOD_SPS,
455                         G_PARAM_READABLE);
456
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,
461                         G_PARAM_READABLE);
462
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,
469                         G_PARAM_READWRITE);
470
471         properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
472                         "sps boundary prop",
473                         "sps boundary data",
474                         G_PARAM_READWRITE);
475
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,
480                         G_PARAM_READWRITE);
481
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,
486                         G_PARAM_READWRITE);
487
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,
492                         G_PARAM_READWRITE);
493
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,
498                         G_PARAM_READWRITE);
499
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,
504                         G_PARAM_READWRITE);
505
506         g_object_class_install_properties (gobject_class,
507                         PROP_MAX,
508                         properties);
509 }