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.
25 #include <vconf-internal-location-keys.h>
26 #include <location-module.h>
28 #include <geoclue/geoclue-position.h>
29 #include <geoclue/geoclue-velocity.h>
30 #include <geoclue/geoclue-satellite.h>
31 #include <geoclue/geoclue-nmea.h>
32 #include <geoclue/geoclue-provider.h>
46 GeoclueSatellite *sat;
47 LocModStatusCB status_cb;
48 LocModPositionCB pos_cb;
49 LocModVelocityCB vel_cb;
50 LocModSatelliteCB sat_cb;
55 #define GPS_MANAGER_SERVICE_NAME "org.freedesktop.Geoclue.Providers.GpsManager"
56 #define GPS_MANAGER_SERVICE_PATH "/org/freedesktop/Geoclue/Providers/GpsManager"
59 static void status_callback(GeoclueProvider * provider, gint status, gpointer userdata)
61 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
62 g_return_if_fail(gps_manager);
63 g_return_if_fail(gps_manager->status_cb);
66 case GEOCLUE_STATUS_ERROR:
67 case GEOCLUE_STATUS_UNAVAILABLE:
68 case GEOCLUE_STATUS_ACQUIRING:
69 MOD_LOGD("GEOCLUE_STATUS_ACQUIRING/ERROR/UNAVAILABLE");
70 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
72 case GEOCLUE_STATUS_AVAILABLE:
73 MOD_LOGD("GEOCLUE_STATUS_AVAILABLE");
74 gps_manager->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gps_manager->userdata);
81 static void satellite_callback(GeoclueSatellite * satellite, int timestamp,
82 int satellite_used, int satellite_visible,
83 GArray * used_prn, GPtrArray * sat_info, gpointer userdata)
85 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
86 g_return_if_fail(gps_manager);
87 g_return_if_fail(gps_manager->sat_cb);
91 LocationSatellite *sat = NULL;
93 sat = location_satellite_new(satellite_visible);
95 sat->timestamp = timestamp;
96 sat->num_of_sat_inview = satellite_visible;
97 sat->num_of_sat_used = satellite_used;
98 for (idx = 0; idx < satellite_visible; idx++) {
99 gboolean used = FALSE;
100 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
101 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
102 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
103 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
104 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
105 for (used_idx = 0; used_idx < satellite_used; used_idx++) {
106 if (prn == g_array_index(used_prn, guint, idx)) {
111 MOD_LOGD("prn[%d] : used %d elev %d azim %d snr %d", prn, used, elev, azim, snr);
112 location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
115 gps_manager->sat_cb(TRUE, sat, gps_manager->userdata);
116 location_satellite_free(sat);
119 static void nmea_callback(GeoclueNmea * nmea, int timestamp, char *data, gpointer userdata)
123 static void position_callback(GeocluePosition * position,
124 GeocluePositionFields fields, int timestamp,
125 double latitude, double longitude, double altitude, GeoclueAccuracy * accuracy, gpointer userdata)
127 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
128 g_return_if_fail(gps_manager);
129 g_return_if_fail(gps_manager->pos_cb);
131 GeoclueAccuracyLevel level;
134 geoclue_accuracy_get_details(accuracy, &level, &horiz_acc, &vert_acc);
136 LocationPosition *pos = NULL;
137 LocationAccuracy *acc = NULL;
139 if ((fields & GEOCLUE_POSITION_FIELDS_LATITUDE)
140 && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
141 if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) {
142 pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
144 pos = location_position_new(timestamp, latitude, longitude, 0.0, LOCATION_STATUS_2D_FIX);
147 pos = location_position_new(0.0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
151 GeoclueAccuracyLevel level;
154 geoclue_accuracy_get_details(accuracy, &level, &horiz_acc, &vert_acc);
155 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
157 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, horiz_acc, vert_acc);
161 ("time(%d) lat(%f) long(%f) alt(%f) status(%d) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
162 pos->timestamp, pos->latitude, pos->longitude, pos->altitude,
163 pos->status, acc->level, acc->horizontal_accuracy, acc->vertical_accuracy);
165 gps_manager->pos_cb(TRUE, pos, acc, gps_manager->userdata);
166 location_position_free(pos);
167 location_accuracy_free(acc);
170 static void velocity_callback(GeoclueVelocity * velocity,
171 GeoclueVelocityFields fields, int timestamp,
172 double speed, double direction, double climb, gpointer userdata)
174 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
175 g_return_if_fail(gps_manager);
176 g_return_if_fail(gps_manager->vel_cb);
178 LocationVelocity *vel = NULL;
179 LocationAccuracy *acc = NULL;
181 if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
182 if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
183 vel = location_velocity_new(timestamp, speed, direction, climb);
185 vel = location_velocity_new(timestamp, speed, direction, 0);
186 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
188 vel = location_velocity_new(0, 0, 0, 0);
189 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
192 ("timestamp(%d) speed(%f) direction(%f) climb(%f) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
193 vel->timestamp, vel->speed, vel->direction, vel->climb, acc->level,
194 acc->horizontal_accuracy, acc->vertical_accuracy);
196 gps_manager->vel_cb(TRUE, vel, acc, gps_manager->userdata);
197 location_velocity_free(vel);
198 location_accuracy_free(acc);
201 static void unref_gps_manager(GpsManagerData * gps_manager)
203 if (gps_manager->pos) {
204 g_signal_handlers_disconnect_by_func(G_OBJECT
206 (gps_manager->pos)), G_CALLBACK(status_callback), gps_manager);
207 g_signal_handlers_disconnect_by_func(G_OBJECT
209 (gps_manager->pos)), G_CALLBACK(position_callback), gps_manager);
210 g_object_unref(gps_manager->pos);
211 gps_manager->pos = NULL;
214 if (gps_manager->vel) {
215 g_signal_handlers_disconnect_by_func(G_OBJECT
217 (gps_manager->vel)), G_CALLBACK(velocity_callback), gps_manager);
218 g_object_unref(gps_manager->vel);
219 gps_manager->vel = NULL;
222 if (gps_manager->nmea) {
223 g_signal_handlers_disconnect_by_func(G_OBJECT
225 (gps_manager->nmea)), G_CALLBACK(nmea_callback), gps_manager);
226 g_object_unref(gps_manager->nmea);
227 gps_manager->nmea = NULL;
230 if (gps_manager->sat) {
231 g_signal_handlers_disconnect_by_func(G_OBJECT
233 (gps_manager->sat)), G_CALLBACK(satellite_callback), gps_manager);
234 g_object_unref(gps_manager->sat);
235 gps_manager->sat = NULL;
238 gps_manager->is_started = FALSE;
241 static gboolean ref_gps_manager(GpsManagerData * gps_manager)
243 gchar *service, *path;
245 if (gps_manager->is_started == TRUE) {
246 MOD_LOGW("gps-manager is alredy started");
250 service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
251 path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
253 if (!gps_manager->pos) {
254 gps_manager->pos = geoclue_position_new(service, path);
256 if (!gps_manager->vel) {
257 gps_manager->vel = geoclue_velocity_new(service, path);
259 if (!gps_manager->nmea) {
260 gps_manager->nmea = geoclue_nmea_new(service, path);
262 if (!gps_manager->sat) {
263 gps_manager->sat = geoclue_satellite_new(service, path);
269 if (!gps_manager->pos || !gps_manager->vel || !gps_manager->nmea || !gps_manager->sat) {
270 MOD_LOGW("Error while creating Geoclue object.");
271 unref_gps_manager(gps_manager);
275 gps_manager->is_started = TRUE;
278 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->pos)),
279 "status-changed", G_CALLBACK(status_callback), gps_manager);
280 MOD_LOGD("gsignal_connect status-changed %d", ret);
282 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->pos)),
283 "position-changed", G_CALLBACK(position_callback), gps_manager);
284 MOD_LOGD("gsignal_connect position-changed %d", ret);
286 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->vel)),
287 "velocity-changed", G_CALLBACK(velocity_callback), gps_manager);
288 MOD_LOGD("gsignal_connect velocity-changed %d", ret);
290 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->sat)),
291 "satellite-changed", G_CALLBACK(satellite_callback), gps_manager);
292 MOD_LOGD("gsignal_connect satellite-changed %d", ret);
294 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->nmea)),
295 "nmea-changed", G_CALLBACK(nmea_callback), gps_manager);
296 MOD_LOGD("gsignal_connect nmea-changed %d", ret);
301 static int start(gpointer handle, LocModStatusCB status_cb, LocModPositionCB pos_cb, LocModVelocityCB vel_cb, LocModSatelliteCB sat_cb, gpointer userdata)
304 GpsManagerData *gps_manager = (GpsManagerData *) handle;
305 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
306 g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
307 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
308 g_return_val_if_fail(vel_cb, LOCATION_ERROR_NOT_AVAILABLE);
310 gps_manager->status_cb = status_cb;
311 gps_manager->pos_cb = pos_cb;
312 gps_manager->vel_cb = vel_cb;
313 gps_manager->sat_cb = sat_cb;
314 gps_manager->userdata = userdata;
316 if (!ref_gps_manager(gps_manager))
317 return LOCATION_ERROR_NOT_AVAILABLE;
320 GError *error = NULL;
322 options = g_hash_table_new(g_str_hash, g_str_equal);
323 g_hash_table_insert(options, "CMD", "START");
325 if (!geoclue_provider_set_options(GEOCLUE_PROVIDER(gps_manager->pos), options, &error)) {
326 MOD_LOGE("Error geoclue_provider_set_options(START) : %s", error->message);
329 g_hash_table_destroy(options);
330 return LOCATION_ERROR_NOT_AVAILABLE;
332 MOD_LOGD("Success to geoclue_provider_set_options(START)");
334 g_hash_table_destroy(options);
336 return LOCATION_ERROR_NONE;
339 static int stop(gpointer handle)
342 GpsManagerData *gps_manager = (GpsManagerData *) handle;
343 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
344 g_return_val_if_fail(gps_manager->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
347 GError *error = NULL;
349 options = g_hash_table_new(g_str_hash, g_str_equal);
350 g_hash_table_insert(options, "CMD", "STOP");
352 if (!geoclue_provider_set_options(GEOCLUE_PROVIDER(gps_manager->pos), options, &error)) {
353 MOD_LOGE("Error geoclue_provider_set_options(STOP) : %s", error->message);
356 g_hash_table_destroy(options);
357 return LOCATION_ERROR_NOT_AVAILABLE;
359 MOD_LOGD("Success to geoclue_provider_set_options(STOP)");
361 g_hash_table_destroy(options);
363 unref_gps_manager(gps_manager);
364 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
365 return LOCATION_ERROR_NONE;
368 static int get_position(gpointer handle, LocationPosition ** position, LocationAccuracy ** accuracy)
370 MOD_LOGD("get_position");
371 GpsManagerData *gps_manager = (GpsManagerData *) handle;
372 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
373 g_return_val_if_fail(gps_manager->pos, LOCATION_ERROR_NOT_AVAILABLE);
374 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
375 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
377 GeocluePositionFields fields;
379 double lat, lon, alt;
380 GeoclueAccuracy *_accuracy = NULL;
381 GError *error = NULL;
383 fields = geoclue_position_get_position(gps_manager->pos, ×tamp, &lat, &lon, &alt, &_accuracy, &error);
385 MOD_LOGD("Error getting position: %s", error->message);
387 return LOCATION_ERROR_NOT_AVAILABLE;
390 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
391 if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
392 *position = location_position_new(timestamp, lat, lon, alt, LOCATION_STATUS_3D_FIX);
394 *position = location_position_new(timestamp, lat, lon, 0, LOCATION_STATUS_2D_FIX);
396 *position = location_position_new(0, 0, 0, 0, LOCATION_STATUS_NO_FIX);
399 GeoclueAccuracyLevel level;
402 geoclue_accuracy_get_details(_accuracy, &level, &horiz_acc, &vert_acc);
403 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
404 geoclue_accuracy_free(_accuracy);
406 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
408 return LOCATION_ERROR_NONE;
411 static int get_velocity(gpointer handle, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
413 MOD_LOGD("get_velocity");
414 GpsManagerData *gps_manager = (GpsManagerData *) handle;
415 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
416 g_return_val_if_fail(gps_manager->vel, LOCATION_ERROR_NOT_AVAILABLE);
417 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
418 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
420 GeoclueVelocityFields fields;
422 double spd, dir, climb;
423 GError *error = NULL;
425 fields = geoclue_velocity_get_velocity(gps_manager->vel, ×tamp, &spd, &dir, &climb, &error);
427 MOD_LOGD("Error getting velocity: %s", error->message);
429 return LOCATION_ERROR_NOT_AVAILABLE;
432 if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
433 if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
434 *velocity = location_velocity_new(timestamp, spd, dir, climb);
436 *velocity = location_velocity_new(timestamp, spd, dir, 0);
437 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
439 *velocity = location_velocity_new(0, 0, 0, 0);
440 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
442 return LOCATION_ERROR_NONE;
445 static int get_nmea(gpointer handle, gchar ** nmea_data)
447 MOD_LOGD("get_nmea");
448 GpsManagerData *gps_manager = (GpsManagerData *) handle;
449 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
450 g_return_val_if_fail(gps_manager->nmea, LOCATION_ERROR_NOT_AVAILABLE);
451 g_return_val_if_fail(nmea_data, LOCATION_ERROR_PARAMETER);
453 gboolean ret = FALSE;
455 char *_nmea_data = NULL;
456 GError *error = NULL;
457 ret = geoclue_nmea_get_nmea(gps_manager->nmea, ×tamp, &_nmea_data, &error);
459 MOD_LOGD("\t Error getting nmea: %s", error->message);
461 return LOCATION_ERROR_NOT_AVAILABLE;
463 *nmea_data = g_strdup(_nmea_data);
465 return LOCATION_ERROR_NONE;
468 static int get_satellite(gpointer handle, LocationSatellite ** satellite)
470 MOD_LOGD("get_satellite");
471 GpsManagerData *gps_manager = (GpsManagerData *) handle;
472 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
473 g_return_val_if_fail(gps_manager->sat, LOCATION_ERROR_NOT_AVAILABLE);
474 g_return_val_if_fail(satellite, LOCATION_ERROR_PARAMETER);
480 GArray *u_prn = NULL;
481 GPtrArray *sat_info = NULL;
482 GError *error = NULL;
484 geoclue_satellite_get_satellite(gps_manager->sat, ×tamp, &sat_used, &sat_vis, &u_prn, &sat_info, &error);
486 MOD_LOGW("\t Error getting satellite: %s", error->message);
488 return LOCATION_ERROR_NOT_AVAILABLE;
490 *satellite = location_satellite_new(sat_vis);
491 (*satellite)->timestamp = timestamp;
493 for (idx = 0; idx < sat_vis; idx++) {
494 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
495 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
496 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
497 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
498 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
501 gboolean is_used = FALSE;
502 for (used_idx = 0; used_idx < sat_used; used_idx++) {
503 if ((guint) prn == (guint) g_array_index(u_prn, guint, used_idx)) {
508 location_satellite_set_satellite_details(*satellite, idx,
509 (guint) prn, is_used, (guint) elev, (guint) azim, (guint) snr);
513 g_array_free(u_prn, TRUE);
515 g_ptr_array_free(sat_info, TRUE);
517 return LOCATION_ERROR_NONE;
520 static int get_last_position(gpointer handle, LocationPosition ** position, LocationAccuracy ** accuracy)
522 MOD_LOGD("get_last_position");
523 GpsManagerData *gps_manager = (GpsManagerData *) handle;
524 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
525 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
526 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
529 double longitude = 0.0, latitude = 0.0, altitude = 0.0;
530 double hor_accuracy = 0.0, ver_accuracy = 0.0;
531 LocationStatus status = LOCATION_STATUS_NO_FIX;
532 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
534 if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp) ||
535 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, &latitude) ||
536 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, &longitude) ||
537 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, &altitude) ||
538 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
539 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
542 return LOCATION_ERROR_NOT_AVAILABLE;
546 if (altitude) status = LOCATION_STATUS_3D_FIX;
547 else status = LOCATION_STATUS_2D_FIX;
552 return LOCATION_ERROR_NOT_AVAILABLE;
555 level = LOCATION_ACCURACY_LEVEL_DETAILED;
556 *position = location_position_new(timestamp, latitude, longitude, altitude, status);
557 *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
559 return LOCATION_ERROR_NONE;
562 static int get_last_velocity(gpointer handle, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
564 MOD_LOGD("get_last_velocity");
565 GpsManagerData *gps_manager = (GpsManagerData *) handle;
566 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
567 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
568 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
571 gdouble speed = 0.0, direction = 0.0;
572 gdouble hor_accuracy = 0.0, ver_accuracy = 0.0;
574 if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp) ||
575 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_SPEED, &speed) ||
576 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, &direction) ||
577 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
578 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
581 return LOCATION_ERROR_NOT_AVAILABLE;;
584 if (!timestamp || (speed < 0 && direction < 0)) {
587 return LOCATION_ERROR_NOT_AVAILABLE;
590 *velocity = location_velocity_new ((guint) timestamp, speed, direction, 0.0);
591 *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, hor_accuracy, ver_accuracy);
593 return LOCATION_ERROR_NONE;
596 static int get_last_satellite(gpointer handle, LocationSatellite ** satellite)
598 MOD_LOGD("get_last_satellite");
599 GpsManagerData *gps_manager = (GpsManagerData *) handle;
600 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
601 g_return_val_if_fail(satellite, LOCATION_ERROR_PARAMETER);
607 GArray *u_prn = NULL;
608 GPtrArray *sat_info = NULL;
609 GError *error = NULL;
610 gchar *service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
611 gchar *path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
613 GeoclueSatellite *last_sat = geoclue_satellite_new(service, path);
615 geoclue_satellite_get_last_satellite(last_sat, ×tamp, &sat_used, &sat_vis, &u_prn, &sat_info, &error);
617 MOD_LOGW("\t Error getting last satellite: %s", error->message);
619 g_object_unref(last_sat);
622 return LOCATION_ERROR_NOT_AVAILABLE;
624 *satellite = location_satellite_new(sat_vis);
625 (*satellite)->timestamp = timestamp;
627 for (idx = 0; idx < sat_vis; idx++) {
628 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
629 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
630 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
631 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
632 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
635 gboolean is_used = FALSE;
636 for (used_idx = 0; used_idx < sat_used; used_idx++) {
637 if ((guint) prn == (guint) g_array_index(u_prn, guint, used_idx)) {
642 location_satellite_set_satellite_details(*satellite, idx,
643 (guint) prn, is_used, (guint) elev, (guint) azim, (guint) snr);
647 g_array_free(u_prn, TRUE);
649 g_ptr_array_free(sat_info, TRUE);
651 g_object_unref(last_sat);
655 return LOCATION_ERROR_NONE;
658 static int set_devname(gpointer handle, const char *devname)
660 GpsManagerData *gps_manager = (GpsManagerData *) handle;
661 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
662 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
663 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
664 MOD_LOGD("set_devname: %s --> %s", gps_manager->devname, devname);
665 g_stpcpy(gps_manager->devname, devname);
667 return LOCATION_ERROR_NONE;
670 static int get_devname(gpointer handle, char **devname)
672 GpsManagerData *gps_manager = (GpsManagerData *) handle;
673 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
674 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
675 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
676 *devname = g_strdup(gps_manager->devname);
677 MOD_LOGD("get_devname: %s", *devname);
679 return LOCATION_ERROR_NONE;
682 LOCATION_MODULE_API gpointer init(LocModGpsOps * ops)
686 g_return_val_if_fail(ops, NULL);
689 ops->get_position = get_position;
690 ops->get_velocity = get_velocity;
691 ops->get_last_position = get_last_position;
692 ops->get_last_velocity = get_last_velocity;
695 if (dladdr(&get_position, &info) == 0) {
696 MOD_LOGD("Failed to get module name");
697 } else if (g_strrstr(info.dli_fname, "gps")) {
698 ops->get_nmea = get_nmea;
699 ops->get_satellite = get_satellite;
700 ops->get_last_satellite = get_last_satellite;
701 ops->set_devname = set_devname;
702 ops->get_devname = get_devname;
705 GpsManagerData *gps_manager = g_new0(GpsManagerData, 1);
706 g_return_val_if_fail(gps_manager, NULL);
708 g_stpcpy(gps_manager->devname, "/dev/ttySAC1");
709 gps_manager->pos = NULL;
710 gps_manager->vel = NULL;
711 gps_manager->nmea = NULL;
712 gps_manager->sat = NULL;
713 gps_manager->status_cb = NULL;
714 gps_manager->pos_cb = NULL;
715 gps_manager->vel_cb = NULL;
716 gps_manager->userdata = NULL;
717 gps_manager->is_started = FALSE;
719 return (gpointer) gps_manager;
722 LOCATION_MODULE_API void shutdown(gpointer handle)
724 MOD_LOGD("shutdown");
725 g_return_if_fail(handle);
726 GpsManagerData *gps_manager = (GpsManagerData *) handle;
728 unref_gps_manager(gps_manager);
729 if (gps_manager->status_cb)
730 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);