Release Tizen2.0 beta
[platform/core/location/lbs-location.git] / location / manager / location-cps.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-setting.h"
27 #include "location-log.h"
28
29 #include "module-internal.h"
30
31 #include "location-cps.h"
32 #include "location-marshal.h"
33 #include "location-ielement.h"
34 #include "location-signaling-util.h"
35 #include "location-common-util.h"
36
37 typedef struct _LocationCpsPrivate {
38         LocationCpsMod *mod;
39         gboolean is_started;
40         gboolean set_noti;
41         gboolean enabled;
42         guint pos_updated_timestamp;
43         guint pos_interval;
44         guint vel_updated_timestamp;
45         guint vel_interval;
46         LocationPosition *pos;
47         LocationVelocity *vel;
48         LocationAccuracy *acc;
49         GList *boundary_list;
50         ZoneStatus zone_status;
51         guint pos_timer;
52         guint vel_timer;
53 } LocationCpsPrivate;
54
55 enum {
56         PROP_0,
57         PROP_METHOD_TYPE,
58         PROP_POS_INTERVAL,
59         PROP_VEL_INTERVAL,
60         PROP_BOUNDARY,
61         PROP_REMOVAL_BOUNDARY,
62         PROP_MAX
63 };
64
65 static guint32 signals[LAST_SIGNAL] = {0, };
66 static GParamSpec *properties[PROP_MAX] = {NULL, };
67
68
69 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_CPS, LocationCpsPrivate))
70
71 static void location_ielement_interface_init (LocationIElementInterface *iface);
72
73 G_DEFINE_TYPE_WITH_CODE (LocationCps, location_cps, G_TYPE_OBJECT,
74                          G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
75                          location_ielement_interface_init));
76
77 static gboolean
78 _position_timeout_cb (gpointer data)
79 {
80         GObject *object = (GObject *)data;
81         LocationCpsPrivate *priv = GET_PRIVATE(object);
82         if (!priv) return FALSE;
83
84         LocationPosition *pos = NULL;
85         LocationAccuracy *acc = NULL;
86
87         if (priv->pos) {
88                 pos = location_position_copy(priv->pos);
89         }
90         else {
91                 pos = location_position_new (0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
92         }
93
94         if (priv->acc) {
95                 acc = location_accuracy_copy (priv->acc);
96         }
97         else {
98                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
99         }
100
101         LOCATION_LOGD("VELOCITY SERVICE_UPDATED");
102         g_signal_emit(object, signals[SERVICE_UPDATED], 0, POSITION_UPDATED, pos, acc);
103
104         location_position_free (pos);
105         location_accuracy_free (acc);
106
107         return TRUE;
108 }
109
110 static gboolean
111 _velocity_timeout_cb (gpointer data)
112 {
113         GObject *object = (GObject *)data;
114         LocationCpsPrivate *priv = GET_PRIVATE(object);
115         if (!priv) return FALSE;
116
117         LocationVelocity *vel = NULL;
118         LocationAccuracy *acc = NULL;
119
120         if (priv->vel) {
121                 vel = location_velocity_copy(priv->vel);
122         }
123         else {
124                 vel = location_velocity_new (0, 0.0, 0.0, 0.0);
125         }
126
127         if (priv->acc) {
128                 acc = location_accuracy_copy (priv->acc);
129         }
130         else {
131                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
132         }
133
134         LOCATION_LOGD("VELOCITY SERVICE_UPDATED");
135         g_signal_emit(object, signals[SERVICE_UPDATED], 0, VELOCITY_UPDATED, vel, acc);
136
137         location_velocity_free (vel);
138         location_accuracy_free (acc);
139
140         return TRUE;
141 }
142
143 static void
144 cps_status_cb (gboolean enabled,
145         LocationStatus status,
146         gpointer self)
147 {
148         LOCATION_LOGD("cps_status_cb");
149         g_return_if_fail(self);
150         LocationCpsPrivate* priv = GET_PRIVATE(self);
151         enable_signaling(self, signals, &(priv->enabled), enabled, status);
152         if (!priv->enabled) {
153                 if (priv->pos_timer) {
154                         g_source_remove(g_source_remove(priv->pos_timer));
155                         priv->pos_timer = 0;
156                 }
157                 if (priv->vel_timer) {
158                         g_source_remove(g_source_remove(priv->vel_timer));
159                         priv->vel_timer = 0;
160                 }
161         }
162 }
163
164 static void
165 cps_position_cb (gboolean enabled,
166         LocationPosition *pos,
167         LocationAccuracy *acc,
168         gpointer self)
169 {
170         LOCATION_LOGD("cps_position_cb");
171         g_return_if_fail(self);
172         g_return_if_fail(pos);
173         g_return_if_fail(acc);
174         LocationCpsPrivate* priv = GET_PRIVATE(self);
175
176         if (enabled && !priv->enabled) {
177                 if (!priv->pos_timer) priv->pos_timer = g_timeout_add_seconds (priv->pos_interval, _position_timeout_cb, self);
178                 if (!priv->vel_timer) priv->vel_timer = g_timeout_add_seconds (priv->vel_interval, _velocity_timeout_cb, self);
179         }
180
181         enable_signaling(self, signals, &(priv->enabled), enabled, pos->status);
182         position_signaling(self, signals, &(priv->enabled), priv->pos_interval, FALSE, &(priv->pos_updated_timestamp), &(priv->pos), &(priv->acc), priv->boundary_list, &(priv->zone_status), pos, acc);
183 }
184
185 static void
186 cps_velocity_cb(gboolean enabled,
187         LocationVelocity *vel,
188         LocationAccuracy *acc,
189         gpointer self)
190 {
191         LOCATION_LOGD("cps_velocity_cb");
192         g_return_if_fail(self);
193         LocationCpsPrivate* priv = GET_PRIVATE(self);
194         velocity_signaling(self, signals, &(priv->enabled), priv->vel_interval, FALSE, &(priv->vel_updated_timestamp), &(priv->vel), vel, acc);
195 }
196
197 static void
198 location_setting_cps_cb (keynode_t *key,
199                 gpointer self)
200 {
201         LOCATION_LOGD("location_setting_cps_cb");
202         g_return_if_fail (key);
203         g_return_if_fail (self);
204
205         LocationCpsPrivate *priv = GET_PRIVATE(self);
206         g_return_if_fail (priv->mod);
207         g_return_if_fail (priv->mod->handler);
208
209         int ret = LOCATION_ERROR_NONE;
210
211         if (location_setting_get_key_val (key) == 0) {
212                 if (priv->mod->ops.stop && priv->is_started) {
213                         ret = priv->mod->ops.stop (priv->mod->handler);
214                         if (ret == LOCATION_ERROR_NONE) {
215                                 priv->is_started = FALSE;
216                         }
217                 }
218         }
219         else {
220                 if (1 == location_setting_get_int (VCONFKEY_LOCATION_NETWORK_ENABLED) && priv->mod->ops.start && !priv->is_started) {
221                         LOCATION_LOGD("location resumed by setting");
222                         ret = priv->mod->ops.start (priv->mod->handler, cps_status_cb, cps_position_cb, cps_velocity_cb, NULL, self);
223                         if (ret == LOCATION_ERROR_NONE) {
224                                 priv->is_started = TRUE;
225                         }
226                 }
227         }
228 }
229
230 static void
231 location_cps_dispose (GObject *gobject)
232 {
233         LOCATION_LOGD("location_cps_dispose");
234
235         LocationCpsPrivate *priv = GET_PRIVATE(gobject);
236         if (priv->set_noti == TRUE) {
237                 location_setting_ignore_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_cps_cb);
238                 priv->set_noti = FALSE;
239         }
240
241         if (priv->pos_timer) {
242                 g_source_remove (priv->pos_timer);
243                 priv->pos_timer = 0;
244         }
245
246         if (priv->vel_timer) {
247                 g_source_remove (priv->vel_timer);
248                 priv->vel_timer = 0;
249         }
250
251         G_OBJECT_CLASS (location_cps_parent_class)->dispose (gobject);
252 }
253
254 static void
255 location_cps_finalize (GObject *gobject)
256 {
257         LOCATION_LOGD("location_cps_finalize");
258         LocationCpsPrivate* priv = GET_PRIVATE(gobject);
259         module_free(priv->mod, "cps");
260         priv->mod = NULL;
261
262         if (priv->boundary_list) {
263                 g_list_free_full (priv->boundary_list, free_boundary_list);
264                 priv->boundary_list = NULL;
265         }
266
267         if (priv->pos) {
268                 location_position_free(priv->pos);
269                 priv->pos = NULL;
270         }
271
272         if (priv->vel) {
273                 location_velocity_free(priv->vel);
274                 priv->vel = NULL;
275         }
276
277         if (priv->acc) {
278                 location_accuracy_free(priv->acc);
279                 priv->acc = NULL;
280         }
281
282         G_OBJECT_CLASS (location_cps_parent_class)->finalize (gobject);
283 }
284
285 static void
286 location_cps_set_property (GObject *object,
287         guint property_id,
288         GValue *value,
289         GParamSpec *pspec)
290 {
291         LocationCpsPrivate *priv = GET_PRIVATE(object);
292
293         int ret = 0;
294
295         switch (property_id) {
296                 case PROP_BOUNDARY:{
297                         GList *boundary_list = (GList *)g_list_copy(g_value_get_pointer(value));
298                         ret     = set_prop_boundary(&priv->boundary_list, boundary_list);
299                         if(ret != 0) LOCATION_LOGD("Set boundary. Error[%d]", ret);
300                         break;
301                 }
302                 case PROP_REMOVAL_BOUNDARY: {
303                         LocationBoundary *req_boundary = (LocationBoundary*) g_value_dup_boxed(value);
304                         ret = set_prop_removal_boundary(&priv->boundary_list, req_boundary);
305                         if(ret != 0) LOCATION_LOGD("Set removal boundary. Error[%d]", ret);
306                         break;
307                 }
308                 case PROP_POS_INTERVAL: {
309                         guint interval = g_value_get_uint (value);
310
311                         if (interval > 0) {
312                                 if (interval < LOCATION_UPDATE_INTERVAL_MAX)
313                                         priv->pos_interval = interval;
314                                 else
315                                         priv->pos_interval = (guint) LOCATION_UPDATE_INTERVAL_MAX;
316                         }
317                         else {
318                                 priv->pos_interval = (guint) LOCATION_UPDATE_INTERVAL_DEFAULT;
319                         }
320
321                         if (priv->pos_timer) {
322                                 g_source_remove (priv->pos_timer);
323                                 priv->pos_timer = g_timeout_add_seconds (priv->pos_interval, _position_timeout_cb, object);
324                         }
325
326                         break;
327                 }
328
329                 case PROP_VEL_INTERVAL: {
330                         guint interval = g_value_get_uint(value);
331                         if(interval > 0) {
332                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
333                                         priv->vel_interval = interval;
334                                 else
335                                         priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
336                         }
337                         else
338                                 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
339
340                         if (priv->vel_timer) {
341                                 g_source_remove (priv->vel_timer);
342                                 priv->vel_timer = g_timeout_add_seconds (priv->vel_interval, _velocity_timeout_cb, object);
343                         }
344
345                         break;
346                 }
347                 default:
348                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
349                         break;
350         }
351 }
352
353 static void
354 location_cps_get_property (GObject *object,
355         guint property_id,
356         GValue *value,
357         GParamSpec *pspec)
358 {
359         LocationCpsPrivate *priv = GET_PRIVATE (object);
360
361         switch (property_id){
362                 case PROP_METHOD_TYPE:
363                         g_value_set_int(value, LOCATION_METHOD_CPS);
364                         break;
365                 case PROP_BOUNDARY:
366                         g_value_set_pointer(value, g_list_first(priv->boundary_list));
367                         break;
368                 case PROP_POS_INTERVAL: {
369                         g_value_set_uint (value, priv->pos_interval);
370                         break;
371                 }
372                 default:
373                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
374                         break;
375         }
376 }
377
378 static int
379 location_cps_start (LocationCps *self)
380 {
381         LOCATION_LOGD("location_cps_start");
382
383         LocationCpsPrivate* priv = GET_PRIVATE(self);
384         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
385         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
386         g_return_val_if_fail (priv->mod->ops.start, LOCATION_ERROR_NOT_AVAILABLE);
387
388         if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
389
390         int ret = LOCATION_ERROR_NONE;
391
392         if (!location_setting_get_int (VCONFKEY_LOCATION_NETWORK_ENABLED)) {
393                 ret = LOCATION_ERROR_NOT_ALLOWED;
394         }
395         else {
396                 ret = priv->mod->ops.start (priv->mod->handler, cps_status_cb, cps_position_cb, cps_velocity_cb, NULL, self);
397                 if (ret == LOCATION_ERROR_NONE) {
398                         priv->is_started = TRUE;
399                 }
400                 else {
401                         return ret;
402                 }
403         }
404
405         if (priv->set_noti == FALSE) {
406                 location_setting_add_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_cps_cb, self);
407                 priv->set_noti = TRUE;
408         }
409
410         return ret;
411 }
412
413 static int
414 location_cps_stop (LocationCps *self)
415 {
416         LOCATION_LOGD("location_cps_stop");
417         LocationCpsPrivate* priv = GET_PRIVATE(self);
418         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
419         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
420         g_return_val_if_fail (priv->mod->ops.stop, LOCATION_ERROR_NOT_AVAILABLE);
421
422         int ret = LOCATION_ERROR_NONE;
423
424         if (priv->is_started == TRUE) {
425                 ret = priv->mod->ops.stop (priv->mod->handler);
426                 if (ret == LOCATION_ERROR_NONE) {
427                         priv->is_started = FALSE;
428                 }
429                 else {
430                         return ret;
431                 }
432         }
433
434         if (priv->set_noti == TRUE) {
435                 location_setting_ignore_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_cps_cb);
436                 priv->set_noti = FALSE;
437         }
438
439         return ret;
440 }
441
442 static int
443 location_cps_get_position (LocationCps *self,
444                 LocationPosition **position,
445                 LocationAccuracy **accuracy)
446 {
447         int ret = LOCATION_ERROR_NOT_AVAILABLE;
448         LOCATION_LOGD("location_cps_get_position");
449
450         LocationCpsPrivate *priv = GET_PRIVATE (self);
451         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
452
453         setting_retval_if_fail(VCONFKEY_LOCATION_NETWORK_ENABLED);
454
455         if (priv->pos) {
456                 *position = location_position_copy (priv->pos);
457                 ret = LOCATION_ERROR_NONE;
458         }
459
460         if (priv->acc) {
461         }
462         else {
463                 *accuracy = location_accuracy_copy (priv->acc);
464         }
465
466         return ret;
467 }
468
469 static int
470 location_cps_get_last_position (LocationCps *self,
471                 LocationPosition **position,
472                 LocationAccuracy **accuracy)
473 {
474         LOCATION_LOGD("location_cps_get_last_position");
475
476         /* Do not need to check GPS_ENABLED and NETWORK_ENABLED */
477
478         LocationCpsPrivate *priv = GET_PRIVATE(self);
479         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
480
481         LocModCpsOps ops = priv->mod->ops;
482         g_return_val_if_fail (priv->mod->handler, LOCATION_ERROR_NOT_AVAILABLE);
483         g_return_val_if_fail (ops.get_last_position, LOCATION_ERROR_NOT_AVAILABLE);
484
485         return ops.get_last_position (priv->mod->handler, position, accuracy);
486 }
487
488 static int
489 location_cps_get_velocity (LocationCps *self,
490                 LocationVelocity **velocity,
491                 LocationAccuracy **accuracy)
492 {
493         LOCATION_LOGD("location_cps_get_velocity");
494         return LOCATION_ERROR_NOT_SUPPORTED;
495 }
496
497 static int
498 location_cps_get_last_velocity (LocationCps *self,
499                 LocationVelocity **velocity,
500                 LocationAccuracy **accuracy)
501 {
502         LOCATION_LOGD("location_cps_get_last_velocity");
503         return LOCATION_ERROR_NOT_SUPPORTED;
504 }
505
506 static int
507 location_cps_get_satellite (LocationCps *self,
508                 LocationSatellite **satellite)
509 {
510         LOCATION_LOGD("location_cps_get_satellite");
511         return LOCATION_ERROR_NOT_SUPPORTED;
512 }
513
514 static int
515 location_cps_get_last_satellite (LocationCps *self)
516 {
517         LOCATION_LOGD("location_cps_get_last_satellite");
518         return LOCATION_ERROR_NOT_SUPPORTED;
519 }
520
521 static void
522 location_ielement_interface_init (LocationIElementInterface *iface)
523 {
524         iface->start = (TYPE_START_FUNC) location_cps_start;
525         iface->stop = (TYPE_STOP_FUNC) location_cps_stop;
526         iface->get_position = (TYPE_GET_POSITION) location_cps_get_position;
527         iface->get_last_position = (TYPE_GET_POSITION) location_cps_get_last_position;
528         iface->get_velocity = (TYPE_GET_VELOCITY) location_cps_get_velocity;
529         iface->get_last_velocity = (TYPE_GET_VELOCITY)location_cps_get_last_velocity;
530         iface->get_satellite = (TYPE_GET_SATELLITE)location_cps_get_satellite;
531         iface->get_last_satellite = (TYPE_GET_SATELLITE)location_cps_get_last_satellite;
532 }
533
534 static void
535 location_cps_init (LocationCps *self)
536 {
537         LOCATION_LOGD("location_cps_init");
538         LocationCpsPrivate* priv = GET_PRIVATE(self);
539
540         priv->mod = (LocationCpsMod*)module_new("cps");
541         if(!priv->mod) LOCATION_LOGW("module loading failed");
542
543         priv->is_started = FALSE;
544         priv->set_noti = FALSE;
545         priv->enabled = FALSE;
546
547         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
548         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
549
550         priv->pos_updated_timestamp = 0;
551         priv->vel_updated_timestamp = 0;
552
553         priv->pos = NULL;
554         priv->acc = NULL;
555         priv->vel = NULL;
556         priv->zone_status = ZONE_STATUS_NONE;
557         priv->boundary_list = NULL;
558
559         priv->pos_timer = 0;
560         priv->vel_timer = 0;
561 }
562
563 static void
564 location_cps_class_init (LocationCpsClass *klass)
565 {
566         LOCATION_LOGD("location_cps_class_init");
567         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
568
569         gobject_class->get_property = location_cps_get_property;
570         gobject_class->set_property = location_cps_set_property;
571
572         gobject_class->dispose = location_cps_dispose;
573         gobject_class->finalize = location_cps_finalize;
574
575         g_type_class_add_private (klass, sizeof (LocationCpsPrivate));
576
577         signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
578                         G_TYPE_FROM_CLASS (klass),
579                         G_SIGNAL_RUN_FIRST |
580                         G_SIGNAL_NO_RECURSE,
581                         G_STRUCT_OFFSET (LocationCpsClass, enabled),
582                         NULL, NULL,
583                         location_VOID__UINT,
584                         G_TYPE_NONE, 1,
585                         G_TYPE_UINT);
586
587         signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
588                         G_TYPE_FROM_CLASS (klass),
589                         G_SIGNAL_RUN_FIRST |
590                         G_SIGNAL_NO_RECURSE,
591                         G_STRUCT_OFFSET (LocationCpsClass, disabled),
592                         NULL, NULL,
593                         location_VOID__UINT,
594                         G_TYPE_NONE, 1,
595                         G_TYPE_UINT);
596
597         signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
598                         G_TYPE_FROM_CLASS (klass),
599                         G_SIGNAL_RUN_FIRST |
600                         G_SIGNAL_NO_RECURSE,
601                         G_STRUCT_OFFSET (LocationCpsClass, updated),
602                         NULL, NULL,
603                         location_VOID__UINT_POINTER_POINTER,
604                         G_TYPE_NONE, 3,
605                         G_TYPE_UINT,
606                         G_TYPE_POINTER,
607                         G_TYPE_POINTER);
608
609         signals[ZONE_IN] = g_signal_new ("zone-in",
610                         G_TYPE_FROM_CLASS (klass),
611                         G_SIGNAL_RUN_FIRST |
612                         G_SIGNAL_NO_RECURSE,
613                         G_STRUCT_OFFSET (LocationCpsClass, zone_in),
614                         NULL, NULL,
615                         location_VOID__UINT_POINTER_POINTER,
616                         G_TYPE_NONE, 3,
617                         G_TYPE_UINT,
618                         G_TYPE_POINTER,
619                         G_TYPE_POINTER);
620
621         signals[ZONE_OUT] = g_signal_new ("zone-out",
622                         G_TYPE_FROM_CLASS (klass),
623                         G_SIGNAL_RUN_FIRST |
624                         G_SIGNAL_NO_RECURSE,
625                         G_STRUCT_OFFSET (LocationCpsClass, zone_out),
626                         NULL, NULL,
627                         location_VOID__UINT_POINTER_POINTER,
628                         G_TYPE_NONE, 3,
629                         G_TYPE_UINT,
630                         G_TYPE_POINTER,
631                         G_TYPE_POINTER);
632
633         properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
634                                 "method type",
635                                 "location method type name",
636                                 LOCATION_METHOD_CPS,
637                                 LOCATION_METHOD_CPS,
638                                 LOCATION_METHOD_CPS,
639                                 G_PARAM_READABLE);
640
641         properties[PROP_POS_INTERVAL] = g_param_spec_uint ("pos-interval",
642                                 "cps position interval prop",
643                                 "cps position interval data",
644                                 LOCATION_UPDATE_INTERVAL_MIN,
645                                 LOCATION_UPDATE_INTERVAL_MAX,
646                                 LOCATION_UPDATE_INTERVAL_DEFAULT,
647                                 G_PARAM_READWRITE);
648
649         properties[PROP_VEL_INTERVAL] = g_param_spec_uint ("vel-interval",
650                         "cps velocity interval prop",
651                         "cps velocity interval data",
652                         LOCATION_UPDATE_INTERVAL_MIN,
653                         LOCATION_UPDATE_INTERVAL_MAX,
654                         LOCATION_UPDATE_INTERVAL_DEFAULT,
655                         G_PARAM_READWRITE);
656
657         properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
658                         "cps boundary prop",
659                         "cps boundary data",
660                         G_PARAM_READWRITE);
661
662         properties[PROP_REMOVAL_BOUNDARY] = g_param_spec_boxed("removal-boundary",
663                         "cps removal boundary prop",
664                         "cps removal boundary data",
665                         LOCATION_TYPE_BOUNDARY,
666                         G_PARAM_READWRITE);
667
668         g_object_class_install_properties (gobject_class,
669                         PROP_MAX,
670                         properties);
671
672 }