tizen beta release
[framework/location/gps-manager.git] / gps-manager / server.c
1 /*
2  * gps-manager
3  *
4  * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  */
21
22 #include <stdio.h>
23 #include <signal.h>
24 #include <stdlib.h>
25
26 #include <unistd.h>
27 #include <sys/types.h>
28 #include <sys/wait.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <pthread.h>
32 #include <string.h>
33
34 #include "server.h"
35 #include "gps_manager_data_types.h"
36 #include "gps_manager_plugin_intf.h"
37 #include "nmea_logger.h"
38 #include "data_connection.h"
39 #include "setting.h"
40 #include "plugin_module.h"
41 #include "debug_util.h"
42 #include "last_position.h"
43
44 #include <MapiControl.h>
45 #include <MapiTransport.h>
46 #include <MapiMessage.h>
47 #include <sysman.h>
48
49 #include <vconf.h>
50 #include <vconf-keys.h>
51 #include <pmapi.h>
52 #include <dlog.h>
53 #include <heynoti.h>
54
55 #include <glib.h>
56 #include <glib-object.h>
57 #include <glib/gthread.h>
58 #include <dbus/dbus-glib.h>
59
60 #define GPS_NI_POPUP            "/usr/bin/gps_popup"
61 #define GPS_NI_BTN              "BTN"
62 #define GPS_NI_WITHOUT_BTN      "NONE"
63 #define YES_EXIT_STATUS         174
64 #define NO_EXIT_STATUS          175
65
66 #define REPLAY_MODULE           "replay"
67
68 typedef struct {
69         void *handle;
70         char *name;
71 } gps_plugin_handler_t;
72
73 gps_plugin_handler_t g_gps_plugin;
74 gps_server_param_t g_gps_params;
75
76 pos_data_t *gps_pos_data = NULL;
77 sv_data_t *gps_sv_data = NULL;
78 nmea_data_t *gps_nmea_data = NULL;
79 last_pos_t *gps_last_pos = NULL;
80
81 int g_dnet_used = 0;
82
83 gboolean logging_enabled = FALSE;
84 gboolean replay_enabled = FALSE;
85
86 static pthread_t msg_thread = 0;        /* Register SUPL NI cb to msg server Thread */
87 static pthread_t popup_thread = 0;      /* Register SUPL NI cb to msg server Thread */
88 static int msg_thread_status;
89
90 gps_session_state_t gps_session_state = GPS_SESSION_STOPPED;
91
92 struct gps_callbacks g_update_cb;
93 void *g_user_data;
94
95 static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info);
96
97 static void _gps_mode_changed_cb(keynode_t * key, void *data)
98 {
99         int int_val;
100
101         if (setting_get_int(GPS_SESSION, &int_val) == FALSE) {
102                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_SESSION setting get failed");
103                 int_val = GPS_SESSION_TRACKING_MODE;
104         }
105         g_gps_params.session_type = int_val;
106
107         if (setting_get_int(GPS_OPERATION, &int_val) == FALSE) {
108                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_OPERATION setting get failed");
109                 int_val = GPS_OPERATION_STANDALONE;
110         }
111         g_gps_params.operation_mode = int_val;
112
113         if (setting_get_int(GPS_STARTING, &int_val) == FALSE) {
114                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_STARTING setting get failed");
115                 int_val = GPS_STARTING_HOT_;
116         }
117         g_gps_params.starting_type = int_val;
118
119         return;
120 }
121
122 static void _gps_supl_changed_cb(keynode_t * key, void *data)
123 {
124         int int_val;
125         char *str;
126
127         str = setting_get_string(SUPL_SERVER);
128
129         if (str == NULL) {
130                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", SUPL_SERVER_URL_DEFAULT);
131                 LOG_GPS(DBG_ERR, "vconf fail to get Server URL [Default URL]");
132         } else {
133                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", str);
134         }
135
136         if (setting_get_int(SUPL_PORT, &int_val) == FALSE) {
137                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_PORT setting get failed");
138                 int_val = SUPL_SERVER_PORT_DEFAULT;
139         }
140         g_gps_params.supl_port = int_val;
141
142         return;
143 }
144
145 static void _gps_setting_changed_cb(keynode_t * key, void *data)
146 {
147         int int_val;
148
149         if (setting_get_int(SUPL_SSL, &int_val) == FALSE) {
150                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_SSL setting get failed");
151                 int_val = 0;
152         }
153         g_gps_params.ssl_mode = int_val;
154         return;
155 }
156
157 static void _gps_nmea_changed_cb(keynode_t * key, void *data)
158 {
159         int int_val;
160         if (setting_get_int(NMEA_LOGGING, &int_val) == FALSE) {
161                 LOG_GPS(DBG_ERR, "NMEA_LOGGING get Failed.");
162                 int_val = 0;
163         }
164         logging_enabled = (int_val == 1) ? TRUE : FALSE;
165         return;
166 }
167
168 static gboolean get_replay_enabled()
169 {
170         int int_val;
171         gboolean ret;
172
173         if (setting_get_int(REPLAY_ENABLED, &int_val) == FALSE) {
174                 LOG_GPS(DBG_ERR, "REPLAY_ENABLED get Failed.");
175                 int_val = 0;
176         }
177
178         ret = (int_val == 1) ? TRUE : FALSE;
179
180         return ret;
181 }
182
183 static void reload_plugin_module()
184 {
185         char *module_name;
186         gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL;
187
188         if (replay_enabled == TRUE) {
189                 module_name = REPLAY_MODULE;
190         } else {
191                 module_name = g_gps_plugin.name;
192         }
193
194         LOG_GPS(DBG_LOW, "Loading plugin.name : %s", module_name);
195
196         if (!get_plugin_module()->deinit(&ReasonCode)) {
197                 LOG_GPS(DBG_ERR, "Fail to GPS plugin deinit");
198         } else {
199                 unload_plugin_module(&g_gps_plugin.handle);
200                 if (!load_plugin_module(module_name, &g_gps_plugin.handle)) {
201                         LOG_GPS(DBG_ERR, "Fail to load %s plugin", module_name);
202                 } else {
203                         if (!get_plugin_module()->init(_gps_server_gps_event_cb, &g_gps_params)) {
204                                 LOG_GPS(DBG_ERR, "Fail to %s plugin init", module_name);
205                                 return;
206                         }
207                 }
208         }
209 }
210
211 static void _gps_replay_changed_cb(keynode_t * key, void *data)
212 {
213
214         replay_enabled = get_replay_enabled();
215         reload_plugin_module();
216
217         return;
218 }
219
220 static void _gps_server_set_indicator(int gps_state)
221 {
222         int ret;
223         int wps_state = 0;
224
225         setting_get_int(VCONFKEY_WPS_STATE, &wps_state);
226         LOG_GPS(DBG_LOW, "gps state : [%d], wps state : [%d]", gps_state, wps_state);
227
228         if (gps_state == POSITION_CONNECTED || wps_state == POSITION_CONNECTED) {
229                 ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_CONNECTED);
230         } else {
231                 if (gps_state == POSITION_OFF && wps_state == POSITION_OFF) {
232                         ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_OFF);
233                 } else {
234                         ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_SEARCHING);
235                 }
236         }
237
238         if (ret == 1) {
239                 LOG_GPS(DBG_LOW, "Succesee to set indicator");
240         } else {
241                 LOG_GPS(DBG_ERR, "Fail to setting_set_int(VCONF_GPS_STATE, ...)");
242         }
243 }
244
245 static gboolean _initialize_data()
246 {
247         gboolean result = TRUE;
248         if (gps_pos_data == NULL) {
249                 gps_pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
250                 if (gps_pos_data == NULL) {
251                         LOG_GPS(DBG_ERR, "Failed to alloc gps_pos_data");
252                         result = FALSE;
253                 } else {
254                         memset(gps_pos_data, 0x00, sizeof(pos_data_t));
255                 }
256         }
257
258         if (gps_sv_data == NULL) {
259                 gps_sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
260                 if (gps_sv_data == NULL) {
261                         LOG_GPS(DBG_ERR, "Failed to alloc gps_sv_data");
262                         result = FALSE;
263                 } else {
264                         memset(gps_sv_data, 0x00, sizeof(sv_data_t));
265                 }
266         }
267
268         if (gps_nmea_data == NULL) {
269                 gps_nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
270                 if (gps_nmea_data == NULL) {
271                         LOG_GPS(DBG_ERR, "Failed to alloc gps_nmea_data");
272                         result = FALSE;
273                 } else {
274                         memset(gps_nmea_data, 0x00, sizeof(nmea_data_t));
275                 }
276         }
277
278         if (gps_last_pos == NULL) {
279                 gps_last_pos = (last_pos_t *) malloc(sizeof(last_pos_t));
280                 if (gps_last_pos == NULL) {
281                         LOG_GPS(DBG_ERR, "Failed to alloc gps_last_pos");
282                         result = FALSE;
283                 } else {
284                         memset(gps_last_pos, 0x00, sizeof(last_pos_t));
285                 }
286         }
287         return result;
288 }
289
290 int request_start_session()
291 {
292         int status = TRUE;
293         gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
294
295         if (gps_session_state != GPS_SESSION_STOPPED && gps_session_state != GPS_SESSION_STOPPING) {
296                 LOG_GPS(DBG_LOW, "Main: GPS Session Already Started!");
297                 return TRUE;
298         }
299
300         status = get_plugin_module()->request(GPS_ACTION_START_SESSION, &g_gps_params, &reason_code);
301
302         if (status == FALSE) {
303                 LOG_GPS(DBG_ERR, "Main: sending GPS_ACTION_START_SESSION Fail !");
304                 return FALSE;
305         }
306
307         LOG_GPS(DBG_LOW, "Main: sending GPS_ACTION_START_SESSION OK !");
308         _initialize_data();
309
310         gps_session_state = GPS_SESSION_STARTING;
311         LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state);
312         setting_ignore_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
313
314         return TRUE;
315 }
316
317 int request_stop_session()
318 {
319         unsigned int status = TRUE;
320         gboolean cur_replay_enabled = FALSE;
321         gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
322
323         LOG_GPS(DBG_LOW, "Main: Stop GPS Session, ==GPSSessionState[%d]", gps_session_state);
324         if (gps_session_state == GPS_SESSION_STARTED || gps_session_state == GPS_SESSION_STARTING) {
325                 status = get_plugin_module()->request(GPS_ACTION_STOP_SESSION, NULL, &reason_code);
326                 if (status) {
327                         gps_session_state = GPS_SESSION_STOPPING;
328                         LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state);
329                         cur_replay_enabled = get_replay_enabled();
330                         if (replay_enabled != cur_replay_enabled) {
331                                 replay_enabled = cur_replay_enabled;
332                                 reload_plugin_module();
333                         }
334                         setting_notify_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
335                 } else {
336                         LOG_GPS(DBG_LOW, "  plugin->request to LBS_GPS_STOP_SESSION Failed, reasonCode =%d", reason_code);
337                 }
338         } else {
339                 // If request is not sent, keep the client registed
340                 LOG_GPS(DBG_LOW,
341                         " LBS_GPS_STOP_SESSION is not sent because the GPS state is not started, keep the client registed ");
342         }
343         return status;
344 }
345
346 static void _gps_plugin_handler_init(char *module_name)
347 {
348         g_gps_plugin.handle = NULL;
349         g_gps_plugin.name = (char *)malloc(strlen(module_name) + 1);
350         snprintf(g_gps_plugin.name, strlen(module_name) + 1, "%s", module_name);
351 }
352
353 static void _gps_plugin_handler_deinit()
354 {
355         if (g_gps_plugin.handle != NULL) {
356                 g_gps_plugin.handle = NULL;
357         }
358
359         if (g_gps_plugin.name != NULL) {
360                 free(g_gps_plugin.name);
361                 g_gps_plugin.name = NULL;
362         }
363 }
364
365 static void _gps_read_params()
366 {
367         int int_val = 0;
368         char *str;
369
370         if (setting_get_int(GPS_SESSION, &int_val) == FALSE) {
371                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_SESSION setting get failed");
372                 int_val = GPS_SESSION_TRACKING_MODE;    //set to default
373         }
374         g_gps_params.session_type = int_val;
375
376         if (setting_get_int(GPS_OPERATION, &int_val) == FALSE) {
377                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_OPERATION setting get failed");
378                 int_val = GPS_OPERATION_STANDALONE;     //set to default
379         }
380         g_gps_params.operation_mode = int_val;
381
382         if (setting_get_int(GPS_STARTING, &int_val) == FALSE) {
383                 LOG_GPS(DBG_ERR, "//ERROR!! TING_MODE setting get failed");
384                 int_val = GPS_STARTING_HOT_;
385         }
386         g_gps_params.starting_type = int_val;
387
388         g_gps_params.time_bn_fixes = 1;
389
390         str = setting_get_string(SUPL_SERVER);
391         if (str == NULL) {
392                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", SUPL_SERVER_URL_DEFAULT);
393                 LOG_GPS(DBG_ERR, "vconf fail to get Server URL [Default URL]");
394         } else {
395                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", str);
396         }
397
398         if (setting_get_int(SUPL_PORT, &int_val) == FALSE) {
399                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_PORT setting get failed");
400                 int_val = SUPL_SERVER_PORT_DEFAULT;
401         }
402         g_gps_params.supl_port = int_val;
403
404         LOG_GPS(DBG_LOW, "First Read!! SUPL server:%s, port:%d", g_gps_params.supl_url, g_gps_params.supl_port);
405
406         if (setting_get_int(SUPL_SSL, &int_val) == FALSE) {
407                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_SSL setting get failed");
408                 int_val = 0;
409         }
410         g_gps_params.ssl_mode = int_val;
411
412         if (setting_get_int(NMEA_LOGGING, &int_val) == FALSE) {
413                 LOG_GPS(DBG_ERR, "//NMEA_LOGGING get Failed.");
414                 int_val = 0;
415         }
416         logging_enabled = (int_val == 1) ? TRUE : FALSE;
417
418         if (setting_get_int(REPLAY_ENABLED, &int_val) == FALSE) {
419                 LOG_GPS(DBG_ERR, "//REPLAY_ENABLED get Failed.");
420                 int_val = 0;
421         }
422         replay_enabled = (int_val == 1) ? TRUE : FALSE;
423 }
424
425 static void _gps_notify_params()
426 {
427         setting_notify_key_changed(GPS_SESSION, _gps_mode_changed_cb);
428         setting_notify_key_changed(GPS_OPERATION, _gps_mode_changed_cb);
429         setting_notify_key_changed(GPS_STARTING, _gps_mode_changed_cb);
430         setting_notify_key_changed(SUPL_SERVER, _gps_supl_changed_cb);
431         setting_notify_key_changed(SUPL_PORT, _gps_supl_changed_cb);
432         setting_notify_key_changed(SUPL_SSL, _gps_setting_changed_cb);
433         setting_notify_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb);
434         setting_notify_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
435 }
436
437 static void _gps_ignore_params()
438 {
439         setting_ignore_key_changed(GPS_SESSION, _gps_mode_changed_cb);
440         setting_ignore_key_changed(GPS_OPERATION, _gps_mode_changed_cb);
441         setting_ignore_key_changed(GPS_STARTING, _gps_mode_changed_cb);
442         setting_ignore_key_changed(SUPL_SERVER, _gps_supl_changed_cb);
443         setting_ignore_key_changed(SUPL_PORT, _gps_supl_changed_cb);
444         setting_ignore_key_changed(SUPL_SSL, _gps_setting_changed_cb);
445         setting_ignore_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb);
446         setting_ignore_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
447 }
448
449 static void _gps_server_start_event()
450 {
451         LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STARTED);
452         gps_session_state = GPS_SESSION_STARTED;
453
454         if (logging_enabled) {
455                 start_nmea_log();
456         }
457
458         if (gps_pos_data == NULL) {
459                 gps_pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
460                 if (gps_pos_data == NULL) {
461                         LOG_GPS(DBG_WARN, "//callback: gps_pos_data re-malloc Failed!!");
462                 } else {
463                         memset(gps_pos_data, 0x00, sizeof(pos_data_t));
464                 }
465         }
466         if (gps_sv_data == NULL) {
467                 gps_sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
468                 if (gps_sv_data == NULL) {
469                         LOG_GPS(DBG_WARN, "//callback: gps_sv_data re-malloc Failed!!");
470                 } else {
471                         memset(gps_sv_data, 0x00, sizeof(sv_data_t));
472                 }
473         }
474         if (gps_nmea_data == NULL) {
475                 gps_nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
476                 if (gps_nmea_data == NULL) {
477                         LOG_GPS(DBG_WARN, "//callback: gps_nmea_data re-malloc Failed!!");
478                 } else {
479                         memset(gps_nmea_data, 0x00, sizeof(nmea_data_t));
480                 }
481         }
482
483         if (gps_last_pos == NULL) {
484                 gps_last_pos = (last_pos_t *) malloc(sizeof(last_pos_t));
485                 if (gps_last_pos == NULL) {
486                         LOG_GPS(DBG_WARN, "//callback: gps_last_pos re-malloc Failed!!");
487                 } else {
488                         memset(gps_last_pos, 0x00, sizeof(last_pos_t));
489                         gps_manager_get_last_position(gps_last_pos);
490                 }
491         }
492
493         _gps_server_set_indicator(POSITION_SEARCHING);
494         pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
495 }
496
497 static void _gps_server_stop_event()
498 {
499         LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STOPPED);
500         gps_session_state = GPS_SESSION_STOPPED;
501         LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state);
502
503         _gps_server_set_indicator(POSITION_OFF);
504         pm_unlock_state(LCD_NORMAL, PM_RESET_TIMER);
505
506         if (logging_enabled) {
507                 stop_nmea_log();
508         }
509
510         if (gps_pos_data != NULL) {
511                 free(gps_pos_data);
512                 gps_pos_data = NULL;
513         }
514         if (gps_sv_data != NULL) {
515                 free(gps_sv_data);
516                 gps_sv_data = NULL;
517         }
518         if (gps_nmea_data != NULL) {
519                 free(gps_nmea_data);
520                 gps_nmea_data = NULL;
521         }
522         if (gps_last_pos != NULL) {
523                 free(gps_last_pos);
524                 gps_last_pos = NULL;
525         }
526 }
527
528 static void _report_pos_event(gps_event_info_t * gps_event)
529 {
530         if (gps_pos_data != NULL) {
531                 memcpy(gps_pos_data, &(gps_event->event_data.pos_ind.pos), sizeof(pos_data_t));
532                 g_update_cb.pos_cb(gps_pos_data, gps_event->event_data.pos_ind.error, g_user_data);
533                 if (gps_manager_distance_to_last_position(gps_pos_data, gps_last_pos) != -1) {
534                         gps_manager_update_last_position(gps_pos_data, gps_last_pos);
535                 }
536                 memset(gps_pos_data, 0x00, sizeof(pos_data_t));
537         } else {
538                 LOG_GPS(DBG_ERR, "gps_sv_data is NULL");
539         }
540 }
541
542 static void _report_sv_event(gps_event_info_t * gps_event)
543 {
544         if (gps_sv_data != NULL) {
545                 memcpy(gps_sv_data, &(gps_event->event_data.sv_ind.sv), sizeof(sv_data_t));
546                 g_update_cb.sv_cb(gps_sv_data, g_user_data);
547                 memset(gps_sv_data, 0x00, sizeof(sv_data_t));
548         } else {
549                 LOG_GPS(DBG_ERR, "gps_sv_data is NULL");
550         }
551 }
552
553 static void _report_nmea_event(gps_event_info_t * gps_event)
554 {
555         if (gps_nmea_data == NULL) {
556                 LOG_GPS(DBG_ERR, "gps_nmea_data is NULL");
557                 return;
558         }
559
560         gps_nmea_data->len = gps_event->event_data.nmea_ind.nmea.len;
561         LOG_GPS(DBG_LOW, "gps_nmea_data->len : [%d]", gps_nmea_data->len);
562         gps_nmea_data->data = (char *)malloc(gps_nmea_data->len);
563         memset(gps_nmea_data->data, 0x00, gps_nmea_data->len);
564         memcpy(gps_nmea_data->data, gps_event->event_data.nmea_ind.nmea.data, gps_nmea_data->len);
565         g_update_cb.nmea_cb(gps_nmea_data, g_user_data);
566         free(gps_nmea_data->data);
567         memset(gps_nmea_data, 0x00, sizeof(nmea_data_t));
568
569         if (logging_enabled) {
570                 int nmea_len;
571                 char *p_nmea_data;
572                 nmea_len = gps_event->event_data.nmea_ind.nmea.len;
573                 p_nmea_data = gps_event->event_data.nmea_ind.nmea.data;
574                 write_nmea_log(p_nmea_data, nmea_len);
575         }
576 }
577
578 static int _gps_server_open_data_connection()
579 {
580         LOG_GPS(DBG_LOW, "Enter _gps_server_open_data_connection");
581
582         g_dnet_used++;
583
584         if (g_dnet_used > 1) {
585                 LOG_GPS(DBG_LOW, "g_dnet_used : [ %d ]", g_dnet_used);
586                 return TRUE;
587         } else {
588                 LOG_GPS(DBG_LOW, "First open the data connection");
589         }
590
591         unsigned char result;
592
593         result = start_pdp_connection();
594
595         if (result == TRUE) {
596                 LOG_GPS(DBG_LOW, "//Open PDP Conn for SUPL Success.");
597         } else {
598                 LOG_GPS(DBG_ERR, "//Open PDP Conn for SUPL Fail.");
599                 return FALSE;
600         }
601         return TRUE;
602 }
603
604 static int _gps_server_close_data_connection()
605 {
606         LOG_GPS(DBG_LOW, "Enter _gps_server_close_data_connection");
607
608         if (g_dnet_used > 0) {
609                 g_dnet_used--;
610         }
611
612         if (g_dnet_used != 0) {
613                 LOG_GPS(DBG_LOW, "Cannot stop the data connection! [ g_dnet_used : %d ]", g_dnet_used);
614                 return TRUE;
615         } else {
616                 LOG_GPS(DBG_LOW, "Close the data connection");
617         }
618
619         unsigned char result;
620
621         result = stop_pdp_connection();
622         if (result == TRUE) {
623                 LOG_GPS(DBG_LOW, "Close PDP Conn for SUPL Success.");
624         } else {
625                 LOG_GPS(DBG_ERR, "//Close PDP Conn for SUPL Fail.");
626                 return FALSE;
627         }
628
629         return TRUE;
630 }
631
632 static int _gps_server_resolve_dns(char *domain)
633 {
634         LOG_GPS(DBG_LOW, "Enter _gps_server_resolve_dns");
635
636         unsigned char result;
637         gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
638         unsigned int ipaddr;
639         int port;
640
641         result = query_dns(domain, &ipaddr, &port);
642         if (result == TRUE) {
643                 LOG_GPS(DBG_LOW, "Success to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
644                 get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
645         } else {
646                 ipaddr = 0;
647                 LOG_GPS(DBG_ERR, "Fail to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
648                 get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
649                 return FALSE;
650         }
651
652         return TRUE;
653 }
654
655 static void _gps_server_send_facttest_result(double snr_data, int prn, unsigned short result)
656 {
657 }
658
659 static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info)
660 {
661         FUNC_ENTRANCE_SERVER;
662         int result = TRUE;
663         if (gps_event_info == NULL) {
664                 LOG_GPS(DBG_WARN, "//NULL pointer variable passed");
665                 return result;
666         }
667
668         switch (gps_event_info->event_id) {
669         case GPS_EVENT_START_SESSION:
670                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_START_SESSION :::::::::::::::");
671                 if (gps_event_info->event_data.start_session_rsp.error == GPS_ERR_NONE) {
672                         _gps_server_start_event();
673                 } else {
674                         LOG_GPS(DBG_ERR, "//Start Session Failed, error : %d",
675                                 gps_event_info->event_data.start_session_rsp.error);
676                 }
677                 break;
678         case GPS_EVENT_SET_OPTION:
679                 {
680                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SET_OPTION :::::::::::::::");
681                         if (gps_event_info->event_data.set_option_rsp.error != GPS_ERR_NONE) {
682                                 LOG_GPS(DBG_ERR, "//Set Option Failed, error : %d",
683                                         gps_event_info->event_data.set_option_rsp.error);
684                         }
685                 }
686                 break;
687
688         case GPS_EVENT_STOP_SESSION:
689                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_STOP_SESSION :::::::::::::::");
690                 if (gps_event_info->event_data.stop_session_rsp.error == GPS_ERR_NONE) {
691                         _gps_server_close_data_connection();
692                         _gps_server_stop_event();
693                 } else {
694                         LOG_GPS(DBG_ERR, "//Stop Session Failed, error : %d",
695                                 gps_event_info->event_data.stop_session_rsp.error);
696                 }
697
698                 break;
699         case GPS_EVENT_REPORT_POSITION:
700                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_POSITION :::::::::::::::");
701                 if (gps_event_info->event_data.pos_ind.error == GPS_ERR_NONE) {
702                         _report_pos_event(gps_event_info);
703                 } else {
704                         LOG_GPS(DBG_ERR, "GPS_EVENT_POSITION Failed, error : %d", gps_event_info->event_data.pos_ind.error);
705                 }
706                 break;
707         case GPS_EVENT_REPORT_SATELLITE:
708                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SATELLITE :::::::::::::::");
709                 if (gps_event_info->event_data.sv_ind.error == GPS_ERR_NONE) {
710                         if (gps_event_info->event_data.sv_ind.sv.pos_valid) {
711                                 _gps_server_set_indicator(POSITION_CONNECTED);
712                         } else {
713                                 _gps_server_set_indicator(POSITION_SEARCHING);
714                         }
715                         _report_sv_event(gps_event_info);
716                 } else {
717                         LOG_GPS(DBG_ERR, "GPS_EVENT_SATELLITE Failed, error : %d", gps_event_info->event_data.sv_ind.error);
718                 }
719                 break;
720         case GPS_EVENT_REPORT_NMEA:
721                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_NMEA :::::::::::::::");
722                 if (gps_event_info->event_data.nmea_ind.error == GPS_ERR_NONE) {
723                         _report_nmea_event(gps_event_info);
724                 } else {
725                         LOG_GPS(DBG_ERR, "GPS_EVENT_NMEA Failed, error : %d", gps_event_info->event_data.nmea_ind.error);
726                 }
727                 break;
728         case GPS_EVENT_ERR_CAUSE:
729                 break;
730         case GPS_EVENT_AGPS_VERIFICATION_INDI:
731                 break;
732         case GPS_EVENT_GET_IMSI:
733                 break;
734         case GPS_EVENT_GET_REF_LOCATION:
735                 break;
736         case GPS_EVENT_OPEN_DATA_CONNECTION:
737                 {
738                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_OPEN_DATA_CONNECTION :::::::::::::::");
739                         result = _gps_server_open_data_connection();
740                 }
741                 break;
742         case GPS_EVENT_CLOSE_DATA_CONNECTION:
743                 {
744                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_CLOSE_DATA_CONNECTION :::::::::::::::");
745                         result = _gps_server_close_data_connection();
746                 }
747                 break;
748         case GPS_EVENT_DNS_LOOKUP_IND:
749                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_DNS_LOOKUP_IND :::::::::::::::");
750                 if (gps_event_info->event_data.dns_query_ind.error == GPS_ERR_NONE) {
751                         result = _gps_server_resolve_dns(gps_event_info->event_data.dns_query_ind.domain_name);
752                 } else {
753                         result = FALSE;
754                 }
755                 if (result == TRUE) {
756                         LOG_GPS(DBG_LOW, "Success to get the DNS Query about [ %s ]",
757                                 gps_event_info->event_data.dns_query_ind.domain_name);
758                 }
759                 break;
760         case GPS_EVENT_FACTORY_TEST:
761                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_FACTORY_TEST :::::::::::::::");
762                 if (gps_event_info->event_data.factory_test_rsp.error == GPS_ERR_NONE) {
763                         LOG_GPS(DBG_LOW, "[LBS server] Response Factory test result success");
764                         _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
765                                                          gps_event_info->event_data.factory_test_rsp.prn, TRUE);
766                 } else {
767                         LOG_GPS(DBG_ERR, "//[LBS server] Response Factory test result ERROR");
768                         _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
769                                                          gps_event_info->event_data.factory_test_rsp.prn, FALSE);
770                 }
771                 break;
772         default:
773                 LOG_GPS(DBG_WARN, "//Error: Isettingalid Event Type %d", gps_event_info->event_id);
774                 break;
775         }
776         return result;
777 }
778
779 static void *_gps_launch_popup(void *data)
780 {
781         gps_ni_popup_data_t *msgData = (gps_ni_popup_data_t *) data;
782
783         int status;
784         char *argv[5];
785         char temp[16];
786         gps_failure_reason_t reason_code;
787
788         // Max size of SMS message is 255
789         // Max size of WAP PUSH is ??????
790         snprintf(temp, sizeof(temp), "%d", msgData->msg_size);
791
792         argv[0] = GPS_NI_POPUP;
793         if (msgData->num_btn == 2)
794                 argv[1] = GPS_NI_BTN;
795         else
796                 argv[1] = GPS_NI_WITHOUT_BTN;
797         argv[2] = temp;
798         argv[3] = msgData->msg_body;
799         argv[4] = NULL;
800
801         if (msgData->num_btn == 2) {
802                 wait(&status);
803                 if (status != YES_EXIT_STATUS && status != NO_EXIT_STATUS)
804                         status = YES_EXIT_STATUS;
805                 status = status / 256;
806         } else {
807                 // Popup application Timer is 2 sec
808                 sleep(2);
809                 status = YES_EXIT_STATUS;
810         }
811
812         status = NO_EXIT_STATUS - status;
813         LOG_GPS(DBG_LOW, "EXIT_STATUS from the LBS Popup is [ %d ]", status);
814
815         agps_supl_ni_info_t info;
816         info.msg_body = (char *)msgData->msg_body;
817         info.msg_size = msgData->msg_size;
818         info.status = status;
819
820         if (!get_plugin_module()->request(GPS_ACTION_REQUEST_SUPL_NI, &info, &reason_code)) {
821                 LOG_GPS(DBG_ERR, "Failed to request SUPL NI (code:%d)", reason_code);
822         }
823
824         return NULL;
825
826 }
827
828 static void _gps_supl_networkinit_smscb(MSG_HANDLE_T hMsgHandle, msg_message_t msg, void *user_param)
829 {
830         LOG_GPS(DBG_ERR, "_gps_supl_networkinit_smscb is called");
831         LOG_GPS(DBG_ERR, "SUPLNI MSG size is [ %d ]", msg_get_message_body_size(msg));
832
833         gps_ni_popup_data_t new_message;
834         memset(&new_message, 0x00, sizeof(new_message));
835
836         new_message.msg_body = (char *)msg_sms_get_message_body(msg);
837         new_message.msg_size = msg_get_message_body_size(msg);
838         // TODO: Button number of LBS Popup
839         new_message.num_btn = 2;
840
841         pthread_attr_t attr;
842         pthread_attr_init(&attr);
843         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
844
845         if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &new_message) != 0) {
846                 LOG_GPS(DBG_WARN, "Can not make pthread......");
847         }
848
849 }
850
851 static void _gps_supl_networkinit_wappushcb(MSG_HANDLE_T hMsgHandle, const char *pPushHeader, const char *pPushBody,
852                                             int pushBodyLen, void *user_param)
853 {
854         LOG_GPS(DBG_ERR, "_gps_supl_networkinit_wappushcb is called");
855         LOG_GPS(DBG_ERR, "SUPLNI WAPPush MSG size is [ %d ]", pushBodyLen);
856
857         gps_ni_popup_data_t new_message;
858         memset(&new_message, 0x00, sizeof(new_message));
859
860         new_message.msg_body = (char *)pPushBody;
861         new_message.msg_size = pushBodyLen;
862         // TODO: Button number of LBS Popup
863         new_message.num_btn = 2;
864
865         pthread_attr_t attr;
866         pthread_attr_init(&attr);
867         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
868
869         if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &new_message) != 0) {
870                 LOG_GPS(DBG_WARN, "Can not make pthread......");
871         }
872
873 }
874
875 static void *_gps_register_msgfwcb()
876 {
877         MSG_HANDLE_T msgHandle = NULL;
878         MSG_ERROR_T err = MSG_SUCCESS;
879
880         int setValue = 0;
881         int ret;
882
883         int cnt = 60;
884
885         while (cnt > 0) {
886                 ret = vconf_get_bool(VCONFKEY_MSG_SERVER_READY, &setValue);
887
888                 if (ret == -1) {
889                         LOG_GPS(DBG_WARN, "Fail to get VCONFKEY_MSG_SERVER_READY");
890                         return NULL;
891                 }
892
893                 if (setValue) {
894                         LOG_GPS(DBG_LOW, "MSG server is READY!!");
895                         cnt = -1;
896                 } else {
897                         sleep(5);
898                         cnt--;
899                         if (cnt == 0) {
900                                 LOG_GPS(DBG_WARN, "Never connect to MSG Server for 300 secs.");
901                                 return NULL;
902                         }
903                 }
904         }
905
906         err = msg_open_msg_handle(&msgHandle);
907
908         if (err != MSG_SUCCESS) {
909                 LOG_GPS(DBG_WARN, "Fail to MsgOpenMsgHandle. Error type = [ %d ]", err);
910                 return NULL;
911         }
912
913         err = msg_reg_sms_message_callback(msgHandle, &_gps_supl_networkinit_smscb, 7275, NULL);
914
915         if (err != MSG_SUCCESS) {
916                 LOG_GPS(DBG_WARN, "Fail to MsgRegSmsMessageCallback. Error type = [ %d ]", err);
917                 return NULL;
918         }
919
920         err = msg_reg_lbs_message_callback(msgHandle, &_gps_supl_networkinit_wappushcb, NULL);
921
922         if (err != MSG_SUCCESS) {
923                 LOG_GPS(DBG_WARN, "Fail to MsgRegLBSMessageCallback. Error type = [ %d ]", err);
924                 return NULL;
925         }
926
927         LOG_GPS(DBG_LOW, "Success to lbs_register_msgfwcb");
928         return NULL;
929
930 }
931
932 static void _gps_hibernation_enter_callback(void *data)
933 {
934         LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_enter_callback");
935
936         if (msg_thread != 0) {
937                 pthread_cancel(msg_thread);
938
939                 pthread_join(msg_thread, (void *)&msg_thread_status);
940                 msg_thread = 0;
941         }
942 }
943
944 static void _gps_hibernation_leave_callback(void *data)
945 {
946         LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_leave_callback");
947
948         if (msg_thread != 0) {
949                 pthread_cancel(msg_thread);
950
951                 pthread_join(msg_thread, (void *)&msg_thread_status);
952                 msg_thread = 0;
953         }
954         if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) {
955                 LOG_GPS(DBG_WARN, "Can not make pthread......");
956         }
957 }
958
959 static void _print_help()
960 {
961         printf("Usage: gps-manager [OPTION] [NAME]\n"
962                " -h         Help\n"
963                " -l [NAME]  Load a specific plugin module\n");
964         exit(0);
965 }
966
967 static int _parse_argument(const int argc, char **argv, const int buffer_size, char *out_buffer)
968 {
969         int opt;
970
971         memset(out_buffer, 0x00, buffer_size);
972         while ((opt = getopt(argc, argv, "hl:")) != -1) {
973                 switch (opt) {
974                 case 'l':
975                         snprintf(out_buffer, buffer_size, "%s", optarg);
976                         break;
977                 case 'h':
978                 default:
979                         _print_help();
980                         break;
981                 }
982         }
983
984         return 0;
985 }
986
987 int initialize_server(int argc, char **argv)
988 {
989         char module_name[16];
990
991         _parse_argument(argc, argv, sizeof(module_name), module_name);
992
993         FUNC_ENTRANCE_SERVER;
994
995         _gps_plugin_handler_init(module_name);
996         _gps_read_params();
997         _gps_notify_params();
998
999         if (!load_plugin_module(g_gps_plugin.name, &g_gps_plugin.handle)) {
1000                 LOG_GPS(DBG_ERR, "Failed to load plugin module.");
1001                 return -1;
1002         }
1003
1004         LOG_GPS(DBG_LOW, "after read parameters......");
1005
1006         if (!get_plugin_module()->init(_gps_server_gps_event_cb, &g_gps_params)) {
1007                 LOG_GPS(DBG_WARN, "//GPS Initialization failed");
1008                 return -1;
1009         }
1010         // Register SUPL NI cb to MSG server
1011         if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) {
1012                 LOG_GPS(DBG_WARN, "Can not make pthread......");
1013         }
1014         // Register Hibernation cb to re-connect msg-server
1015         int notifd;
1016         notifd = heynoti_init();
1017         heynoti_subscribe(notifd, "HIBERNATION_ENTER", _gps_hibernation_enter_callback, NULL);
1018         heynoti_subscribe(notifd, "HIBERNATION_LEAVE", _gps_hibernation_leave_callback, NULL);
1019         heynoti_attach_handler(notifd);
1020
1021         LOG_GPS(DBG_LOW, "Initialization is completed.");
1022
1023         return 0;
1024 }
1025
1026 int deinitialize_server()
1027 {
1028         gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL;
1029
1030         // Wait termination of msg thread
1031         pthread_join(msg_thread, (void *)&msg_thread_status);
1032
1033         _gps_ignore_params();
1034
1035         if (!get_plugin_module()->deinit(&ReasonCode)) {
1036                 LOG_GPS(DBG_WARN, "GPS De-Initialization failed.");
1037         }
1038
1039         unload_plugin_module(g_gps_plugin.handle);
1040         _gps_plugin_handler_deinit();
1041
1042         return 0;
1043 }
1044
1045 int register_update_callbacks(struct gps_callbacks *gps_callback, void *user_data)
1046 {
1047         g_update_cb = *gps_callback;
1048         g_user_data = user_data;
1049         return 0;
1050 }