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 <location-module.h>
27 #include <geoclue/geoclue-position.h>
28 #include <geoclue/geoclue-velocity.h>
29 #include <geoclue/geoclue-satellite.h>
30 #include <geoclue/geoclue-nmea.h>
31 #include <geoclue/geoclue-provider.h>
40 #define VCONF_LOCATION_PATH "db/location"
41 #define LOCATION_LAST_PATH VCONF_LOCATION_PATH"/last"
42 #define GPS_LAST_PATH LOCATION_LAST_PATH"/gps"
43 #define GPS_LAST_TIMESTAMP GPS_LAST_PATH"/Timestamp"
44 #define GPS_LAST_LATITUDE GPS_LAST_PATH"/Latitude"
45 #define GPS_LAST_LONGITUDE GPS_LAST_PATH"/Longitude"
46 #define GPS_LAST_ALTITUDE GPS_LAST_PATH"/Altitude"
47 #define GPS_LAST_HORACCURACY GPS_LAST_PATH"/HorAccuracy"
48 #define GPS_LAST_VERACCURACY GPS_LAST_PATH"/VerAccuracy"
49 #define GPS_LAST_SPEED GPS_LAST_PATH"/Speed"
50 #define GPS_LAST_DIRECTION GPS_LAST_PATH"/Direction"
58 GeoclueSatellite *sat;
59 LocModStatusCB status_cb;
60 LocModPositionCB pos_cb;
61 LocModVelocityCB vel_cb;
62 LocModSatelliteCB sat_cb;
67 #define GPS_MANAGER_SERVICE_NAME "org.freedesktop.Geoclue.Providers.GpsManager"
68 #define GPS_MANAGER_SERVICE_PATH "/org/freedesktop/Geoclue/Providers/GpsManager"
71 static void status_callback(GeoclueProvider * provider, gint status, gpointer userdata)
73 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
74 g_return_if_fail(gps_manager);
75 g_return_if_fail(gps_manager->status_cb);
78 case GEOCLUE_STATUS_ERROR:
79 case GEOCLUE_STATUS_UNAVAILABLE:
80 case GEOCLUE_STATUS_ACQUIRING:
81 MOD_LOGD("GEOCLUE_STATUS_ACQUIRING/ERROR/UNAVAILABLE");
82 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
84 case GEOCLUE_STATUS_AVAILABLE:
85 MOD_LOGD("GEOCLUE_STATUS_AVAILABLE");
86 gps_manager->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gps_manager->userdata);
93 static void satellite_callback(GeoclueSatellite * satellite, int timestamp,
94 int satellite_used, int satellite_visible,
95 GArray * used_prn, GPtrArray * sat_info, gpointer userdata)
97 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
98 g_return_if_fail(gps_manager);
99 g_return_if_fail(gps_manager->sat_cb);
102 LocationSatellite *sat = NULL;
104 sat = location_satellite_new(satellite_visible);
106 sat->timestamp = timestamp;
107 sat->num_of_sat_inview = satellite_visible;
108 sat->num_of_sat_used = satellite_used;
109 for (idx = 0; idx < satellite_visible; idx++) {
112 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
113 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
114 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
115 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
116 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
117 for (used_idx = 0; used_idx < satellite_used; used_idx++) {
118 if (prn == g_array_index(used_prn, guint, idx)) {
125 MOD_LOGD("prn[%d] : used %d elev %d azim %d snr %d", prn, used, elev, azim, snr);
126 location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
129 gps_manager->sat_cb(TRUE, sat, gps_manager->userdata);
130 location_satellite_free(sat);
133 static void nmea_callback(GeoclueNmea * nmea, int timestamp, char *data, gpointer userdata)
137 static void position_callback(GeocluePosition * position,
138 GeocluePositionFields fields, int timestamp,
139 double latitude, double longitude, double altitude, GeoclueAccuracy * accuracy, gpointer userdata)
141 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
142 g_return_if_fail(gps_manager);
143 g_return_if_fail(gps_manager->pos_cb);
145 GeoclueAccuracyLevel level;
148 geoclue_accuracy_get_details(accuracy, &level, &horiz_acc, &vert_acc);
150 LocationPosition *pos = NULL;
151 LocationAccuracy *acc = NULL;
153 if ((fields & GEOCLUE_POSITION_FIELDS_LATITUDE)
154 && (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
155 if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) {
156 pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
158 pos = location_position_new(timestamp, latitude, longitude, 0.0, LOCATION_STATUS_2D_FIX);
161 pos = location_position_new(0.0, 0.0, 0.0, 0.0, LOCATION_STATUS_NO_FIX);
165 GeoclueAccuracyLevel level;
168 geoclue_accuracy_get_details(accuracy, &level, &horiz_acc, &vert_acc);
169 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
171 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, horiz_acc, vert_acc);
175 ("time(%d) lat(%f) long(%f) alt(%f) status(%d) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
176 pos->timestamp, pos->latitude, pos->longitude, pos->altitude,
177 pos->status, acc->level, acc->horizontal_accuracy, acc->vertical_accuracy);
179 gps_manager->pos_cb(TRUE, pos, acc, gps_manager->userdata);
180 location_position_free(pos);
181 location_accuracy_free(acc);
184 static void velocity_callback(GeoclueVelocity * velocity,
185 GeoclueVelocityFields fields, int timestamp,
186 double speed, double direction, double climb, gpointer userdata)
188 GpsManagerData *gps_manager = (GpsManagerData *) userdata;
189 g_return_if_fail(gps_manager);
190 g_return_if_fail(gps_manager->vel_cb);
192 LocationVelocity *vel = NULL;
193 LocationAccuracy *acc = NULL;
195 if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
196 if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
197 vel = location_velocity_new(timestamp, speed, direction, climb);
199 vel = location_velocity_new(timestamp, speed, direction, 0);
200 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
202 vel = location_velocity_new(0, 0, 0, 0);
203 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
206 ("timestamp(%d) speed(%f) direction(%f) climb(%f) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
207 vel->timestamp, vel->speed, vel->direction, vel->climb, acc->level,
208 acc->horizontal_accuracy, acc->vertical_accuracy);
210 gps_manager->vel_cb(TRUE, vel, acc, gps_manager->userdata);
211 location_velocity_free(vel);
212 location_accuracy_free(acc);
215 static void unref_gps_manager(GpsManagerData * gps_manager)
217 if (gps_manager->pos) {
218 g_signal_handlers_disconnect_by_func(G_OBJECT
220 (gps_manager->pos)), G_CALLBACK(status_callback), gps_manager);
221 g_signal_handlers_disconnect_by_func(G_OBJECT
223 (gps_manager->pos)), G_CALLBACK(position_callback), gps_manager);
224 g_object_unref(gps_manager->pos);
225 gps_manager->pos = NULL;
228 if (gps_manager->vel) {
229 g_signal_handlers_disconnect_by_func(G_OBJECT
231 (gps_manager->vel)), G_CALLBACK(velocity_callback), gps_manager);
232 g_object_unref(gps_manager->vel);
233 gps_manager->vel = NULL;
236 if (gps_manager->nmea) {
237 g_signal_handlers_disconnect_by_func(G_OBJECT
239 (gps_manager->nmea)), G_CALLBACK(nmea_callback), gps_manager);
240 g_object_unref(gps_manager->nmea);
241 gps_manager->nmea = NULL;
244 if (gps_manager->sat) {
245 g_signal_handlers_disconnect_by_func(G_OBJECT
247 (gps_manager->sat)), G_CALLBACK(satellite_callback), gps_manager);
248 g_object_unref(gps_manager->sat);
249 gps_manager->sat = NULL;
252 gps_manager->is_started = FALSE;
255 static gboolean ref_gps_manager(GpsManagerData * gps_manager)
257 gchar *service, *path;
259 if (gps_manager->is_started == TRUE) {
260 MOD_LOGW("gps-manager is alredy started");
264 service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
265 path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
267 if (!gps_manager->pos) {
268 gps_manager->pos = geoclue_position_new(service, path);
270 if (!gps_manager->vel) {
271 gps_manager->vel = geoclue_velocity_new(service, path);
273 if (!gps_manager->nmea) {
274 gps_manager->nmea = geoclue_nmea_new(service, path);
276 if (!gps_manager->sat) {
277 gps_manager->sat = geoclue_satellite_new(service, path);
283 if (!gps_manager->pos || !gps_manager->vel || !gps_manager->nmea || !gps_manager->sat) {
284 MOD_LOGW("Error while creating Geoclue object.");
285 unref_gps_manager(gps_manager);
289 gps_manager->is_started = TRUE;
292 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->pos)),
293 "status-changed", G_CALLBACK(status_callback), gps_manager);
294 g_debug("gsignal_connect status-changed %d", ret);
296 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->pos)),
297 "position-changed", G_CALLBACK(position_callback), gps_manager);
298 g_debug("gsignal_connect position-changed %d", ret);
300 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->vel)),
301 "velocity-changed", G_CALLBACK(velocity_callback), gps_manager);
302 g_debug("gsignal_connect velocity-changed %d", ret);
304 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->sat)),
305 "satellite-changed", G_CALLBACK(satellite_callback), gps_manager);
306 g_debug("gsignal_connect satellite-changed %d", ret);
308 g_signal_connect(G_OBJECT(GEOCLUE_PROVIDER(gps_manager->nmea)),
309 "nmea-changed", G_CALLBACK(nmea_callback), gps_manager);
310 g_debug("gsignal_connect nmea-changed %d", ret);
315 static int start(gpointer handle, LocModStatusCB status_cb, LocModPositionCB pos_cb, LocModVelocityCB vel_cb, LocModSatelliteCB sat_cb, gpointer userdata)
318 GpsManagerData *gps_manager = (GpsManagerData *) handle;
319 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
320 g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
321 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
322 g_return_val_if_fail(vel_cb, LOCATION_ERROR_NOT_AVAILABLE);
324 gps_manager->status_cb = status_cb;
325 gps_manager->pos_cb = pos_cb;
326 gps_manager->vel_cb = vel_cb;
327 gps_manager->sat_cb = sat_cb;
328 gps_manager->userdata = userdata;
330 if (!ref_gps_manager(gps_manager))
331 return LOCATION_ERROR_NOT_AVAILABLE;
332 return LOCATION_ERROR_NONE;
335 static int stop(gpointer handle)
338 GpsManagerData *gps_manager = (GpsManagerData *) handle;
339 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
340 g_return_val_if_fail(gps_manager->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
341 unref_gps_manager(gps_manager);
342 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
343 return LOCATION_ERROR_NONE;
346 static int get_position(gpointer handle, LocationPosition ** position, LocationAccuracy ** accuracy)
348 MOD_LOGD("get_position");
349 GpsManagerData *gps_manager = (GpsManagerData *) handle;
350 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
351 g_return_val_if_fail(gps_manager->pos, LOCATION_ERROR_NOT_AVAILABLE);
352 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
353 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
355 GeocluePositionFields fields;
357 double lat, lon, alt;
358 GeoclueAccuracy *_accuracy = NULL;
359 GError *error = NULL;
361 fields = geoclue_position_get_position(gps_manager->pos, ×tamp, &lat, &lon, &alt, &_accuracy, &error);
363 MOD_LOGD("Error getting position: %s", error->message);
365 return LOCATION_ERROR_NOT_AVAILABLE;
368 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
369 if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
370 *position = location_position_new(timestamp, lat, lon, alt, LOCATION_STATUS_3D_FIX);
372 *position = location_position_new(timestamp, lat, lon, 0, LOCATION_STATUS_2D_FIX);
374 *position = location_position_new(0, 0, 0, 0, LOCATION_STATUS_NO_FIX);
377 GeoclueAccuracyLevel level;
380 geoclue_accuracy_get_details(_accuracy, &level, &horiz_acc, &vert_acc);
381 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
382 geoclue_accuracy_free(_accuracy);
384 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
386 return LOCATION_ERROR_NONE;
389 static int get_velocity(gpointer handle, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
391 MOD_LOGD("get_velocity");
392 GpsManagerData *gps_manager = (GpsManagerData *) handle;
393 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
394 g_return_val_if_fail(gps_manager->vel, LOCATION_ERROR_NOT_AVAILABLE);
395 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
396 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
398 GeoclueVelocityFields fields;
400 double spd, dir, climb;
401 GError *error = NULL;
403 fields = geoclue_velocity_get_velocity(gps_manager->vel, ×tamp, &spd, &dir, &climb, &error);
405 MOD_LOGD("Error getting velocity: %s", error->message);
407 return LOCATION_ERROR_NOT_AVAILABLE;
410 if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
411 if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
412 *velocity = location_velocity_new(timestamp, spd, dir, climb);
414 *velocity = location_velocity_new(timestamp, spd, dir, 0);
415 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
417 *velocity = location_velocity_new(0, 0, 0, 0);
418 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
420 return LOCATION_ERROR_NONE;
423 static int get_nmea(gpointer handle, gchar ** nmea_data)
425 MOD_LOGD("get_nmea");
426 GpsManagerData *gps_manager = (GpsManagerData *) handle;
427 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
428 g_return_val_if_fail(gps_manager->nmea, LOCATION_ERROR_NOT_AVAILABLE);
429 g_return_val_if_fail(nmea_data, LOCATION_ERROR_PARAMETER);
431 gboolean ret = FALSE;
433 char *_nmea_data = NULL;
434 GError *error = NULL;
435 ret = geoclue_nmea_get_nmea(gps_manager->nmea, ×tamp, &_nmea_data, &error);
437 MOD_LOGD("\t Error getting nmea: %s", error->message);
439 return LOCATION_ERROR_NOT_AVAILABLE;
441 *nmea_data = g_strdup(_nmea_data);
443 return LOCATION_ERROR_NONE;
446 static int get_satellite(gpointer handle, LocationSatellite ** satellite)
448 MOD_LOGD("get_satellite");
449 GpsManagerData *gps_manager = (GpsManagerData *) handle;
450 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
451 g_return_val_if_fail(gps_manager->sat, LOCATION_ERROR_NOT_AVAILABLE);
452 g_return_val_if_fail(satellite, LOCATION_ERROR_PARAMETER);
458 GArray *u_prn = NULL;
459 GPtrArray *sat_info = NULL;
460 GError *error = NULL;
462 geoclue_satellite_get_satellite(gps_manager->sat, ×tamp, &sat_used, &sat_vis, &u_prn, &sat_info, &error);
464 MOD_LOGW("\t Error getting satellite: %s", error->message);
466 return LOCATION_ERROR_NOT_AVAILABLE;
468 *satellite = location_satellite_new(sat_vis);
469 (*satellite)->timestamp = timestamp;
471 for (idx = 0; idx < sat_vis; idx++) {
472 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
473 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
474 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
475 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
476 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
479 gboolean is_used = FALSE;
480 for (used_idx = 0; used_idx < sat_used; used_idx++) {
481 if ((guint) prn == (guint) g_array_index(u_prn, guint, used_idx)) {
486 location_satellite_set_satellite_details(*satellite, idx,
487 (guint) prn, is_used, (guint) elev, (guint) azim, (guint) snr);
491 g_array_free(u_prn, TRUE);
493 g_ptr_array_free(sat_info, TRUE);
495 return LOCATION_ERROR_NONE;
498 static int get_last_position(gpointer handle, LocationPosition ** position, LocationAccuracy ** accuracy)
500 MOD_LOGD("get_last_position");
501 GpsManagerData *gps_manager = (GpsManagerData *) handle;
502 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
503 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
504 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
506 #if 0 /* replaced by reading vconf directly */
507 GeocluePositionFields fields;
509 double lat, lon, alt;
510 GeoclueAccuracy *_accuracy = NULL;
511 GError *error = NULL;
513 gchar *service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
514 gchar *path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
516 GeocluePosition *last_pos = geoclue_position_new(service, path);
518 fields = geoclue_position_get_last_position(last_pos, ×tamp, &lat, &lon, &alt, &_accuracy, &error);
520 MOD_LOGD("Error getting last position: %s", error->message);
522 g_object_unref(last_pos);
525 return LOCATION_ERROR_NOT_AVAILABLE;
528 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
529 if (fields & GEOCLUE_POSITION_FIELDS_ALTITUDE)
530 *position = location_position_new(timestamp, lat, lon, alt, LOCATION_STATUS_3D_FIX);
532 *position = location_position_new(timestamp, lat, lon, 0, LOCATION_STATUS_2D_FIX);
534 *position = location_position_new(0, 0, 0, 0, LOCATION_STATUS_NO_FIX);
537 GeoclueAccuracyLevel level;
540 geoclue_accuracy_get_details(_accuracy, &level, &horiz_acc, &vert_acc);
541 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc);
542 geoclue_accuracy_free(_accuracy);
544 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
546 g_object_unref(last_pos);
550 return LOCATION_ERROR_NONE;
553 double longitude = 0.0, latitude = 0.0, altitude = 0.0;
554 double hor_accuracy = 0.0, ver_accuracy = 0.0;
555 LocationStatus status = LOCATION_STATUS_NO_FIX;
556 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
558 if (vconf_get_int(GPS_LAST_TIMESTAMP, ×tamp) ||
559 vconf_get_dbl(GPS_LAST_LATITUDE, &latitude) ||
560 vconf_get_dbl(GPS_LAST_LONGITUDE, &longitude) ||
561 vconf_get_dbl(GPS_LAST_ALTITUDE, &altitude) ||
562 vconf_get_dbl(GPS_LAST_HORACCURACY, &hor_accuracy) ||
563 vconf_get_dbl(GPS_LAST_VERACCURACY, &ver_accuracy)) {
566 return LOCATION_ERROR_NOT_AVAILABLE;
570 if (altitude) status = LOCATION_STATUS_3D_FIX;
571 else status = LOCATION_STATUS_2D_FIX;
576 return LOCATION_ERROR_NOT_AVAILABLE;
579 level = LOCATION_ACCURACY_LEVEL_DETAILED;
580 *position = location_position_new(timestamp, latitude, longitude, altitude, status);
581 *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
583 return LOCATION_ERROR_NONE;
588 static int get_last_velocity(gpointer handle, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
590 MOD_LOGD("get_last_velocity");
591 GpsManagerData *gps_manager = (GpsManagerData *) handle;
592 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
593 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
594 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
596 #if 0 /* replaced by reading vconf directly */
597 GeoclueVelocityFields fields;
599 double spd, dir, climb;
600 GError *error = NULL;
602 gchar *service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
603 gchar *path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
605 GeoclueVelocity *last_vel = geoclue_velocity_new(service, path);
607 fields = geoclue_velocity_get_last_velocity(last_vel, ×tamp, &spd, &dir, &climb, &error);
609 MOD_LOGD("Error getting last velocity: %s", error->message);
611 g_object_unref(last_vel);
614 return LOCATION_ERROR_NOT_AVAILABLE;
617 if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) {
618 if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB)
619 *velocity = location_velocity_new(timestamp, spd, dir, climb);
621 *velocity = location_velocity_new(timestamp, spd, dir, 0);
622 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0);
624 *velocity = location_velocity_new(0, 0, 0, 0);
625 *accuracy = location_accuracy_new(LOCATION_ACCURACY_LEVEL_NONE, 0, 0);
628 g_object_unref(last_vel);
632 return LOCATION_ERROR_NONE;
635 gdouble speed = 0.0, direction = 0.0;
636 gdouble hor_accuracy = 0.0, ver_accuracy = 0.0;
638 if (vconf_get_int(GPS_LAST_TIMESTAMP, ×tamp) ||
639 vconf_get_dbl(GPS_LAST_SPEED, &speed) ||
640 vconf_get_dbl(GPS_LAST_DIRECTION, &direction) ||
641 vconf_get_dbl(GPS_LAST_HORACCURACY, &hor_accuracy) ||
642 vconf_get_dbl(GPS_LAST_VERACCURACY, &ver_accuracy)) {
645 return LOCATION_ERROR_NOT_AVAILABLE;;
648 if (!timestamp || (speed < 0 && direction < 0)) {
651 return LOCATION_ERROR_NOT_AVAILABLE;
654 *velocity = location_velocity_new ((guint) timestamp, speed, direction, 0.0);
655 *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, hor_accuracy, ver_accuracy);
657 return LOCATION_ERROR_NONE;
661 static int get_last_satellite(gpointer handle, LocationSatellite ** satellite)
663 MOD_LOGD("get_last_satellite");
664 GpsManagerData *gps_manager = (GpsManagerData *) handle;
665 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
666 g_return_val_if_fail(satellite, LOCATION_ERROR_PARAMETER);
672 GArray *u_prn = NULL;
673 GPtrArray *sat_info = NULL;
674 GError *error = NULL;
675 gchar *service = g_strdup_printf(GPS_MANAGER_SERVICE_NAME);
676 gchar *path = g_strdup_printf(GPS_MANAGER_SERVICE_PATH);
678 GeoclueSatellite *last_sat = geoclue_satellite_new(service, path);
680 geoclue_satellite_get_last_satellite(last_sat, ×tamp, &sat_used, &sat_vis, &u_prn, &sat_info, &error);
682 MOD_LOGW("\t Error getting last satellite: %s", error->message);
684 g_object_unref(last_sat);
687 return LOCATION_ERROR_NOT_AVAILABLE;
689 *satellite = location_satellite_new(sat_vis);
690 (*satellite)->timestamp = timestamp;
692 for (idx = 0; idx < sat_vis; idx++) {
693 GValueArray *vals = (GValueArray *) g_ptr_array_index(sat_info, idx);
694 gint prn = g_value_get_int(g_value_array_get_nth(vals, 0));
695 gint elev = g_value_get_int(g_value_array_get_nth(vals, 1));
696 gint azim = g_value_get_int(g_value_array_get_nth(vals, 2));
697 gint snr = g_value_get_int(g_value_array_get_nth(vals, 3));
700 gboolean is_used = FALSE;
701 for (used_idx = 0; used_idx < sat_used; used_idx++) {
702 if ((guint) prn == (guint) g_array_index(u_prn, guint, used_idx)) {
707 location_satellite_set_satellite_details(*satellite, idx,
708 (guint) prn, is_used, (guint) elev, (guint) azim, (guint) snr);
712 g_array_free(u_prn, TRUE);
714 g_ptr_array_free(sat_info, TRUE);
716 g_object_unref(last_sat);
720 return LOCATION_ERROR_NONE;
723 static int set_devname(gpointer handle, const char *devname)
725 GpsManagerData *gps_manager = (GpsManagerData *) handle;
726 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
727 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
728 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
729 MOD_LOGD("set_devname: %s --> %s", gps_manager->devname, devname);
730 g_stpcpy(gps_manager->devname, devname);
732 return LOCATION_ERROR_NONE;
735 static int get_devname(gpointer handle, char **devname)
737 GpsManagerData *gps_manager = (GpsManagerData *) handle;
738 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
739 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
740 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
741 *devname = g_strdup(gps_manager->devname);
742 MOD_LOGD("get_devname: %s", *devname);
744 return LOCATION_ERROR_NONE;
747 LOCATION_MODULE_API gpointer init(LocModGpsOps * ops)
751 g_return_val_if_fail(ops, NULL);
754 ops->get_position = get_position;
755 ops->get_velocity = get_velocity;
756 ops->get_last_position = get_last_position;
757 ops->get_last_velocity = get_last_velocity;
760 if (dladdr(&get_position, &info) == 0) {
761 MOD_LOGD("Failed to get module name");
762 } else if (g_strrstr(info.dli_fname, "gps")) {
763 ops->get_nmea = get_nmea;
764 ops->get_satellite = get_satellite;
765 ops->get_last_satellite = get_last_satellite;
766 ops->set_devname = set_devname;
767 ops->get_devname = get_devname;
770 GpsManagerData *gps_manager = g_new0(GpsManagerData, 1);
771 g_return_val_if_fail(gps_manager, NULL);
773 g_stpcpy(gps_manager->devname, "/dev/ttySAC1");
774 gps_manager->pos = NULL;
775 gps_manager->vel = NULL;
776 gps_manager->nmea = NULL;
777 gps_manager->sat = NULL;
778 gps_manager->status_cb = NULL;
779 gps_manager->pos_cb = NULL;
780 gps_manager->vel_cb = NULL;
781 gps_manager->userdata = NULL;
782 gps_manager->is_started = FALSE;
784 return (gpointer) gps_manager;
787 LOCATION_MODULE_API void shutdown(gpointer handle)
789 MOD_LOGD("shutdown");
790 g_return_if_fail(handle);
791 GpsManagerData *gps_manager = (GpsManagerData *) handle;
793 unref_gps_manager(gps_manager);
794 if (gps_manager->status_cb)
795 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);