4 * Copyright (c) 2016-2017 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 LOCATION_FUSED_HIGH 0
40 #define LOCATION_FUSED_BALANCED 1
43 lbs_client_dbus_h lbs_client;
44 LocModPositionExtCB pos_cb;
51 static void position_callback(GVariant *param, void *user_data)
53 ModFusedData *module = (ModFusedData *)user_data;
54 g_return_if_fail(module);
55 g_return_if_fail(module->pos_cb);
57 int method = 0, fields = 0 , timestamp = 0 , level = 0;
58 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;
59 GVariant *accuracy = NULL;
61 g_variant_get(param, "(iiidddddd@(idd))", &method, &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
63 // MOD_FUSED_LOGD("position_callback [method: %d] GPS=0, WPS=1/AGPS=2/GEOFENCE/MOCK/FUSED", method);
65 if (method != LBS_CLIENT_METHOD_GPS && method != LBS_CLIENT_METHOD_NPS) {
66 if (method != LBS_CLIENT_METHOD_MOCK) {
67 MOD_FUSED_LOGD("Method is not LBS_CLIENT_METHOD_FUSED: %d", method);
72 g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
74 LocationPosition *pos = NULL;
75 LocationVelocity *vel = NULL;
76 LocationAccuracy *acc = NULL;
78 pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
79 vel = location_velocity_new(timestamp, speed, direction, climb);
80 acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
82 module->pos_cb(TRUE, pos, vel, acc, module->userdata);
84 location_position_free(pos);
85 location_velocity_free(vel);
86 location_accuracy_free(acc);
87 g_variant_unref(accuracy);
90 static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
92 if (!g_strcmp0(sig, "PositionChanged")) {
93 position_callback(param, user_data);
97 static int start_gps(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
99 MOD_FUSED_LOGD("Fused : start_gps");
100 ModFusedData *module = (ModFusedData *)handle;
101 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
102 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
104 module->pos_cb = pos_cb;
105 module->userdata = userdata;
107 int ret = LBS_CLIENT_ERROR_NONE;
108 ret = lbs_client_create(LBS_CLIENT_METHOD_GPS, &(module->lbs_client));
109 if (ret != LBS_CLIENT_ERROR_NONE || !module->lbs_client) {
110 MOD_FUSED_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
111 return LOCATION_ERROR_NOT_AVAILABLE;
113 MOD_FUSED_LOGD("Fused : gps-manger(%p) pos_cb (%p) user_data(%p)", module, module->pos_cb, module->userdata);
115 ret = lbs_client_start(module->lbs_client, pos_update_interval, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_LOCATION_STATUS_CB, on_signal_callback, LOCATION_FUSED_HIGH, module);
116 if (ret != LBS_CLIENT_ERROR_NONE) {
117 if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
118 MOD_FUSED_LOGE("Access denied[%d]", ret);
119 return LOCATION_ERROR_NOT_ALLOWED;
121 MOD_FUSED_LOGE("Fail to start_gps lbs_client_h. Error[%d]", ret);
122 lbs_client_destroy(module->lbs_client);
123 module->lbs_client = NULL;
125 return LOCATION_ERROR_NOT_AVAILABLE;
128 module->pos_interval = pos_update_interval;
129 module->fused_mode = LOCATION_FUSED_HIGH;
130 return LOCATION_ERROR_NONE;
133 static int start_wps(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
135 MOD_FUSED_LOGD("Fused : start_wps");
136 ModFusedData *module = (ModFusedData *)handle;
137 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
138 g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
139 module->pos_cb = pos_cb;
140 module->userdata = userdata;
142 int ret = LBS_CLIENT_ERROR_NONE;
143 ret = lbs_client_create(LBS_CLIENT_METHOD_NPS, &(module->lbs_client));
144 if (ret != LBS_CLIENT_ERROR_NONE || !module->lbs_client) {
145 MOD_FUSED_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
146 return LOCATION_ERROR_NOT_AVAILABLE;
148 MOD_FUSED_LOGD("wps-manger(%p) pos_cb (%p) user_data(%p)", module, module->pos_cb, module->userdata);
150 ret = lbs_client_start(module->lbs_client, pos_update_interval, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_LOCATION_STATUS_CB, on_signal_callback, LOCATION_FUSED_BALANCED, module);
151 if (ret != LBS_CLIENT_ERROR_NONE) {
152 if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
153 MOD_FUSED_LOGE("Access denied[%d]", ret);
154 return LOCATION_ERROR_NOT_ALLOWED;
156 MOD_FUSED_LOGE("Fail to start_wps lbs_client_h. Error[%d]", ret);
157 lbs_client_destroy(module->lbs_client);
158 module->lbs_client = NULL;
160 return LOCATION_ERROR_NOT_AVAILABLE;
162 module->pos_interval = pos_update_interval;
163 module->fused_mode = LOCATION_FUSED_BALANCED;
164 return LOCATION_ERROR_NONE;
167 static int stop(gpointer handle)
169 MOD_FUSED_LOGD("stop");
170 ModFusedData *module = (ModFusedData *) handle;
171 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
172 g_return_val_if_fail(module->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
174 int ret = LBS_CLIENT_ERROR_NONE;
176 ret = lbs_client_stop(module->lbs_client, module->pos_interval, module->fused_mode);
177 MOD_FUSED_LOGD("stop gps interval [%d]", module->pos_interval);
178 if (ret != LBS_CLIENT_ERROR_NONE) {
179 MOD_FUSED_LOGE("Fail to stop. Error[%d]", ret);
180 lbs_client_destroy(module->lbs_client);
181 module->lbs_client = NULL;
182 return LOCATION_ERROR_NOT_AVAILABLE;
185 ret = lbs_client_destroy(module->lbs_client);
186 if (ret != LBS_CLIENT_ERROR_NONE) {
187 MOD_FUSED_LOGE("Fail to destroy. Error[%d]", ret);
188 return LOCATION_ERROR_NOT_AVAILABLE;
190 module->lbs_client = NULL;
191 module->pos_cb = NULL;
193 return LOCATION_ERROR_NONE;
196 static int get_last_position(gpointer handle, LocationPosition **position, LocationVelocity **velocity, LocationAccuracy **accuracy)
198 MOD_FUSED_LOGD("get_last_position");
200 ModFusedData *module = (ModFusedData *)handle;
201 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
204 char location[128] = {0,};
205 char *last_location[MAX_GPS_LOC_ITEM] = {0,};
208 double longitude = 0.0, latitude = 0.0, altitude = 0.0;
209 double speed = 0.0, direction = 0.0;
210 double hor_accuracy = 0.0, ver_accuracy = 0.0;
212 LocationStatus status = LOCATION_STATUS_NO_FIX;
213 LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
215 if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp)) {
216 MOD_FUSED_LOGD("Error to get VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP");
217 return LOCATION_ERROR_NOT_AVAILABLE;
219 if (timestamp != 0) {
220 if (vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, &latitude) ||
221 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, &longitude) ||
222 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, &altitude) ||
223 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_SPEED, &speed) ||
224 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, &direction) ||
225 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
226 vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
227 return LOCATION_ERROR_NOT_AVAILABLE;
230 if (vconf_get_int(VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP, ×tamp)) {
231 MOD_FUSED_LOGD("Error to get VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP");
232 return LOCATION_ERROR_NOT_AVAILABLE;
234 str = vconf_get_str(VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION);
236 MOD_FUSED_LOGD("Error to get VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION");
237 return LOCATION_ERROR_NOT_AVAILABLE;
239 snprintf(location, sizeof(location), "%s", str);
243 last_location[index] = (char *)strtok_r(location, ";", &last);
244 while (last_location[index] != NULL) {
247 latitude = strtod(last_location[index], NULL);
250 longitude = strtod(last_location[index], NULL);
253 altitude = strtod(last_location[index], NULL);
256 speed = strtod(last_location[index], NULL);
259 direction = strtod(last_location[index], NULL);
262 hor_accuracy = strtod(last_location[index], NULL);
265 ver_accuracy = strtod(last_location[index], NULL);
270 if (++index == MAX_GPS_LOC_ITEM) break;
271 last_location[index] = (char *)strtok_r(NULL, ";", &last);
277 status = LOCATION_STATUS_3D_FIX;
279 return LOCATION_ERROR_NOT_AVAILABLE;
282 level = LOCATION_ACCURACY_LEVEL_DETAILED;
284 *position = location_position_new(timestamp, latitude, longitude, altitude, status);
286 *velocity = location_velocity_new((guint) timestamp, speed, direction, 0.0);
288 *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
290 return LOCATION_ERROR_NONE;
293 static int set_position_update_interval(gpointer handle, guint interval)
295 ModFusedData *module = (ModFusedData *) handle;
296 g_return_val_if_fail(module, LOCATION_ERROR_NOT_AVAILABLE);
297 g_return_val_if_fail(module->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
300 MOD_FUSED_LOGD("set_position_update inteval [%d] -> [%d]", module->pos_interval, interval);
301 ret = lbs_client_set_position_update_interval(module->lbs_client, interval, module->pos_interval);
302 if (ret != LBS_CLIENT_ERROR_NONE) {
303 if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
304 MOD_LOGE("Access denied[%d]", ret);
305 return LOCATION_ERROR_NOT_ALLOWED;
307 MOD_LOGE("Failed lbs_client_set_position_update_interval. Error[%d]", ret);
308 return LOCATION_ERROR_NOT_AVAILABLE;
311 module->pos_interval = interval;
313 return LOCATION_ERROR_NONE;
316 LOCATION_MODULE_API gpointer init(LocModFusedOps *ops)
318 MOD_FUSED_LOGD("init");
320 g_return_val_if_fail(ops, NULL);
321 ops->start_gps = start_gps;
322 ops->start_wps = start_wps;
324 ops->get_last_position = get_last_position;
325 ops->set_position_update_interval = set_position_update_interval;
327 ModFusedData *module = g_new0(ModFusedData, 1);
328 g_return_val_if_fail(module, NULL);
330 module->pos_cb = NULL;
331 module->userdata = NULL;
332 module->is_started = FALSE;
333 module->pos_interval = 0;
334 module->fused_mode = LOCATION_FUSED_HIGH;
336 return (gpointer) module;
339 LOCATION_MODULE_API void shutdown(gpointer handle)
341 MOD_FUSED_LOGD("shutdown");
342 g_return_if_fail(handle);
343 ModFusedData *module = (ModFusedData *) handle;
345 if (module->lbs_client) {
346 lbs_client_stop(module->lbs_client, module->pos_interval, module->fused_mode);
347 lbs_client_destroy(module->lbs_client);
348 module->lbs_client = NULL;
351 module->pos_cb = NULL;
352 module->pos_interval = 0;
353 module->fused_mode = LOCATION_FUSED_HIGH;