upload tizen1.0 source
[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 pos_data_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 = (pos_data_t *) malloc(sizeof(pos_data_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(pos_data_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         if (strcmp(REPLAY_MODULE, g_gps_plugin.name) == 0) {
352                 setting_set_int(REPLAY_ENABLED, 1);
353         } else {
354                 setting_set_int(REPLAY_ENABLED, 0);
355         }
356 }
357
358 static void _gps_plugin_handler_deinit()
359 {
360         setting_set_int(REPLAY_ENABLED, 0);
361
362         if (g_gps_plugin.handle != NULL) {
363                 g_gps_plugin.handle = NULL;
364         }
365
366         if (g_gps_plugin.name != NULL) {
367                 free(g_gps_plugin.name);
368                 g_gps_plugin.name = NULL;
369         }
370 }
371
372 static void _gps_read_params()
373 {
374         int int_val = 0;
375         char *str;
376
377         if (setting_get_int(GPS_SESSION, &int_val) == FALSE) {
378                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_SESSION setting get failed");
379                 int_val = GPS_SESSION_TRACKING_MODE;
380         }
381         g_gps_params.session_type = int_val;
382
383         if (setting_get_int(GPS_OPERATION, &int_val) == FALSE) {
384                 LOG_GPS(DBG_ERR, "//ERROR!! GPS_OPERATION setting get failed");
385                 int_val = GPS_OPERATION_STANDALONE;
386         }
387         g_gps_params.operation_mode = int_val;
388
389         if (setting_get_int(GPS_STARTING, &int_val) == FALSE) {
390                 LOG_GPS(DBG_ERR, "//ERROR!! TING_MODE setting get failed");
391                 int_val = GPS_STARTING_HOT_;
392         }
393         g_gps_params.starting_type = int_val;
394
395         g_gps_params.time_bn_fixes = 1;
396
397         str = setting_get_string(SUPL_SERVER);
398         if (str == NULL) {
399                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", SUPL_SERVER_URL_DEFAULT);
400                 LOG_GPS(DBG_ERR, "vconf fail to get Server URL [Default URL]");
401         } else {
402                 snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", str);
403         }
404
405         if (setting_get_int(SUPL_PORT, &int_val) == FALSE) {
406                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_PORT setting get failed");
407                 int_val = SUPL_SERVER_PORT_DEFAULT;
408         }
409         g_gps_params.supl_port = int_val;
410
411         LOG_GPS(DBG_LOW, "First Read!! SUPL server:%s, port:%d", g_gps_params.supl_url, g_gps_params.supl_port);
412
413         if (setting_get_int(SUPL_SSL, &int_val) == FALSE) {
414                 LOG_GPS(DBG_ERR, "//ERROR!! SUPL_SSL setting get failed");
415                 int_val = 0;
416         }
417         g_gps_params.ssl_mode = int_val;
418
419         if (setting_get_int(NMEA_LOGGING, &int_val) == FALSE) {
420                 LOG_GPS(DBG_ERR, "//NMEA_LOGGING get Failed.");
421                 int_val = 0;
422         }
423         logging_enabled = (int_val == 1) ? TRUE : FALSE;
424
425         if (setting_get_int(REPLAY_ENABLED, &int_val) == FALSE) {
426                 LOG_GPS(DBG_ERR, "//REPLAY_ENABLED get Failed.");
427                 int_val = 0;
428         }
429         replay_enabled = (int_val == 1) ? TRUE : FALSE;
430 }
431
432 static void _gps_notify_params()
433 {
434         setting_notify_key_changed(GPS_SESSION, _gps_mode_changed_cb);
435         setting_notify_key_changed(GPS_OPERATION, _gps_mode_changed_cb);
436         setting_notify_key_changed(GPS_STARTING, _gps_mode_changed_cb);
437         setting_notify_key_changed(SUPL_SERVER, _gps_supl_changed_cb);
438         setting_notify_key_changed(SUPL_PORT, _gps_supl_changed_cb);
439         setting_notify_key_changed(SUPL_SSL, _gps_setting_changed_cb);
440         setting_notify_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb);
441         setting_notify_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
442 }
443
444 static void _gps_ignore_params()
445 {
446         setting_ignore_key_changed(GPS_SESSION, _gps_mode_changed_cb);
447         setting_ignore_key_changed(GPS_OPERATION, _gps_mode_changed_cb);
448         setting_ignore_key_changed(GPS_STARTING, _gps_mode_changed_cb);
449         setting_ignore_key_changed(SUPL_SERVER, _gps_supl_changed_cb);
450         setting_ignore_key_changed(SUPL_PORT, _gps_supl_changed_cb);
451         setting_ignore_key_changed(SUPL_SSL, _gps_setting_changed_cb);
452         setting_ignore_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb);
453         setting_ignore_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb);
454 }
455
456 static void _gps_server_start_event()
457 {
458         LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STARTED);
459         gps_session_state = GPS_SESSION_STARTED;
460
461         if (logging_enabled) {
462                 start_nmea_log();
463         }
464
465         if (gps_pos_data == NULL) {
466                 gps_pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
467                 if (gps_pos_data == NULL) {
468                         LOG_GPS(DBG_WARN, "//callback: gps_pos_data re-malloc Failed!!");
469                 } else {
470                         memset(gps_pos_data, 0x00, sizeof(pos_data_t));
471                 }
472         }
473         if (gps_sv_data == NULL) {
474                 gps_sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
475                 if (gps_sv_data == NULL) {
476                         LOG_GPS(DBG_WARN, "//callback: gps_sv_data re-malloc Failed!!");
477                 } else {
478                         memset(gps_sv_data, 0x00, sizeof(sv_data_t));
479                 }
480         }
481         if (gps_nmea_data == NULL) {
482                 gps_nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
483                 if (gps_nmea_data == NULL) {
484                         LOG_GPS(DBG_WARN, "//callback: gps_nmea_data re-malloc Failed!!");
485                 } else {
486                         memset(gps_nmea_data, 0x00, sizeof(nmea_data_t));
487                 }
488         }
489
490         if (gps_last_pos == NULL) {
491                 gps_last_pos = (pos_data_t *) malloc(sizeof(pos_data_t));
492                 if (gps_last_pos == NULL) {
493                         LOG_GPS(DBG_WARN, "//callback: gps_last_pos re-malloc Failed!!");
494                 } else {
495                         memset(gps_last_pos, 0x00, sizeof(pos_data_t));
496                         gps_manager_get_last_position(gps_last_pos);
497                 }
498         }
499
500         _gps_server_set_indicator(POSITION_SEARCHING);
501         pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
502 }
503
504 static void _gps_server_stop_event()
505 {
506         LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STOPPED);
507         gps_session_state = GPS_SESSION_STOPPED;
508         LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state);
509
510         _gps_server_set_indicator(POSITION_OFF);
511         pm_unlock_state(LCD_NORMAL, PM_RESET_TIMER);
512
513         if (logging_enabled) {
514                 stop_nmea_log();
515         }
516
517         if (gps_pos_data != NULL) {
518                 free(gps_pos_data);
519                 gps_pos_data = NULL;
520         }
521         if (gps_sv_data != NULL) {
522                 free(gps_sv_data);
523                 gps_sv_data = NULL;
524         }
525         if (gps_nmea_data != NULL) {
526                 free(gps_nmea_data);
527                 gps_nmea_data = NULL;
528         }
529         if (gps_last_pos != NULL) {
530                 free(gps_last_pos);
531                 gps_last_pos = NULL;
532         }
533 }
534
535 static void _report_pos_event(gps_event_info_t * gps_event)
536 {
537         if (gps_pos_data != NULL) {
538                 memcpy(gps_pos_data, &(gps_event->event_data.pos_ind.pos), sizeof(pos_data_t));
539                 memcpy(gps_last_pos, gps_pos_data, sizeof(pos_data_t));
540                 g_update_cb.pos_cb(gps_pos_data, gps_event->event_data.pos_ind.error, g_user_data);
541                 gps_manager_set_last_position(gps_last_pos);
542                 memset(gps_pos_data, 0x00, sizeof(pos_data_t));
543         } else {
544                 LOG_GPS(DBG_ERR, "gps_sv_data is NULL");
545         }
546 }
547
548 static void _report_sv_event(gps_event_info_t * gps_event)
549 {
550         if (gps_sv_data != NULL) {
551                 memcpy(gps_sv_data, &(gps_event->event_data.sv_ind.sv), sizeof(sv_data_t));
552                 g_update_cb.sv_cb(gps_sv_data, g_user_data);
553                 memset(gps_sv_data, 0x00, sizeof(sv_data_t));
554         } else {
555                 LOG_GPS(DBG_ERR, "gps_sv_data is NULL");
556         }
557 }
558
559 static void _report_nmea_event(gps_event_info_t * gps_event)
560 {
561         if (gps_nmea_data == NULL) {
562                 LOG_GPS(DBG_ERR, "gps_nmea_data is NULL");
563                 return;
564         }
565
566         gps_nmea_data->len = gps_event->event_data.nmea_ind.nmea.len;
567         LOG_GPS(DBG_LOW, "gps_nmea_data->len : [%d]", gps_nmea_data->len);
568         gps_nmea_data->data = (char *)malloc(gps_nmea_data->len);
569         memset(gps_nmea_data->data, 0x00, gps_nmea_data->len);
570         memcpy(gps_nmea_data->data, gps_event->event_data.nmea_ind.nmea.data, gps_nmea_data->len);
571         g_update_cb.nmea_cb(gps_nmea_data, g_user_data);
572         free(gps_nmea_data->data);
573         memset(gps_nmea_data, 0x00, sizeof(nmea_data_t));
574
575         if (logging_enabled) {
576                 int nmea_len;
577                 char *p_nmea_data;
578                 nmea_len = gps_event->event_data.nmea_ind.nmea.len;
579                 p_nmea_data = gps_event->event_data.nmea_ind.nmea.data;
580                 write_nmea_log(p_nmea_data, nmea_len);
581         }
582 }
583
584 static int _gps_server_open_data_connection()
585 {
586         LOG_GPS(DBG_LOW, "Enter _gps_server_open_data_connection");
587
588         g_dnet_used++;
589
590         if (g_dnet_used > 1) {
591                 LOG_GPS(DBG_LOW, "g_dnet_used : [ %d ]", g_dnet_used);
592                 return TRUE;
593         } else {
594                 LOG_GPS(DBG_LOW, "First open the data connection");
595         }
596
597         unsigned char result;
598
599         result = start_pdp_connection();
600
601         if (result == TRUE) {
602                 LOG_GPS(DBG_LOW, "//Open PDP Conn for SUPL Success.");
603         } else {
604                 LOG_GPS(DBG_ERR, "//Open PDP Conn for SUPL Fail.");
605                 return FALSE;
606         }
607         return TRUE;
608 }
609
610 static int _gps_server_close_data_connection()
611 {
612         LOG_GPS(DBG_LOW, "Enter _gps_server_close_data_connection");
613
614         if (g_dnet_used > 0) {
615                 g_dnet_used--;
616         }
617
618         if (g_dnet_used != 0) {
619                 LOG_GPS(DBG_LOW, "Cannot stop the data connection! [ g_dnet_used : %d ]", g_dnet_used);
620                 return TRUE;
621         } else {
622                 LOG_GPS(DBG_LOW, "Close the data connection");
623         }
624
625         unsigned char result;
626
627         result = stop_pdp_connection();
628         if (result == TRUE) {
629                 LOG_GPS(DBG_LOW, "Close PDP Conn for SUPL Success.");
630         } else {
631                 LOG_GPS(DBG_ERR, "//Close PDP Conn for SUPL Fail.");
632                 return FALSE;
633         }
634
635         return TRUE;
636 }
637
638 static int _gps_server_resolve_dns(char *domain)
639 {
640         LOG_GPS(DBG_LOW, "Enter _gps_server_resolve_dns");
641
642         unsigned char result;
643         gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
644         unsigned int ipaddr;
645         int port;
646
647         result = query_dns(domain, &ipaddr, &port);
648         if (result == TRUE) {
649                 LOG_GPS(DBG_LOW, "Success to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
650                 get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
651         } else {
652                 ipaddr = 0;
653                 LOG_GPS(DBG_ERR, "Fail to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
654                 get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
655                 return FALSE;
656         }
657
658         return TRUE;
659 }
660
661 static void _gps_server_send_facttest_result(double snr_data, int prn, unsigned short result)
662 {
663 }
664
665 static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info)
666 {
667         FUNC_ENTRANCE_SERVER;
668         int result = TRUE;
669         if (gps_event_info == NULL) {
670                 LOG_GPS(DBG_WARN, "//NULL pointer variable passed");
671                 return result;
672         }
673
674         switch (gps_event_info->event_id) {
675         case GPS_EVENT_START_SESSION:
676                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_START_SESSION :::::::::::::::");
677                 if (gps_event_info->event_data.start_session_rsp.error == GPS_ERR_NONE) {
678                         _gps_server_start_event();
679                 } else {
680                         LOG_GPS(DBG_ERR, "//Start Session Failed, error : %d",
681                                 gps_event_info->event_data.start_session_rsp.error);
682                 }
683                 break;
684         case GPS_EVENT_SET_OPTION:
685                 {
686                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SET_OPTION :::::::::::::::");
687                         if (gps_event_info->event_data.set_option_rsp.error != GPS_ERR_NONE) {
688                                 LOG_GPS(DBG_ERR, "//Set Option Failed, error : %d",
689                                         gps_event_info->event_data.set_option_rsp.error);
690                         }
691                 }
692                 break;
693
694         case GPS_EVENT_STOP_SESSION:
695                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_STOP_SESSION :::::::::::::::");
696                 if (gps_event_info->event_data.stop_session_rsp.error == GPS_ERR_NONE) {
697                         _gps_server_close_data_connection();
698                         _gps_server_stop_event();
699                 } else {
700                         LOG_GPS(DBG_ERR, "//Stop Session Failed, error : %d",
701                                 gps_event_info->event_data.stop_session_rsp.error);
702                 }
703
704                 break;
705         case GPS_EVENT_REPORT_POSITION:
706                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_POSITION :::::::::::::::");
707                 if (gps_event_info->event_data.pos_ind.error == GPS_ERR_NONE) {
708                         _report_pos_event(gps_event_info);
709                 } else {
710                         LOG_GPS(DBG_ERR, "GPS_EVENT_POSITION Failed, error : %d", gps_event_info->event_data.pos_ind.error);
711                 }
712                 break;
713         case GPS_EVENT_REPORT_SATELLITE:
714                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SATELLITE :::::::::::::::");
715                 if (gps_event_info->event_data.sv_ind.error == GPS_ERR_NONE) {
716                         if (gps_event_info->event_data.sv_ind.sv.pos_valid) {
717                                 _gps_server_set_indicator(POSITION_CONNECTED);
718                         } else {
719                                 _gps_server_set_indicator(POSITION_SEARCHING);
720                         }
721                         _report_sv_event(gps_event_info);
722                 } else {
723                         LOG_GPS(DBG_ERR, "GPS_EVENT_SATELLITE Failed, error : %d", gps_event_info->event_data.sv_ind.error);
724                 }
725                 break;
726         case GPS_EVENT_REPORT_NMEA:
727                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_NMEA :::::::::::::::");
728                 if (gps_event_info->event_data.nmea_ind.error == GPS_ERR_NONE) {
729                         _report_nmea_event(gps_event_info);
730                 } else {
731                         LOG_GPS(DBG_ERR, "GPS_EVENT_NMEA Failed, error : %d", gps_event_info->event_data.nmea_ind.error);
732                 }
733                 break;
734         case GPS_EVENT_ERR_CAUSE:
735                 break;
736         case GPS_EVENT_AGPS_VERIFICATION_INDI:
737                 break;
738         case GPS_EVENT_GET_IMSI:
739                 break;
740         case GPS_EVENT_GET_REF_LOCATION:
741                 break;
742         case GPS_EVENT_OPEN_DATA_CONNECTION:
743                 {
744                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_OPEN_DATA_CONNECTION :::::::::::::::");
745                         result = _gps_server_open_data_connection();
746                 }
747                 break;
748         case GPS_EVENT_CLOSE_DATA_CONNECTION:
749                 {
750                         LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_CLOSE_DATA_CONNECTION :::::::::::::::");
751                         result = _gps_server_close_data_connection();
752                 }
753                 break;
754         case GPS_EVENT_DNS_LOOKUP_IND:
755                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_DNS_LOOKUP_IND :::::::::::::::");
756                 if (gps_event_info->event_data.dns_query_ind.error == GPS_ERR_NONE) {
757                         result = _gps_server_resolve_dns(gps_event_info->event_data.dns_query_ind.domain_name);
758                 } else {
759                         result = FALSE;
760                 }
761                 if (result == TRUE) {
762                         LOG_GPS(DBG_LOW, "Success to get the DNS Query about [ %s ]",
763                                 gps_event_info->event_data.dns_query_ind.domain_name);
764                 }
765                 break;
766         case GPS_EVENT_FACTORY_TEST:
767                 LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_FACTORY_TEST :::::::::::::::");
768                 if (gps_event_info->event_data.factory_test_rsp.error == GPS_ERR_NONE) {
769                         LOG_GPS(DBG_LOW, "[LBS server] Response Factory test result success");
770                         _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
771                                                          gps_event_info->event_data.factory_test_rsp.prn, TRUE);
772                 } else {
773                         LOG_GPS(DBG_ERR, "//[LBS server] Response Factory test result ERROR");
774                         _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
775                                                          gps_event_info->event_data.factory_test_rsp.prn, FALSE);
776                 }
777                 break;
778         default:
779                 LOG_GPS(DBG_WARN, "//Error: Isettingalid Event Type %d", gps_event_info->event_id);
780                 break;
781         }
782         return result;
783 }
784
785 static void *_gps_launch_popup(void *data)
786 {
787         gps_ni_popup_data_t *msgData = (gps_ni_popup_data_t *) data;
788
789         int status;
790         char *argv[5];
791         char temp[16];
792         gps_failure_reason_t reason_code;
793
794         // Max size of SMS message is 255
795         // Max size of WAP PUSH is ??????
796         snprintf(temp, sizeof(temp), "%d", msgData->msg_size);
797
798         argv[0] = GPS_NI_POPUP;
799         if (msgData->num_btn == 2)
800                 argv[1] = GPS_NI_BTN;
801         else
802                 argv[1] = GPS_NI_WITHOUT_BTN;
803         argv[2] = temp;
804         argv[3] = msgData->msg_body;
805         argv[4] = NULL;
806
807         if (msgData->num_btn == 2) {
808                 wait(&status);
809                 if (status != YES_EXIT_STATUS && status != NO_EXIT_STATUS)
810                         status = YES_EXIT_STATUS;
811                 status = status / 256;
812         } else {
813                 // Popup application Timer is 2 sec
814                 sleep(2);
815                 status = YES_EXIT_STATUS;
816         }
817
818         status = NO_EXIT_STATUS - status;
819         LOG_GPS(DBG_LOW, "EXIT_STATUS from the LBS Popup is [ %d ]", status);
820
821         agps_supl_ni_info_t info;
822         info.msg_body = (char *)msgData->msg_body;
823         info.msg_size = msgData->msg_size;
824         info.status = status;
825
826         if (!get_plugin_module()->request(GPS_ACTION_REQUEST_SUPL_NI, &info, &reason_code)) {
827                 LOG_GPS(DBG_ERR, "Failed to request SUPL NI (code:%d)", reason_code);
828         }
829
830         return NULL;
831
832 }
833
834 static void _gps_supl_networkinit_smscb(MSG_HANDLE_T hMsgHandle, msg_message_t msg, void *user_param)
835 {
836         LOG_GPS(DBG_ERR, "_gps_supl_networkinit_smscb is called");
837         LOG_GPS(DBG_ERR, "SUPLNI MSG size is [ %d ]", msg_get_message_body_size(msg));
838
839         gps_ni_popup_data_t new_message;
840         memset(&new_message, 0x00, sizeof(new_message));
841
842         new_message.msg_body = (char *)msg_sms_get_message_body(msg);
843         new_message.msg_size = msg_get_message_body_size(msg);
844         // TODO: Button number of LBS Popup
845         new_message.num_btn = 2;
846
847         pthread_attr_t attr;
848         pthread_attr_init(&attr);
849         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
850
851         if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &new_message) != 0) {
852                 LOG_GPS(DBG_WARN, "Can not make pthread......");
853         }
854
855 }
856
857 static void _gps_supl_networkinit_wappushcb(MSG_HANDLE_T hMsgHandle, const char *pPushHeader, const char *pPushBody,
858                                             int pushBodyLen, void *user_param)
859 {
860         LOG_GPS(DBG_ERR, "_gps_supl_networkinit_wappushcb is called");
861         LOG_GPS(DBG_ERR, "SUPLNI WAPPush MSG size is [ %d ]", pushBodyLen);
862
863         gps_ni_popup_data_t new_message;
864         memset(&new_message, 0x00, sizeof(new_message));
865
866         new_message.msg_body = (char *)pPushBody;
867         new_message.msg_size = pushBodyLen;
868         // TODO: Button number of LBS Popup
869         new_message.num_btn = 2;
870
871         pthread_attr_t attr;
872         pthread_attr_init(&attr);
873         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
874
875         if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &new_message) != 0) {
876                 LOG_GPS(DBG_WARN, "Can not make pthread......");
877         }
878
879 }
880
881 static void *_gps_register_msgfwcb()
882 {
883         MSG_HANDLE_T msgHandle = NULL;
884         MSG_ERROR_T err = MSG_SUCCESS;
885
886         int setValue = 0;
887         int ret;
888
889         int cnt = 60;
890
891         while (cnt > 0) {
892                 ret = vconf_get_bool(VCONFKEY_MSG_SERVER_READY, &setValue);
893
894                 if (ret == -1) {
895                         LOG_GPS(DBG_WARN, "Fail to get VCONFKEY_MSG_SERVER_READY");
896                         return NULL;
897                 }
898
899                 if (setValue) {
900                         LOG_GPS(DBG_LOW, "MSG server is READY!!");
901                         cnt = -1;
902                 } else {
903                         sleep(5);
904                         cnt--;
905                         if (cnt == 0) {
906                                 LOG_GPS(DBG_WARN, "Never connect to MSG Server for 300 secs.");
907                                 return NULL;
908                         }
909                 }
910         }
911
912         err = msg_open_msg_handle(&msgHandle);
913
914         if (err != MSG_SUCCESS) {
915                 LOG_GPS(DBG_WARN, "Fail to MsgOpenMsgHandle. Error type = [ %d ]", err);
916                 return NULL;
917         }
918
919         err = msg_reg_sms_message_callback(msgHandle, &_gps_supl_networkinit_smscb, 7275, NULL);
920
921         if (err != MSG_SUCCESS) {
922                 LOG_GPS(DBG_WARN, "Fail to MsgRegSmsMessageCallback. Error type = [ %d ]", err);
923                 return NULL;
924         }
925
926         err = msg_reg_lbs_message_callback(msgHandle, &_gps_supl_networkinit_wappushcb, NULL);
927
928         if (err != MSG_SUCCESS) {
929                 LOG_GPS(DBG_WARN, "Fail to MsgRegLBSMessageCallback. Error type = [ %d ]", err);
930                 return NULL;
931         }
932
933         LOG_GPS(DBG_LOW, "Success to lbs_register_msgfwcb");
934         return NULL;
935
936 }
937
938 static void _gps_hibernation_enter_callback(void *data)
939 {
940         LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_enter_callback");
941
942         if (msg_thread != 0) {
943                 pthread_cancel(msg_thread);
944
945                 pthread_join(msg_thread, (void *)&msg_thread_status);
946                 msg_thread = 0;
947         }
948 }
949
950 static void _gps_hibernation_leave_callback(void *data)
951 {
952         LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_leave_callback");
953
954         if (msg_thread != 0) {
955                 pthread_cancel(msg_thread);
956
957                 pthread_join(msg_thread, (void *)&msg_thread_status);
958                 msg_thread = 0;
959         }
960         if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) {
961                 LOG_GPS(DBG_WARN, "Can not make pthread......");
962         }
963 }
964
965 static void _print_help()
966 {
967         printf("Usage: gps-manager [OPTION] [NAME]\n"
968                " -h         Help\n"
969                " -l [NAME]  Load a specific plugin module\n");
970         exit(0);
971 }
972
973 static int _parse_argument(const int argc, char **argv, const int buffer_size, char *out_buffer)
974 {
975         int opt;
976
977         memset(out_buffer, 0x00, buffer_size);
978         while ((opt = getopt(argc, argv, "hl:")) != -1) {
979                 switch (opt) {
980                 case 'l':
981                         snprintf(out_buffer, buffer_size, "%s", optarg);
982                         break;
983                 case 'h':
984                 default:
985                         _print_help();
986                         break;
987                 }
988         }
989
990         return 0;
991 }
992
993 int initialize_server(int argc, char **argv)
994 {
995         char module_name[16];
996
997         _parse_argument(argc, argv, sizeof(module_name), module_name);
998
999         FUNC_ENTRANCE_SERVER;
1000
1001         _gps_plugin_handler_init(module_name);
1002         _gps_read_params();
1003         _gps_notify_params();
1004
1005         if (!load_plugin_module(g_gps_plugin.name, &g_gps_plugin.handle)) {
1006                 LOG_GPS(DBG_ERR, "Failed to load plugin module.");
1007                 return -1;
1008         }
1009
1010         LOG_GPS(DBG_LOW, "after read parameters......");
1011
1012         if (!get_plugin_module()->init(_gps_server_gps_event_cb, &g_gps_params)) {
1013                 LOG_GPS(DBG_WARN, "//GPS Initialization failed");
1014                 return -1;
1015         }
1016         // Register SUPL NI cb to MSG server
1017         if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) {
1018                 LOG_GPS(DBG_WARN, "Can not make pthread......");
1019         }
1020         // Register Hibernation cb to re-connect msg-server
1021         int notifd;
1022         notifd = heynoti_init();
1023         heynoti_subscribe(notifd, "HIBERNATION_ENTER", _gps_hibernation_enter_callback, NULL);
1024         heynoti_subscribe(notifd, "HIBERNATION_LEAVE", _gps_hibernation_leave_callback, NULL);
1025         heynoti_attach_handler(notifd);
1026
1027         LOG_GPS(DBG_LOW, "Initialization is completed.");
1028
1029         return 0;
1030 }
1031
1032 int deinitialize_server()
1033 {
1034         gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL;
1035
1036         // Wait termination of msg thread
1037         pthread_join(msg_thread, (void *)&msg_thread_status);
1038
1039         _gps_ignore_params();
1040
1041         if (!get_plugin_module()->deinit(&ReasonCode)) {
1042                 LOG_GPS(DBG_WARN, "GPS De-Initialization failed.");
1043         }
1044
1045         unload_plugin_module(g_gps_plugin.handle);
1046         _gps_plugin_handler_deinit();
1047
1048         return 0;
1049 }
1050
1051 int register_update_callbacks(struct gps_callbacks *gps_callback, void *user_data)
1052 {
1053         g_update_cb = *gps_callback;
1054         g_user_data = user_data;
1055         return 0;
1056 }