Fix a crash after changes that velocity is updated before position
[platform/core/location/lbs-location.git] / location / manager / location-wps.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-wps.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  * forward definitions
38  */
39
40 typedef struct _LocationWpsPrivate {
41         LocationWpsMod* mod;
42         gboolean is_started;
43         gboolean set_noti;
44         gboolean enabled;
45         guint   pos_updated_timestamp;
46         guint   pos_interval;
47         guint   vel_updated_timestamp;
48         guint   vel_interval;
49         LocationPosition *pos;
50         LocationVelocity *vel;
51         LocationAccuracy *acc;
52         GList *boundary_list;
53         ZoneStatus zone_status;
54
55         guint           pos_timer;
56         guint           vel_timer;
57 } LocationWpsPrivate;
58
59 enum {
60         PROP_0,
61         PROP_METHOD_TYPE,
62         PROP_LAST_POSITION,
63         PROP_POS_INTERVAL,
64         PROP_VEL_INTERVAL,
65         PROP_BOUNDARY,
66         PROP_REMOVAL_BOUNDARY,
67         PROP_MAX
68 };
69
70 static guint32 signals[LAST_SIGNAL] = {0, };
71 static GParamSpec *properties[PROP_MAX] = {NULL, };
72
73 #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOCATION_TYPE_WPS, LocationWpsPrivate))
74
75 static void location_ielement_interface_init (LocationIElementInterface *iface);
76
77 G_DEFINE_TYPE_WITH_CODE (LocationWps, location_wps, G_TYPE_OBJECT,
78                          G_IMPLEMENT_INTERFACE (LOCATION_TYPE_IELEMENT,
79                          location_ielement_interface_init));
80
81 static gboolean
82 _position_timeout_cb (gpointer data)
83 {
84         GObject *object = (GObject *)data;
85         LocationWpsPrivate *priv = GET_PRIVATE(object);
86         if (!priv) return FALSE;
87
88         LocationPosition *pos = NULL;
89         LocationAccuracy *acc = NULL;
90
91         if (priv->pos) {
92                 pos = location_position_copy(priv->pos);
93         }
94         else {
95                 pos = location_position_new (0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
96         }
97
98         if (priv->acc) {
99                 acc = location_accuracy_copy (priv->acc);
100         }
101         else {
102                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
103         }
104
105         LOCATION_LOGD("POSITION SERVICE_UPDATED");
106         g_signal_emit(object, signals[SERVICE_UPDATED], 0, POSITION_UPDATED, pos, acc);
107
108         location_position_free (pos);
109         location_accuracy_free (acc);
110
111         return TRUE;
112 }
113
114 static gboolean
115 _velocity_timeout_cb (gpointer data)
116 {
117         GObject *object = (GObject *)data;
118         LocationWpsPrivate *priv = GET_PRIVATE(object);
119         if (!priv) return FALSE;
120
121         LocationVelocity *vel = NULL;
122         LocationAccuracy *acc = NULL;
123
124         if (priv->vel) {
125                 vel = location_velocity_copy(priv->vel);
126         }
127         else {
128                 vel = location_velocity_new (0, 0.0, 0.0, 0.0);
129         }
130
131         if (priv->acc) {
132                 acc = location_accuracy_copy (priv->acc);
133         }
134         else {
135                 acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0.0, 0.0);
136         }
137
138         LOCATION_LOGD("POSITION SERVICE_UPDATED");
139         g_signal_emit(object, signals[SERVICE_UPDATED], 0, VELOCITY_UPDATED, vel, acc);
140
141         location_velocity_free (vel);
142         location_accuracy_free (acc);
143
144         return TRUE;
145 }
146
147 static void
148 wps_status_cb (gboolean enabled,
149         LocationStatus status,
150         gpointer self)
151 {
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);
159                         priv->pos_timer = 0;
160                 }
161                 if (priv->vel_timer) {
162                         g_source_remove (priv->vel_timer);
163                         priv->vel_timer = 0;
164                 }
165         }
166 }
167
168 static void
169 wps_position_cb (gboolean enabled,
170         LocationPosition *pos,
171         LocationAccuracy *acc,
172         gpointer self)
173 {
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);
179
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);
183         }
184
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);
187 }
188
189 static void
190 wps_velocity_cb(gboolean enabled,
191         LocationVelocity *vel,
192         LocationAccuracy *acc,
193         gpointer self)
194 {
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);
199 }
200
201 static void
202 location_setting_wps_cb(keynode_t *key,
203         gpointer self)
204 {
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);
211
212         int ret = LOCATION_ERROR_NONE;
213
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;
219                         }
220                 }
221         }
222         else {
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;
228                         }
229                 }
230         }
231
232 }
233
234 static int
235 location_wps_start (LocationWps *self)
236 {
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);
242
243         if (priv->is_started == TRUE) return LOCATION_ERROR_NONE;
244
245         int ret = LOCATION_ERROR_NONE;
246
247         if (!location_setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED)) {
248                 ret = LOCATION_ERROR_NOT_ALLOWED;
249         }
250         else {
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;
254                 }
255                 else {
256                         return ret;
257                 }
258         }
259
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;
263         }
264
265         return ret;
266 }
267
268 static int
269 location_wps_stop (LocationWps *self)
270 {
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);
276
277         int ret = LOCATION_ERROR_NONE;
278
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;
283                 }
284                 else {
285                         return ret;
286                 }
287         }
288
289         if (priv->set_noti == TRUE) {
290                 location_setting_ignore_notify (VCONFKEY_LOCATION_NETWORK_ENABLED, location_setting_wps_cb);
291                 priv->set_noti = FALSE;
292         }
293
294         return ret;
295 }
296
297 static void
298 location_wps_dispose (GObject *gobject)
299 {
300         LOCATION_LOGD("location_wps_dispose");
301
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;
306
307                 if (priv->pos_timer) {
308                         g_source_remove (priv->pos_timer);
309                         priv->pos_timer = 0;
310                 }
311                 if (priv->vel_timer) {
312                         g_source_remove (priv->vel_timer);
313                         priv->vel_timer = 0;
314                 }
315
316         }
317
318         G_OBJECT_CLASS (location_wps_parent_class)->dispose (gobject);
319 }
320
321 static void
322 location_wps_finalize (GObject *gobject)
323 {
324         LOCATION_LOGD("location_wps_finalize");
325         LocationWpsPrivate* priv = GET_PRIVATE(gobject);
326         module_free(priv->mod, "wps");
327
328         if (priv->boundary_list) {
329                 g_list_free_full (priv->boundary_list, free_boundary_list);
330                 priv->boundary_list = NULL;
331         }
332
333         if (priv->pos) {
334                 location_position_free(priv->pos);
335                 priv->pos = NULL;
336         }
337
338         if (priv->vel) {
339                 location_velocity_free(priv->vel);
340                 priv->vel = NULL;
341         }
342
343         if (priv->acc) {
344                 location_accuracy_free(priv->acc);
345                 priv->acc = NULL;
346         }
347         G_OBJECT_CLASS (location_wps_parent_class)->finalize (gobject);
348 }
349
350 static void
351 location_wps_set_property (GObject *object,
352         guint property_id,
353         const GValue *value,
354         GParamSpec *pspec)
355 {
356         LocationWpsPrivate* priv = GET_PRIVATE(object);
357         int ret = 0;
358
359         switch (property_id){
360                 case PROP_BOUNDARY:{
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);
364                         break;
365                 }
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);
370                         break;
371                 }
372                 case PROP_POS_INTERVAL: {
373                         guint interval = g_value_get_uint(value);
374                         if(interval > 0) {
375                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
376                                         priv->pos_interval = interval;
377                                 else
378                                         priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
379                         }
380                         else
381                                 priv->pos_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
382
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);
386                         }
387
388                         break;
389                 }
390                 case PROP_VEL_INTERVAL: {
391                         guint interval = g_value_get_uint(value);
392                         if(interval > 0) {
393                                 if(interval < LOCATION_UPDATE_INTERVAL_MAX)
394                                         priv->vel_interval = interval;
395                                 else
396                                         priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_MAX;
397                         }
398                         else
399                                 priv->vel_interval = (guint)LOCATION_UPDATE_INTERVAL_DEFAULT;
400
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);
404                         }
405
406                         break;
407                 }
408                 default:
409                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
410                         break;
411         }
412 }
413
414 static void
415 location_wps_get_property (GObject *object,
416         guint property_id,
417         GValue *value,
418         GParamSpec *pspec)
419 {
420         LocationWpsPrivate *priv = GET_PRIVATE (object);
421
422         switch (property_id){
423                 case PROP_METHOD_TYPE:
424                         g_value_set_int(value, LOCATION_METHOD_WPS);
425                         break;
426                 case PROP_LAST_POSITION:
427                         g_value_set_boxed (value, priv->pos);
428                         break;
429                 case PROP_BOUNDARY:
430                         g_value_set_pointer(value, g_list_first(priv->boundary_list));
431                         break;
432                 case PROP_POS_INTERVAL:
433                         g_value_set_uint(value, priv->pos_interval);
434                         break;
435                 case PROP_VEL_INTERVAL:
436                         g_value_set_uint(value, priv->vel_interval);
437                         break;
438                 default:
439                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
440                         break;
441         }
442 }
443
444 static int
445 location_wps_get_position (LocationWps *self,
446         LocationPosition **position,
447         LocationAccuracy **accuracy)
448 {
449         int ret = LOCATION_ERROR_NOT_AVAILABLE;
450         LOCATION_LOGD("location_wps_get_position");
451
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);
455
456         if (priv->pos) {
457                 *position = location_position_copy (priv->pos);
458                 ret = LOCATION_ERROR_NONE;
459         }
460         if (priv->acc) {
461                 *accuracy = location_accuracy_copy (priv->acc);
462         }
463
464         return ret;
465 }
466
467 static int
468 location_wps_get_last_position (LocationWps *self,
469         LocationPosition **position,
470         LocationAccuracy **accuracy)
471 {
472         LOCATION_LOGD("location_wps_get_last_position");
473
474         /* Do not need to check VCONFKEY_LOCATION_ENABLED and VCONFKEY_LOCATION_NETWORK_ENABLED */
475
476         LocationWpsPrivate *priv = GET_PRIVATE (self);
477         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
478
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);
482
483         return ops.get_last_position(priv->mod->handler, position, accuracy);
484
485 }
486
487 static int
488 location_wps_get_velocity (LocationWps *self,
489         LocationVelocity **velocity,
490         LocationAccuracy **accuracy)
491 {
492         int ret = LOCATION_ERROR_NOT_AVAILABLE;
493         LOCATION_LOGD("location_wps_get_velocity");
494
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);
498
499         if (priv->vel) {
500                 *velocity = location_velocity_copy (priv->vel);
501                 ret = LOCATION_ERROR_NONE;
502         }
503
504         if (priv->acc) {
505                 *accuracy = location_accuracy_copy (priv->acc);
506         }
507
508         return ret;
509 }
510
511 static int
512 location_wps_get_last_velocity (LocationWps *self,
513         LocationVelocity **velocity,
514         LocationAccuracy **accuracy)
515 {
516         LOCATION_LOGD("location_wps_get_last_velocity");
517
518         /* Do not need to check VCONFKEY_LOCATION_ENABLED and VCONFKEY_LOCATION_NETWORK_ENABLED */
519
520         LocationWpsPrivate *priv = GET_PRIVATE (self);
521         g_return_val_if_fail (priv->mod, LOCATION_ERROR_NOT_AVAILABLE);
522
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);
527
528 }
529
530 static int
531 location_wps_get_satellite (LocationWps *self,
532                 LocationSatellite **satellite)
533 {
534         LOCATION_LOGD("location_wps_get_satellite");
535         return LOCATION_ERROR_NOT_SUPPORTED;
536 }
537
538 static int
539 location_wps_get_last_satellite (LocationWps *self,
540                 LocationSatellite **satellite)
541 {
542         LOCATION_LOGD("location_wps_get_last_satellite");
543         return LOCATION_ERROR_NOT_SUPPORTED;
544 }
545
546 static void
547 location_ielement_interface_init (LocationIElementInterface *iface)
548 {
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;
557 }
558
559 static void
560 location_wps_init (LocationWps *self)
561 {
562         LOCATION_LOGD("location_wps_init");
563         LocationWpsPrivate* priv = GET_PRIVATE(self);
564
565         priv->mod = (LocationWpsMod*)module_new("wps");
566         if(!priv->mod) LOCATION_LOGW("module loading failed");
567
568         priv->is_started = FALSE;
569         priv->set_noti = FALSE;
570         priv->enabled= FALSE;
571
572         priv->pos_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
573         priv->vel_interval = LOCATION_UPDATE_INTERVAL_DEFAULT;
574
575         priv->pos_updated_timestamp = 0;
576         priv->vel_updated_timestamp = 0;
577
578         priv->pos = NULL;
579         priv->vel = NULL;
580         priv->acc = NULL;
581         priv->zone_status = ZONE_STATUS_NONE;
582         priv->boundary_list = NULL;
583
584         priv->pos_timer = 0;
585         priv->vel_timer = 0;
586 }
587
588 static void
589 location_wps_class_init (LocationWpsClass *klass)
590 {
591         LOCATION_LOGD("location_wps_class_init");
592         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
593
594         gobject_class->set_property = location_wps_set_property;
595         gobject_class->get_property = location_wps_get_property;
596
597         gobject_class->dispose = location_wps_dispose;
598         gobject_class->finalize = location_wps_finalize;
599
600         g_type_class_add_private (klass, sizeof (LocationWpsPrivate));
601
602         signals[SERVICE_ENABLED] = g_signal_new ("service-enabled",
603                         G_TYPE_FROM_CLASS (klass),
604                         G_SIGNAL_RUN_FIRST |
605                         G_SIGNAL_NO_RECURSE,
606                         G_STRUCT_OFFSET (LocationWpsClass, enabled),
607                         NULL, NULL,
608                         location_VOID__UINT,
609                         G_TYPE_NONE, 1,
610                         G_TYPE_UINT);
611
612         signals[SERVICE_DISABLED] = g_signal_new ("service-disabled",
613                         G_TYPE_FROM_CLASS (klass),
614                         G_SIGNAL_RUN_FIRST |
615                         G_SIGNAL_NO_RECURSE,
616                         G_STRUCT_OFFSET (LocationWpsClass, disabled),
617                         NULL, NULL,
618                         location_VOID__UINT,
619                         G_TYPE_NONE, 1,
620                         G_TYPE_UINT);
621
622         signals[SERVICE_UPDATED] = g_signal_new ("service-updated",
623                         G_TYPE_FROM_CLASS (klass),
624                         G_SIGNAL_RUN_FIRST |
625                         G_SIGNAL_NO_RECURSE,
626                         G_STRUCT_OFFSET (LocationWpsClass, updated),
627                         NULL, NULL,
628                         location_VOID__UINT_POINTER_POINTER,
629                         G_TYPE_NONE, 3,
630                         G_TYPE_UINT,
631                         G_TYPE_POINTER,
632                         G_TYPE_POINTER);
633
634         signals[ZONE_IN] = g_signal_new ("zone-in",
635                         G_TYPE_FROM_CLASS (klass),
636                         G_SIGNAL_RUN_FIRST |
637                         G_SIGNAL_NO_RECURSE,
638                         G_STRUCT_OFFSET (LocationWpsClass, zone_in),
639                         NULL, NULL,
640                         location_VOID__UINT_POINTER_POINTER,
641                         G_TYPE_NONE, 3,
642                         G_TYPE_UINT,
643                         G_TYPE_POINTER,
644                         G_TYPE_POINTER);
645
646         signals[ZONE_OUT] = g_signal_new ("zone-out",
647                         G_TYPE_FROM_CLASS (klass),
648                         G_SIGNAL_RUN_FIRST |
649                         G_SIGNAL_NO_RECURSE,
650                         G_STRUCT_OFFSET (LocationWpsClass, zone_out),
651                         NULL, NULL,
652                         location_VOID__UINT_POINTER_POINTER,
653                         G_TYPE_NONE, 3,
654                         G_TYPE_UINT,
655                         G_TYPE_POINTER,
656                         G_TYPE_POINTER);
657
658         properties[PROP_METHOD_TYPE] = g_param_spec_int ("method",
659                         "method type",
660                         "location method type name",
661                         LOCATION_METHOD_WPS,
662                         LOCATION_METHOD_WPS,
663                         LOCATION_METHOD_WPS,
664                         G_PARAM_READABLE);
665
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,
670                         G_PARAM_READABLE);
671
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,
678                         G_PARAM_READWRITE);
679
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,
686                         G_PARAM_READWRITE);
687
688         properties[PROP_BOUNDARY] = g_param_spec_pointer ("boundary",
689                         "wps boundary prop",
690                         "wps boundary data",
691                         G_PARAM_READWRITE);
692
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,
697                         G_PARAM_READWRITE);
698
699         g_object_class_install_properties (gobject_class,
700                         PROP_MAX,
701                         properties);
702 }
703