tizen 2.3 release
[framework/location/libslp-lbs-plugin-replay.git] / gps-plugin / src / gps_plugin_replay.c
1 /*
2  * gps replay plugin
3  *
4  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7  *                      Genie Kim <daejins.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 <stdlib.h>
24 #include <string.h>
25 #include <glib.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30
31 #include <gps_plugin_intf.h>
32 #include <dd-display.h>
33
34 #include "gps_plugin_debug.h"
35 #include "nmea_parser.h"
36 #include "setting.h"
37
38 #define REPLAY_NMEA_SET_SIZE            4096
39 #define REPLAY_NMEA_SENTENCE_SIZE       128
40
41 #define LBS_SERVER_FOLDER       "/opt/usr/media/lbs-server"
42 #define BATCH_LOG                       "/opt/usr/media/lbs-server/location_batch.log"
43
44 gps_event_cb g_gps_event_cb = NULL;
45 void *g_user_data = NULL;
46
47 typedef struct {
48         FILE *fd;
49         FILE *batch_fd;
50         int interval;
51         int replay_mode;
52
53         int batch_mode;
54         int batch_period;
55         int num_of_batch;
56         time_t batch_start_time;
57
58         pos_data_t *pos_data;
59         batch_data_t *batch_data;
60         sv_data_t *sv_data;
61         nmea_data_t *nmea_data;
62
63         GSource *timeout_src;
64         GMainContext *default_context;
65 } replay_timeout;
66
67 replay_timeout *g_replay_timer = NULL;
68
69 int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, void *user_data);
70 int gps_plugin_replay_gps_deinit(gps_failure_reason_t * reason_code);
71 int gps_plugin_replay_gps_request(gps_action_t gps_action, void *gps_action_data, gps_failure_reason_t * reason_code);
72
73 static const gps_plugin_interface g_gps_plugin_replay_interface = {
74         gps_plugin_replay_gps_init,
75         gps_plugin_replay_gps_deinit,
76         gps_plugin_replay_gps_request
77 };
78
79 void gps_plugin_replay_pos_event(pos_data_t * data)
80 {
81         gps_event_info_t gps_event;
82         time_t timestamp;
83
84         memset(&gps_event, 0, sizeof(gps_event_info_t));
85         time(&timestamp);
86
87         gps_event.event_id = GPS_EVENT_REPORT_POSITION;
88
89         if (data == NULL) {
90                 LOG_PLUGIN(DBG_ERR, "NULL POS data.");
91                 gps_event.event_data.pos_ind.error = GPS_ERR_COMMUNICATION;
92         } else {
93                 gps_event.event_data.pos_ind.error = GPS_ERR_NONE;
94                 gps_event.event_data.pos_ind.pos.timestamp = timestamp;
95                 gps_event.event_data.pos_ind.pos.latitude = data->latitude;
96                 gps_event.event_data.pos_ind.pos.longitude = data->longitude;
97                 gps_event.event_data.pos_ind.pos.altitude = data->altitude;
98                 gps_event.event_data.pos_ind.pos.speed = data->speed;
99                 gps_event.event_data.pos_ind.pos.bearing = data->bearing;
100                 gps_event.event_data.pos_ind.pos.hor_accuracy = data->hor_accuracy;
101                 gps_event.event_data.pos_ind.pos.ver_accuracy = data->ver_accuracy;
102         }
103
104         //LOG_PLUGIN(DBG_LOW, "%d", gps_event.event_data.pos_ind.pos.timestamp);
105
106         if (g_gps_event_cb != NULL) {
107                 g_gps_event_cb(&gps_event, g_user_data);
108         }
109 }
110
111 void gps_plugin_replay_batch_event(pos_data_t * data, replay_timeout * timer)
112 {
113         time_t timestamp;
114         time(&timestamp);
115
116         if (timer->batch_fd == NULL) {
117                 if (timer->batch_mode == BATCH_MODE_ON) {
118                         LOG_PLUGIN(DBG_ERR, "Fail to open file [Not available batch_fd]");
119                         return ;
120                 }
121         }
122
123         if (data != NULL) {
124                 if (timer->batch_mode == BATCH_MODE_ON) {
125                         int ret = -1;
126                         char buf[256] = {0, };
127
128                         sprintf(buf, "%ld;%.6lf;%.6lf;%.2lf;%.2lf;%.2lf;%.2lf;%.2lf;\n", timestamp, data->latitude, data->longitude, data->altitude, data->speed, data->bearing, data->hor_accuracy, data->ver_accuracy);
129                         LOG_PLUGIN(DBG_LOW, "Add location info to batch file [%s]", buf);
130
131                         ret = fwrite(buf, 1, strlen(buf), timer->batch_fd);
132                         if (ret != strlen(buf)) {
133                                 LOG_PLUGIN(DBG_ERR, "Fail to write file[%s]", BATCH_LOG);
134                         }
135
136                         (timer->num_of_batch)++ ;
137                 }
138         }
139
140         if ( ((timestamp - timer->batch_start_time) >= timer->batch_period) || (timer->batch_mode == BATCH_MODE_EXPIRED) ) {
141                 LOG_PLUGIN(DBG_LOW, "Batch invoked, Batch interval is expired or Batch stopped");
142                 gps_event_info_t gps_event;
143                 memset(&gps_event, 0, sizeof(gps_event_info_t));
144
145                 gps_event.event_id = GPS_EVENT_REPORT_BATCH;
146                 timer->batch_mode = BATCH_MODE_OFF;
147
148                 if (timer->num_of_batch < 1) {
149                         LOG_PLUGIN(DBG_ERR, "There is no Batch data");
150                         gps_event.event_data.batch_ind.error = GPS_ERR_COMMUNICATION;
151                 } else {
152                         gps_event.event_data.batch_ind.error = GPS_ERR_NONE;
153                         gps_event.event_data.batch_ind.batch.num_of_location = timer->num_of_batch;
154                 }
155
156                 if (g_gps_event_cb != NULL) {
157                         g_gps_event_cb(&gps_event, g_user_data);
158                 }
159
160                 if (timer->batch_fd != NULL) {
161                         fclose(timer->batch_fd);
162                         timer->batch_fd = NULL;
163                         timer->num_of_batch = 0;
164                 }
165         }
166 }
167
168 void gps_plugin_replay_sv_event(sv_data_t * data)
169 {
170         int i;
171         gps_event_info_t gps_event;
172         time_t timestamp;
173
174         memset(&gps_event, 0, sizeof(gps_event_info_t));
175         time(&timestamp);
176         gps_event.event_id = GPS_EVENT_REPORT_SATELLITE;
177
178         if (data == NULL) {
179                 LOG_PLUGIN(DBG_ERR, "NULL SV data.");
180                 gps_event.event_data.sv_ind.error = GPS_ERR_COMMUNICATION;
181         } else {
182                 gps_event.event_data.sv_ind.error = GPS_ERR_NONE;
183                 gps_event.event_data.sv_ind.sv.timestamp = timestamp;
184                 gps_event.event_data.sv_ind.sv.pos_valid = data->pos_valid;
185                 gps_event.event_data.sv_ind.sv.num_of_sat = data->num_of_sat;
186                 for (i = 0; i < data->num_of_sat; i++) {
187                         gps_event.event_data.sv_ind.sv.sat[i].used = data->sat[i].used;
188                         gps_event.event_data.sv_ind.sv.sat[i].prn = data->sat[i].prn;
189                         gps_event.event_data.sv_ind.sv.sat[i].snr = data->sat[i].snr;
190                         gps_event.event_data.sv_ind.sv.sat[i].elevation = data->sat[i].elevation;
191                         gps_event.event_data.sv_ind.sv.sat[i].azimuth = data->sat[i].azimuth;
192                 }
193         }
194
195         if (g_gps_event_cb != NULL) {
196                 g_gps_event_cb(&gps_event, g_user_data);
197         }
198 }
199
200 void gps_plugin_replay_nmea_event(nmea_data_t * data)
201 {
202         gps_event_info_t gps_event;
203         time_t timestamp;
204
205         memset(&gps_event, 0, sizeof(gps_event_info_t));
206         time(&timestamp);
207
208         gps_event.event_id = GPS_EVENT_REPORT_NMEA;
209
210         if (data == NULL) {
211                 LOG_PLUGIN(DBG_ERR, "NULL NMEA data.");
212                 gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
213         } else {
214                 if (data->len > REPLAY_NMEA_SENTENCE_SIZE) {
215                         LOG_PLUGIN(DBG_WARN, "The Size of NMEA[ %d ] is larger then max ", data->len);
216                         data->len = REPLAY_NMEA_SENTENCE_SIZE;
217                         gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
218                 } else {
219                         gps_event.event_data.nmea_ind.error = GPS_ERR_NONE;
220                 }
221                 gps_event.event_data.nmea_ind.nmea.timestamp = timestamp;
222                 gps_event.event_data.nmea_ind.nmea.len = data->len;
223                 gps_event.event_data.nmea_ind.nmea.data = (char *)malloc(data->len);
224                 memset(gps_event.event_data.nmea_ind.nmea.data, 0x00, data->len);
225                 memcpy(gps_event.event_data.nmea_ind.nmea.data, data->data, data->len);
226                 //LOG_PLUGIN(DBG_LOW, "NMEA[%d] : %s", gps_event.event_data.nmea_ind.nmea.len, gps_event.event_data.nmea_ind.nmea.data);
227         }
228
229         if (g_gps_event_cb != NULL) {
230                 g_gps_event_cb(&gps_event, g_user_data);
231         }
232
233         if (gps_event.event_data.nmea_ind.nmea.data != NULL) {
234                 free(gps_event.event_data.nmea_ind.nmea.data);
235                 gps_event.event_data.nmea_ind.nmea.data = NULL;
236         }
237 }
238
239 void gps_plugin_respond_start_session(gboolean ret)
240 {
241         gps_event_info_t gps_event;
242         gps_event.event_id = GPS_EVENT_START_SESSION;
243
244         if (ret == TRUE) {
245                 gps_event.event_data.start_session_rsp.error = GPS_ERR_NONE;
246         } else {
247                 gps_event.event_data.start_session_rsp.error = GPS_ERR_COMMUNICATION;
248         }
249
250         if (g_gps_event_cb != NULL) {
251                 g_gps_event_cb(&gps_event, g_user_data);
252         }
253 }
254
255 void gps_plugin_respond_stop_session(void)
256 {
257         gps_event_info_t gps_event;
258
259         gps_event.event_id = GPS_EVENT_STOP_SESSION;
260         gps_event.event_data.stop_session_rsp.error = GPS_ERR_NONE;
261
262         if (g_gps_event_cb != NULL) {
263                 g_gps_event_cb(&gps_event, g_user_data);
264         }
265 }
266
267 gboolean gps_plugin_replay_read_nmea(replay_timeout * timer, char *nmea_data)
268 {
269         gboolean ret = FALSE;
270         int ref = 0;
271         char buf[REPLAY_NMEA_SENTENCE_SIZE] = { 0, };
272
273         if (timer->fd == NULL) {
274                 LOG_PLUGIN(DBG_ERR, "nmea fd is NULL");
275                 return FALSE;
276         }
277
278         if (nmea_data == NULL) {
279                 LOG_PLUGIN(DBG_ERR, "nmea_data is NULL");
280                 fclose(timer->fd);
281                 timer->fd = NULL;
282                 return FALSE;
283         }
284
285         while (fgets(buf, REPLAY_NMEA_SENTENCE_SIZE, timer->fd) != NULL) {
286                 if (strncmp(buf, "$GPGGA", 6) == 0) {
287                         ref++;
288                         if (ref > 1) {
289                                 fseek(timer->fd, -strlen(buf), SEEK_CUR);
290                                 LOG_PLUGIN(DBG_LOW, "2nd GPGGA : stop to read nmea data");
291                                 ret = TRUE;
292                                 break;
293                         } else if (ref == 1) {
294                                 LOG_PLUGIN(DBG_LOW, "1st GPGGA : start to read nmea data");
295                                 strncpy(nmea_data, buf, strlen(buf));
296                         }
297                 } else {
298                         if (strlen(nmea_data) + strlen(buf) > REPLAY_NMEA_SET_SIZE) {
299                                 LOG_PLUGIN(DBG_ERR, "read nmea data size is too long");
300                                 break;
301                         } else {
302                                 strncat(nmea_data, buf, strlen(buf));
303                         }
304                 }
305                 timer->nmea_data->len = strlen(buf);
306                 timer->nmea_data->data = buf;
307                 gps_plugin_replay_nmea_event(timer->nmea_data);
308         }
309
310         if (feof(timer->fd)) {
311                 LOG_PLUGIN(DBG_ERR, "end of file");
312                 rewind(timer->fd);
313                 ret = TRUE;
314         } else {
315                 LOG_PLUGIN(DBG_LOW, "read nmea data [%s]", nmea_data);
316         }
317         return ret;
318 }
319
320 gboolean gps_plugin_replay_read_manual(pos_data_t * pos_data)
321 {
322         gboolean ret = TRUE;
323
324         if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LATITUDE, &pos_data->latitude) == FALSE) {
325                 LOG_PLUGIN(DBG_ERR, "Fail to get latitude");
326                 ret = FALSE;
327         }
328         if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LONGITUDE, &pos_data->longitude) == FALSE) {
329                 LOG_PLUGIN(DBG_ERR, "Fail to get longitude");
330                 ret = FALSE;
331         }
332         if (setting_get_double(VCONFKEY_LOCATION_MANUAL_ALTITUDE, &pos_data->altitude) == FALSE) {
333                 LOG_PLUGIN(DBG_ERR, "Fail to get altitude");
334                 ret = FALSE;
335         }
336
337         return ret;
338 }
339
340 gboolean gps_plugin_replay_timeout_cb(gpointer data)
341 {
342         gboolean ret = FALSE;
343         read_error_t err = READ_SUCCESS;
344         char nmea_data[REPLAY_NMEA_SET_SIZE] = { 0, };
345         replay_timeout *timer = (replay_timeout *) data;
346
347         if (timer == NULL) {
348                 LOG_PLUGIN(DBG_ERR, "replay handel[timer] is NULL");
349                 return FALSE;
350         }
351
352         memset(timer->pos_data, 0, sizeof(pos_data_t));
353         memset(timer->batch_data, 0, sizeof(batch_data_t));
354         memset(timer->sv_data, 0, sizeof(sv_data_t));
355
356         if (timer->replay_mode == REPLAY_NMEA) {
357                 if (gps_plugin_replay_read_nmea(timer, nmea_data) == FALSE) {
358                         LOG_PLUGIN(DBG_ERR, "Fail to read nmea data from file");
359                         return FALSE;
360                 } else {
361                         err = nmea_parser(nmea_data, timer->pos_data, timer->sv_data);
362                         if (err == READ_ERROR) {
363                                 LOG_PLUGIN(DBG_ERR, "Fail to parser nmea data from file");
364                                 //return FALSE;
365                         } else if (err == READ_NOT_FIXED) {
366                                 LOG_PLUGIN(DBG_LOW, "GPS position is not fixed");
367                                 timer->sv_data->pos_valid = FALSE;
368                         }
369                 }
370         } else if (timer->replay_mode == REPLAY_MANUAL) {
371                 if (gps_plugin_replay_read_manual(timer->pos_data) == FALSE) {
372                         LOG_PLUGIN(DBG_ERR, "Fail to read manual data");
373                         err = READ_ERROR;
374                         return FALSE;
375                 } else {
376                         timer->sv_data->pos_valid = TRUE;
377                         err = READ_SUCCESS;
378                 }
379         } else if (timer->replay_mode == REPLAY_OFF) {
380                 LOG_PLUGIN(DBG_WARN, "replay_mode is OFF");
381                 err = READ_NOT_FIXED;
382                 timer->sv_data->pos_valid = FALSE;
383         }
384
385         if (g_gps_event_cb != NULL) {
386                 if (err != READ_NOT_FIXED) {
387                         gps_plugin_replay_pos_event(timer->pos_data);
388                 }
389                 gps_plugin_replay_sv_event(timer->sv_data);
390
391                 if (timer->batch_mode != BATCH_MODE_OFF){
392                         gps_plugin_replay_batch_event(timer->pos_data, timer);
393                 }
394         }
395         ret = TRUE;
396         return ret;
397 }
398
399 gboolean gps_plugin_batch_replay_timeout_cb(gpointer data)
400 {
401         gboolean ret = FALSE;
402         read_error_t err = READ_SUCCESS;
403         char nmea_data[REPLAY_NMEA_SET_SIZE] = { 0, };
404         replay_timeout *timer = (replay_timeout *) data;
405
406         if (timer == NULL) {
407                 LOG_PLUGIN(DBG_ERR, "replay handel[timer] is NULL");
408                 return FALSE;
409         }
410
411         memset(timer->pos_data, 0, sizeof(pos_data_t));
412         memset(timer->batch_data, 0, sizeof(batch_data_t));
413         memset(timer->sv_data, 0, sizeof(sv_data_t));
414
415         if (timer->replay_mode == REPLAY_NMEA) {
416                 if (gps_plugin_replay_read_nmea(timer, nmea_data) == FALSE) {
417                         LOG_PLUGIN(DBG_ERR, "Fail to read nmea data from file");
418                         return FALSE;
419                 } else {
420                         err = nmea_parser(nmea_data, timer->pos_data, timer->sv_data);
421                         if (err == READ_ERROR) {
422                                 LOG_PLUGIN(DBG_ERR, "Fail to parser nmea data from file");
423                         } else if (err == READ_NOT_FIXED) {
424                                 LOG_PLUGIN(DBG_LOW, "GPS position is not fixed");
425                                 timer->sv_data->pos_valid = FALSE;
426                         }
427                 }
428         } else if (timer->replay_mode == REPLAY_MANUAL) {
429                 if (gps_plugin_replay_read_manual(timer->pos_data) == FALSE) {
430                         LOG_PLUGIN(DBG_ERR, "Fail to read manual data");
431                         err = READ_ERROR;
432                         return FALSE;
433                 } else {
434                         timer->sv_data->pos_valid = TRUE;
435                         err = READ_SUCCESS;
436                 }
437         } else if (timer->replay_mode == REPLAY_OFF) {
438                 LOG_PLUGIN(DBG_WARN, "replay_mode is OFF");
439                 err = READ_NOT_FIXED;
440                 timer->sv_data->pos_valid = FALSE;
441         }
442
443         if (g_gps_event_cb != NULL) {
444
445                 if (timer->batch_mode != BATCH_MODE_OFF){
446                         gps_plugin_replay_batch_event(timer->pos_data, timer);
447                 }
448         }
449         ret = TRUE;
450         return ret;
451 }
452
453 void gps_plugin_stop_replay_mode(replay_timeout * timer)
454 {
455         if (timer->replay_mode == REPLAY_NMEA && fclose(timer->fd) != 0) {
456                 LOG_PLUGIN(DBG_ERR, "fclose failed");
457         }
458         timer->fd = NULL;
459
460         if (timer->timeout_src != NULL && timer->default_context != NULL && !g_source_is_destroyed(timer->timeout_src)) {
461                 if (timer->default_context == g_source_get_context(timer->timeout_src)) {
462                         g_source_destroy(timer->timeout_src);
463                         LOG_PLUGIN(DBG_LOW, "g_source_destroy timeout_src");
464                 } else {
465                         LOG_PLUGIN(DBG_WARN, "timer->timeout_src is attatched to 0x%x (actual 0x%x)",
466                                 g_source_get_context(timer->timeout_src), timer->default_context);
467                 }
468                 timer->timeout_src = NULL;
469                 timer->default_context = NULL;
470         } else {
471                 LOG_PLUGIN(DBG_WARN, "timeout_src or default_context is NULL or timeout_src is already destroyed");
472         }
473         gps_plugin_respond_stop_session();
474
475         display_unlock_state(LCD_OFF, PM_RESET_TIMER);
476         LOG_PLUGIN(DBG_LOW, "display_unlock_state(LCD_OFF, PM_RESET_TIMER);");
477 }
478
479 gboolean gps_plugin_get_nmea_fd(replay_timeout * timer)
480 {
481         char replay_file_path[256];
482         char *str;
483
484         str = setting_get_string(VCONFKEY_LOCATION_NMEA_FILE_NAME);
485         if (str == NULL) {
486                 return FALSE;
487         }
488         snprintf(replay_file_path, sizeof(replay_file_path), NMEA_FILE_PATH"%s", str);
489         SECLOG_PLUGIN(DBG_ERR, "replay file name : %s", replay_file_path);
490         free(str);
491
492         timer->fd = fopen(replay_file_path, "r");
493         if (timer->fd == NULL) {
494                 SECLOG_PLUGIN(DBG_ERR, "fopen(%s) failed", replay_file_path);
495                 timer->fd = fopen(DEFAULT_NMEA_LOG, "r");
496                 if (timer->fd == NULL) {
497                         SECLOG_PLUGIN(DBG_ERR, "fopen(%s) failed", DEFAULT_NMEA_LOG);
498                         return FALSE;
499                 }
500         }
501         return TRUE;
502 }
503
504 gboolean gps_plugin_start_replay_mode(replay_timeout * timer)
505 {
506         gboolean ret = FALSE;
507
508         if (timer->replay_mode == REPLAY_NMEA) {
509                 if (gps_plugin_get_nmea_fd(timer) == FALSE) {
510                         return FALSE;
511                 }
512         }
513
514         if (timer->default_context == NULL) {
515                 timer->default_context = g_main_context_default();
516                 if (timer->default_context == NULL) {
517                         return ret;
518                 }
519         }
520
521         if (timer->timeout_src != NULL) {
522                 LOG_PLUGIN(DBG_ERR, "timeout_src is already existed");
523                 ret = FALSE;
524         } else {
525                 timer->timeout_src = g_timeout_source_new_seconds(timer->interval);
526                 if (timer->timeout_src != NULL) {
527                         g_source_set_callback(timer->timeout_src, &gps_plugin_replay_timeout_cb, timer, NULL);
528                         if (g_source_attach(timer->timeout_src, timer->default_context) > 0) {
529                                 LOG_PLUGIN(DBG_LOW, "timeout_src(0x%x) is created & attatched to 0x%x", timer->timeout_src,
530                                         timer->default_context);
531                                 ret = TRUE;
532                         } else {
533                                 gps_plugin_stop_replay_mode(timer);
534                                 ret = FALSE;
535                         }
536                 }
537         }
538
539         display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
540         LOG_PLUGIN(DBG_LOW, "display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);");
541
542         gps_plugin_respond_start_session(ret);
543
544         return ret;
545 }
546
547 gboolean gps_plugin_start_batch_mode(replay_timeout * timer, int batch_interval, int batch_period)
548 {
549         gboolean ret = FALSE;
550         time_t timestamp;
551         time(&timestamp);
552
553         if (timer->replay_mode == REPLAY_NMEA) {
554                 if (gps_plugin_get_nmea_fd(timer) == FALSE) {
555                         return FALSE;
556                 }
557         }
558
559         if (timer->default_context == NULL) {
560                 timer->default_context = g_main_context_default();
561                 if (timer->default_context == NULL) {
562                         return ret;
563                 }
564         }
565
566         if (timer->timeout_src != NULL) {
567                 LOG_PLUGIN(DBG_ERR, "timeout_src is already existed");
568                 ret = FALSE;
569         } else {
570                 timer->timeout_src = g_timeout_source_new_seconds(batch_interval);
571                 if (timer->timeout_src != NULL) {
572                         g_source_set_callback(timer->timeout_src, &gps_plugin_batch_replay_timeout_cb, timer, NULL);
573                         if (g_source_attach(timer->timeout_src, timer->default_context) > 0) {
574                                 LOG_PLUGIN(DBG_LOW, "timeout_src(0x%x) is created & attatched to 0x%x", timer->timeout_src, timer->default_context);
575                                 ret = TRUE;
576                         } else {
577                                 gps_plugin_stop_replay_mode(timer);
578                                 ret = FALSE;
579                         }
580                 }
581         }
582
583         gps_plugin_respond_start_session(ret);
584
585         timer->batch_mode = BATCH_MODE_ON;
586         timer->batch_period = batch_period;
587         timer->batch_start_time = timestamp;
588
589         struct stat st = {0};
590         if (stat(LBS_SERVER_FOLDER, &st) == -1) {
591                 if (mkdir(LBS_SERVER_FOLDER, 0777) == -1) {
592                         LOG_PLUGIN(DBG_ERR, "Fail to create lbs-server folder");
593                         ret = FALSE;
594                 }
595         }
596
597         timer->batch_fd = fopen(BATCH_LOG, "w+");
598         if (timer->batch_fd == NULL) {
599                 LOG_PLUGIN(DBG_ERR, "Fail to file create for location batch mode");
600         }
601
602         return ret;
603 }
604
605 void gps_plugin_stop_batch_mode(replay_timeout * timer)
606 {
607         if (timer->batch_mode == BATCH_MODE_ON) {
608                 timer->batch_mode = BATCH_MODE_EXPIRED;
609         }
610 }
611
612 static void replay_mode_changed_cb(keynode_t * key, void *data)
613 {
614         if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &g_replay_timer->replay_mode) == FALSE) {
615                 g_replay_timer->replay_mode = REPLAY_OFF;
616         }
617
618         if (g_replay_timer->replay_mode == REPLAY_NMEA) {
619                 if (gps_plugin_get_nmea_fd(g_replay_timer) == FALSE) {
620                         LOG_PLUGIN(DBG_ERR, "Fail to get nmea fd.");
621                 }
622         } else {
623                 if (g_replay_timer->fd != NULL) {
624                         fclose(g_replay_timer->fd);
625                         g_replay_timer->fd = NULL;
626                 }
627         }
628         return;
629 }
630
631 replay_timeout *gps_plugin_replay_timer_init()
632 {
633         replay_timeout *timer = NULL;
634
635         timer = (replay_timeout *) malloc(sizeof(replay_timeout));
636         if (timer == NULL) {
637                 LOG_PLUGIN(DBG_ERR, "replay_timeout allocation is failed.");
638                 return NULL;
639         }
640
641         timer->fd = NULL;
642         timer->interval = 1;
643
644         timer->batch_fd = NULL;
645         timer->num_of_batch = 0;
646         timer->batch_mode = BATCH_MODE_OFF;
647
648         if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &timer->replay_mode) == FALSE) {
649                 timer->replay_mode = REPLAY_OFF;
650         }
651         setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
652
653         timer->pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
654         if (timer->pos_data == NULL) {
655                 LOG_PLUGIN(DBG_ERR, "pos_data allocation is failed.");
656                 free(timer);
657                 return NULL;
658         }
659
660         timer->batch_data = (batch_data_t *) malloc(sizeof(batch_data_t));
661         if (timer->batch_data == NULL) {
662                 LOG_PLUGIN(DBG_ERR, "batch_data allocation is failed.");
663                 free(timer->pos_data);
664                 free(timer);
665                 return NULL;
666         }
667
668         timer->sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
669         if (timer->sv_data == NULL) {
670                 LOG_PLUGIN(DBG_ERR, "sv_data allocation is failed.");
671                 free(timer->pos_data);
672                 free(timer->batch_data);
673                 free(timer);
674                 return NULL;
675         }
676
677         timer->nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
678         if (timer->nmea_data == NULL) {
679                 LOG_PLUGIN(DBG_ERR, "nmea_data allocation is failed.");
680                 free(timer->pos_data);
681                 free(timer->batch_data);
682                 free(timer->sv_data);
683                 free(timer);
684                 return NULL;
685         }
686
687         timer->timeout_src = NULL;
688         timer->default_context = NULL;
689
690         return timer;
691 }
692
693 void gps_plugin_replay_timer_deinit(replay_timeout * timer)
694 {
695         if (timer == NULL) {
696                 return;
697         }
698
699         if (timer->pos_data != NULL) {
700                 free(timer->pos_data);
701                 timer->pos_data = NULL;
702         }
703         if (timer->sv_data != NULL) {
704                 free(timer->sv_data);
705                 timer->sv_data = NULL;
706         }
707         if (timer->nmea_data != NULL) {
708                 free(timer->nmea_data);
709                 timer->nmea_data = NULL;
710         }
711
712         setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
713
714         free(timer);
715         timer = NULL;
716 }
717
718 int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, void *user_data)
719 {
720         g_gps_event_cb = gps_event_cb;
721         g_replay_timer = gps_plugin_replay_timer_init();
722         g_user_data = user_data;
723
724         return TRUE;
725 }
726
727 int gps_plugin_replay_gps_deinit(gps_failure_reason_t * reason_code)
728 {
729         gps_plugin_replay_timer_deinit(g_replay_timer);
730         g_gps_event_cb = NULL;
731         g_user_data = NULL;
732
733         return TRUE;
734 }
735
736 int gps_plugin_replay_gps_request(gps_action_t gps_action, void *gps_action_data, gps_failure_reason_t * reason_code)
737 {
738         gps_action_start_data_t *gps_start_data = gps_action_data;
739
740         switch (gps_action) {
741         case GPS_ACTION_SEND_PARAMS:
742                 break;
743         case GPS_ACTION_START_SESSION:
744                 gps_plugin_start_replay_mode(g_replay_timer);
745                 break;
746         case GPS_ACTION_STOP_SESSION:
747                 gps_plugin_stop_replay_mode(g_replay_timer);
748                 break;
749         case GPS_ACTION_START_BATCH:
750                 gps_plugin_start_batch_mode(g_replay_timer, gps_start_data->interval, gps_start_data->period);
751                 break;
752         case GPS_ACTION_STOP_BATCH:
753                 gps_plugin_stop_batch_mode(g_replay_timer);
754                 gps_plugin_stop_replay_mode(g_replay_timer);
755                 break;
756         case GPS_INDI_SUPL_VERIFICATION:
757         case GPS_INDI_SUPL_DNSQUERY:
758         case GPS_ACTION_START_FACTTEST:
759         case GPS_ACTION_STOP_FACTTEST:
760         case GPS_ACTION_REQUEST_SUPL_NI:
761                 LOG_PLUGIN(DBG_LOW, "Don't use action type : [ %d ]", gps_action);
762                 break;
763         default:
764                 break;
765         }
766
767         return TRUE;
768 }
769
770 EXPORT_API const gps_plugin_interface *get_gps_plugin_interface()
771 {
772         return &g_gps_plugin_replay_interface;
773 }