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.
24 #include <glib-object.h>
28 #include <lbs_dbus_server.h>
30 #include "gps_plugin_data_types.h"
31 #include "lbs_server.h"
33 #include "nps_plugin_module.h"
34 #include "nps_plugin_intf.h"
37 #include "last_position.h"
38 #include "debug_util.h"
41 #include "location-types.h"
44 #define MOCK_LOCATION_CLEAR_VALUE 999
45 #define MOCK_RUNNING_OFF LBS_SERVER_METHOD_SIZE
46 #define MAX_INTERVAL 120
47 #define MAX_BATCH_INTERVAL 255
48 #define MAX_BATCH_PERIOD 60000
59 gboolean is_gps_running;
60 gint gps_client_count;
63 NpsManagerHandle nps_handle;
65 NpsManagerPositionExt pos;
66 NpsManagerLastPositionExt last_pos;
67 Plugin_LocationInfo location;
69 gboolean is_nps_running;
70 gint nps_client_count;
73 /* shared variables */
79 /* dynamic interval update */
80 GHashTable *dynamic_interval_table;
81 guint *optimized_interval;
82 guint temp_minimum_interval;
83 gboolean is_needed_changing_interval;
85 GHashTable *batch_interval_table;
86 guint *optimized_batch_array;
89 lbs_server_dbus_h lbs_dbus_server;
94 NpsManagerPositionExt mock_pos;
95 GVariant *mock_accuracy;
98 gint fused_high_count;
99 gint fused_balanced_count;
100 gboolean is_fused_running;
101 gint current_location_source;
105 lbs_server_s *lbs_server;
107 } dynamic_interval_updator_user_data;
111 LBS_BATCH_INTERVAL = 0,
114 } lbs_batch_interval;
118 LOCATION_SOURCE_NONE = 0,
121 LOCATION_SOURCE_BOTH,
122 } lbs_current_location_source;
127 _LBS_CLIENT_REMOVE_ALL,
130 static gboolean gps_remove_all_clients(lbs_server_s *lbs_server);
131 static NpsManagerPositionExt g_mock_position;
132 static void set_mock_location_cb(gint method, gdouble latitude, gdouble longitude, gdouble altitude, gdouble speed, gdouble direction, gdouble accuracy, gpointer userdata);
133 static void mock_start_tracking(lbs_server_s *lbs_server);
134 static void mock_stop_tracking(lbs_server_s *lbs_server);
135 static void client_count_updater(lbs_server_s *lbs_server, lbs_server_method_e method, lbs_client_count type, gint fused_mode);
138 static void __setting_gps_cb(keynode_t *key, gpointer user_data)
140 LOG_GPS(DBG_LOW, "__setting_gps_cb");
141 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
143 gboolean ret = FALSE;
145 setting_get_int(VCONFKEY_LOCATION_ENABLED, &onoff);
148 ret = gps_remove_all_clients(lbs_server);
151 LOG_GPS(DBG_LOW, "already removed.");
155 static void __setting_mock_cb(keynode_t *key, gpointer user_data)
157 LOG_GPS(DBG_LOW, "__setting_mock_cb");
158 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
161 setting_get_int(VCONFKEY_LOCATION_MOCK_ENABLED, &onoff);
164 mock_stop_tracking(lbs_server);
165 setting_ignore_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb);
169 static void nps_set_last_position(NpsManagerPositionExt pos)
171 LOG_NPS(DBG_LOW, "nps_set_last_position[%d]", pos.timestamp);
173 char location[128] = {0,};
174 snprintf(location, sizeof(location), "%.6lf;%.6lf;%.2lf;%.2lf;%.2lf;%.2lf;", pos.latitude, pos.longitude, pos.altitude, pos.speed, pos.direction, pos.hor_accuracy);
176 setting_set_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, pos.timestamp);
177 setting_set_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION, location);
180 static void nps_set_position(lbs_server_s *lbs_server, NpsManagerPositionExt pos)
182 LOG_NPS(DBG_LOW, "set position timestamp : %d", pos.timestamp);
183 lbs_server->last_pos.timestamp = pos.timestamp;
184 setting_set_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, lbs_server->last_pos.timestamp);
186 if ((lbs_server->last_pos.latitude != pos.latitude) || (lbs_server->last_pos.longitude != pos.longitude)) {
187 lbs_server->last_pos.latitude = pos.latitude;
188 lbs_server->last_pos.longitude = pos.longitude;
189 lbs_server->last_pos.altitude = pos.altitude;
190 lbs_server->last_pos.hor_accuracy = pos.hor_accuracy;
191 lbs_server->last_pos.speed = pos.speed;
192 lbs_server->last_pos.direction = pos.direction;
194 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LATITUDE, lbs_server->last_pos.latitude);
195 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LONGITUDE, lbs_server->last_pos.longitude);
196 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_ALTITUDE, lbs_server->last_pos.altitude);
197 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_SPEED, lbs_server->last_pos.speed);
198 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_DIRECTION, lbs_server->last_pos.direction);
199 setting_set_double(VCONFKEY_LOCATION_LAST_WPS_HOR_ACCURACY, lbs_server->last_pos.hor_accuracy);
202 int last_timestamp = 0;
203 setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, &last_timestamp);
205 LOG_NPS(DBG_LOW, "last_time stamp: %d, pos.timestamp: %d, UPDATE_INTERVAL: %d ", last_timestamp, pos.timestamp, UPDATE_INTERVAL);
206 if ((pos.timestamp - last_timestamp) > UPDATE_INTERVAL)
207 nps_set_last_position(pos);
210 static void nps_set_status(lbs_server_s *lbs_server, LbsStatus status)
213 LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
216 LOG_NPS(DBG_LOW, "Previous status: %d, Current status: %d", lbs_server->status, status);
217 if (lbs_server->status == status) {
218 LOG_NPS(DBG_WARN, "Don't update NPS status");
222 lbs_server->status = status;
224 if (lbs_server->status == LBS_STATUS_AVAILABLE)
225 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_CONNECTED);
226 else if (lbs_server->status == LBS_STATUS_ACQUIRING)
227 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_SEARCHING);
229 setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_OFF);
231 if (status != LBS_STATUS_AVAILABLE)
232 lbs_server->pos.fields = LBS_POSITION_FIELDS_NONE;
234 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_NPS, status);
237 static void nps_update_position(lbs_server_s *lbs_server, NpsManagerPositionExt pos)
240 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
244 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF)
247 GVariant *accuracy = NULL;
249 lbs_server->pos.fields = pos.fields;
250 lbs_server->pos.timestamp = pos.timestamp;
251 lbs_server->pos.latitude = pos.latitude;
252 lbs_server->pos.longitude = pos.longitude;
253 lbs_server->pos.altitude = pos.altitude;
254 lbs_server->pos.hor_accuracy = pos.hor_accuracy;
255 lbs_server->pos.ver_accuracy = pos.ver_accuracy;
257 accuracy = g_variant_ref_sink(g_variant_new("(idd)", lbs_server->pos.acc_level, lbs_server->pos.hor_accuracy, lbs_server->pos.ver_accuracy));
259 LOG_NPS(DBG_LOW, "time:%d", lbs_server->pos.timestamp);
262 send_wps_position_to_fused_engine(pos.timestamp, pos.latitude, pos.longitude, pos.hor_accuracy, pos.ver_accuracy);
265 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_NPS,
266 lbs_server->pos.fields, lbs_server->pos.timestamp, lbs_server->pos.latitude,
267 lbs_server->pos.longitude, lbs_server->pos.altitude, lbs_server->pos.speed,
268 lbs_server->pos.direction, 0.0, accuracy);
270 g_variant_unref(accuracy);
273 static gboolean nps_report_callback(gpointer user_data)
275 LOG_NPS(DBG_LOW, "ENTER >>>");
276 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
278 LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
282 double vertical_accuracy = -1.0; /* vertical accuracy's invalid value is -1 */
284 Plugin_LocationInfo location;
286 g_mutex_lock(&lbs_server->mutex);
287 memset(&location, 0x00, sizeof(Plugin_LocationInfo));
288 memcpy(&location, &lbs_server->location, sizeof(Plugin_LocationInfo));
289 g_mutex_unlock(&lbs_server->mutex);
292 if (timestamp == lbs_server->last_pos.timestamp)
295 nps_set_status(lbs_server, LBS_STATUS_AVAILABLE);
297 NpsManagerPositionExt pos;
298 memset(&pos, 0x00, sizeof(NpsManagerPositionExt));
300 pos.timestamp = timestamp;
302 if (location.latitude) {
303 pos.fields |= LBS_POSITION_EXT_FIELDS_LATITUDE;
304 pos.latitude = location.latitude;
307 if (location.longitude) {
308 pos.fields |= LBS_POSITION_EXT_FIELDS_LONGITUDE;
309 pos.longitude = location.longitude;
312 if (location.altitude) {
313 pos.fields |= LBS_POSITION_EXT_FIELDS_ALTITUDE;
314 pos.altitude = location.altitude;
317 if (location.speed >= 0) {
318 pos.fields |= LBS_POSITION_EXT_FIELDS_SPEED;
319 pos.speed = location.speed;
321 if (location.bearing >= 0) {
322 pos.fields |= LBS_POSITION_EXT_FIELDS_DIRECTION;
323 pos.direction = location.bearing;
326 pos.acc_level = LBS_ACCURACY_LEVEL_STREET;
327 pos.hor_accuracy = location.hpe;
328 pos.ver_accuracy = vertical_accuracy;
330 nps_update_position(lbs_server, pos);
332 nps_set_position(lbs_server, pos);
337 static void __nps_callback(void *arg, const Plugin_LocationInfo *location, const void *reserved)
339 LOG_NPS(DBG_LOW, "ENTER >>>");
340 lbs_server_s *lbs_server = (lbs_server_s *)arg;
342 LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
347 LOG_NPS(DBG_LOW, "NULL is returned from plugin...");
348 nps_set_status(lbs_server, LBS_STATUS_ACQUIRING);
352 g_mutex_lock(&lbs_server->mutex);
353 memcpy(&lbs_server->location, location, sizeof(Plugin_LocationInfo));
354 g_mutex_unlock(&lbs_server->mutex);
356 g_main_context_invoke(NULL, nps_report_callback, arg);
359 static void _nps_token_callback(void *arg, const unsigned char *token, unsigned tokenSize)
361 LOG_NPS(DBG_LOW, "ENTER >>>");
362 lbs_server_s *lbs_server = (lbs_server_s *)arg;
363 if (NULL == lbs_server) {
364 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
369 LOG_NPS(DBG_ERR, "*** no token to save\n");
371 /* save the token in persistent storage */
372 g_mutex_lock(&lbs_server->mutex);
373 lbs_server->token = g_new0(unsigned char, tokenSize);
375 if (lbs_server->token)
376 memcpy(lbs_server->token, token, tokenSize);
378 g_mutex_unlock(&lbs_server->mutex);
380 LOG_NPS(DBG_LOW, "_nps_token_callback ended");
383 #if 0 /* Not needed */
384 static void _network_enabled_cb(keynode_t *key, void *user_data)
386 LOG_GPS(DBG_LOW, "ENTER >>>");
389 setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
391 /* This is vestige of nps-server
392 lbs_server_s *lbs_server = (lbs_server_s *)user_data;
395 if (lbs_server->loop != NULL) {
396 g_main_loop_quit(lbs_server->loop);
403 static gboolean nps_offline_location(lbs_server_s *lbs_server)
405 LOG_NPS(DBG_LOW, "ENTER >>>");
406 if (lbs_server == NULL) {
407 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
410 char key[NPS_UNIQUE_ID_LEN] = { 0, };
412 if (setting_get_unique_id(key)) {
413 LOG_NPS(DBG_LOW, "key = %s", key);
414 get_nps_plugin_module()->getOfflineToken((unsigned char *)key, NPS_UNIQUE_ID_LEN,
415 _nps_token_callback, lbs_server);
416 if (lbs_server->token != NULL) {
417 LOG_NPS(DBG_LOW, "Token = %s", lbs_server->token);
418 int ret = get_nps_plugin_module()->offlineLocation((unsigned char *)key,
419 NPS_UNIQUE_ID_LEN, lbs_server->token, 0,
420 __nps_callback, lbs_server);
422 if (lbs_server->is_nps_running) {
423 LOG_NPS(DBG_LOW, "offlineLocation() called nps_callback successfully.");
428 LOG_NPS(DBG_ERR, "getOfflineToken(): Token is NULL");
431 LOG_NPS(DBG_ERR, "lbs_get_unique_id() failed.");
436 static void __nps_cancel_callback(void *arg)
438 LOG_NPS(DBG_LOW, "__nps_cancel_callback");
439 lbs_server_s *lbs_server = (lbs_server_s *) arg;
441 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
445 g_mutex_lock(&lbs_server->mutex);
446 lbs_server->is_nps_running = FALSE;
447 g_cond_signal(&lbs_server->cond);
448 g_mutex_unlock(&lbs_server->mutex);
451 static gboolean location_source_selector(lbs_server_s *lbs_server, gint fused_mode);
452 static void plugin_status_controller(lbs_server_s *lbs_server);
454 static void start_tracking(lbs_server_s *lbs_server, lbs_server_method_e method, gint fused_mode)
456 LOG_GPS(DBG_LOW, ">>> start_tracking");
459 case LBS_SERVER_METHOD_GPS:
460 client_count_updater(lbs_server, LBS_SERVER_METHOD_GPS, _LBS_CLIENT_ADD, fused_mode);
462 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF && lbs_server->is_gps_running == FALSE && lbs_server->is_nps_running == FALSE)
463 mock_start_tracking(lbs_server);
465 if (location_source_selector(lbs_server, fused_mode) == TRUE) {
466 plugin_status_controller(lbs_server);
470 case LBS_SERVER_METHOD_NPS:
471 client_count_updater(lbs_server, LBS_SERVER_METHOD_NPS, _LBS_CLIENT_ADD, fused_mode);
473 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF && lbs_server->is_gps_running == FALSE && lbs_server->is_nps_running == FALSE)
474 mock_start_tracking(lbs_server);
476 if (location_source_selector(lbs_server, fused_mode) == TRUE) {
477 plugin_status_controller(lbs_server);
480 if (nps_is_dummy_plugin_module() != TRUE)
481 nps_offline_location(lbs_server);
483 LOG_NPS(DBG_ERR, "Failed to start NPS");
484 nps_set_status(lbs_server, LBS_STATUS_ERROR);
487 case LBS_SERVER_METHOD_PASSIVE:
491 LOG_GPS(DBG_LOW, "start_tracking Invalid");
497 static gboolean nps_plugin_stop(lbs_server_s *lbs_server)
501 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
505 int ret = get_nps_plugin_module()->stop(lbs_server->nps_handle, __nps_cancel_callback, lbs_server);
507 g_mutex_lock(&lbs_server->mutex);
509 while (lbs_server->is_nps_running)
510 g_cond_wait(&lbs_server->cond, &lbs_server->mutex);
512 lbs_server->is_nps_running = FALSE;
513 g_mutex_unlock(&lbs_server->mutex);
515 /* This is vestige of nps-server
517 if (lbs_server->loop != NULL) {
518 LOG_NPS(DBG_ERR, "module->stop() is failed. nps is cloesed.");
519 g_main_loop_quit(lbs_server->loop);
525 nps_set_status(lbs_server, LBS_STATUS_UNAVAILABLE);
530 static void stop_tracking(lbs_server_s *lbs_server, lbs_server_method_e method, gint fused_mode)
534 case LBS_SERVER_METHOD_GPS:
535 LOG_GPS(DBG_LOW, "stop_tracking GPS [client: %d]", lbs_server->gps_client_count);
537 if (lbs_server->is_mock_running == MOCK_RUNNING_OFF)
538 gps_set_last_position(&lbs_server->position);
540 client_count_updater(lbs_server, LBS_SERVER_METHOD_GPS, _LBS_CLIENT_REMOVE, fused_mode);
542 if (location_source_selector(lbs_server, fused_mode) == TRUE) {
543 plugin_status_controller(lbs_server);
546 if (lbs_server->is_gps_running == FALSE) {
547 lbs_server->status = LBS_STATUS_UNAVAILABLE;
548 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_UNAVAILABLE);
552 case LBS_SERVER_METHOD_NPS:
553 LOG_NPS(DBG_LOW, "_stop_tracking NPS");
555 client_count_updater(lbs_server, LBS_SERVER_METHOD_NPS, _LBS_CLIENT_REMOVE, fused_mode);
557 if (location_source_selector(lbs_server, fused_mode) == TRUE) {
558 plugin_status_controller(lbs_server);
562 case LBS_SERVER_METHOD_PASSIVE:
566 LOG_GPS(DBG_LOW, "stop_tracking Invalid");
571 static gboolean _set_current_location_source(lbs_server_s *lbs_server, gint mode)
573 if (lbs_server->current_location_source != mode) {
574 LOG_GPS(DBG_LOW, "location source changed[%d]", mode);
575 lbs_server->current_location_source = mode;
581 static gboolean location_source_selector(lbs_server_s *lbs_server, gint fused_mode)
584 if (lbs_server == NULL) {
585 LOG_GPS(DBG_LOW, "lbs_server is null");
589 /* set fused running status */
590 if (fused_mode == LOCATION_FUSED_HIGH || fused_mode == LOCATION_FUSED_BALANCED) {
591 if (lbs_server->fused_high_count == 0 && lbs_server->fused_balanced_count == 0) {
592 LOG_GPS(DBG_LOW, "-- Checking to stop fused mode");
593 if (lbs_server->is_fused_running) {
594 g_mutex_lock(&lbs_server->mutex);
595 lbs_server->is_fused_running = FALSE;
596 g_mutex_unlock(&lbs_server->mutex);
598 location_fused_stop();
601 LOG_GPS(DBG_LOW, "-- Checking to start fused mode");
602 if (lbs_server->is_fused_running == FALSE) {
603 g_mutex_lock(&lbs_server->mutex);
604 lbs_server->is_fused_running = TRUE;
605 g_mutex_unlock(&lbs_server->mutex);
607 location_fused_start();
612 /* set fused_optimized_mode */
613 if (lbs_server->fused_high_count == 0 || lbs_server->fused_balanced_count == 0)
614 lbs_server->fused_optimized_mode = LOCATION_FUSED_NONE;
615 else if (lbs_server->fused_high_count > 0)
616 lbs_server->fused_optimized_mode = LOCATION_FUSED_HIGH;
617 else if (lbs_server->fused_high_count == 0 && lbs_server->fused_balanced_count > 0)
618 lbs_server->fused_optimized_mode = LOCATION_FUSED_BALANCED;
620 lbs_server->fused_optimized_mode = LOCATION_FUSED_NONE;
622 LOG_GPS(DBG_LOW, "---- fused_optimized_mode [high: %d, balanced: %d, mode: %d]",
623 lbs_server->fused_high_count, lbs_server->fused_balanced_count, lbs_server->fused_optimized_mode);
627 /* Define all condition to select optimized location source
628 gps, high ==> 1(gps0, high0) 2(gps3, high0) 3(gps3, high1) 4(gps3, high3)
629 wps, balance ==> A(wps0, bal0) B(wps3, bal0) C(wps3, bal1) D(wps3, bal3)
631 LOCATION_SOURCE_GPS : 2A, 2D, 3A, 3D, 4A, 4D
632 LOCATION_SOURCE_WPS : 1B, 1C, 1D
633 LOCATION_SOURCE_BOTH : 2B, 2C, 3B, 2C, 4B, 4C
634 LOCATION_SOURCE_NONE : 1A
637 gint pure_wps_count = lbs_server->nps_client_count - lbs_server->fused_balanced_count;
639 if (lbs_server->gps_client_count > 0) { /* case 2, 3, 4 */
641 if (lbs_server->nps_client_count > 0) {
642 if (pure_wps_count > 0) { /* 2B, 2C, 3B, 3C, 4B, 4C */
643 if (_set_current_location_source(lbs_server, LOCATION_SOURCE_BOTH) == TRUE) return TRUE;
644 } else { /* 2D, 3D, 4D */
645 if (_set_current_location_source(lbs_server, LOCATION_SOURCE_GPS) == TRUE) return TRUE;
647 } else { /* 2A, 3A, 4A */
648 if (_set_current_location_source(lbs_server, LOCATION_SOURCE_GPS) == TRUE) return TRUE;
652 if (lbs_server->nps_client_count > 0) { /* 1B, 1C, 1D */
653 if (_set_current_location_source(lbs_server, LOCATION_SOURCE_WPS) == TRUE) return TRUE;
655 if (_set_current_location_source(lbs_server, LOCATION_SOURCE_NONE) == TRUE) return TRUE;
663 static gboolean gps_plugin_start(lbs_server_s *lbs_server)
667 LOG_GPS(DBG_ERR, "lbs-server is NULL!!");
671 lbs_server->status = LBS_STATUS_ACQUIRING;
673 if (request_start_session((int)(lbs_server->optimized_interval[LBS_SERVER_METHOD_GPS])) == TRUE) {
674 g_mutex_lock(&lbs_server->mutex);
675 lbs_server->is_gps_running = TRUE;
676 g_mutex_unlock(&lbs_server->mutex);
678 lbs_server->is_needed_changing_interval = FALSE;
679 setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
681 LOG_GPS(DBG_ERR, "Failed to request_start_session");
686 static gboolean gps_plugin_stop(lbs_server_s *lbs_server)
690 LOG_GPS(DBG_ERR, "lbs-server is NULL!!");
694 if (request_stop_session() == TRUE) {
695 lbs_server->is_gps_running = FALSE;
696 lbs_server->sv_used = FALSE;
697 setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
702 static gboolean nps_plugin_start(lbs_server_s *lbs_server)
706 LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
710 LOG_NPS(DBG_LOW, "_nps_plugin_start LBS_SERVER_METHOD_NPS");
711 nps_set_status(lbs_server, LBS_STATUS_ACQUIRING);
713 void *handle_str = NULL;
714 int ret = get_nps_plugin_module()->start(lbs_server->period, __nps_callback, lbs_server, &(handle_str));
715 LOG_NPS(DBG_LOW, "after get_nps_plugin_module()->location");
718 LOG_NPS(DBG_LOW, "get_nps_plugin_module()->start() success, ret[%d]", ret);
719 lbs_server->nps_handle = handle_str;
720 g_mutex_lock(&lbs_server->mutex);
721 lbs_server->is_nps_running = TRUE;
722 g_mutex_unlock(&lbs_server->mutex);
724 /* calling key_changed API was comment out.
725 vconf_ignore_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb);
733 static void plugin_status_controller(lbs_server_s *lbs_server)
736 if (lbs_server->current_location_source == LOCATION_SOURCE_GPS) {
737 LOG_FUSED(DBG_LOW, ">>> --- LOCATION_SOURCE_GPS");
738 if (lbs_server->is_gps_running == FALSE) {
739 gps_plugin_start(lbs_server);
741 if (lbs_server->is_nps_running) {
742 LOG_FUSED(DBG_LOW, ">>> WPS stopped from Location source controller !!!");
743 nps_plugin_stop(lbs_server);
745 } else if (lbs_server->current_location_source == LOCATION_SOURCE_WPS) {
746 LOG_FUSED(DBG_LOW, ">>> --- LOCATION_SOURCE_WPS");
747 if (lbs_server->is_gps_running) {
748 LOG_FUSED(DBG_LOW, ">>> GPS stopped from Location source controller !!!");
749 gps_plugin_stop(lbs_server);
751 if (lbs_server->is_nps_running == FALSE) {
752 LOG_FUSED(DBG_LOW, ">>> WPS started from Location source controller !!!");
753 nps_plugin_start(lbs_server);
755 } else if (lbs_server->current_location_source == LOCATION_SOURCE_BOTH) {
756 LOG_FUSED(DBG_LOW, ">>> --- LOCATION_SOURCE_BOTH");
757 if (lbs_server->is_gps_running == FALSE) {
758 LOG_FUSED(DBG_LOW, ">>> GPS stopped from Location source controller !!!");
759 gps_plugin_start(lbs_server);
761 if (lbs_server->is_nps_running == FALSE) {
762 LOG_FUSED(DBG_LOW, ">>> WPS started from Location source controller !!!");
763 nps_plugin_start(lbs_server);
765 } else if (lbs_server->current_location_source == LOCATION_SOURCE_NONE) {
766 LOG_FUSED(DBG_LOW, ">>> --- LOCATION_SOURCE_NONE");
767 if (lbs_server->is_gps_running) {
768 LOG_FUSED(DBG_LOW, ">>> GPS stopped from Location source controller !!!");
769 gps_plugin_stop(lbs_server);
771 if (lbs_server->is_nps_running) {
772 LOG_FUSED(DBG_LOW, ">>> WPS stopped from Location source controller !!!");
773 nps_plugin_stop(lbs_server);
779 * manipulate the dynamic_interval_table.
782 static void find_min_interval_foreach_cb(gpointer key, gpointer value, gpointer userdata)
784 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
785 guint interval = GPOINTER_TO_UINT(key);
786 LOG_GPS(DBG_LOW, "list : interval [%u], count [%u]", interval, GPOINTER_TO_UINT(value));
787 if (lbs_server->temp_minimum_interval > interval)
788 lbs_server->temp_minimum_interval = interval;
791 static void update_dynamic_interval_table_foreach_cb(gpointer key, gpointer value, gpointer userdata)
793 GHashTable *interval_table = (GHashTable *) value;
794 dynamic_interval_updator_user_data *updator_ud = (dynamic_interval_updator_user_data *)userdata;
795 lbs_server_s *lbs_server = updator_ud->lbs_server;
797 g_hash_table_foreach(interval_table, (GHFunc) find_min_interval_foreach_cb, (gpointer) lbs_server);
798 LOG_GPS(DBG_LOW, "foreach_cb, client:[%s] temp_min[%u], hash_size[%u]", (char *)key, lbs_server->temp_minimum_interval, g_hash_table_size(interval_table));
801 static void __add_interval_table(GHashTable *interval_table, guint interval)
803 gpointer *value = (gpointer *) g_hash_table_lookup(interval_table, GUINT_TO_POINTER(interval));
805 guint count = GPOINTER_TO_UINT(value);
806 g_hash_table_insert(interval_table, GUINT_TO_POINTER(interval), GUINT_TO_POINTER(count + 1));
808 g_hash_table_insert(interval_table, GUINT_TO_POINTER(interval), GUINT_TO_POINTER(1));
812 static void __remove_interval_table(GHashTable *interval_table, guint interval)
814 gpointer *value = (gpointer *) g_hash_table_lookup(interval_table, GUINT_TO_POINTER(interval));
816 guint count = GPOINTER_TO_UINT(value);
818 if (g_hash_table_remove(interval_table, GUINT_TO_POINTER(interval)) != TRUE)
819 LOG_GPS(DBG_LOW, "Remove interval[%u] failed from g_hash_table", interval);
821 g_hash_table_insert(interval_table, GUINT_TO_POINTER(interval), GUINT_TO_POINTER(count - 1));
824 LOG_GPS(DBG_LOW, "Remove interval : lookup result is null");
828 static void __update_interval_table(GHashTable *interval_table, guint interval, guint prev_interval)
830 LOG_GPS(DBG_LOW, "Update interval [%u -> %u]", prev_interval, interval);
831 __remove_interval_table(interval_table, prev_interval);
832 __add_interval_table(interval_table, interval);
835 static gboolean update_pos_tracking_interval(lbs_server_interval_manipulation_type type, const gchar *client, int method, guint interval, guint prev_interval, gpointer userdata)
837 LOG_GPS(DBG_LOW, ">>> update_pos_tracking_interval");
838 if (userdata == NULL) return FALSE;
839 if (client == NULL) {
840 LOG_GPS(DBG_ERR, "client is NULL");
844 if (method != LBS_SERVER_METHOD_GPS)
847 gboolean ret_val = FALSE;
848 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
850 /* manipulate logic for dynamic-interval hash table */
852 case LBS_SERVER_INTERVAL_ADD: {
853 gchar *client_cpy = NULL;
854 client_cpy = g_strdup(client);
856 GHashTable *interval_table = (GHashTable *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client_cpy);
857 LOG_GPS(DBG_LOW, "ADD, interval[%u], client[%s], interval_table(%p)", interval, client, interval_table);
858 if (interval_table) {
859 __add_interval_table(interval_table, interval);
862 LOG_GPS(DBG_LOW, "create gps hash_table to add first key[%s]", client);
863 interval_table = g_hash_table_new(g_direct_hash, g_direct_equal);
864 g_hash_table_insert(interval_table, GUINT_TO_POINTER(interval), GUINT_TO_POINTER(1));
865 g_hash_table_insert(lbs_server->dynamic_interval_table, (gpointer) client_cpy, (gpointer) interval_table);
868 LOG_GPS(DBG_LOW, "ADD, done");
872 case LBS_SERVER_INTERVAL_REMOVE: {
873 GHashTable *interval_table = (GHashTable *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
874 LOG_GPS(DBG_LOW, "REMOVE, interval[%u, %u] , client[%s], interval_table(%p)", interval, prev_interval, client, interval_table);
875 if (interval_table) {
876 if ((interval == 0) && (prev_interval == 0)) {
877 LOG_GPS(DBG_INFO, "client[%s] removed by force.", client);
878 g_hash_table_remove_all(interval_table);
879 g_hash_table_destroy(interval_table);
880 if (g_hash_table_contains(lbs_server->dynamic_interval_table, client)) {
881 if (g_hash_table_remove(lbs_server->dynamic_interval_table, client) != TRUE)
882 LOG_GPS(DBG_LOW, "g_hash_table_remove is failed.");
886 __remove_interval_table(interval_table, interval);
889 LOG_GPS(DBG_INFO, "Client[%s] Method[%d] is already removed from interval-table", client, method);
893 if (g_hash_table_size(interval_table) == 0) {
894 LOG_GPS(DBG_LOW, "Remove client[%s] from dynamic_interval_table", client);
895 g_hash_table_destroy(interval_table);
896 if (g_hash_table_contains(lbs_server->dynamic_interval_table, client)) {
897 if (g_hash_table_remove(lbs_server->dynamic_interval_table, client) != TRUE)
898 LOG_GPS(DBG_LOW, "g_hash_table_remove is failed.");
902 LOG_GPS(DBG_LOW, "REMOVE, done.");
907 case LBS_SERVER_INTERVAL_UPDATE: {
908 GHashTable *interval_table = (GHashTable *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
909 LOG_GPS(DBG_LOW, "UPDATE, interval[%u -> %u], client[%s], interval_table(%p)", prev_interval, interval, client, interval_table);
910 if (interval_table) {
911 __update_interval_table(interval_table, interval, prev_interval);
913 LOG_GPS(DBG_LOW, "Client[%s] is not exist in interval-table", client);
916 LOG_GPS(DBG_LOW, "UPDATE, done.");
921 LOG_GPS(DBG_ERR, "unhandled interval-update type");
926 /* update logic for optimized-interval value */
927 if (g_hash_table_size(lbs_server->dynamic_interval_table) == 0) {
928 LOG_GPS(DBG_LOW, "dynamic_interval_table size is zero. It will be updated all value as 0");
929 lbs_server->is_needed_changing_interval = FALSE;
931 for (i = 0; i < LBS_SERVER_METHOD_SIZE; i++)
932 lbs_server->optimized_interval[i] = 0;
936 LOG_GPS(DBG_LOW, "update dynamic_interval_table");
937 dynamic_interval_updator_user_data updator_user_data;
938 updator_user_data.lbs_server = lbs_server;
939 updator_user_data.method = method;
941 lbs_server->temp_minimum_interval = MAX_INTERVAL;
942 g_hash_table_foreach(lbs_server->dynamic_interval_table, (GHFunc) update_dynamic_interval_table_foreach_cb, (gpointer) &updator_user_data);
944 if (lbs_server->optimized_interval[method] != lbs_server->temp_minimum_interval) {
945 LOG_GPS(DBG_INFO, "Changing method[GPS]'s optimized_interval value %u -> [ %u ]",
946 lbs_server->optimized_interval[method], lbs_server->temp_minimum_interval);
947 lbs_server->optimized_interval[method] = lbs_server->temp_minimum_interval;
949 /* need to send message to provider device */
950 LOG_GPS(DBG_LOW, "--> set needed_changing_interval");
951 lbs_server->is_needed_changing_interval = TRUE;
954 if (lbs_server->is_needed_changing_interval)
962 static void request_change_pos_update_interval(int method, gpointer userdata)
964 LOG_GPS(DBG_LOW, "ENTER >>>");
965 if (!userdata) return;
967 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
969 case LBS_SERVER_METHOD_GPS:
970 request_change_pos_update_interval_standalone_gps(lbs_server->optimized_interval[method]);
977 static void get_nmea(int *timestamp, gchar **nmea_data, gpointer userdata)
979 LOG_GPS(DBG_LOW, "ENTER >>>");
980 if (!userdata) return;
982 get_nmea_from_server(timestamp, nmea_data);
984 LOG_GPS(DBG_LOW, "timestmap: %d, nmea_data: %s", *timestamp, *nmea_data);
988 static gboolean update_batch_tracking_interval(lbs_server_interval_manipulation_type type, const gchar *client, guint interval, guint period, gpointer userdata);
989 static void start_batch_tracking(lbs_server_s *lbs_server, int batch_interval, int batch_period);
990 static void stop_batch_tracking(lbs_server_s *lbs_server, int batch_interval, int batch_period);
993 static void set_options(GVariant *options, const gchar *client, gpointer userdata)
995 LOG_GPS(DBG_LOW, "ENTER >>>");
996 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1000 GVariant *value = NULL;
1001 gboolean ret = FALSE;
1002 #ifndef _TIZEN_PUBLIC_
1003 char *msg_header = NULL;
1004 char *msg_body = NULL;
1008 char *option = NULL;
1009 char *app_id = NULL;
1011 guint prev_interval = 0;
1012 gint fused_mode = 0;
1014 lbs_server_method_e method = 0;
1016 g_variant_iter_init(&iter, options);
1017 ret = g_variant_iter_next(&iter, "{&sv}", &key, &value);
1019 LOG_GPS(DBG_ERR, "Invalid GVariant");
1022 if (!g_strcmp0(key, "CMD")) {
1023 LOG_GPS(DBG_LOW, "set_options [%s]", g_variant_get_string(value, &length));
1024 if (!g_strcmp0(g_variant_get_string(value, &length), "START")) {
1026 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1027 if (!g_strcmp0(key, "METHOD"))
1028 method = g_variant_get_int32(value);
1029 else if (!g_strcmp0(key, "INTERVAL"))
1030 interval = g_variant_get_uint32(value);
1031 else if (!g_strcmp0(key, "APP_ID"))
1032 app_id = g_variant_dup_string(value, &length);
1033 else if (!g_strcmp0(key, "FUSED_MODE"))
1034 fused_mode = g_variant_get_int32(value);
1036 LOG_GPS(DBG_LOW, "METHOD [%d], INTERVAL [%u], APP_ID [%s]", method, interval, app_id);
1039 LOG_GPS(DBG_LOW, "update_pos_tracking_interval -> START");
1040 update_pos_tracking_interval(LBS_SERVER_INTERVAL_ADD, client, method, interval, 0, lbs_server);
1044 if (LBS_SERVER_METHOD_GPS == method)
1045 gps_dump_log("START GPS", app_id);
1050 start_tracking(lbs_server, method, fused_mode);
1052 if (lbs_server->is_needed_changing_interval) {
1053 lbs_server->is_needed_changing_interval = FALSE;
1054 request_change_pos_update_interval(method, (gpointer)lbs_server);
1057 else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP")) {
1058 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1059 if (!g_strcmp0(key, "METHOD"))
1060 method = g_variant_get_int32(value);
1061 else if (!g_strcmp0(key, "INTERVAL"))
1062 interval = g_variant_get_uint32(value);
1063 else if (!g_strcmp0(key, "APP_ID"))
1064 app_id = g_variant_dup_string(value, &length);
1065 else if (!g_strcmp0(key, "FUSED_MODE"))
1066 fused_mode = g_variant_get_int32(value);
1068 LOG_GPS(DBG_LOW, "METHOD [%d], INTERVAL [%u], APP_ID [%s]", method, interval, app_id);
1071 LOG_GPS(DBG_LOW, "update_pos_tracking_interval -> STOP");
1072 update_pos_tracking_interval(LBS_SERVER_INTERVAL_REMOVE, client, method, interval, 0, lbs_server);
1076 if (LBS_SERVER_METHOD_GPS == method)
1077 gps_dump_log("STOP GPS", app_id);
1082 stop_tracking(lbs_server, method, fused_mode);
1084 if (lbs_server->is_needed_changing_interval) {
1085 lbs_server->is_needed_changing_interval = FALSE;
1086 request_change_pos_update_interval(method, (gpointer)lbs_server);
1089 #ifndef TIZEN_DEVICE
1090 else if (!g_strcmp0(g_variant_get_string(value, &length), "START_BATCH")) {
1092 gint b_interval = 0, b_period = 0;
1093 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1095 if (!g_strcmp0(key, "BATCH_INTERVAL"))
1096 b_interval = g_variant_get_int32(value);
1097 else if (!g_strcmp0(key, "BATCH_PERIOD"))
1098 b_period = g_variant_get_int32(value);
1100 LOG_GPS(DBG_LOW, "BATCH_INTERVAL [%d], BATCH_PERIOD [%d]", b_interval, b_period);
1103 update_batch_tracking_interval(LBS_SERVER_INTERVAL_ADD, client, b_interval, b_period, lbs_server);
1105 start_batch_tracking(lbs_server, lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL],
1106 lbs_server->optimized_batch_array[LBS_BATCH_PERIOD]);
1108 } else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP_BATCH")) {
1111 update_batch_tracking_interval(LBS_SERVER_INTERVAL_REMOVE, client, 0, 0, lbs_server);
1113 stop_batch_tracking(lbs_server, lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL],
1114 lbs_server->optimized_batch_array[LBS_BATCH_PERIOD]);
1118 #ifndef _TIZEN_PUBLIC_
1119 else if (!g_strcmp0(g_variant_get_string(value, &length), "SUPLNI")) {
1120 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1121 if (!g_strcmp0(key, "HEADER")) {
1122 msg_header = g_variant_dup_string(value, &length);
1123 } else if (!g_strcmp0(key, "BODY")) {
1124 size = (int) g_variant_get_size(value);
1125 msg_body = (char *) g_malloc0(sizeof(char) * size);
1126 memcpy(msg_body, g_variant_get_data(value), size);
1127 } else if (!g_strcmp0(key, "SIZE")) {
1128 size = (int) g_variant_get_int32(value);
1131 request_supl_ni_session(msg_header, msg_body, size);
1132 if (msg_header) g_free(msg_header);
1133 if (msg_body) g_free(msg_body);
1136 else if (!g_strcmp0(g_variant_get_string(value, &length), "SET:OPT")) {
1137 LOG_GPS(DBG_LOW, "SET:OPT is called");
1138 gboolean is_update_interval = FALSE, is_update_interval_method = FALSE;
1140 while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
1142 if (!g_strcmp0(key, "OPTION")) {
1143 option = g_variant_dup_string(value, &length);
1144 LOG_GPS(DBG_ERR, "option [%s]", option);
1146 if (!g_strcmp0(option, "DELGPS")) {
1147 if (request_delete_gps_data() != TRUE)
1148 LOG_GPS(DBG_ERR, "Fail to request_delete_gps_data");
1149 } else if (!g_strcmp0(option, "USE_SV")) {
1150 g_mutex_lock(&lbs_server->mutex);
1151 if (lbs_server->sv_used == FALSE)
1152 lbs_server->sv_used = TRUE;
1153 g_mutex_unlock(&lbs_server->mutex);
1154 } else if (!g_strcmp0(option, "USE_NMEA")) {
1155 if (lbs_server->nmea_used == FALSE)
1156 lbs_server->nmea_used = TRUE;
1157 } else if (!g_strcmp0(option, "UNUSE_NMEA")) {
1158 if (lbs_server->nmea_used == TRUE)
1159 lbs_server->nmea_used = FALSE;
1162 } else if (!g_strcmp0(key, "METHOD")) {
1163 method = g_variant_get_int32(value);
1164 LOG_GPS(DBG_LOW, "METHOD [%d]", method);
1165 is_update_interval_method = TRUE;
1166 } else if (!g_strcmp0(key, "INTERVAL_UPDATE")) {
1167 interval = g_variant_get_uint32(value);
1168 } else if (!g_strcmp0(key, "PREV_INTERVAL")) {
1169 prev_interval = g_variant_get_uint32(value);
1170 } else if (!g_strcmp0(key, "FUSED_MODE")) {
1171 fused_mode = g_variant_get_int32(value);
1175 LOG_GPS(DBG_LOW, "PREV_INTERVAL [%u] --> INTERVAL_UPDATE [%u], min [%u] ", prev_interval, interval, lbs_server->temp_minimum_interval);
1176 if ((interval != prev_interval) && (prev_interval > 0))
1177 is_update_interval = TRUE;
1179 if (is_update_interval && is_update_interval_method && client) {
1180 LOG_GPS(DBG_LOW, "update_pos_tracking_interval -> SET:OPT");
1181 update_pos_tracking_interval(LBS_SERVER_INTERVAL_UPDATE, client, method, interval, prev_interval, lbs_server);
1182 if (lbs_server->is_needed_changing_interval) {
1183 lbs_server->is_needed_changing_interval = FALSE;
1184 request_change_pos_update_interval(method, (gpointer)lbs_server);
1191 static gboolean gps_remove_all_clients(lbs_server_s *lbs_server)
1193 LOG_GPS(DBG_LOW, "remove_all_clients[%d] GPS", lbs_server->gps_client_count);
1194 if (lbs_server->is_mock_running == LBS_SERVER_METHOD_GPS) {
1195 mock_stop_tracking(lbs_server);
1196 setting_ignore_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb);
1199 if (lbs_server->gps_client_count <= 0) {
1200 lbs_server->gps_client_count = 0;
1204 lbs_server->gps_client_count = 0;
1205 stop_tracking(lbs_server, LBS_SERVER_METHOD_GPS, LOCATION_FUSED_NONE);
1210 static void shutdown(gpointer userdata, gboolean *shutdown_arr)
1212 LOG_GPS(DBG_LOW, "shutdown callback gps:%d nps:%d", shutdown_arr[LBS_SERVER_METHOD_GPS], shutdown_arr[LBS_SERVER_METHOD_NPS]);
1213 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1215 if (shutdown_arr[LBS_SERVER_METHOD_GPS]) {
1216 LOG_GPS(DBG_LOW, "-> shutdown GPS");
1217 if (lbs_server->is_gps_running) {
1218 if (gps_remove_all_clients(lbs_server))
1219 LOG_GPS(DBG_ERR, "<<<< Abnormal shutdown >>>>");
1223 if (shutdown_arr[LBS_SERVER_METHOD_NPS]) {
1224 LOG_NPS(DBG_LOW, "-> shutdown NPS");
1225 if (lbs_server->is_nps_running) {
1226 LOG_NPS(DBG_ERR, "lbs_server is running. nps_plugin_stop");
1227 nps_plugin_stop(lbs_server);
1231 #if 0 /* Not needed */
1233 setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
1235 if (lbs_server->loop != NULL)
1236 g_main_loop_quit(lbs_server->loop);
1238 if (vconf_notify_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb, lbs_server))
1239 LOG_NPS(DBG_ERR, "fail to notify VCONFKEY_LOCATION_NETWORK_ENABLED");
1245 static void fused_update_position_cb(fl_location *location, gpointer user_data)
1248 if (location == NULL || user_data == NULL) {
1249 LOG_FUSED(LOG_ERROR, "parameter is NULL");
1252 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1253 LbsPositionExtFields fields = (LBS_POSITION_EXT_FIELDS_LATITUDE | LBS_POSITION_EXT_FIELDS_LONGITUDE
1254 | LBS_POSITION_EXT_FIELDS_ALTITUDE | LBS_POSITION_EXT_FIELDS_SPEED | LBS_POSITION_EXT_FIELDS_DIRECTION | LBS_POSITION_EXT_FIELDS_CLIMB);
1256 GVariant *accuracy = g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED,
1257 location->accuracy.horizontal_accuracy, // TODO: or from location->sigma.of_horizontal_pos
1258 location->accuracy.vertical_accuracy); // TODO: or from location->sigma.of_altitude
1260 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_FUSED,
1261 fields, location->pos.timestamp,
1262 location->pos.latitude, location->pos.longitude, location->pos.altitude,
1263 location->vel.speed, location->vel.direction, location->vel.climb, accuracy);
1267 static void gps_update_position_cb(pos_data_t *pos, gps_error_t error, void *user_data)
1269 GVariant *accuracy = NULL;
1270 LbsPositionExtFields fields;
1272 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1274 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF)
1277 memcpy(&lbs_server->position, pos, sizeof(pos_data_t));
1279 if (lbs_server->status != LBS_STATUS_AVAILABLE) {
1280 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
1281 lbs_server->status = LBS_STATUS_AVAILABLE;
1284 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);
1286 accuracy = g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED, pos->hor_accuracy, pos->ver_accuracy);
1287 if (accuracy == NULL)
1288 LOG_GPS(DBG_LOW, "accuracy is NULL");
1290 gps_set_position(pos);
1293 send_gps_position_to_fused_engine(pos->timestamp, pos->latitude, pos->longitude, pos->altitude,
1294 pos->speed, pos->bearing, pos->hor_accuracy, pos->ver_accuracy);
1297 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, fields, pos->timestamp,
1298 pos->latitude, pos->longitude, pos->altitude, pos->speed, pos->bearing, 0.0, accuracy);
1301 static void gps_update_batch_cb(batch_data_t *batch, void *user_data)
1303 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1304 memcpy(&lbs_server->batch, batch, sizeof(batch_data_t));
1306 if (lbs_server->status != LBS_STATUS_AVAILABLE) {
1307 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
1308 lbs_server->status = LBS_STATUS_AVAILABLE;
1311 lbs_server_emit_batch_changed(lbs_server->lbs_dbus_server, batch->num_of_location);
1314 static void gps_update_satellite_cb(sv_data_t *sv, void *user_data)
1316 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1317 if (lbs_server->sv_used == FALSE)
1322 int satellite_used = 0;
1323 GVariant *used_prn = NULL;
1324 GVariant *satellite_info = NULL;
1325 GVariantBuilder *used_prn_builder = NULL;
1326 GVariantBuilder *satellite_info_builder = NULL;
1328 memcpy(&lbs_server->satellite, sv, sizeof(sv_data_t));
1329 timestamp = sv->timestamp;
1331 used_prn_builder = g_variant_builder_new(G_VARIANT_TYPE("ai"));
1332 for (index = 0; index < sv->num_of_sat; ++index) {
1333 if (sv->sat[index].used) {
1334 g_variant_builder_add(used_prn_builder, "i", sv->sat[index].prn);
1338 used_prn = g_variant_builder_end(used_prn_builder);
1340 satellite_info_builder = g_variant_builder_new(G_VARIANT_TYPE("a(iiii)"));
1341 for (index = 0; index < sv->num_of_sat; ++index) {
1342 g_variant_builder_add(satellite_info_builder, "(iiii)", sv->sat[index].prn,
1343 sv->sat[index].elevation, sv->sat[index].azimuth, sv->sat[index].snr);
1345 satellite_info = g_variant_builder_end(satellite_info_builder);
1347 lbs_server_emit_satellite_changed(lbs_server->lbs_dbus_server, timestamp, satellite_used,
1348 sv->num_of_sat, used_prn, satellite_info);
1351 static void gps_update_nmea_cb(nmea_data_t *nmea, void *user_data)
1353 lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
1355 if (lbs_server->nmea.data) {
1356 g_free(lbs_server->nmea.data);
1357 lbs_server->nmea.len = 0;
1358 lbs_server->nmea.data = NULL;
1360 lbs_server->nmea.timestamp = lbs_server->position.timestamp;
1361 lbs_server->nmea.data = g_malloc(nmea->len + 1);
1362 g_return_if_fail(lbs_server->nmea.data);
1364 g_memmove(lbs_server->nmea.data, nmea->data, nmea->len);
1365 lbs_server->nmea.data[nmea->len] = '\0';
1366 lbs_server->nmea.len = nmea->len;
1368 if (lbs_server->nmea_used == FALSE)
1371 /* LOG_GPS(DBG_LOW, "[%d] %s", lbs_server->nmea.timestamp, lbs_server->nmea.data); */
1372 lbs_server_emit_nmea_changed(lbs_server->lbs_dbus_server, lbs_server->nmea.timestamp, lbs_server->nmea.data);
1375 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)
1377 lbs_server_s *lbs_server = (lbs_server_s *)data;
1378 lbs_server_emit_gps_geofence_changed(lbs_server->lbs_dbus_server, geofence_id, transition, latitude, longitude, altitude, speed, bearing, hor_accuracy);
1382 int gps_update_geofence_service_status(int status, void *data)
1384 lbs_server_s *lbs_server = (lbs_server_s *)data;
1385 lbs_server_emit_gps_geofence_status_changed(lbs_server->lbs_dbus_server, status);
1389 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)
1391 request_add_geofence(fence_id, latitude, longitude, radius, last_state, monitor_states, notification_responsiveness, unknown_timer);
1394 static void remove_fence(gint fence_id, gpointer userdata)
1396 request_delete_geofence(fence_id);
1399 static void pause_fence(gint fence_id, gpointer userdata)
1401 request_pause_geofence(fence_id);
1404 static void resume_fence(gint fence_id, gint monitor_states, gpointer userdata)
1406 request_resume_geofence(fence_id, monitor_states);
1409 static void nps_init(lbs_server_s *lbs_server);
1411 static void lbs_server_init(lbs_server_s *lbs_server)
1413 LOG_GPS(DBG_LOW, "lbs_server_init");
1415 lbs_server->status = LBS_STATUS_UNAVAILABLE;
1416 g_mutex_init(&lbs_server->mutex);
1418 memset(&lbs_server->position, 0x00, sizeof(pos_data_t));
1419 memset(&lbs_server->satellite, 0x00, sizeof(sv_data_t));
1420 memset(&lbs_server->nmea, 0x00, sizeof(nmea_data_t));
1422 lbs_server->is_gps_running = FALSE;
1423 lbs_server->is_fused_running = FALSE;
1424 lbs_server->sv_used = FALSE;
1425 lbs_server->nmea_used = FALSE;
1426 lbs_server->gps_client_count = 0;
1427 lbs_server->fused_high_count = 0;
1428 lbs_server->fused_balanced_count = 0;
1429 lbs_server->current_location_source = LOCATION_SOURCE_NONE;
1431 nps_init(lbs_server);
1433 /* create resource for dynamic-interval */
1434 lbs_server->dynamic_interval_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
1435 lbs_server->optimized_interval = (guint *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(guint));
1436 lbs_server->is_needed_changing_interval = FALSE;
1438 /* Mock Location init */
1439 lbs_server->is_mock_running = MOCK_RUNNING_OFF;
1440 lbs_server->mock_timer = 0;
1441 lbs_server->mock_accuracy = NULL;
1443 #ifndef TIZEN_DEVICE
1444 lbs_server->batch_interval_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
1445 lbs_server->optimized_batch_array = (guint *)g_malloc0(LBS_BATCH_SIZE * sizeof(guint));
1446 lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL] = MAX_BATCH_INTERVAL;
1447 lbs_server->optimized_batch_array[LBS_BATCH_PERIOD] = MAX_BATCH_PERIOD;
1451 location_fused_init(fused_update_position_cb, lbs_server);
1455 static void nps_get_last_position(lbs_server_s *lbs_server)
1458 char location[128] = {0,};
1459 char *last_location[MAX_NPS_LOC_ITEM] = {0,};
1464 setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, ×tamp);
1465 str = setting_get_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION);
1469 snprintf(location, sizeof(location), "%s", str);
1472 last_location[index] = (char *)strtok_r(location, ";", &last);
1473 lbs_server->last_pos.timestamp = timestamp;
1475 while (last_location[index] != NULL) {
1478 lbs_server->last_pos.latitude = strtod(last_location[index], NULL);
1481 lbs_server->last_pos.longitude = strtod(last_location[index], NULL);
1484 lbs_server->last_pos.altitude = strtod(last_location[index], NULL);
1487 lbs_server->last_pos.speed = strtod(last_location[index], NULL);
1490 lbs_server->last_pos.direction = strtod(last_location[index], NULL);
1493 lbs_server->last_pos.hor_accuracy = strtod(last_location[index], NULL);
1498 if (++index == MAX_NPS_LOC_ITEM) break;
1499 last_location[index] = (char *)strtok_r(NULL, ";", &last);
1501 LOG_NPS(DBG_LOW, "[%d] %lf, %lf", lbs_server->last_pos.timestamp, lbs_server->last_pos.latitude, lbs_server->last_pos.longitude);
1504 static void nps_init(lbs_server_s *lbs_server)
1506 LOG_NPS(DBG_LOW, "nps_init");
1508 lbs_server->nps_handle = NULL;
1509 lbs_server->period = 5000;
1510 nps_set_status(lbs_server, LBS_STATUS_UNAVAILABLE);
1512 lbs_server->pos.fields = LBS_POSITION_EXT_FIELDS_NONE;
1513 lbs_server->pos.timestamp = 0;
1514 lbs_server->pos.latitude = 0.0;
1515 lbs_server->pos.longitude = 0.0;
1516 lbs_server->pos.altitude = 0.0;
1517 lbs_server->pos.acc_level = LBS_POSITION_EXT_FIELDS_NONE;
1518 lbs_server->pos.hor_accuracy = -1.0;
1519 lbs_server->pos.ver_accuracy = -1.0;
1521 lbs_server->last_pos.timestamp = 0;
1522 lbs_server->last_pos.latitude = 0.0;
1523 lbs_server->last_pos.longitude = 0.0;
1524 lbs_server->last_pos.altitude = 0.0;
1525 lbs_server->last_pos.hor_accuracy = 0.0;
1526 lbs_server->last_pos.speed = 0.0;
1527 lbs_server->last_pos.direction = 0.0;
1529 #if !GLIB_CHECK_VERSION(2, 31, 0)
1530 GMutex *mutex_temp = g_mutex_new();
1531 lbs_server->mutex = *mutex_temp;
1532 GCond *cond_temp = g_cond_new();
1533 lbs_server->cond = *cond_temp;
1536 g_mutex_init(&lbs_server->mutex);
1537 g_cond_init(&lbs_server->cond);
1539 lbs_server->is_nps_running = FALSE;
1540 lbs_server->nps_client_count = 0;
1542 if (!get_nps_plugin_module()->load()) {
1543 LOG_NPS(DBG_ERR, "lbs_server plugin load() failed.");
1547 nps_get_last_position(lbs_server);
1550 static void nps_deinit(lbs_server_s *lbs_server)
1552 LOG_NPS(DBG_LOW, "nps_deinit");
1553 if (get_nps_plugin_module()->unload()) {
1554 if (lbs_server->is_nps_running) {
1555 g_mutex_lock(&lbs_server->mutex);
1556 lbs_server->is_nps_running = FALSE;
1557 g_cond_signal(&lbs_server->cond);
1558 g_mutex_unlock(&lbs_server->mutex);
1561 if (lbs_server->token) {
1562 g_mutex_lock(&lbs_server->mutex);
1563 g_free(lbs_server->token);
1564 g_mutex_unlock(&lbs_server->mutex);
1567 LOG_NPS(DBG_ERR, "unload() failed.");
1570 lbs_server->nps_handle = NULL;
1571 lbs_server->is_nps_running = FALSE;
1572 lbs_server->nps_client_count = 0;
1574 #if !GLIB_CHECK_VERSION(2, 31, 0)
1575 g_cond_free(&lbs_server->cond);
1576 g_mutex_free(&lbs_server->mutex);
1579 g_cond_clear(&lbs_server->cond);
1580 g_mutex_clear(&lbs_server->mutex);
1582 nps_set_status(lbs_server, LBS_STATUS_UNAVAILABLE);
1585 static void _glib_log(const gchar *log_domain, GLogLevelFlags log_level,
1586 const gchar *msg, gpointer user_data)
1588 LOG_NPS(DBG_ERR, "GLIB[%d] : %s", log_level, msg);
1591 int main(int argc, char **argv)
1593 lbs_server_s *lbs_server = NULL;
1594 struct gps_callbacks g_update_cb;
1596 g_update_cb.pos_cb = gps_update_position_cb;
1597 g_update_cb.batch_cb = gps_update_batch_cb;
1598 g_update_cb.sv_cb = gps_update_satellite_cb;
1599 g_update_cb.nmea_cb = gps_update_nmea_cb;
1601 #if !GLIB_CHECK_VERSION(2, 31, 0)
1602 if (!g_thread_supported())
1603 g_thread_init(NULL);
1606 #if !GLIB_CHECK_VERSION(2, 35, 0)
1610 ret = initialize_server(argc, argv);
1612 LOG_GPS(DBG_ERR, "initialize_server failed");
1616 lbs_server = g_new0(lbs_server_s, 1);
1618 LOG_GPS(DBG_ERR, "Failed to create lbs_server_s create");
1621 lbs_server_init(lbs_server);
1624 register_update_callbacks(&g_update_cb, lbs_server);
1626 g_log_set_default_handler(_glib_log, lbs_server);
1628 /* create lbs-dbus server */
1629 lbs_server_dbus_cb_t *lbs_server_dbus_cb = g_new0(lbs_server_dbus_cb_t, 1);
1630 if (!lbs_server_dbus_cb) {
1631 LOG_GPS(DBG_ERR, "Failed to create lbs_server_dbus_cb");
1635 lbs_server_dbus_cb->set_options_cb = set_options;
1636 lbs_server_dbus_cb->shutdown_cb = shutdown;
1637 lbs_server_dbus_cb->update_interval_cb = update_pos_tracking_interval;
1638 lbs_server_dbus_cb->request_change_interval_cb = request_change_pos_update_interval;
1639 lbs_server_dbus_cb->get_nmea_cb = get_nmea;
1640 lbs_server_dbus_cb->add_hw_fence_cb = add_fence;
1641 lbs_server_dbus_cb->delete_hw_fence_cb = remove_fence;
1642 lbs_server_dbus_cb->pause_hw_fence_cb = pause_fence;
1643 lbs_server_dbus_cb->resume_hw_fence_cb = resume_fence;
1644 lbs_server_dbus_cb->set_mock_location_cb = set_mock_location_cb;
1646 ret = lbs_server_create(SERVICE_NAME, SERVICE_PATH, "lbs-server", "lbs-server",
1647 &(lbs_server->lbs_dbus_server), lbs_server_dbus_cb, (gpointer)lbs_server);
1649 if (ret != LBS_SERVER_ERROR_NONE) {
1650 LOG_GPS(DBG_ERR, "lbs_server_create failed");
1654 LOG_GPS(DBG_LOW, "lbs_server_create called");
1656 lbs_server->loop = g_main_loop_new(NULL, TRUE);
1657 g_main_loop_run(lbs_server->loop);
1659 LOG_GPS(DBG_LOW, "lbs_server deamon Stop....");
1662 location_fused_deinit();
1667 /* destroy resource for dynamic-interval */
1668 g_free(lbs_server->optimized_interval);
1669 g_hash_table_destroy(lbs_server->dynamic_interval_table);
1670 #ifndef TIZEN_DEVICE
1671 g_free(lbs_server->optimized_batch_array);
1672 g_hash_table_destroy(lbs_server->batch_interval_table);
1674 /* free dbus callback */
1675 g_free(lbs_server_dbus_cb);
1677 /* destroy lbs-dbus server */
1678 lbs_server_destroy(lbs_server->lbs_dbus_server);
1679 LOG_GPS(DBG_LOW, "lbs_server_destroy called");
1681 g_main_loop_unref(lbs_server->loop);
1683 nps_deinit(lbs_server);
1686 deinitialize_server();
1694 static void set_mock_location_cb(gint method, gdouble latitude, gdouble longitude, gdouble altitude,
1695 gdouble speed, gdouble direction, gdouble accuracy, gpointer userdata)
1697 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1700 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1703 LOG_SEC("[set_mock_location] lat = %lf, lng = %lf", latitude, longitude);
1704 memset(&g_mock_position, 0x00, sizeof(NpsManagerPositionExt));
1705 if (latitude == MOCK_LOCATION_CLEAR_VALUE) {
1706 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF) {
1707 g_mutex_lock(&lbs_server->mutex);
1708 lbs_server->is_mock_running = MOCK_RUNNING_OFF;
1709 g_mutex_unlock(&lbs_server->mutex);
1711 mock_stop_tracking(lbs_server);
1712 setting_ignore_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb);
1713 g_mock_position.timestamp = 0;
1720 g_mock_position.fields |= LBS_POSITION_EXT_FIELDS_DIRTY;
1721 g_mock_position.timestamp = timestamp;
1722 g_mock_position.latitude = latitude;
1723 g_mock_position.longitude = longitude;
1724 g_mock_position.altitude = altitude;
1725 g_mock_position.speed = speed;
1726 g_mock_position.direction = direction;
1727 g_mock_position.acc_level = LBS_ACCURACY_LEVEL_DETAILED;
1728 g_mock_position.hor_accuracy = accuracy;
1729 g_mock_position.ver_accuracy = -1;
1731 if (lbs_server->is_mock_running == MOCK_RUNNING_OFF) {
1732 g_mutex_lock(&lbs_server->mutex);
1733 lbs_server->is_mock_running = method;
1734 g_mutex_unlock(&lbs_server->mutex);
1737 if (lbs_server->is_gps_running || lbs_server->is_nps_running)
1738 mock_start_tracking(lbs_server);
1740 gps_set_last_mock(timestamp, latitude, longitude, altitude, speed, direction, accuracy);
1743 int __copy_mock_location(lbs_server_s *lbs_server)
1746 LOG_MOCK(DBG_ERR, "lbs_server is NULL!!");
1750 memset(&lbs_server->mock_pos, 0x00, sizeof(NpsManagerPositionExt));
1751 memcpy(&lbs_server->mock_pos, &g_mock_position, sizeof(NpsManagerPositionExt));
1752 g_mock_position.fields = LBS_POSITION_EXT_FIELDS_NONE;
1753 LOG_SEC("[%d] lat = %lf, lng = %lf", lbs_server->mock_pos.timestamp, lbs_server->mock_pos.latitude, lbs_server->mock_pos.longitude);
1755 if (lbs_server->mock_pos.latitude >= -90 && lbs_server->mock_pos.latitude <= 90)
1756 lbs_server->mock_pos.fields |= LBS_POSITION_EXT_FIELDS_LATITUDE;
1758 if (lbs_server->mock_pos.longitude >= -180 && lbs_server->mock_pos.longitude <= 180)
1759 lbs_server->mock_pos.fields |= LBS_POSITION_EXT_FIELDS_LONGITUDE;
1761 lbs_server->mock_pos.fields |= LBS_POSITION_EXT_FIELDS_ALTITUDE;
1763 if (lbs_server->mock_pos.speed >= 0)
1764 lbs_server->mock_pos.fields |= LBS_POSITION_EXT_FIELDS_SPEED;
1766 if (lbs_server->mock_pos.direction >= 0 && lbs_server->mock_pos.direction <= 360)
1767 lbs_server->mock_pos.fields |= LBS_POSITION_EXT_FIELDS_DIRECTION;
1769 lbs_server->mock_accuracy = g_variant_ref_sink(g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED, lbs_server->mock_pos.hor_accuracy, -1));
1774 static gboolean __mock_position_update_cb(gpointer userdata)
1776 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1779 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1783 if (g_mock_position.timestamp) {
1784 if (g_mock_position.fields & LBS_POSITION_EXT_FIELDS_DIRTY)
1785 __copy_mock_location(lbs_server);
1790 LOG_SEC("[%d] lat = %lf, lng = %lf", lbs_server->mock_pos.timestamp, lbs_server->mock_pos.latitude, lbs_server->mock_pos.longitude);
1792 lbs_server->mock_pos.timestamp = timestamp;
1793 lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_MOCK,
1794 lbs_server->mock_pos.fields, lbs_server->mock_pos.timestamp,
1795 lbs_server->mock_pos.latitude, lbs_server->mock_pos.longitude, lbs_server->mock_pos.altitude,
1796 lbs_server->mock_pos.speed, lbs_server->mock_pos.direction, 0.0, lbs_server->mock_accuracy);
1802 static void mock_start_tracking(lbs_server_s *lbs_server)
1804 LOG_MOCK(DBG_LOW, "ENTER >>> mock_start_tracking");
1806 LOG_MOCK(DBG_ERR, "lbs_server is NULL!!");
1810 __copy_mock_location(lbs_server);
1812 if (!lbs_server->mock_timer) {
1813 lbs_server->mock_timer = g_timeout_add_seconds(1, __mock_position_update_cb, lbs_server);
1814 setting_notify_key_changed(VCONFKEY_LOCATION_MOCK_ENABLED, __setting_mock_cb, lbs_server);
1818 static void mock_stop_tracking(lbs_server_s *lbs_server)
1820 LOG_MOCK(DBG_LOW, ">>> mock_stop_tracking");
1822 LOG_MOCK(DBG_ERR, "lbs-server is NULL!!");
1826 if (lbs_server->mock_timer)
1827 g_source_remove(lbs_server->mock_timer);
1829 lbs_server->mock_timer = 0;
1830 if (lbs_server->mock_accuracy)
1831 g_variant_unref(lbs_server->mock_accuracy);
1833 if (lbs_server->is_mock_running != MOCK_RUNNING_OFF) {
1834 g_mutex_lock(&lbs_server->mutex);
1835 lbs_server->is_mock_running = MOCK_RUNNING_OFF;
1836 g_mutex_unlock(&lbs_server->mutex);
1840 static void client_count_updater(lbs_server_s *lbs_server, lbs_server_method_e method, lbs_client_count type, gint fused_mode)
1842 if (lbs_server == NULL) return;
1845 case LBS_SERVER_METHOD_GPS: {
1846 g_mutex_lock(&lbs_server->mutex);
1847 if (type == _LBS_CLIENT_ADD)
1848 lbs_server->gps_client_count++;
1849 else if (type == _LBS_CLIENT_REMOVE)
1850 lbs_server->gps_client_count--;
1851 else if (type == _LBS_CLIENT_REMOVE_ALL)
1852 lbs_server->gps_client_count = 0;
1854 g_mutex_unlock(&lbs_server->mutex);
1857 case LBS_SERVER_METHOD_NPS: {
1858 g_mutex_lock(&lbs_server->mutex);
1859 if (type == _LBS_CLIENT_ADD)
1860 lbs_server->nps_client_count++;
1861 else if (type == _LBS_CLIENT_REMOVE)
1862 lbs_server->nps_client_count--;
1863 else if (type == _LBS_CLIENT_REMOVE_ALL)
1864 lbs_server->nps_client_count = 0;
1866 g_mutex_unlock(&lbs_server->mutex);
1870 LOG_GPS(DBG_ERR, "Invalid method");
1875 if (type == _LBS_CLIENT_ADD) {
1876 if (fused_mode == LOCATION_FUSED_HIGH)
1877 lbs_server->fused_high_count++;
1878 else if (fused_mode == LOCATION_FUSED_BALANCED)
1879 lbs_server->fused_balanced_count++;
1880 } else if (type == _LBS_CLIENT_REMOVE) {
1881 if (fused_mode == LOCATION_FUSED_HIGH)
1882 lbs_server->fused_high_count--;
1883 else if (fused_mode == LOCATION_FUSED_BALANCED)
1884 lbs_server->fused_balanced_count--;
1885 } else if (type == _LBS_CLIENT_REMOVE_ALL) {
1886 lbs_server->fused_high_count = 0;
1887 lbs_server->fused_balanced_count = 0;
1890 if (lbs_server->fused_high_count < 0) {
1891 LOG_GPS(DBG_ERR, "---- fused_high count is negative value");
1892 lbs_server->fused_high_count = 0;
1895 if (lbs_server->fused_balanced_count < 0) {
1896 LOG_GPS(DBG_ERR, "---- fused_balanced count is negative value");
1897 lbs_server->fused_balanced_count = 0;
1902 #ifndef TIZEN_DEVICE
1903 static void start_batch_tracking(lbs_server_s *lbs_server, int batch_interval, int batch_period)
1905 LOG_GPS(DBG_LOW, "start batch tracking");
1906 client_count_updater(lbs_server, LBS_SERVER_METHOD_GPS, _LBS_CLIENT_ADD, LOCATION_FUSED_NONE);
1908 if (lbs_server->is_gps_running == FALSE) {
1909 LOG_GPS(DBG_LOW, "Batch: start tracking GPS");
1910 lbs_server->status = LBS_STATUS_ACQUIRING;
1913 if (request_start_batch_session(batch_interval, batch_period) == TRUE) {
1914 g_mutex_lock(&lbs_server->mutex);
1915 lbs_server->is_gps_running = TRUE;
1916 g_mutex_unlock(&lbs_server->mutex);
1918 setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
1920 LOG_GPS(DBG_ERR, "Batch: Fail to request_start_batch_session");
1924 static void stop_batch_tracking(lbs_server_s *lbs_server, int batch_interval, int batch_period)
1926 LOG_GPS(DBG_LOW, "Batch: stop_tracking GPS");
1927 client_count_updater(lbs_server, LBS_SERVER_METHOD_GPS, _LBS_CLIENT_REMOVE, LOCATION_FUSED_NONE);
1929 if (lbs_server->is_gps_running == FALSE) {
1930 LOG_GPS(DBG_LOW, "Batch: gps- is already stopped");
1934 int session_status = 1; /* Keep current status */
1935 if (lbs_server->gps_client_count <= 0) {
1936 g_mutex_lock(&lbs_server->mutex);
1937 lbs_server->gps_client_count = 0;
1938 g_mutex_unlock(&lbs_server->mutex);
1939 session_status = 0; /* stop */
1942 /* TRUE: All clients stopped, FALSE: Some clients are running with GPS or BATCH */
1943 if (request_stop_batch_session(batch_interval, batch_period, session_status) == TRUE) {
1944 g_mutex_lock(&lbs_server->mutex);
1945 lbs_server->is_gps_running = FALSE;
1946 lbs_server->sv_used = FALSE;
1947 g_mutex_unlock(&lbs_server->mutex);
1949 setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
1952 lbs_server->status = LBS_STATUS_UNAVAILABLE;
1953 lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_UNAVAILABLE);
1956 static void update_batch_interval_table_foreach_cb(gpointer key, gpointer value, gpointer userdata)
1958 guint *interval_array = (guint *)value;
1959 dynamic_interval_updator_user_data *updator_ud = (dynamic_interval_updator_user_data *)userdata;
1960 lbs_server_s *lbs_server = updator_ud->lbs_server;
1962 if (lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL] > interval_array[LBS_BATCH_INTERVAL])
1963 lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL] = interval_array[LBS_BATCH_INTERVAL];
1965 if (lbs_server->optimized_batch_array[LBS_BATCH_PERIOD] > interval_array[LBS_BATCH_PERIOD])
1966 lbs_server->optimized_batch_array[LBS_BATCH_PERIOD] = interval_array[LBS_BATCH_PERIOD];
1968 LOG_GPS(DBG_LOW, "foreach dynamic-batch. key:[%s]-batch[interval:%u, period:%u], optimized [%u, %u]", (char *)key, interval_array[LBS_BATCH_INTERVAL], interval_array[LBS_BATCH_PERIOD], lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL], lbs_server->optimized_batch_array[LBS_BATCH_PERIOD]);
1971 static gboolean update_batch_tracking_interval(lbs_server_interval_manipulation_type type, const gchar *client, guint interval, guint period, gpointer userdata)
1973 LOG_GPS(DBG_INFO, "update_batch_tracking_interval");
1974 if (userdata == NULL) return FALSE;
1975 if (client == NULL) {
1976 LOG_GPS(DBG_ERR, "client is NULL");
1980 lbs_server_s *lbs_server = (lbs_server_s *)userdata;
1983 case LBS_SERVER_INTERVAL_ADD: {
1984 LOG_GPS(DBG_LOW, "ADD, client[%s], interval[%u], period[%u]", client, interval, period);
1985 gchar *client_cpy = NULL;
1986 client_cpy = g_strdup(client);
1988 guint* interval_array = (guint *) g_hash_table_lookup(lbs_server->batch_interval_table, client_cpy);
1989 if (!interval_array) {
1990 LOG_GPS(DBG_LOW, "first add key[%s] to batch-table", client);
1991 interval_array = (guint *)g_malloc0(LBS_BATCH_SIZE * sizeof(guint));
1992 if (!interval_array) {
1993 LOG_GPS(DBG_ERR, "interval_array is NULL");
1997 g_hash_table_insert(lbs_server->batch_interval_table, (gpointer)client_cpy, (gpointer)interval_array);
1999 interval_array[LBS_BATCH_INTERVAL] = interval;
2000 interval_array[LBS_BATCH_PERIOD] = period;
2004 case LBS_SERVER_INTERVAL_REMOVE: {
2005 LOG_GPS(DBG_LOW, "REMOVE, client[%s]", client);
2006 guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->batch_interval_table, client);
2007 if (!interval_array) {
2008 LOG_GPS(DBG_INFO, "Client[%s] is already removed from batch-table", client);
2011 LOG_GPS(DBG_LOW, "Remove interval_array(%p):[%u, %u] from batch-table", interval_array, interval_array[LBS_BATCH_INTERVAL], interval_array[LBS_BATCH_PERIOD]);
2013 if (!g_hash_table_remove(lbs_server->batch_interval_table, client))
2014 LOG_GPS(DBG_ERR, "g_hash_table_remove is failed.");
2020 LOG_GPS(DBG_ERR, "unhandled interval-update type");
2025 lbs_server->optimized_batch_array[LBS_BATCH_INTERVAL] = MAX_BATCH_INTERVAL + 1;
2026 lbs_server->optimized_batch_array[LBS_BATCH_PERIOD] = MAX_BATCH_PERIOD + 1;
2028 if (g_hash_table_size(lbs_server->batch_interval_table) == 0) {
2031 LOG_GPS(DBG_LOW, "updates optimized-batch-interval.");
2032 dynamic_interval_updator_user_data updator_user_data;
2033 updator_user_data.lbs_server = lbs_server;
2035 g_hash_table_foreach(lbs_server->batch_interval_table,
2036 (GHFunc) update_batch_interval_table_foreach_cb, (gpointer) &updator_user_data);
2038 LOG_GPS(DBG_LOW, "Updates_batch_tracking_interval done.");