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.
27 #include <glib-object.h>
31 #include <lbs_dbus_server.h>
33 #include "gps_plugin_data_types.h"
34 #include "lbs_server.h"
36 #include "nps_plugin_module.h"
37 #include "nps_plugin_intf.h"
40 #include "last_position.h"
41 #include "debug_util.h"
46 #define VCONFKEY_LOCATION_MOCK_ENABLED "db/location/setting/MockEnabled"
47 #define VCONFKEY_LOCATION_MOCK_STATE "memory/location/mock/state"
50 #define MOCK_LOCATION_CLEAR_VALUE 999
61 gboolean is_gps_running;
62 gint gps_client_count;
65 NpsManagerHandle handle;
67 NpsManagerPositionExt pos;
68 NpsManagerLastPositionExt last_pos;
69 Plugin_LocationInfo location;
71 gboolean is_nps_running;
72 gint nps_client_count;
75 /* shared variables */
81 /* dynamic interval update */
82 GHashTable *dynamic_interval_table;
83 guint *optimized_interval_array;
84 guint temp_minimum_interval;
85 gboolean is_needed_changing_interval;
87 lbs_server_dbus_h lbs_dbus_server;
90 gboolean is_mock_running;
91 gint mock_client_count;
93 LbsStatus mock_status;
95 NpsManagerPositionExt mock_position;
96 GVariant *mock_accuracy;
101 lbs_server_s *lbs_server;
103 } dynamic_interval_updator_user_data;
105 static gboolean gps_remove_all_clients(lbs_server_s *lbs_server);
106 static NpsManagerPositionExt g_mock_position;
107 static void set_mock_location_cb(gint method, gdouble latitude, gdouble longitude, gdouble altitude, gdouble speed, gdouble direction, gdouble accuracy, gpointer userdata);
108 static int mock_start_tracking(lbs_server_s *lbs_server);
109 static int mock_stop_tracking(lbs_server_s *lbs_server);
110 static void mock_set_status(lbs_server_s *lbs_server, LbsStatus status);
111 static void __setting_mock_cb(keynode_t *key, gpointer user_data);
114 static void __setting_gps_cb(keynode_t *key, gpointer user_data)
116 LOG_GPS(DBG_LOW, "ENTER >>>");
117 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
119 gboolean ret = FALSE;
121 setting_get_int(VCONFKEY_LOCATION_ENABLED, &onoff);
124 ret = gps_remove_all_clients(lbs_server);
127 LOG_GPS(DBG_LOW, "already removed.");
131 static void nps_set_last_position(NpsManagerPositionExt pos)
133 LOG_NPS(DBG_LOW, "nps_set_last_position[%d]", pos.timestamp);
135 char location[128] = {0,};
136 snprintf(location, sizeof(location), "%.6lf;%.6lf;%.2lf;%.2lf;%.2lf;%.2lf;", pos.latitude, pos.longitude, pos.altitude, pos.speed, pos.direction, pos.hor_accuracy);
138 setting_set_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, pos.timestamp);
139 setting_set_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION, location);
142 static void nps_set_position(lbs_server_s *lbs_server_nps, NpsManagerPositionExt pos)
144 LOG_NPS(DBG_LOW, "set position timestamp : %d", pos.timestamp);
145 lbs_server_nps->last_pos.timestamp = pos.timestamp;
146 setting_set_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, lbs_server_nps->last_pos.timestamp);
148 if ((lbs_server_nps->last_pos.latitude != pos.latitude) || (lbs_server_nps->last_pos.longitude != pos.longitude)) {
149 lbs_server_nps->last_pos.latitude = pos.latitude;
150 lbs_server_nps->last_pos.longitude = pos.longitude;
151 lbs_server_nps->last_pos.altitude = pos.altitude;
152 lbs_server_nps->last_pos.hor_accuracy = pos.hor_accuracy;
153 lbs_server_nps->last_pos.speed = pos.speed;
154 lbs_server_nps->last_pos.direction = pos.direction;
156 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LATITUDE, lbs_server_nps->last_pos.latitude);
157 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LONGITUDE, lbs_server_nps->last_pos.longitude);
158 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_ALTITUDE, lbs_server_nps->last_pos.altitude);
159 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_SPEED, lbs_server_nps->last_pos.speed);
160 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_DIRECTION, lbs_server_nps->last_pos.direction);
161 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_HOR_ACCURACY, lbs_server_nps->last_pos.hor_accuracy);
164 int last_timestamp = 0;
165 setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, &last_timestamp);
167 LOG_NPS(DBG_LOW, "last_time stamp: %d, pos.timestamp: %d, UPDATE_INTERVAL: %d ", last_timestamp, pos.timestamp, UPDATE_INTERVAL);
168 if ((pos.timestamp - last_timestamp) > UPDATE_INTERVAL)
169 nps_set_last_position(pos);
172 static void nps_set_status(lbs_server_s *lbs_server_nps, LbsStatus status)
174 if (!lbs_server_nps) {
175 LOG_NPS(DBG_ERR, "lbs_server_nps is NULL!!");
178 LOG_NPS(DBG_LOW, "Previous status: %d, Current status: %d", lbs_server_nps->status, status);
179 if (lbs_server_nps->status == status) {
180 LOG_NPS(DBG_WARN, "Don't update NPS status");
184 lbs_server_nps->status = status;
186 if (lbs_server_nps->status == LBS_STATUS_AVAILABLE)
187 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_CONNECTED);
188 else if (lbs_server_nps->status == LBS_STATUS_ACQUIRING)
189 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_SEARCHING);
191 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_OFF);
193 if (status != LBS_STATUS_AVAILABLE)
194 lbs_server_nps->pos.fields = LBS_POSITION_FIELDS_NONE;
196 lbs_server_emit_status_changed(lbs_server_nps->lbs_dbus_server, LBS_SERVER_METHOD_NPS, status);
199 static void nps_update_position(lbs_server_s *lbs_server_nps, NpsManagerPositionExt pos)
201 if (!lbs_server_nps) {
202 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
206 GVariant *accuracy = NULL;
208 lbs_server_nps->pos.fields = pos.fields;
209 lbs_server_nps->pos.timestamp = pos.timestamp;
210 lbs_server_nps->pos.latitude = pos.latitude;
211 lbs_server_nps->pos.longitude = pos.longitude;
212 lbs_server_nps->pos.altitude = pos.altitude;
213 lbs_server_nps->pos.hor_accuracy = pos.hor_accuracy;
214 lbs_server_nps->pos.ver_accuracy = pos.ver_accuracy;
216 accuracy = g_variant_ref_sink(g_variant_new("(idd)", lbs_server_nps->pos.acc_level, lbs_server_nps->pos.hor_accuracy, lbs_server_nps->pos.ver_accuracy));
218 LOG_NPS(DBG_LOW, "time:%d", lbs_server_nps->pos.timestamp);
220 lbs_server_emit_position_changed(lbs_server_nps->lbs_dbus_server, LBS_SERVER_METHOD_NPS,
221 lbs_server_nps->pos.fields, lbs_server_nps->pos.timestamp, lbs_server_nps->pos.latitude,
222 lbs_server_nps->pos.longitude, lbs_server_nps->pos.altitude, lbs_server_nps->pos.speed,
223 lbs_server_nps->pos.direction, 0.0, accuracy);
225 g_variant_unref(accuracy);
228 static gboolean nps_report_callback(gpointer user_data)
230 LOG_NPS(DBG_LOW, "ENTER >>>");
231 lbs_server_s *lbs_server_nps = (lbs_server_s *)user_data;
232 if (!lbs_server_nps) {
233 LOG_NPS(DBG_ERR, "lbs_server_nps is NULL!!");
237 double vertical_accuracy = -1.0; /* vertical accuracy's invalid value is -1 */
239 Plugin_LocationInfo location;
241 g_mutex_lock(&lbs_server_nps->mutex);
242 memset(&location, 0x00, sizeof(Plugin_LocationInfo));
243 memcpy(&location, &lbs_server_nps->location, sizeof(Plugin_LocationInfo));
244 g_mutex_unlock(&lbs_server_nps->mutex);
247 if (timestamp == lbs_server_nps->last_pos.timestamp)
250 nps_set_status(lbs_server_nps, LBS_STATUS_AVAILABLE);
252 NpsManagerPositionExt pos;
253 memset(&pos, 0x00, sizeof(NpsManagerPositionExt));
255 pos.timestamp = timestamp;
257 if (location.latitude) {
258 pos.fields |= LBS_POSITION_EXT_FIELDS_LATITUDE;
259 pos.latitude = location.latitude;
262 if (location.longitude) {
263 pos.fields |= LBS_POSITION_EXT_FIELDS_LONGITUDE;
264 pos.longitude = location.longitude;
267 if (location.altitude) {
268 pos.fields |= LBS_POSITION_EXT_FIELDS_ALTITUDE;
269 pos.altitude = location.altitude;
272 if (location.speed >= 0) {
273 pos.fields |= LBS_POSITION_EXT_FIELDS_SPEED;
274 pos.speed = location.speed;
276 if (location.bearing >= 0) {
277 pos.fields |= LBS_POSITION_EXT_FIELDS_DIRECTION;
278 pos.direction = location.bearing;
281 pos.acc_level = LBS_ACCURACY_LEVEL_STREET;
282 pos.hor_accuracy = location.hpe;
283 pos.ver_accuracy = vertical_accuracy;
285 nps_update_position(lbs_server_nps, pos);
287 nps_set_position(lbs_server_nps, pos);
292 static void __nps_callback(void *arg, const Plugin_LocationInfo *location, const void *reserved)
294 LOG_NPS(DBG_LOW, "ENTER >>>");
295 lbs_server_s *lbs_server = (lbs_server_s *)arg;
297 LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
302 LOG_NPS(DBG_LOW, "NULL is returned from plugin...");
303 nps_set_status (lbs_server , LBS_STATUS_ACQUIRING);
307 g_mutex_lock(&lbs_server->mutex);
308 memcpy(&lbs_server->location, location, sizeof(Plugin_LocationInfo));
309 g_mutex_unlock(&lbs_server->mutex);
311 g_main_context_invoke(NULL, nps_report_callback, arg);
314 static void _nps_token_callback(void *arg, const unsigned char *token, unsigned tokenSize)
316 LOG_NPS(DBG_LOW, "ENTER >>>");
317 lbs_server_s *lbs_server_nps = (lbs_server_s *)arg;
318 if (NULL == lbs_server_nps) {
319 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
324 LOG_NPS(DBG_ERR, "*** no token to save\n");
326 /* save the token in persistent storage */
327 g_mutex_lock(&lbs_server_nps->mutex);
328 lbs_server_nps->token = g_new0(unsigned char, tokenSize);
330 if (lbs_server_nps->token)
331 memcpy(lbs_server_nps->token, token, tokenSize);
333 g_mutex_unlock(&lbs_server_nps->mutex);
335 LOG_NPS(DBG_LOW, "_nps_token_callback ended");
338 #if 0 /* Not needed */
339 static void _network_enabled_cb(keynode_t *key, void *user_data)
341 LOG_GPS(DBG_LOW, "ENTER >>>");
344 setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
346 /* This is vestige of nps-server
347 lbs_server_s *lbs_server_nps = (lbs_server_s *)user_data;
350 if (lbs_server_nps->loop != NULL) {
351 g_main_loop_quit(lbs_server_nps->loop);
358 static gboolean nps_offline_location(lbs_server_s *lbs_server)
360 LOG_NPS(DBG_LOW, "ENTER >>>");
361 if (NULL == lbs_server) {
362 LOG_GPS(DBG_ERR, "lbs-server is NULL!!");
365 char key[NPS_UNIQUE_ID_LEN] = { 0, };
367 if (setting_get_unique_id(key)) {
368 LOG_NPS(DBG_LOW, "key = %s", key);
369 get_nps_plugin_module()->getOfflineToken((unsigned char *)key, NPS_UNIQUE_ID_LEN,
370 _nps_token_callback, lbs_server);
371 if (lbs_server->token != NULL) {
372 LOG_NPS(DBG_LOW, "Token = %s", lbs_server->token);
373 int ret = get_nps_plugin_module()->offlineLocation((unsigned char *)key,
374 NPS_UNIQUE_ID_LEN, lbs_server->token, 0,
375 __nps_callback, lbs_server);
377 if (lbs_server->is_nps_running) {
378 LOG_NPS(DBG_LOW, "offlineLocation() called nps_callback successfully.");
383 LOG_NPS(DBG_ERR, "getOfflineToken(): Token is NULL");
386 LOG_NPS(DBG_ERR, "lbs_get_unique_id() failed.");
391 static void __nps_cancel_callback(void *arg)
393 LOG_NPS(DBG_LOW, "__nps_cancel_callback");
394 lbs_server_s *lbs_server = (lbs_server_s *) arg;
396 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
400 g_mutex_lock(&lbs_server->mutex);
401 lbs_server->is_nps_running = FALSE;
402 g_cond_signal(&lbs_server->cond);
403 g_mutex_unlock(&lbs_server->mutex);
406 static void start_batch_tracking(lbs_server_s *lbs_server, int batch_interval, int batch_period)
408 g_mutex_lock(&lbs_server->mutex);
409 lbs_server->gps_client_count++;
410 g_mutex_unlock(&lbs_server->mutex);
412 if (lbs_server->is_gps_running == TRUE) {
413 LOG_GPS(DBG_LOW, "Batch: gps is already running");
416 LOG_GPS(DBG_LOW, "Batch: start_tracking GPS");
417 lbs_server->status = LBS_STATUS_ACQUIRING;
419 if (request_start_batch_session(batch_interval, batch_period) == TRUE) {
420 g_mutex_lock(&lbs_server->mutex);
421 lbs_server->is_gps_running = TRUE;
422 g_mutex_unlock(&lbs_server->mutex);
424 lbs_server->is_needed_changing_interval = FALSE;
427 setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
429 LOG_GPS(DBG_ERR, "Batch: Fail to request_start_batch_session");
433 static void stop_batch_tracking(lbs_server_s *lbs_server)
435 LOG_GPS(DBG_LOW, "ENTER >>>");
437 g_mutex_lock(&lbs_server->mutex);
438 lbs_server->gps_client_count--;
439 g_mutex_unlock(&lbs_server->mutex);
441 if (lbs_server->is_gps_running == FALSE) {
442 LOG_GPS(DBG_LOW, "Batch: gps- is already stopped");
446 if (lbs_server->gps_client_count <= 0) {
447 g_mutex_lock(&lbs_server->mutex);
448 lbs_server->gps_client_count = 0;
450 if (request_stop_batch_session() == TRUE) {
451 lbs_server->is_gps_running = FALSE;
452 lbs_server->sv_used = FALSE;
454 setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
455 g_mutex_unlock(&lbs_server->mutex);
459 lbs_server->status = LBS_STATUS_UNAVAILABLE;
460 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_UNAVAILABLE);
463 static void start_tracking(lbs_server_s *lbs_server, lbs_server_method_e method)
465 LOG_GPS(DBG_LOW, ">>> start_tracking");
469 case LBS_SERVER_METHOD_GPS:
471 g_mutex_lock(&lbs_server->mutex);
472 lbs_server->gps_client_count++;
473 g_mutex_unlock(&lbs_server->mutex);
475 if (lbs_server->is_gps_running == TRUE) {
476 LOG_GPS(DBG_LOW, "gps is already running");
479 LOG_GPS(DBG_LOW, "start_tracking GPS");
480 lbs_server->status = LBS_STATUS_ACQUIRING;
482 if (request_start_session((int)(lbs_server->optimized_interval_array[method])) == TRUE) {
483 g_mutex_lock(&lbs_server->mutex);
484 lbs_server->is_gps_running = TRUE;
485 g_mutex_unlock(&lbs_server->mutex);
487 lbs_server->is_needed_changing_interval = FALSE;
490 setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
492 LOG_GPS(DBG_ERR, "Failed to request_start_session");
497 case LBS_SERVER_METHOD_NPS:
498 g_mutex_lock(&lbs_server->mutex);
499 lbs_server->nps_client_count++;
500 g_mutex_unlock(&lbs_server->mutex);
502 if (lbs_server->is_nps_running == TRUE) {
503 LOG_NPS(DBG_LOW, "nps is already running");
507 LOG_NPS(DBG_LOW, "start_tracking - LBS_SERVER_METHOD_NPS");
508 nps_set_status(lbs_server, LBS_STATUS_ACQUIRING);
510 void *handle_str = NULL;
511 ret = get_nps_plugin_module()->start(lbs_server->period, __nps_callback, lbs_server, &(handle_str));
512 LOG_NPS(DBG_LOW, "after get_nps_plugin_module()->location");
515 lbs_server->handle = handle_str;
516 g_mutex_lock(&lbs_server->mutex);
517 lbs_server->is_nps_running = TRUE;
518 g_mutex_unlock(&lbs_server->mutex);
519 /* calling key_changed API was comment out.
520 vconf_ignore_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb);
525 if (nps_is_dummy_plugin_module() != TRUE)
526 nps_offline_location(lbs_server);
528 LOG_NPS(DBG_ERR, "Filed to start NPS");
529 nps_set_status(lbs_server, LBS_STATUS_ERROR);
532 case LBS_SERVER_METHOD_MOCK:
533 g_mutex_lock(&lbs_server->mutex);
534 lbs_server->mock_client_count++;
535 g_mutex_unlock(&lbs_server->mutex);
537 if (lbs_server->is_mock_running == TRUE) {
538 LOG_MOCK(DBG_LOW, "mock is already running");
542 LOG_MOCK(DBG_LOW, "start_tracking MOCK");
543 ret = mock_start_tracking(lbs_server);
545 g_mutex_lock(&lbs_server->mutex);
546 lbs_server->is_mock_running = TRUE;
547 g_mutex_unlock(&lbs_server->mutex);
550 setting_notify_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb, lbs_server);
553 LOG_MOCK(DBG_ERR, "Failed to start MOCK");
558 LOG_GPS(DBG_LOW, "start_tracking Invalid");
564 static gboolean nps_stop(lbs_server_s *lbs_server_nps)
566 LOG_NPS(DBG_LOW, "ENTER >>>");
567 if (!lbs_server_nps) {
568 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
572 int ret = get_nps_plugin_module()->stop(lbs_server_nps->handle, __nps_cancel_callback, lbs_server_nps);
574 g_mutex_lock(&lbs_server_nps->mutex);
576 while (lbs_server_nps->is_nps_running)
577 g_cond_wait(&lbs_server_nps->cond, &lbs_server_nps->mutex);
579 lbs_server_nps->is_nps_running = FALSE;
580 g_mutex_unlock(&lbs_server_nps->mutex);
582 /* This is vestige of nps-server
584 if (lbs_server_nps->loop != NULL) {
585 LOG_NPS(DBG_ERR, "module->stop() is failed. nps is cloesed.");
586 g_main_loop_quit(lbs_server_nps->loop);
592 nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
597 static void stop_tracking(lbs_server_s *lbs_server, lbs_server_method_e method)
600 case LBS_SERVER_METHOD_GPS:
601 LOG_GPS(DBG_LOW, "stop_tracking GPS");
603 gps_set_last_position(&lbs_server->position);
605 g_mutex_lock(&lbs_server->mutex);
606 lbs_server->gps_client_count--;
607 g_mutex_unlock(&lbs_server->mutex);
609 if (lbs_server->is_gps_running == FALSE) {
610 LOG_GPS(DBG_LOW, "gps is already stopped");
614 if (lbs_server->gps_client_count <= 0) {
615 g_mutex_lock(&lbs_server->mutex);
616 lbs_server->gps_client_count = 0;
618 if (request_stop_session() == TRUE) {
619 lbs_server->is_gps_running = FALSE;
620 lbs_server->sv_used = FALSE;
622 setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
624 g_mutex_unlock(&lbs_server->mutex);
627 lbs_server->status = LBS_STATUS_UNAVAILABLE;
628 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_UNAVAILABLE);
631 case LBS_SERVER_METHOD_NPS:
632 LOG_NPS(DBG_LOW, "stop_tracking NPS");
634 g_mutex_lock(&lbs_server->mutex);
635 lbs_server->nps_client_count--;
636 g_mutex_unlock(&lbs_server->mutex);
638 if (lbs_server->is_nps_running == FALSE) {
639 LOG_NPS(DBG_LOW, "nps is already stopped");
643 if (lbs_server->nps_client_count <= 0) {
644 g_mutex_lock(&lbs_server->mutex);
645 lbs_server->nps_client_count = 0;
646 g_mutex_unlock(&lbs_server->mutex);
648 LOG_NPS(DBG_LOW, "lbs_server_nps Normal stop");
649 nps_stop(lbs_server);
653 case LBS_SERVER_METHOD_MOCK:
654 LOG_NPS(DBG_LOW, "stop_tracking MOCK");
656 g_mutex_lock(&lbs_server->mutex);
657 lbs_server->mock_client_count--;
658 g_mutex_unlock(&lbs_server->mutex);
660 if (lbs_server->is_mock_running == FALSE) {
661 LOG_NPS(DBG_LOW, "mock is already stopped");
665 if (lbs_server->mock_client_count <= 0) {
666 g_mutex_lock(&lbs_server->mutex);
667 lbs_server->mock_client_count = 0;
668 g_mutex_unlock(&lbs_server->mutex);
670 LOG_NPS(DBG_LOW, "lbs_server_mock Normal stop");
671 mock_stop_tracking(lbs_server);
672 setting_ignore_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb);
677 LOG_GPS(DBG_LOW, "stop_tracking Invalid");
682 static void update_dynamic_interval_table_foreach_cb(gpointer key, gpointer value, gpointer userdata)
684 guint *interval_array = (guint *)value;
685 dynamic_interval_updator_user_data *updator_ud = (dynamic_interval_updator_user_data *)userdata;
686 lbs_server_s *lbs_server = updator_ud->lbs_server;
687 int method = updator_ud->method;
689 LOG_GPS(DBG_LOW, "method:[%d], key:[%s] interval:[%u], current optimized interval [%u]", method, (char *)key, interval_array[method], lbs_server->optimized_interval_array[method]);
690 if ((lbs_server->temp_minimum_interval > interval_array[method]))
691 lbs_server->temp_minimum_interval = interval_array[method];
694 static gboolean update_pos_tracking_interval(lbs_server_interval_manipulation_type type, const gchar *client, int method, guint interval, gpointer userdata)
696 LOG_GPS(DBG_LOW, "ENTER >>>");
697 if (userdata == NULL) return FALSE;
698 if (client == NULL) {
699 LOG_GPS(DBG_ERR, "client is NULL");
703 if (method < LBS_SERVER_METHOD_GPS || method >= LBS_SERVER_METHOD_SIZE) {
704 LOG_GPS(DBG_ERR, "unavailable method [%d]", method);
708 gboolean ret_val = FALSE;
709 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
711 /* manipulate logic for dynamic-interval hash table */
713 case LBS_SERVER_INTERVAL_ADD: {
714 LOG_GPS(DBG_LOW, "ADD, client[%s], method[%d], interval[%u]", client, method, interval);
715 gchar *client_cpy = NULL;
716 client_cpy = g_strdup(client);
718 guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client_cpy);
719 if (!interval_array) {
720 /* LOG_GPS(DBG_LOW, "first add key[%s] to interval-table", client); */
721 interval_array = (guint *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(guint));
722 if (!interval_array) {
723 /* LOG_GPS(DBG_ERR, "interval_array is NULL"); */
727 g_hash_table_insert(lbs_server->dynamic_interval_table, (gpointer)client_cpy, (gpointer)interval_array);
729 interval_array[method] = interval;
730 lbs_server->temp_minimum_interval = interval;
731 /* LOG_GPS(DBG_LOW, "ADD done"); */
735 case LBS_SERVER_INTERVAL_REMOVE: {
736 LOG_GPS(DBG_LOW, "REMOVE, client[%s], method[%d]", client, method);
737 lbs_server->temp_minimum_interval = 120; /* interval max value */
738 guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
739 if (!interval_array) {
740 LOG_GPS(DBG_INFO, "Client[%s] Method[%d] is already removed from interval-table", client, method);
743 LOG_GPS(DBG_LOW, "Found interval_array[%d](%p):[%u] from interval-table", method, interval_array, interval_array[method]);
744 interval_array[method] = 0;
747 guint interval_each = 0;
748 gboolean is_need_remove_client_from_table = TRUE;
749 for (i = 0; i < LBS_SERVER_METHOD_SIZE; i++) {
750 interval_each = interval_array[i];
751 if (interval_each != 0) {
752 LOG_GPS(DBG_LOW, "[%s] method[%d]'s interval is not zero - interval: %d. It will not be removed.", client, i, interval_each);
753 is_need_remove_client_from_table = FALSE;
758 if (is_need_remove_client_from_table) {
759 LOG_GPS(DBG_LOW, "is_need_remove_client_from_table is TRUE");
760 if (!g_hash_table_remove(lbs_server->dynamic_interval_table, client))
761 LOG_GPS(DBG_ERR, "g_hash_table_remove is failed.");
763 LOG_GPS(DBG_LOW, "REMOVE done.");
768 case LBS_SERVER_INTERVAL_UPDATE: {
769 LOG_GPS(DBG_LOW, "UPDATE client[%s], method[%d], interval[%u]", client, method, interval);
770 guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
771 if (!interval_array) {
772 LOG_GPS(DBG_LOW, "Client[%s] is not exist in interval-table", client, method);
775 interval_array[method] = interval;
776 lbs_server->temp_minimum_interval = interval;
777 LOG_GPS(DBG_LOW, "UPDATE done.");
782 LOG_GPS(DBG_ERR, "unhandled interval-update type");
787 /* update logic for optimized-interval value */
788 if (g_hash_table_size(lbs_server->dynamic_interval_table) == 0) {
789 LOG_GPS(DBG_LOW, "dynamic_interval_table size is zero. It will be updated all value as 0");
791 for (i = 0; i < LBS_SERVER_METHOD_SIZE; i++)
792 lbs_server->optimized_interval_array[i] = 0;
796 LOG_GPS(DBG_LOW, "dynamic_interval_table size is not zero.");
798 dynamic_interval_updator_user_data updator_user_data;
799 updator_user_data.lbs_server = lbs_server;
800 updator_user_data.method = method;
802 g_hash_table_foreach(lbs_server->dynamic_interval_table, (GHFunc)update_dynamic_interval_table_foreach_cb, (gpointer)&updator_user_data);
804 if (lbs_server->optimized_interval_array[method] != lbs_server->temp_minimum_interval) {
805 LOG_GPS(DBG_INFO, "Changing optimized_interval value [%u -> %u] for method [%d]",
806 lbs_server->optimized_interval_array[method], lbs_server->temp_minimum_interval, method);
807 lbs_server->optimized_interval_array[method] = lbs_server->temp_minimum_interval;
809 /* need to send message to provider device */
810 lbs_server->is_needed_changing_interval = TRUE;
813 if (lbs_server->is_needed_changing_interval)
818 LOG_GPS(DBG_LOW, "update_pos_tracking_interval done.");
822 static void request_change_pos_update_interval(int method, gpointer userdata)
824 LOG_GPS(DBG_LOW, "ENTER >>>");
825 if (!userdata) return;
827 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
829 case LBS_SERVER_METHOD_GPS:
830 request_change_pos_update_interval_standalone_gps(lbs_server->optimized_interval_array[method]);
837 static void get_nmea(int *timestamp, gchar **nmea_data, gpointer userdata)
839 LOG_GPS(DBG_LOW, "ENTER >>>");
840 if (!userdata) return;
842 get_nmea_from_server(timestamp, nmea_data);
844 LOG_GPS(DBG_LOW, "timestmap: %d, nmea_data: %s", *timestamp, *nmea_data);
847 static void set_options(GVariant *options, const gchar *client, gpointer userdata)
849 LOG_GPS(DBG_LOW, "ENTER >>>");
850 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
854 GVariant *value = NULL;
855 gboolean ret = FALSE;
856 #ifdef _TIZEN_PUBLIC_
857 char *msg_header = NULL;
858 char *msg_body = NULL;
866 lbs_server_method_e method = 0;
868 g_variant_iter_init(&iter, options);
869 ret = g_variant_iter_next(&iter, "{&sv}", &key, &value);
871 LOG_GPS(DBG_ERR, "Invalid GVariant");
874 if (!g_strcmp0(key, "CMD")) {
875 LOG_GPS(DBG_LOW, "set_options [%s]", g_variant_get_string(value, &length));
876 if (!g_strcmp0(g_variant_get_string(value, &length), "START")) {
878 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
879 if (!g_strcmp0(key, "METHOD")) {
880 method = g_variant_get_int32(value);
881 LOG_GPS(DBG_LOW, "METHOD [%d]", method);
884 if (!g_strcmp0(key, "INTERVAL")) {
885 interval = g_variant_get_uint32(value);
886 LOG_GPS(DBG_LOW, "INTERVAL [%u]", interval);
889 if (!g_strcmp0(key, "APP_ID")) {
890 app_id = g_variant_dup_string(value, &length);
891 LOG_GPS(DBG_LOW, "APP_ID [%s]", app_id);
896 update_pos_tracking_interval(LBS_SERVER_INTERVAL_ADD, client, method, interval, lbs_server);
899 if (LBS_SERVER_METHOD_GPS == method)
900 gps_dump_log("START GPS", app_id);
905 start_tracking(lbs_server, method);
907 if (lbs_server->is_needed_changing_interval) {
908 lbs_server->is_needed_changing_interval = FALSE;
909 request_change_pos_update_interval(method, (gpointer)lbs_server);
911 } else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP")) {
913 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
914 if (!g_strcmp0(key, "METHOD")) {
915 method = g_variant_get_int32(value);
916 LOG_GPS(DBG_LOW, "METHOD [%d]", method);
919 if (!g_strcmp0(key, "APP_ID")) {
920 app_id = g_variant_dup_string(value, &length);
921 LOG_GPS(DBG_LOW, "APP_ID [%s]", app_id);
926 update_pos_tracking_interval(LBS_SERVER_INTERVAL_REMOVE, client, method, interval, lbs_server);
929 if (LBS_SERVER_METHOD_GPS == method)
930 gps_dump_log("STOP GPS", app_id);
935 stop_tracking(lbs_server, method);
937 if (lbs_server->is_needed_changing_interval) {
938 lbs_server->is_needed_changing_interval = FALSE;
939 request_change_pos_update_interval(method, (gpointer)lbs_server);
941 } else if (!g_strcmp0(g_variant_get_string(value, &length), "START_BATCH")) {
943 int batch_interval = 0;
944 int batch_period = 0;
945 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
947 if (!g_strcmp0(key, "BATCH_INTERVAL")) {
948 batch_interval = g_variant_get_int32(value);
949 LOG_GPS(DBG_LOW, "BATCH_INTERVAL [%d]", batch_interval);
950 } else if (!g_strcmp0(key, "BATCH_PERIOD")) {
951 batch_period = g_variant_get_int32(value);
952 LOG_GPS(DBG_LOW, "BATCH_PERIOD [%d]", batch_period);
957 update_pos_tracking_interval(LBS_SERVER_INTERVAL_ADD, client, method, batch_interval, lbs_server);
959 start_batch_tracking(lbs_server, batch_interval, batch_period);
961 if (lbs_server->is_needed_changing_interval) {
962 lbs_server->is_needed_changing_interval = FALSE;
963 request_change_pos_update_interval(method, (gpointer)lbs_server);
966 } else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP_BATCH")) {
969 update_pos_tracking_interval(LBS_SERVER_INTERVAL_REMOVE, client, method, interval, lbs_server);
971 stop_batch_tracking(lbs_server);
973 if (lbs_server->is_needed_changing_interval) {
974 lbs_server->is_needed_changing_interval = FALSE;
975 request_change_pos_update_interval(method, (gpointer)lbs_server);
978 #ifdef _TIZEN_PUBLIC_
979 else if (!g_strcmp0(g_variant_get_string(value, &length), "SUPLNI")) {
980 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
981 if (!g_strcmp0(key, "HEADER")) {
982 msg_header = g_variant_dup_string(value, &length);
983 } else if (!g_strcmp0(key, "BODY")) {
984 size = (int) g_variant_get_size(value);
985 msg_body = (char *) g_malloc0(sizeof(char) * size);
986 memcpy(msg_body, g_variant_get_data(value), size);
987 } else if (!g_strcmp0(key, "SIZE")) {
988 size = (int) g_variant_get_int32(value);
991 request_supl_ni_session(msg_header, msg_body, size);
992 if (msg_header) g_free(msg_header);
993 if (msg_body) g_free(msg_body);
996 else if (!g_strcmp0(g_variant_get_string(value, &length), "SET:OPT")) {
997 LOG_GPS(DBG_LOW, "SET:OPT is called");
998 gboolean is_update_interval = FALSE, is_update_interval_method = FALSE;
1000 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1002 if (!g_strcmp0(key, "OPTION")) {
1003 option = g_variant_dup_string(value, &length);
1004 LOG_GPS(DBG_ERR, "option [%s]", option);
1006 if (!g_strcmp0(option, "DELGPS")) {
1007 if (request_delete_gps_data() != TRUE)
1008 LOG_GPS(DBG_ERR, "Fail to request_delete_gps_data");
1009 } else if (!g_strcmp0(option, "USE_SV")) {
1010 g_mutex_lock(&lbs_server->mutex);
1011 if (lbs_server->sv_used == FALSE)
1012 lbs_server->sv_used = TRUE;
1013 g_mutex_unlock(&lbs_server->mutex);
1018 if (!g_strcmp0(key, "METHOD")) {
1019 method = g_variant_get_int32(value);
1020 LOG_GPS(DBG_LOW, "METHOD [%d]", method);
1021 is_update_interval_method = TRUE;
1024 if (!g_strcmp0(key, "INTERVAL_UPDATE")) {
1025 interval = g_variant_get_uint32(value);
1026 LOG_GPS(DBG_LOW, "INTERVAL_UPDATE [%u] <-- [%u] ", interval, lbs_server->temp_minimum_interval);
1027 if (interval != lbs_server->temp_minimum_interval)
1028 is_update_interval = TRUE;
1032 if (is_update_interval && is_update_interval_method && client) {
1033 update_pos_tracking_interval(LBS_SERVER_INTERVAL_UPDATE, client, method, interval, lbs_server);
1034 if (lbs_server->is_needed_changing_interval) {
1035 lbs_server->is_needed_changing_interval = FALSE;
1036 request_change_pos_update_interval(method, (gpointer)lbs_server);
1043 static gboolean gps_remove_all_clients(lbs_server_s *lbs_server)
1045 LOG_GPS(DBG_LOW, "remove_all_clients GPS");
1046 if (lbs_server->gps_client_count <= 0) {
1047 lbs_server->gps_client_count = 0;
1051 lbs_server->gps_client_count = 0;
1052 stop_tracking(lbs_server, LBS_SERVER_METHOD_GPS);
1057 static void shutdown(gpointer userdata, gboolean *shutdown_arr)
1059 LOG_GPS(DBG_LOW, "shutdown callback gps:%d nps:%d, mock:%d",
1060 shutdown_arr[LBS_SERVER_METHOD_GPS], shutdown_arr[LBS_SERVER_METHOD_NPS], shutdown_arr[LBS_SERVER_METHOD_MOCK]);
1061 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1063 if (shutdown_arr[LBS_SERVER_METHOD_GPS]) {
1064 LOG_GPS(DBG_LOW, "-> shutdown GPS");
1065 if (lbs_server->is_gps_running) {
1066 if (gps_remove_all_clients(lbs_server))
1067 LOG_GPS(DBG_ERR, "<<<< Abnormal shutdown >>>>");
1071 if (shutdown_arr[LBS_SERVER_METHOD_NPS]) {
1072 LOG_NPS(DBG_LOW, "-> shutdown NPS");
1073 if (lbs_server->is_nps_running) {
1074 LOG_NPS(DBG_ERR, "lbs_server_nps is running. nps_stop");
1075 nps_stop(lbs_server);
1079 if (shutdown_arr[LBS_SERVER_METHOD_MOCK]) {
1080 LOG_NPS(DBG_LOW, "-> shutdown MOCK");
1081 if (lbs_server->is_mock_running) {
1082 LOG_NPS(DBG_ERR, "mock location is running");
1083 mock_stop_tracking(lbs_server);
1087 #if 0 /* Not needed */
1089 setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
1091 if (lbs_server->loop != NULL)
1092 g_main_loop_quit(lbs_server->loop);
1094 if (vconf_notify_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb, lbs_server))
1095 LOG_NPS(DBG_ERR, "fail to notify VCONFKEY_LOCATION_NETWORK_ENABLED");
1100 static void gps_update_position_cb(pos_data_t *pos, gps_error_t error, void *user_data)
1102 /* LOG_GPS(DBG_LOW, "ENTER >>>"); */
1104 GVariant *accuracy = NULL;
1105 LbsPositionExtFields fields;
1107 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1109 memcpy(&lbs_server->position, pos, sizeof(pos_data_t));
1111 if (lbs_server->status != LBS_STATUS_AVAILABLE) {
1112 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
1113 lbs_server->status = LBS_STATUS_AVAILABLE;
1116 fields = (LBS_POSITION_EXT_FIELDS_LATITUDE | LBS_POSITION_EXT_FIELDS_LONGITUDE | LBS_POSITION_EXT_FIELDS_ALTITUDE | LBS_POSITION_EXT_FIELDS_SPEED | LBS_POSITION_EXT_FIELDS_DIRECTION);
1118 accuracy = g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED, pos->hor_accuracy, pos->ver_accuracy);
1119 if (NULL == accuracy)
1120 LOG_GPS(DBG_LOW, "accuracy is NULL");
1122 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, fields, pos->timestamp,
1123 pos->latitude, pos->longitude, pos->altitude, pos->speed, pos->bearing, 0.0, accuracy);
1126 static void gps_update_batch_cb(batch_data_t *batch, void *user_data)
1128 LOG_GPS(DBG_LOW, "ENTER >>>");
1129 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1130 memcpy(&lbs_server->batch, batch, sizeof(batch_data_t));
1132 if (lbs_server->status != LBS_STATUS_AVAILABLE) {
1133 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
1134 lbs_server->status = LBS_STATUS_AVAILABLE;
1137 lbs_server_emit_batch_changed(lbs_server->lbs_dbus_server, batch->num_of_location);
1140 static void gps_update_satellite_cb(sv_data_t *sv, void *user_data)
1142 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1143 if (lbs_server->sv_used == FALSE) {
1144 /*LOG_GPS(DBG_LOW, "sv_used is FALSE"); */
1148 LOG_GPS(DBG_LOW, "ENTER >>>");
1151 int satellite_used = 0;
1152 GVariant *used_prn = NULL;
1153 GVariant *satellite_info = NULL;
1154 GVariantBuilder *used_prn_builder = NULL;
1155 GVariantBuilder *satellite_info_builder = NULL;
1157 memcpy(&lbs_server->satellite, sv, sizeof(sv_data_t));
1158 timestamp = sv->timestamp;
1160 used_prn_builder = g_variant_builder_new(G_VARIANT_TYPE("ai"));
1161 for (index = 0; index < sv->num_of_sat; ++index) {
1162 if (sv->sat[index].used) {
1163 g_variant_builder_add(used_prn_builder, "i", sv->sat[index].prn);
1167 used_prn = g_variant_builder_end(used_prn_builder);
1169 satellite_info_builder = g_variant_builder_new(G_VARIANT_TYPE("a(iiii)"));
1170 for (index = 0; index < sv->num_of_sat; ++index) {
1171 g_variant_builder_add(satellite_info_builder, "(iiii)", sv->sat[index].prn,
1172 sv->sat[index].elevation, sv->sat[index].azimuth, sv->sat[index].snr);
1174 satellite_info = g_variant_builder_end(satellite_info_builder);
1176 lbs_server_emit_satellite_changed(lbs_server->lbs_dbus_server, timestamp, satellite_used, sv->num_of_sat,
1177 used_prn, satellite_info);
1180 static void gps_update_nmea_cb(nmea_data_t *nmea, void *user_data)
1182 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1184 if (lbs_server->nmea.data) {
1185 g_free(lbs_server->nmea.data);
1186 lbs_server->nmea.len = 0;
1187 lbs_server->nmea.data = NULL;
1189 lbs_server->nmea.timestamp = lbs_server->position.timestamp;
1190 lbs_server->nmea.data = g_malloc(nmea->len + 1);
1191 g_return_if_fail(lbs_server->nmea.data);
1193 g_memmove(lbs_server->nmea.data, nmea->data, nmea->len);
1194 lbs_server->nmea.data[nmea->len] = '\0';
1195 lbs_server->nmea.len = nmea->len;
1197 if (lbs_server->nmea_used == FALSE)
1200 LOG_GPS(DBG_LOW, "[%d] %s", lbs_server->nmea.timestamp, lbs_server->nmea.data);
1201 lbs_server_emit_nmea_changed(lbs_server->lbs_dbus_server, lbs_server->nmea.timestamp, lbs_server->nmea.data);
1204 int gps_update_geofence_transition(int geofence_id, geofence_zone_state_t transition, double latitude, double longitude, double altitude, double speed, double bearing, double hor_accuracy, void *data)
1206 lbs_server_s *lbs_server = (lbs_server_s *)data;
1207 lbs_server_emit_gps_geofence_changed(lbs_server->lbs_dbus_server, geofence_id, transition, latitude, longitude, altitude, speed, bearing, hor_accuracy);
1211 int gps_update_geofence_service_status(int status, void *data)
1213 lbs_server_s *lbs_server = (lbs_server_s *)data;
1214 lbs_server_emit_gps_geofence_status_changed(lbs_server->lbs_dbus_server, status);
1218 static void add_fence(gint fence_id, gdouble latitude, gdouble longitude, gint radius, gint last_state, gint monitor_states, gint notification_responsiveness, gint unknown_timer, gpointer userdata)
1220 request_add_geofence(fence_id, latitude, longitude, radius, last_state, monitor_states, notification_responsiveness, unknown_timer);
1223 static void remove_fence(gint fence_id, gpointer userdata)
1225 request_delete_geofence(fence_id);
1228 static void pause_fence(gint fence_id, gpointer userdata)
1230 request_pause_geofence(fence_id);
1233 static void resume_fence(gint fence_id, gint monitor_states, gpointer userdata)
1235 request_resume_geofence(fence_id, monitor_states);
1238 static void nps_init(lbs_server_s *lbs_server_nps);
1240 static void lbs_server_init(lbs_server_s *lbs_server)
1242 LOG_GPS(DBG_LOW, "lbs_server_init");
1244 lbs_server->status = LBS_STATUS_UNAVAILABLE;
1245 g_mutex_init(&lbs_server->mutex);
1247 memset(&lbs_server->position, 0x00, sizeof(pos_data_t));
1248 memset(&lbs_server->satellite, 0x00, sizeof(sv_data_t));
1249 memset(&lbs_server->nmea, 0x00, sizeof(nmea_data_t));
1251 lbs_server->is_gps_running = FALSE;
1252 lbs_server->sv_used = FALSE;
1253 lbs_server->nmea_used = FALSE;
1254 lbs_server->gps_client_count = 0;
1256 nps_init(lbs_server);
1258 /* create resource for dynamic-interval */
1259 lbs_server->dynamic_interval_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1260 lbs_server->optimized_interval_array = (guint *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(guint));
1261 lbs_server->is_needed_changing_interval = FALSE;
1263 /* Mock Location init */
1264 lbs_server->mock_status = LBS_STATUS_UNAVAILABLE;
1265 lbs_server->is_mock_running = FALSE;
1266 lbs_server->gps_client_count = 0;
1267 lbs_server->mock_timer = 0;
1270 static void nps_get_last_position(lbs_server_s *lbs_server_nps)
1273 char location[128] = {0,};
1274 char *last_location[MAX_NPS_LOC_ITEM] = {0,};
1279 setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, ×tamp);
1280 str = setting_get_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION);
1284 snprintf(location, sizeof(location), "%s", str);
1287 last_location[index] = (char *)strtok_r(location, ";", &last);
1288 lbs_server_nps->last_pos.timestamp = timestamp;
1290 while (last_location[index] != NULL) {
1293 lbs_server_nps->last_pos.latitude = strtod(last_location[index], NULL);
1296 lbs_server_nps->last_pos.longitude = strtod(last_location[index], NULL);
1299 lbs_server_nps->last_pos.altitude = strtod(last_location[index], NULL);
1302 lbs_server_nps->last_pos.speed = strtod(last_location[index], NULL);
1305 lbs_server_nps->last_pos.direction = strtod(last_location[index], NULL);
1308 lbs_server_nps->last_pos.hor_accuracy = strtod(last_location[index], NULL);
1313 if (++index == MAX_NPS_LOC_ITEM) break;
1314 last_location[index] = (char *)strtok_r(NULL, ";", &last);
1316 LOG_NPS(DBG_LOW, "[%d] %lf, %lf", lbs_server_nps->last_pos.timestamp, lbs_server_nps->last_pos.latitude, lbs_server_nps->last_pos.longitude);
1319 static void nps_init(lbs_server_s *lbs_server_nps)
1321 LOG_NPS(DBG_LOW, "nps_init");
1323 lbs_server_nps->handle = NULL;
1324 lbs_server_nps->period = 5000;
1325 nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
1327 lbs_server_nps->pos.fields = LBS_POSITION_EXT_FIELDS_NONE;
1328 lbs_server_nps->pos.timestamp = 0;
1329 lbs_server_nps->pos.latitude = 0.0;
1330 lbs_server_nps->pos.longitude = 0.0;
1331 lbs_server_nps->pos.altitude = 0.0;
1332 lbs_server_nps->pos.acc_level = LBS_POSITION_EXT_FIELDS_NONE;
1333 lbs_server_nps->pos.hor_accuracy = -1.0;
1334 lbs_server_nps->pos.ver_accuracy = -1.0;
1336 lbs_server_nps->last_pos.timestamp = 0;
1337 lbs_server_nps->last_pos.latitude = 0.0;
1338 lbs_server_nps->last_pos.longitude = 0.0;
1339 lbs_server_nps->last_pos.altitude = 0.0;
1340 lbs_server_nps->last_pos.hor_accuracy = 0.0;
1341 lbs_server_nps->last_pos.speed = 0.0;
1342 lbs_server_nps->last_pos.direction = 0.0;
1344 #if !GLIB_CHECK_VERSION(2, 31, 0)
1345 GMutex *mutex_temp = g_mutex_new();
1346 lbs_server_nps->mutex = *mutex_temp;
1347 GCond *cond_temp = g_cond_new();
1348 lbs_server_nps->cond = *cond_temp;
1351 g_mutex_init(&lbs_server_nps->mutex);
1352 g_cond_init(&lbs_server_nps->cond);
1354 lbs_server_nps->is_nps_running = FALSE;
1355 lbs_server_nps->nps_client_count = 0;
1357 if (!get_nps_plugin_module()->load()) {
1358 LOG_NPS(DBG_ERR, "lbs_server_nps plugin load() failed.");
1362 nps_get_last_position(lbs_server_nps);
1365 static void nps_deinit(lbs_server_s *lbs_server_nps)
1367 LOG_NPS(DBG_LOW, "nps_deinit");
1368 if (get_nps_plugin_module()->unload()) {
1369 if (lbs_server_nps->is_nps_running) {
1370 g_mutex_lock(&lbs_server_nps->mutex);
1371 lbs_server_nps->is_nps_running = FALSE;
1372 g_cond_signal(&lbs_server_nps->cond);
1373 g_mutex_unlock(&lbs_server_nps->mutex);
1376 if (lbs_server_nps->token) {
1377 g_mutex_lock(&lbs_server_nps->mutex);
1378 g_free(lbs_server_nps->token);
1379 g_mutex_unlock(&lbs_server_nps->mutex);
1382 LOG_NPS(DBG_ERR, "unload() failed.");
1385 lbs_server_nps->handle = NULL;
1386 lbs_server_nps->is_nps_running = FALSE;
1387 lbs_server_nps->nps_client_count = 0;
1389 #if !GLIB_CHECK_VERSION(2, 31, 0)
1390 g_cond_free(&lbs_server_nps->cond);
1391 g_mutex_free(&lbs_server_nps->mutex);
1394 g_cond_clear(&lbs_server_nps->cond);
1395 g_mutex_clear(&lbs_server_nps->mutex);
1397 nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
1400 static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level,
1401 const gchar *msg, gpointer user_data)
1403 LOG_NPS(DBG_ERR, "GLIB[%d] : %s", log_level, msg);
1406 int main(int argc, char **argv)
1408 lbs_server_s *lbs_server = NULL;
1409 struct gps_callbacks cb;
1411 cb.pos_cb = gps_update_position_cb;
1412 cb.batch_cb = gps_update_batch_cb;
1413 cb.sv_cb = gps_update_satellite_cb;
1414 cb.nmea_cb = gps_update_nmea_cb;
1416 #if !GLIB_CHECK_VERSION(2, 31, 0)
1417 if (!g_thread_supported())
1418 g_thread_init(NULL);
1421 #if !GLIB_CHECK_VERSION(2, 35, 0)
1425 ret = initialize_server(argc, argv);
1427 LOG_GPS(DBG_ERR, "initialize_server failed");
1431 lbs_server = g_new0(lbs_server_s, 1);
1433 LOG_GPS(DBG_ERR, "Failed to create lbs_server_s create");
1436 lbs_server_init(lbs_server);
1439 register_update_callbacks(&cb, lbs_server);
1441 g_log_set_default_handler(_glib_log, lbs_server);
1443 /* create lbs-dbus server */
1444 lbs_server_dbus_cb_t *lbs_dbus_callback = g_new0(lbs_server_dbus_cb_t, 1);
1445 if (!lbs_dbus_callback) {
1446 LOG_GPS(DBG_ERR, "Failed to create lbs_server_dbus_cb");
1450 lbs_dbus_callback->set_options_cb = set_options;
1451 lbs_dbus_callback->shutdown_cb = shutdown;
1452 lbs_dbus_callback->update_interval_cb = update_pos_tracking_interval;
1453 lbs_dbus_callback->request_change_interval_cb = request_change_pos_update_interval;
1454 lbs_dbus_callback->get_nmea_cb = get_nmea;
1455 lbs_dbus_callback->add_hw_fence_cb = add_fence;
1456 lbs_dbus_callback->delete_hw_fence_cb = remove_fence;
1457 lbs_dbus_callback->pause_hw_fence_cb = pause_fence;
1458 lbs_dbus_callback->resume_hw_fence_cb = resume_fence;
1460 lbs_dbus_callback->set_mock_location_cb = set_mock_location_cb;
1462 ret = lbs_server_create(SERVICE_NAME, SERVICE_PATH, "lbs-server", "lbs-server",
1463 &(lbs_server->lbs_dbus_server), lbs_dbus_callback, (gpointer)lbs_server);
1465 if (ret != LBS_SERVER_ERROR_NONE) {
1466 LOG_GPS(DBG_ERR, "lbs_server_create failed");
1469 LOG_GPS(DBG_LOW, "lbs_server_create called");
1471 lbs_server->loop = g_main_loop_new(NULL, TRUE);
1472 g_main_loop_run(lbs_server->loop);
1474 LOG_GPS(DBG_LOW, "lbs_server deamon Stop....");
1478 /* destroy resource for dynamic-interval */
1479 g_free(lbs_server->optimized_interval_array);
1480 g_hash_table_destroy(lbs_server->dynamic_interval_table);
1482 /* free dbus callback */
1483 g_free(lbs_dbus_callback);
1485 /* destroy lbs-dbus server */
1486 lbs_server_destroy(lbs_server->lbs_dbus_server);
1487 LOG_GPS(DBG_LOW, "lbs_server_destroy called");
1489 g_main_loop_unref(lbs_server->loop);
1491 nps_deinit(lbs_server);
1494 deinitialize_server();
1502 static void set_mock_location_cb(gint method, gdouble latitude, gdouble longitude, gdouble altitude,
1503 gdouble speed, gdouble direction, gdouble accuracy, gpointer userdata)
1505 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1508 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1511 LOG_SEC("Input lat = %lf, lng = %lf", latitude, longitude);
1512 memset(&g_mock_position, 0x00, sizeof(NpsManagerPositionExt));
1513 if (latitude == MOCK_LOCATION_CLEAR_VALUE) {
1514 LOG_MOCK(DBG_LOW, "MOCK Location is cleared");
1515 mock_set_status(lbs_server, LBS_STATUS_ACQUIRING);
1521 g_mock_position.fields |= LBS_POSITION_EXT_FIELDS_DIRTY;
1522 g_mock_position.timestamp = timestamp;
1523 g_mock_position.latitude = latitude;
1524 g_mock_position.longitude = longitude;
1525 g_mock_position.altitude = altitude;
1526 g_mock_position.speed = speed;
1527 g_mock_position.direction = direction;
1528 g_mock_position.acc_level = LBS_ACCURACY_LEVEL_DETAILED;
1529 g_mock_position.hor_accuracy = accuracy;
1530 g_mock_position.ver_accuracy = -1;
1532 LOG_SEC("[%d] lat = %lf, lng = %lf", g_mock_position.timestamp, g_mock_position.latitude, g_mock_position.longitude);
1535 int __copy_mock_location(lbs_server_s *lbs_server)
1538 LOG_MOCK(DBG_ERR, "lbs_server is NULL!!");
1542 memset(&lbs_server->mock_position, 0x00, sizeof(NpsManagerPositionExt));
1543 memcpy(&lbs_server->mock_position, &g_mock_position, sizeof(NpsManagerPositionExt));
1544 g_mock_position.fields = LBS_POSITION_EXT_FIELDS_NONE;
1545 LOG_SEC("[%ld] lat = %lf, lng = %lf", lbs_server->mock_position.timestamp, lbs_server->mock_position.latitude, lbs_server->mock_position.longitude);
1547 if (lbs_server->mock_position.latitude >= -90 && lbs_server->mock_position.latitude <= 90)
1548 lbs_server->mock_position.fields |= LBS_POSITION_EXT_FIELDS_LATITUDE;
1550 if (lbs_server->mock_position.longitude >= -180 && lbs_server->mock_position.longitude <= 180)
1551 lbs_server->mock_position.fields |= LBS_POSITION_EXT_FIELDS_LONGITUDE;
1553 lbs_server->mock_position.fields |= LBS_POSITION_EXT_FIELDS_ALTITUDE;
1555 if (lbs_server->mock_position.speed >= 0)
1556 lbs_server->mock_position.fields |= LBS_POSITION_EXT_FIELDS_SPEED;
1558 if (lbs_server->mock_position.direction >= 0 && lbs_server->mock_position.direction <= 360)
1559 lbs_server->mock_position.fields |= LBS_POSITION_EXT_FIELDS_DIRECTION;
1561 lbs_server->mock_accuracy = g_variant_ref_sink(g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED, lbs_server->mock_position.hor_accuracy, -1));
1566 static gboolean __mock_position_update_cb(gpointer userdata)
1568 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1571 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1575 if (lbs_server->mock_status == LBS_STATUS_ACQUIRING) {
1576 if (g_mock_position.timestamp) {
1577 __copy_mock_location(lbs_server);
1578 mock_set_status(lbs_server, LBS_STATUS_AVAILABLE);
1580 } else if (lbs_server->mock_status == LBS_STATUS_AVAILABLE) {
1581 if (g_mock_position.timestamp) {
1582 if (g_mock_position.fields & LBS_POSITION_EXT_FIELDS_DIRTY)
1583 __copy_mock_location(lbs_server);
1588 LOG_SEC("[%d] lat = %lf, lng = %lf", lbs_server->mock_position.timestamp,
1589 lbs_server->mock_position.latitude, lbs_server->mock_position.longitude);
1591 lbs_server->mock_position.timestamp = timestamp;
1592 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_MOCK,
1593 lbs_server->mock_position.fields, lbs_server->mock_position.timestamp,
1594 lbs_server->mock_position.latitude, lbs_server->mock_position.longitude, lbs_server->mock_position.altitude,
1595 lbs_server->mock_position.speed, lbs_server->mock_position.direction, 0.0, lbs_server->mock_accuracy);
1597 mock_set_status(lbs_server, LBS_STATUS_ACQUIRING);
1604 static gboolean mock_start_tracking(lbs_server_s *lbs_server)
1606 LOG_MOCK(DBG_LOW, "ENTER >>>");
1608 LOG_MOCK(DBG_ERR, "lbs_server is NULL!!");
1612 __copy_mock_location(lbs_server);
1613 mock_set_status(lbs_server, LBS_STATUS_ACQUIRING);
1615 if (!lbs_server->mock_timer)
1616 lbs_server->mock_timer = g_timeout_add_seconds(1, __mock_position_update_cb, lbs_server);
1621 static int mock_stop_tracking(lbs_server_s *lbs_server)
1623 LOG_MOCK(DBG_LOW, "ENTER >>>");
1625 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1629 if (lbs_server->mock_timer) g_source_remove(lbs_server->mock_timer);
1630 lbs_server->mock_timer = 0;
1631 g_variant_unref(lbs_server->mock_accuracy);
1633 if (lbs_server->is_mock_running) {
1634 g_mutex_lock(&lbs_server->mutex);
1635 lbs_server->is_mock_running = FALSE;
1636 g_mutex_unlock(&lbs_server->mutex);
1639 mock_set_status(lbs_server, LBS_STATUS_UNAVAILABLE);
1644 static void mock_set_status(lbs_server_s *lbs_server, LbsStatus status)
1647 LOG_MOCK(DBG_ERR, "lbs_server is NULL!!");
1650 LOG_MOCK(DBG_LOW, "Previous status: %d, Current status: %d", lbs_server->mock_status, status);
1651 if (lbs_server->mock_status == status) {
1652 LOG_MOCK(DBG_ERR, "Don't update MOCK status");
1656 lbs_server->mock_status = status;
1658 if (lbs_server->mock_status == LBS_STATUS_AVAILABLE)
1659 setting_set_int(VCONFKEY_LOCATION_MOCK_STATE, POSITION_CONNECTED);
1660 else if (lbs_server->mock_status == LBS_STATUS_ACQUIRING)
1661 setting_set_int(VCONFKEY_LOCATION_MOCK_STATE, POSITION_SEARCHING);
1663 setting_set_int(VCONFKEY_LOCATION_MOCK_STATE, POSITION_OFF);
1665 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_MOCK, status);
1668 static gboolean mock_remove_all_clients(lbs_server_s *lbs_server)
1670 LOG_MOCK(DBG_LOW, "remove_all_clients MOCK");
1671 if (lbs_server->mock_client_count <= 0) {
1672 lbs_server->mock_client_count = 0;
1676 lbs_server->mock_client_count = 0;
1677 stop_tracking(lbs_server, LBS_SERVER_METHOD_MOCK);
1682 static void __setting_mock_cb(keynode_t *key, gpointer user_data)
1684 LOG_MOCK(DBG_LOW, "ENTER >>>");
1685 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
1687 gboolean ret = FALSE;
1689 setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED, &onoff);
1692 ret = mock_remove_all_clients(lbs_server);
1695 LOG_MOCK(DBG_LOW, "already removed.");