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