4 * Copyright (c) 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.
29 #include <glib-object.h>
31 #include <dbus/dbus.h>
32 #include <dbus/dbus-glib-bindings.h>
33 #include <dbus/dbus-glib-lowlevel.h>
35 #include <geoclue/gc-provider.h>
36 #include <geoclue/geoclue-error.h>
37 #include <geoclue/gc-iface-position.h>
38 #include <geoclue/gc-iface-velocity.h>
39 #include <geoclue/gc-iface-nmea.h>
40 #include <geoclue/gc-iface-satellite.h>
41 #include "gps_manager_data_types.h"
42 #include "gps_manager.h"
45 #include "last_position.h"
47 #define GEOCLUE_GPSMANAGER_DBUS_SERVICE "org.freedesktop.Geoclue.Providers.GpsManager"
48 #define GEOCLUE_GPSMANAGER_DBUS_PATH "/org/freedesktop/Geoclue/Providers/GpsManager"
59 pos_data_t last_position;
60 sv_data_t last_satellite;
62 GHashTable *connections;
66 GcProviderClass parent_class;
67 } GeoclueGpsManagerClass;
69 #define GEOCLUE_TYPE_GPSMANAGER (geoclue_gpsmanager_get_type ())
70 #define GEOCLUE_GPSMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSMANAGER, GeoclueGpsManager))
72 static void init_position(GcIfacePositionClass * iface);
73 static void init_velocity(GcIfaceVelocityClass * iface);
74 static void init_nmea(GcIfaceNmeaClass * iface);
75 static void init_satellite(GcIfaceSatelliteClass * iface);
76 static void init_geoclue(GcIfaceGeoclueClass * iface);
78 G_DEFINE_TYPE_WITH_CODE(GeoclueGpsManager, geoclue_gpsmanager, GC_TYPE_PROVIDER,
79 G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_POSITION, init_position)
80 G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_VELOCITY, init_velocity)
81 G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_NMEA, init_nmea)
82 G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_SATELLITE, init_satellite)
83 G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE, init_geoclue));
85 static void constructed(GObject * object)
87 GeoclueGpsManager *gps_manager = GEOCLUE_GPSMANAGER(object);
89 gps_manager->connections = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
91 gps_manager->status = GEOCLUE_STATUS_UNAVAILABLE;
93 memset(&gps_manager->position, 0x00, sizeof(pos_data_t));
94 memset(&gps_manager->satellite, 0x00, sizeof(sv_data_t));
95 memset(&gps_manager->nmea, 0x00, sizeof(nmea_data_t));
97 ((GObjectClass *) geoclue_gpsmanager_parent_class)->constructed(object);
100 static void finalize(GObject * object)
102 ((GObjectClass *) geoclue_gpsmanager_parent_class)->finalize(object);
105 static void dispose(GObject * object)
107 GeoclueGpsManager *gpsmanager = GEOCLUE_GPSMANAGER(object);
109 g_hash_table_destroy(gpsmanager->connections);
111 ((GObjectClass *) geoclue_gpsmanager_parent_class)->dispose(object);
114 static gboolean get_status(GcIfaceGeoclue * gc, GeoclueStatus * status, GError ** error)
116 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
118 *status = gpsmanager->status;
123 static gboolean get_provider_info(GcIfaceGeoclue * geoclue, gchar ** name, gchar ** description, GError ** error)
126 *name = g_strdup("geoclue-gpsmanager");
129 *description = g_strdup("Geoclue-gpsmanager");
134 static void print_option(gpointer key, gpointer value, gpointer data)
136 g_print(" %s - %s\n", (char *)key, (char *)value);
139 static gboolean set_options(GcIfaceGeoclue * gc, GHashTable * options, GError ** error)
141 g_print("Options received---\n");
142 g_hash_table_foreach(options, print_option, NULL);
146 static void shutdown(GcProvider * provider)
151 static void start_tracking(GeoclueGpsManager * gpsmanager)
153 gpsmanager->status = GEOCLUE_STATUS_ACQUIRING;
154 request_start_session();
157 static void stop_tracking(GeoclueGpsManager * gpsmanager)
159 request_stop_session();
160 gpsmanager->status = GEOCLUE_STATUS_UNAVAILABLE;
163 static void update_position_cb(pos_data_t * pos, gps_error_t error, void *user_data)
165 GeocluePositionFields fields;
166 GeoclueAccuracy *accuracy;
168 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data));
169 memcpy(&gpsmanager->position, pos, sizeof(pos_data_t));
170 memcpy(&gpsmanager->last_position, pos, sizeof(pos_data_t));
172 gpsmanager->status = GEOCLUE_STATUS_AVAILABLE;
174 fields = (GEOCLUE_POSITION_FIELDS_LATITUDE | GEOCLUE_POSITION_FIELDS_LONGITUDE | GEOCLUE_POSITION_FIELDS_ALTITUDE);
176 accuracy = geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_DETAILED, pos->hor_accuracy, pos->ver_accuracy);
178 gc_iface_position_emit_position_changed(GC_IFACE_POSITION(gpsmanager),
179 fields, pos->timestamp, pos->latitude, pos->longitude, pos->altitude, accuracy);
181 fields = (GEOCLUE_VELOCITY_FIELDS_SPEED | GEOCLUE_VELOCITY_FIELDS_DIRECTION);
183 gc_iface_velocity_emit_velocity_changed(GC_IFACE_VELOCITY(gpsmanager),
184 fields, pos->timestamp, pos->speed, pos->bearing, 0.0);
186 geoclue_accuracy_free(accuracy);
188 gc_iface_geoclue_emit_status_changed(GC_IFACE_GEOCLUE(gpsmanager), GEOCLUE_STATUS_AVAILABLE);
191 static void update_satellite_cb(sv_data_t * sv, void *user_data)
195 int satellite_used = 0;
197 GPtrArray *satellite_info;
199 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data));
200 memcpy(&gpsmanager->satellite, sv, sizeof(sv_data_t));
201 memcpy(&gpsmanager->last_satellite, sv, sizeof(sv_data_t));
202 timestamp = sv->timestamp;
204 used_prn = g_array_new(FALSE, FALSE, sizeof(guint));
205 for (index = 0; index < sv->num_of_sat; ++index) {
206 if (sv->sat[index].used) {
207 g_array_append_val(used_prn, sv->sat[index].prn);
212 satellite_info = g_ptr_array_new();
214 for (index = 0; index < sv->num_of_sat; ++index) {
215 GValue sv_info = { 0, };
216 g_value_init(&sv_info, GEOCLUE_SATELLITE_INFO);
217 g_value_take_boxed(&sv_info, dbus_g_type_specialized_construct(GEOCLUE_SATELLITE_INFO));
218 dbus_g_type_struct_set(&sv_info, 0, sv->sat[index].prn, 1,
219 sv->sat[index].elevation, 2, sv->sat[index].azimuth, 3, sv->sat[index].snr, G_MAXUINT);
220 g_ptr_array_add(satellite_info, g_value_get_boxed(&sv_info));
223 gc_iface_satellite_emit_satellite_changed(GC_IFACE_SATELLITE
224 (gpsmanager), timestamp,
225 satellite_used, sv->num_of_sat, used_prn, satellite_info);
227 g_array_free(used_prn, TRUE);
228 g_ptr_array_free(satellite_info, TRUE);
231 static void update_nmea_cb(nmea_data_t * nmea, void *user_data)
235 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data));
237 gpsmanager->nmea.data = g_malloc(nmea->len + 1);
238 g_memmove(gpsmanager->nmea.data, nmea->data, nmea->len);
239 gpsmanager->nmea.data[nmea->len] = '\0';
241 gc_iface_nmea_emit_nmea_changed(GC_IFACE_NMEA(gpsmanager), timestamp, gpsmanager->nmea.data);
243 g_free(gpsmanager->nmea.data);
246 static void add_reference(GcIfaceGeoclue * gc, DBusGMethodInvocation * context)
248 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
252 sender = dbus_g_method_get_sender(context);
253 if (g_hash_table_size(gpsmanager->connections) == 0) {
254 start_tracking(gpsmanager);
256 pcount = g_hash_table_lookup(gpsmanager->connections, sender);
258 pcount = g_malloc0(sizeof(int));
259 g_hash_table_insert(gpsmanager->connections, sender, pcount);
263 g_debug("add_reference (%s) (%d)", sender, (*pcount));
265 dbus_g_method_return(context);
268 static gboolean remove_client(GeoclueGpsManager * gpsmanager, const char *client)
272 pcount = g_hash_table_lookup(gpsmanager->connections, client);
278 g_hash_table_remove(gpsmanager->connections, client);
280 if (g_hash_table_size(gpsmanager->connections) == 0) {
281 g_debug("There is no connections!");
282 stop_tracking(gpsmanager);
287 static gboolean remove_all_clients(GeoclueGpsManager * gpsmanager, const char *client)
291 pcount = g_hash_table_lookup(gpsmanager->connections, client);
295 g_hash_table_remove(gpsmanager->connections, client);
296 if (g_hash_table_size(gpsmanager->connections) == 0) {
297 g_debug("There is no connections!");
298 stop_tracking(gpsmanager);
303 static void remove_reference(GcIfaceGeoclue * gc, DBusGMethodInvocation * context)
305 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
308 sender = dbus_g_method_get_sender(context);
309 if (!remove_client(gpsmanager, sender)) {
310 g_warning("Unreffed by client taht has not been referenced");
315 dbus_g_method_return(context);
318 static void name_owner_changed(DBusGProxy * proxy, const char *name, const char *prev_owner, const char *new_owner, void *gc)
320 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
321 g_debug("name_owner_changed, name:%s, prev_owner:%s, new_owner:%s", name, prev_owner, new_owner);
322 if (strcmp(new_owner, "") == 0 && strcmp(name, prev_owner) == 0) {
323 if (remove_all_clients(gpsmanager, prev_owner)) {
324 g_warning("Impolite client %s disconnected without unreferencing\n", prev_owner);
329 static void geoclue_gpsmanager_class_init(GeoclueGpsManagerClass * klass)
331 GObjectClass *o_class = (GObjectClass *) klass;
332 GcProviderClass *p_class = (GcProviderClass *) klass;
334 o_class->constructed = constructed;
335 o_class->finalize = finalize;
336 o_class->dispose = dispose;
337 p_class->get_status = get_status;
338 p_class->set_options = set_options;
339 p_class->shutdown = shutdown;
342 static void geoclue_gpsmanager_init(GeoclueGpsManager * gpsmanager)
344 GError *error = NULL;
347 GcProvider *provider;
348 g_debug("geoclue_gpsmanager_init");
350 g_return_if_fail(GC_IS_PROVIDER(gpsmanager));
351 provider = GC_PROVIDER(gpsmanager);
352 g_return_if_fail(provider->connection != NULL);
354 driver = dbus_g_proxy_new_for_name(provider->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
356 if (!org_freedesktop_DBus_request_name(driver, GEOCLUE_GPSMANAGER_DBUS_SERVICE, 0, &request_ret, &error)) {
357 g_warning("%s was unable to register service %s: %s",
358 G_OBJECT_TYPE_NAME(provider), GEOCLUE_GPSMANAGER_DBUS_SERVICE, error->message);
363 dbus_g_proxy_add_signal(driver, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
365 dbus_g_proxy_connect_signal(driver, "NameOwnerChanged", G_CALLBACK(name_owner_changed), provider, NULL);
367 dbus_g_connection_register_g_object(provider->connection, GEOCLUE_GPSMANAGER_DBUS_PATH, G_OBJECT(provider));
369 memset(&gpsmanager->last_position, 0x00, sizeof(pos_data_t));
370 memset(&gpsmanager->last_satellite, 0x00, sizeof(sv_data_t));
372 gps_manager_get_last_position(&gpsmanager->last_position);
375 static gboolean get_position(GcIfacePosition * gc,
376 GeocluePositionFields * fields,
379 double *longitude, double *altitude, GeoclueAccuracy ** accuracy, GError ** error)
381 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
383 if (gpsmanager->status == GEOCLUE_STATUS_ACQUIRING) {
384 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_NOT_AVAILABLE, "ERROR: Acquiring");
388 if (gpsmanager->status != GEOCLUE_STATUS_AVAILABLE) {
389 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available");
394 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters");
398 *fields = GEOCLUE_POSITION_FIELDS_NONE;
401 *timestamp = gpsmanager->position.timestamp;
405 *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
406 *latitude = gpsmanager->position.latitude;
410 *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
411 *longitude = gpsmanager->position.longitude;
415 *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE;
416 *altitude = gpsmanager->position.altitude;
421 geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_DETAILED,
422 gpsmanager->position.hor_accuracy, gpsmanager->position.ver_accuracy);
428 static gboolean get_last_position(GcIfacePosition * gc,
429 GeocluePositionFields * fields,
430 int *timestamp, double *latitude,
431 double *longitude, double *altitude, GeoclueAccuracy ** accuracy, GError ** error)
433 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
436 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters");
440 *fields = GEOCLUE_POSITION_FIELDS_NONE;
443 *timestamp = gpsmanager->last_position.timestamp;
447 *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
448 *latitude = gpsmanager->last_position.latitude;
452 *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
453 *longitude = gpsmanager->last_position.longitude;
457 *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE;
458 *altitude = gpsmanager->last_position.altitude;
464 geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_DETAILED,
465 gpsmanager->last_position.hor_accuracy, gpsmanager->last_position.ver_accuracy);
471 static gboolean get_velocity(GcIfaceVelocity * gc,
472 GeoclueVelocityFields * fields,
473 int *timestamp, double *speed, double *direction, double *climb, GError ** error)
475 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
477 if (gpsmanager->status == GEOCLUE_STATUS_ACQUIRING) {
478 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_NOT_AVAILABLE, "ERROR: Acquiring");
482 if (gpsmanager->status != GEOCLUE_STATUS_AVAILABLE) {
483 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available");
488 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters");
492 *fields = GEOCLUE_VELOCITY_FIELDS_NONE;
495 *timestamp = gpsmanager->position.timestamp;
499 *fields |= GEOCLUE_VELOCITY_FIELDS_SPEED;
500 *speed = gpsmanager->position.speed;
504 *fields |= GEOCLUE_VELOCITY_FIELDS_DIRECTION;
505 *direction = gpsmanager->position.bearing;
508 /* A climb field does not supported because of poor accuracy. */
513 static gboolean get_last_velocity(GcIfaceVelocity * gc,
514 GeoclueVelocityFields * fields,
515 int *timestamp, double *speed, double *direction, double *climb, GError ** error)
517 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
520 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters");
524 *fields = GEOCLUE_VELOCITY_FIELDS_NONE;
527 *timestamp = gpsmanager->last_position.timestamp;
531 *fields |= GEOCLUE_VELOCITY_FIELDS_SPEED;
532 *speed = gpsmanager->last_position.speed;
536 *fields |= GEOCLUE_VELOCITY_FIELDS_DIRECTION;
537 *direction = gpsmanager->last_position.bearing;
543 static gboolean get_nmea(GcIfaceNmea * gc, int *timestamp, char **nmea_data, GError ** error)
545 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
547 if (gpsmanager->status == GEOCLUE_STATUS_UNAVAILABLE || gpsmanager->status == GEOCLUE_STATUS_ERROR) {
548 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available");
553 *timestamp = gpsmanager->position.timestamp;
557 *nmea_data = g_memdup(gpsmanager->nmea.data, gpsmanager->nmea.len);
563 static gboolean get_satellite(GcIfaceSatellite * gc,
566 int *satellite_visible, GArray ** used_prn, GPtrArray ** satellite_info, GError ** error)
568 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
570 if (gpsmanager->status == GEOCLUE_STATUS_UNAVAILABLE || gpsmanager->status == GEOCLUE_STATUS_ERROR) {
571 g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available");
576 *timestamp = gpsmanager->satellite.timestamp;
579 if (satellite_used) {
582 for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) {
583 count += gpsmanager->satellite.sat[index].used ? 1 : 0;
585 *satellite_used = count;
588 if (satellite_visible) {
589 *satellite_visible = gpsmanager->satellite.num_of_sat;
594 *used_prn = g_array_new(FALSE, FALSE, sizeof(guint));
596 for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) {
597 if (gpsmanager->satellite.sat[index].used) {
598 g_array_append_val(*used_prn, gpsmanager->satellite.sat[index].prn);
603 if (satellite_info) {
605 *satellite_info = g_ptr_array_new();
606 for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) {
607 GValue sv_info = { 0, };
608 g_value_init(&sv_info, GEOCLUE_SATELLITE_INFO);
609 g_value_take_boxed(&sv_info, dbus_g_type_specialized_construct(GEOCLUE_SATELLITE_INFO));
610 dbus_g_type_struct_set(&sv_info,
611 0, gpsmanager->satellite.sat[index].prn,
612 1, gpsmanager->satellite.sat[index].elevation,
613 2, gpsmanager->satellite.sat[index].azimuth,
614 3, gpsmanager->satellite.sat[index].snr, G_MAXUINT);
615 g_ptr_array_add(*satellite_info, g_value_get_boxed(&sv_info));
621 static gboolean get_last_satellite(GcIfaceSatellite * gc,
622 int *timestamp, int *satellite_used,
623 int *satellite_visible, GArray ** used_prn, GPtrArray ** satellite_info, GError ** error)
625 GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc));
628 *timestamp = gpsmanager->last_satellite.timestamp;
631 if (satellite_used) {
634 for (index = 0; index < gpsmanager->last_satellite.num_of_sat; ++index) {
635 count += gpsmanager->last_satellite.sat[index].used ? 1 : 0;
637 *satellite_used = count;
640 if (satellite_visible) {
641 *satellite_visible = gpsmanager->last_satellite.num_of_sat;
646 *used_prn = g_array_new(FALSE, FALSE, sizeof(guint));
648 for (index = 0; index < gpsmanager->last_satellite.num_of_sat; ++index) {
649 if (gpsmanager->last_satellite.sat[index].used) {
650 g_array_append_val(*used_prn, gpsmanager->last_satellite.sat[index].prn);
655 if (satellite_info) {
657 *satellite_info = g_ptr_array_new();
658 for (index = 0; index < gpsmanager->last_satellite.num_of_sat; ++index) {
659 GValue sv_info = { 0, };
660 g_value_init(&sv_info, GEOCLUE_SATELLITE_INFO);
661 g_value_take_boxed(&sv_info, dbus_g_type_specialized_construct(GEOCLUE_SATELLITE_INFO));
662 dbus_g_type_struct_set(&sv_info, 0,
663 gpsmanager->last_satellite.sat[index].prn, 1,
664 gpsmanager->last_satellite.sat[index].elevation, 2,
665 gpsmanager->last_satellite.sat[index].azimuth, 3,
666 gpsmanager->last_satellite.sat[index].snr, G_MAXUINT);
667 g_ptr_array_add(*satellite_info, g_value_get_boxed(&sv_info));
674 static void init_position(GcIfacePositionClass * iface)
676 iface->get_position = get_position;
677 iface->get_last_position = get_last_position;
680 static void init_velocity(GcIfaceVelocityClass * iface)
682 iface->get_velocity = get_velocity;
683 iface->get_last_velocity = get_last_velocity;
686 static void init_nmea(GcIfaceNmeaClass * iface)
688 iface->get_nmea = get_nmea;
691 static void init_satellite(GcIfaceSatelliteClass * iface)
693 iface->get_satellite = get_satellite;
694 iface->get_last_satellite = get_last_satellite;
697 static void init_geoclue(GcIfaceGeoclueClass * iface)
699 iface->get_provider_info = get_provider_info;
700 iface->add_reference = add_reference;
701 iface->remove_reference = remove_reference;
704 int main(int argc, char **argv)
706 GeoclueGpsManager *gpsmanager;
707 struct gps_callbacks cb;
708 cb.pos_cb = update_position_cb;
709 cb.sv_cb = update_satellite_cb;
710 cb.nmea_cb = update_nmea_cb;
712 if (!g_thread_supported()) {
715 dbus_g_thread_init();
718 initialize_server(argc, argv);
720 gpsmanager = g_object_new(GEOCLUE_TYPE_GPSMANAGER, NULL);
721 register_update_callbacks(&cb, gpsmanager);
723 gpsmanager->loop = g_main_loop_new(NULL, TRUE);
724 g_main_loop_run(gpsmanager->loop);
726 g_main_loop_unref(gpsmanager->loop);
727 g_object_unref(gpsmanager);
729 deinitialize_server();