4 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7 * Genie Kim <daejins.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>
29 #include <lbs_dbus_client.h>
40 lbs_client_dbus_h lbs_client;
41 LocModStatusCB status_cb;
42 LocModPositionExtCB pos_cb;
43 LocModSatelliteCB sat_cb;
48 #define GPS_MANAGER_SERVICE_NAME "org.tizen.lbs.Providers.GpsManager"
49 #define GPS_MANAGER_SERVICE_PATH "/org/tizen/lbs/Providers/GpsManager"
51 #define MPS_TO_KMPH 3.6 // 1 m/s = 3.6 km/h
53 static void status_callback(GVariant *param, void *user_data)
55 GpsManagerData *gps_manager = (GpsManagerData *) user_data;
56 g_return_if_fail(param);
57 g_return_if_fail(gps_manager);
58 g_return_if_fail(gps_manager->status_cb);
62 g_variant_get (param, "(i)", &status);
64 if (status == 3) { //TODO: LBS_STATUS_AVAILABLE ?
65 MOD_LOGD("LBS_STATUS_AVAILABLE");
66 gps_manager->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gps_manager->userdata);
69 MOD_LOGD("LBS_STATUS_ACQUIRING/ERROR/UNAVAILABLE. Status[%d]", status);
70 gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
74 static void satellite_callback(GVariant *param, void *user_data)
76 GpsManagerData *gps_manager = (GpsManagerData *)user_data;
77 g_return_if_fail(gps_manager);
78 g_return_if_fail(gps_manager->sat_cb);
82 guint *used_prn_array = NULL;
84 int timestamp = 0, satellite_used = 0, satellite_visible = 0;
86 LocationSatellite *sat = NULL;
87 GVariant *used_prn = NULL;
88 GVariantIter *used_prn_iter = NULL;
89 GVariant *sat_info = NULL;
90 GVariantIter *sat_iter = NULL;
91 int prn = 0, elev = 0, azim = 0, snr = 0;
93 g_variant_get(param, "(iii@ai@a(iiii))", ×tamp, &satellite_used, &satellite_visible, &used_prn, &sat_info);
94 g_variant_get(used_prn, "ai", &used_prn_iter);
95 g_variant_get(sat_info, "a(iiii)", &sat_iter);
96 MOD_LOGD("timestamp [%d], satellite_used [%d], satellite_visible[%d]", timestamp, satellite_used, satellite_visible);
98 int num_of_used_prn = g_variant_iter_n_children (used_prn_iter);
99 if (num_of_used_prn > 0) {
100 used_prn_array = (guint *)g_new0(guint, num_of_used_prn);
101 for (idx = 0; idx < num_of_used_prn; idx++) {
102 ret = g_variant_iter_next(used_prn_iter, "i", &tmp_prn);
105 used_prn_array[idx] = tmp_prn;
109 sat = location_satellite_new(satellite_visible);
111 sat->timestamp = timestamp;
112 sat->num_of_sat_inview = satellite_visible;
113 sat->num_of_sat_used = satellite_used;
115 GVariant *tmp_var = NULL;
116 for (idx = 0; idx < satellite_visible; idx++) {
117 gboolean used = FALSE;
118 tmp_var = g_variant_iter_next_value (sat_iter);
119 g_variant_get (tmp_var, "(iiii)", &prn, &elev, &azim, &snr);
120 if (used_prn_array != NULL) {
121 for (used_idx = 0; used_idx < satellite_used; used_idx++) {
122 if (prn == used_prn_array[used_idx]) {
128 MOD_LOGD("prn[%d] : used %d elev %d azim %d snr %d", prn, used, elev, azim, snr);
129 location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
132 gps_manager->sat_cb(TRUE, sat, gps_manager->userdata);
133 location_satellite_free(sat);
135 if (used_prn_array) {
136 g_free(used_prn_array);
137 used_prn_array = NULL;
142 static void nmea_callback(GeoclueNmea * nmea, int timestamp, char *data, gpointer userdata)
147 static void position_callback(GVariant *param, void *user_data)
149 MOD_LOGD("position_callback");
150 GpsManagerData *gps_manager = (GpsManagerData *)user_data;
151 g_return_if_fail(gps_manager);
152 g_return_if_fail(gps_manager->pos_cb);
154 int fields = 0 ,timestamp = 0 , level = 0;
155 double latitude = 0.0, longitude = 0.0, altitude = 0.0, speed = 0.0, direction = 0.0, climb = 0.0, horizontal = 0.0, vertical = 0.0;
156 GVariant *accuracy = NULL;
158 g_variant_get(param, "(iidddddd@(idd))", &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
159 g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
161 LocationPosition *pos = NULL;
162 LocationVelocity *vel = NULL;
163 LocationAccuracy *acc = NULL;
166 pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
168 pos = location_position_new(timestamp, latitude, longitude, 0.0, LOCATION_STATUS_2D_FIX);
171 vel = location_velocity_new(timestamp, speed, direction, climb);
173 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
176 ("time(%d) lat(%f) long(%f) alt(%f) status(%d) acc_level(%d) hoz_acc(%f) vert_acc(%f)",
177 pos->timestamp, pos->latitude, pos->longitude, pos->altitude,
178 pos->status, acc->level, acc->horizontal_accuracy, acc->vertical_accuracy);
180 gps_manager->pos_cb(TRUE, pos, vel, acc, gps_manager->userdata);
182 location_position_free(pos);
183 location_velocity_free(vel);
184 location_accuracy_free(acc);
187 static void on_signal_callback(GDBusConnection *conn, const gchar *name, const gchar *path, const gchar *interface, const gchar *sig, GVariant *param, gpointer user_data)
189 MOD_LOGD("name : %s, path : %s, interface : %s, sig : %s\n", name, path, interface, sig);
191 if (!g_strcmp0(sig, "SatelliteChanged")) {
192 MOD_LOGD("SatelliteChanged");
193 satellite_callback(param, user_data);
195 else if (!g_strcmp0(sig, "PositionChanged")) {
196 MOD_LOGD("PositionChanged");
197 position_callback(param, user_data);
199 else if (!g_strcmp0(sig, "StatusChanged")) {
200 MOD_LOGD("StatusChanged");
201 status_callback(param, user_data);
204 MOD_LOGD("Invaild signal[%s]", sig);
208 static int start(gpointer handle, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
211 GpsManagerData *gps_manager = (GpsManagerData *) handle;
212 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
213 g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
214 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
216 gps_manager->status_cb = status_cb;
217 gps_manager->pos_cb = pos_cb;
218 gps_manager->sat_cb = sat_cb;
219 gps_manager->userdata = userdata;
221 int ret = LBS_CLIENT_ERROR_NONE;
222 ret = lbs_client_create (GPS_MANAGER_SERVICE_NAME, GPS_MANAGER_SERVICE_PATH, &(gps_manager->lbs_client));
223 if (ret != LBS_CLIENT_ERROR_NONE || !gps_manager->lbs_client) {
224 MOD_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
225 return LOCATION_ERROR_NOT_AVAILABLE;
227 MOD_LOGD("gps-manger(%x)", gps_manager);
228 MOD_LOGD("pos_cb (%x), user_data(%x)", gps_manager->pos_cb, gps_manager->userdata);
230 ret = lbs_client_start (gps_manager->lbs_client, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_LOCATION_STATUS_CB | LBS_CLIENT_SATELLITE_CB, on_signal_callback, gps_manager);
231 if (ret != LBS_CLIENT_ERROR_NONE) {
232 MOD_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
233 return LOCATION_ERROR_NOT_AVAILABLE;
236 return LOCATION_ERROR_NONE;
239 static int stop(gpointer handle)
242 GpsManagerData *gps_manager = (GpsManagerData *) handle;
243 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
244 g_return_val_if_fail(gps_manager->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
245 g_return_val_if_fail(gps_manager->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
247 int ret = LBS_CLIENT_ERROR_NONE;
249 ret = lbs_client_stop (gps_manager->lbs_client);
250 if (ret != LBS_CLIENT_ERROR_NONE) {
251 MOD_LOGE("Fail to stop. Error[%d]", ret);
252 return LOCATION_ERROR_NOT_AVAILABLE;
255 lbs_client_destroy(gps_manager->lbs_client);
256 gps_manager->lbs_client = NULL;
258 if (gps_manager->status_cb) {
259 gps_manager->status_cb (FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
262 gps_manager->status_cb = NULL;
263 gps_manager->pos_cb = NULL;
264 gps_manager->sat_cb = NULL;
266 return LOCATION_ERROR_NONE;
269 static int get_nmea(gpointer handle, gchar ** nmea_data)
271 MOD_LOGD("get_nmea");
272 GpsManagerData *gps_manager = (GpsManagerData *) handle;
273 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
274 g_return_val_if_fail(nmea_data, LOCATION_ERROR_PARAMETER);
276 gboolean ret = FALSE;
278 ret = lbs_client_get_nmea(gps_manager->lbs_client, ×tamp, nmea_data);
280 MOD_LOGE("\t Error getting nmea: %d", ret);
281 return LOCATION_ERROR_NOT_AVAILABLE;
284 return LOCATION_ERROR_NONE;
287 static int get_last_position(gpointer handle, LocationPosition ** position, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
289 MOD_LOGD("get_last_position");
290 GpsManagerData *gps_manager = (GpsManagerData *) handle;
291 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
292 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
293 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
296 double longitude = 0.0, latitude = 0.0, altitude = 0.0;
297 double speed = 0.0, direction = 0.0;
298 double hor_accuracy = 0.0, ver_accuracy = 0.0;
299 LocationStatus status = LOCATION_STATUS_NO_FIX;
300 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
302 if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp) ||
303 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, &latitude) ||
304 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, &longitude) ||
305 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, &altitude) ||
306 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_SPEED, &speed) ||
307 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, &direction) ||
308 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
309 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
312 return LOCATION_ERROR_NOT_AVAILABLE;
316 if (altitude) status = LOCATION_STATUS_3D_FIX;
317 else status = LOCATION_STATUS_2D_FIX;
322 return LOCATION_ERROR_NOT_AVAILABLE;
325 level = LOCATION_ACCURACY_LEVEL_DETAILED;
326 *position = location_position_new(timestamp, latitude, longitude, altitude, status);
327 *velocity = location_velocity_new ((guint) timestamp, speed * MPS_TO_KMPH, direction, 0.0);
328 *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
330 return LOCATION_ERROR_NONE;
333 static int set_devname(gpointer handle, const char *devname)
335 GpsManagerData *gps_manager = (GpsManagerData *) handle;
336 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
337 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
338 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
339 MOD_LOGD("set_devname: %s --> %s", gps_manager->devname, devname);
340 g_stpcpy(gps_manager->devname, devname);
342 return LOCATION_ERROR_NONE;
345 static int get_devname(gpointer handle, char **devname)
347 GpsManagerData *gps_manager = (GpsManagerData *) handle;
348 g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
349 g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE);
350 g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER);
351 *devname = g_strdup(gps_manager->devname);
352 MOD_LOGD("get_devname: %s", *devname);
354 return LOCATION_ERROR_NONE;
357 LOCATION_MODULE_API gpointer init(LocModGpsOps * ops)
361 g_return_val_if_fail(ops, NULL);
364 ops->get_last_position = get_last_position;
367 if (dladdr(&get_last_position, &info) == 0) {
368 MOD_LOGD("Failed to get module name");
369 } else if (g_strrstr(info.dli_fname, "gps")) {
370 ops->get_nmea = get_nmea;
371 ops->set_devname = set_devname;
372 ops->get_devname = get_devname;
375 GpsManagerData *gps_manager = g_new0(GpsManagerData, 1);
376 g_return_val_if_fail(gps_manager, NULL);
378 g_stpcpy(gps_manager->devname, "/dev/ttySAC1");
379 gps_manager->status_cb = NULL;
380 gps_manager->pos_cb = NULL;
381 gps_manager->userdata = NULL;
382 gps_manager->is_started = FALSE;
384 return (gpointer) gps_manager;
387 LOCATION_MODULE_API void shutdown(gpointer handle)
389 MOD_LOGD("shutdown");
390 g_return_if_fail(handle);
391 GpsManagerData *gps_manager = (GpsManagerData *) handle;
392 if (gps_manager->lbs_client) {
393 lbs_client_destroy(gps_manager->lbs_client);
394 gps_manager->lbs_client = NULL;