4 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
25 #include <vconf-internal-location-keys.h>
26 #include <location-module.h>
29 #include <lbs_dbus_client.h>
38 #define MAX_GPS_LOC_ITEM 7
39 #define MAX_NPS_LOC_ITEM 6
40 #define UNNECESSARY_INTERVAL 1
41 #define LBS_FUSED_STATUS_NONE 0
44 lbs_client_dbus_h lbs_client;
45 LocModPositionExtCB pos_cb;
46 LocModSatelliteCB sat_cb;
50 static void satellite_callback(GVariant *param, void *user_data)
52 ModPassiveData *module = (ModPassiveData *)user_data;
53 g_return_if_fail(module);
54 g_return_if_fail(module->sat_cb);
58 guint *used_prn_array = NULL;
60 int timestamp = 0, satellite_used = 0, satellite_visible = 0;
62 LocationSatellite *sat = NULL;
63 GVariant *used_prn = NULL;
64 GVariantIter *used_prn_iter = NULL;
65 GVariant *sat_info = NULL;
66 GVariantIter *sat_iter = NULL;
67 int prn = 0, elev = 0, azim = 0, snr = 0;
69 g_variant_get(param, "(iii@ai@a(iiii))", ×tamp, &satellite_used, &satellite_visible, &used_prn, &sat_info);
70 g_variant_get(used_prn, "ai", &used_prn_iter);
71 g_variant_get(sat_info, "a(iiii)", &sat_iter);
72 MOD_LOGD("timestamp [%d], satellite_used [%d], satellite_visible[%d]", timestamp, satellite_used, satellite_visible);
74 int num_of_used_prn = g_variant_iter_n_children(used_prn_iter);
75 if (num_of_used_prn > 0) {
76 used_prn_array = (guint *)g_new0(guint, num_of_used_prn);
77 g_return_if_fail(used_prn_array);
78 for (idx = 0; idx < num_of_used_prn; idx++) {
79 ret = g_variant_iter_next(used_prn_iter, "i", &tmp_prn);
82 used_prn_array[idx] = tmp_prn;
85 sat = location_satellite_new(satellite_visible);
87 sat->timestamp = timestamp;
88 sat->num_of_sat_inview = satellite_visible;
89 sat->num_of_sat_used = satellite_used;
91 GVariant *tmp_var = NULL;
92 for (idx = 0; idx < satellite_visible; idx++) {
93 gboolean used = FALSE;
94 tmp_var = g_variant_iter_next_value(sat_iter);
95 g_variant_get(tmp_var, "(iiii)", &prn, &elev, &azim, &snr);
96 if (used_prn_array != NULL) {
97 for (used_idx = 0; used_idx < satellite_used; used_idx++) {
98 if (prn == used_prn_array[used_idx]) {
104 location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
105 g_variant_unref(tmp_var);
108 module->sat_cb(TRUE, sat, module->userdata);
109 location_satellite_free(sat);
110 g_variant_iter_free(used_prn_iter);
111 g_variant_iter_free(sat_iter);
112 g_variant_unref(used_prn);
113 g_variant_unref(sat_info);
115 if (used_prn_array) {
116 g_free(used_prn_array);
117 used_prn_array = NULL;
121 static void position_callback(GVariant *param, void *user_data)
123 ModPassiveData *module = (ModPassiveData *)user_data;
124 g_return_if_fail(module);
125 g_return_if_fail(module->pos_cb);
127 int method = 0, fields = 0 , timestamp = 0 , level = 0;
128 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;
129 GVariant *accuracy = NULL;
131 g_variant_get(param, "(iiidddddd@(idd))", &method, &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
132 g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
134 LocationPosition *pos = NULL;
135 LocationVelocity *vel = NULL;
136 LocationAccuracy *acc = NULL;
138 pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
139 vel = location_velocity_new(timestamp, speed, direction, climb);
140 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
142 module->pos_cb(TRUE, pos, vel, acc, module->userdata);
144 location_position_free(pos);
145 location_velocity_free(vel);
146 location_accuracy_free(acc);
147 g_variant_unref(accuracy);
150 static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
152 if (!g_strcmp0(sig, "SatelliteChanged"))
153 satellite_callback(param, user_data);
154 else if (!g_strcmp0(sig, "PositionChanged"))
155 position_callback(param, user_data);
157 MOD_LOGD("Invaild signal[%s]", sig);
160 static int start(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
163 ModPassiveData *module = (ModPassiveData *) handle;
164 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
165 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
167 module->pos_cb = pos_cb;
168 module->sat_cb = sat_cb;
169 module->userdata = userdata;
171 int ret = LBS_CLIENT_ERROR_NONE;
172 ret = lbs_client_create(LBS_CLIENT_METHOD_PASSIVE , &(module->lbs_client));
173 if (ret != LBS_CLIENT_ERROR_NONE || !module->lbs_client) {
174 MOD_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
175 return LOCATION_ERROR_NOT_AVAILABLE;
177 MOD_LOGD("fused handle(%p) pos_cb(%p) user_data(%p)", module, module->pos_cb, module->userdata);
179 ret = lbs_client_start(module->lbs_client, UNNECESSARY_INTERVAL, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_SATELLITE_CB, on_signal_callback, LBS_FUSED_STATUS_NONE, module);
180 if (ret != LBS_CLIENT_ERROR_NONE) {
181 if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
182 MOD_LOGE("Access denied[%d]", ret);
183 return LOCATION_ERROR_NOT_ALLOWED;
185 MOD_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
186 lbs_client_destroy(module->lbs_client);
187 module->lbs_client = NULL;
189 return LOCATION_ERROR_NOT_AVAILABLE;
192 return LOCATION_ERROR_NONE;
195 static int stop(gpointer handle)
198 ModPassiveData *module = (ModPassiveData *) handle;
199 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
200 g_return_val_if_fail(module->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
202 int ret = LBS_CLIENT_ERROR_NONE;
204 ret = lbs_client_stop(module->lbs_client, UNNECESSARY_INTERVAL, LBS_FUSED_STATUS_NONE);
205 MOD_LOGE("stop gps interval [%d]", UNNECESSARY_INTERVAL);
206 if (ret != LBS_CLIENT_ERROR_NONE) {
207 MOD_LOGE("Fail to stop. Error[%d]", ret);
208 lbs_client_destroy(module->lbs_client);
209 module->lbs_client = NULL;
210 return LOCATION_ERROR_NOT_AVAILABLE;
213 ret = lbs_client_destroy(module->lbs_client);
214 if (ret != LBS_CLIENT_ERROR_NONE) {
215 MOD_LOGE("Fail to destroy. Error[%d]", ret);
216 return LOCATION_ERROR_NOT_AVAILABLE;
218 module->lbs_client = NULL;
220 module->pos_cb = NULL;
221 module->sat_cb = NULL;
223 return LOCATION_ERROR_NONE;
226 static int get_last_position(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
228 MOD_LOGD("get_last_position");
229 ModPassiveData *module = (ModPassiveData *) handle;
230 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
231 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
232 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
233 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
236 char location[128] = {0,};
237 char *last_location[MAX_GPS_LOC_ITEM] = {0,};
240 double longitude = 0.0, latitude = 0.0, altitude = 0.0;
241 double speed = 0.0, direction = 0.0;
242 double hor_accuracy = 0.0, ver_accuracy = 0.0;
244 LocationStatus status = LOCATION_STATUS_NO_FIX;
245 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
251 if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp)) {
252 MOD_LOGD("Error to get VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP");
253 return LOCATION_ERROR_NOT_AVAILABLE;
255 if (timestamp != 0) {
256 if (vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, &latitude) ||
257 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, &longitude) ||
258 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, &altitude) ||
259 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_SPEED, &speed) ||
260 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, &direction) ||
261 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
262 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
263 return LOCATION_ERROR_NOT_AVAILABLE;
266 if (vconf_get_int(VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP, ×tamp))
267 return LOCATION_ERROR_NOT_AVAILABLE;
269 str = vconf_get_str(VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION);
271 return LOCATION_ERROR_NOT_AVAILABLE;
273 snprintf(location, sizeof(location), "%s", str);
277 last_location[index] = (char *)strtok_r(location, ";", &last);
278 while (last_location[index] != NULL) {
281 latitude = strtod(last_location[index], NULL);
284 longitude = strtod(last_location[index], NULL);
287 altitude = strtod(last_location[index], NULL);
290 speed = strtod(last_location[index], NULL);
293 direction = strtod(last_location[index], NULL);
296 hor_accuracy = strtod(last_location[index], NULL);
299 ver_accuracy = strtod(last_location[index], NULL);
304 if (++index == MAX_GPS_LOC_ITEM) break;
305 last_location[index] = (char *)strtok_r(NULL, ";", &last);
311 status = LOCATION_STATUS_3D_FIX;
313 return LOCATION_ERROR_NOT_AVAILABLE;
315 level = LOCATION_ACCURACY_LEVEL_DETAILED;
316 *position = location_position_new(timestamp, latitude, longitude, altitude, status);
317 *velocity = location_velocity_new((guint) timestamp, speed, direction, 0.0);
318 *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
320 return LOCATION_ERROR_NONE;
323 static int get_last_wps_position(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
325 MOD_LOGD("get_last_wps_position");
326 ModPassiveData *module = (ModPassiveData *) handle;
327 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
328 g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
329 g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
330 g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
333 char location[128] = {0,};
334 char *last_location[MAX_NPS_LOC_ITEM] = {0,};
337 double latitude = 0.0, longitude = 0.0, altitude = 0.0;
338 double speed = 0.0, direction = 0.0;
339 double hor_accuracy = 0.0;
341 LocationStatus status = LOCATION_STATUS_NO_FIX;
342 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
348 if (vconf_get_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, ×tamp)) {
349 MOD_LOGD("Error to get VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP");
350 return LOCATION_ERROR_NOT_AVAILABLE;
352 if (timestamp != 0) {
353 if (vconf_get_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, ×tamp) ||
354 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_LATITUDE, &latitude) ||
355 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_LONGITUDE, &longitude) ||
356 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_ALTITUDE, &altitude) ||
357 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_SPEED, &speed) ||
358 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_DIRECTION, &direction) ||
359 vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_HOR_ACCURACY, &hor_accuracy)) {
360 return LOCATION_ERROR_NOT_AVAILABLE;
363 if (vconf_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, ×tamp)) {
364 MOD_LOGD("Last timestamp failed");
365 return LOCATION_ERROR_NOT_AVAILABLE;
367 str = vconf_get_str(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION);
369 MOD_LOGD("Last wps is null");
370 return LOCATION_ERROR_NOT_AVAILABLE;
372 snprintf(location, sizeof(location), "%s", str);
376 last_location[index] = (char *)strtok_r(location, ";", &last);
377 while (last_location[index] != NULL) {
380 latitude = strtod(last_location[index], NULL);
383 longitude = strtod(last_location[index], NULL);
386 altitude = strtod(last_location[index], NULL);
389 speed = strtod(last_location[index], NULL);
392 direction = strtod(last_location[index], NULL);
395 hor_accuracy = strtod(last_location[index], NULL);
400 if (++index == MAX_NPS_LOC_ITEM) break;
401 last_location[index] = (char *)strtok_r(NULL, ";", &last);
407 status = LOCATION_STATUS_3D_FIX;
409 return LOCATION_ERROR_NOT_AVAILABLE;
411 level = LOCATION_ACCURACY_LEVEL_STREET;
412 *position = location_position_new((guint) timestamp, latitude, longitude, altitude, status);
413 *velocity = location_velocity_new((guint) timestamp, speed, direction, 0.0);
414 *accuracy = location_accuracy_new(level, hor_accuracy, -1.0);
416 return LOCATION_ERROR_NONE;
419 LOCATION_MODULE_API gpointer init(LocModPassiveOps *ops)
423 g_return_val_if_fail(ops, NULL);
426 ops->get_last_position = get_last_position;
427 ops->get_last_wps_position = get_last_wps_position;
429 ModPassiveData *module = g_new0(ModPassiveData, 1);
430 g_return_val_if_fail(module, NULL);
432 module->pos_cb = NULL;
433 module->sat_cb = NULL;
434 module->userdata = NULL;
436 return (gpointer) module;
439 LOCATION_MODULE_API void shutdown(gpointer handle)
441 MOD_LOGD("shutdown");
442 g_return_if_fail(handle);
443 ModPassiveData *module = (ModPassiveData *) handle;
445 if (module->lbs_client) {
446 lbs_client_stop(module->lbs_client, UNNECESSARY_INTERVAL, LBS_FUSED_STATUS_NONE);
447 lbs_client_destroy(module->lbs_client);
448 module->lbs_client = NULL;
451 module->pos_cb = NULL;
452 module->sat_cb = NULL;