2 * gps-manager replay plugin
4 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
7 * Genie Kim <daejins.kim@samsung.com>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <gps_manager_plugin_intf.h>
31 #include "gps_plugin_debug.h"
32 #include "nmea_parser.h"
35 #define REPLAY_NMEA_SET_SIZE 4096
36 #define REPLAY_NMEA_SENTENCE_SIZE 128
38 gps_event_cb g_gps_event_cb = NULL;
47 nmea_data_t *nmea_data;
50 GMainContext *default_context;
53 replay_timeout *g_replay_timer = NULL;
55 int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, gps_server_param_t * gps_params);
56 int gps_plugin_replay_gps_deinit(gps_failure_reason_t * reason_code);
57 int gps_plugin_replay_gps_request(gps_action_t gps_action, void *data, gps_failure_reason_t * reason_code);
60 This is the interface that will be given to the gps-manager to call the API's of this plug-in module.
61 Init is called immediately after loading the plugin.
62 Deinit is called during the shut-down.
63 Request is called with specific parameter for the required operations.
65 static const gps_plugin_interface g_gps_plugin_replay_interface = {
66 gps_plugin_replay_gps_init,
67 gps_plugin_replay_gps_deinit,
68 gps_plugin_replay_gps_request
71 void gps_plugin_replay_pos_event(pos_data_t * data)
73 gps_event_info_t gps_event;
76 memset(&gps_event, 0, sizeof(gps_event_info_t));
79 gps_event.event_id = GPS_EVENT_REPORT_POSITION;
82 LOG_PLUGIN(DBG_ERR, "NULL POS data.");
83 gps_event.event_data.pos_ind.error = GPS_ERR_COMMUNICATION;
85 gps_event.event_data.pos_ind.error = GPS_ERR_NONE;
86 gps_event.event_data.pos_ind.pos.timestamp = timestamp;
87 gps_event.event_data.pos_ind.pos.latitude = data->latitude;
88 gps_event.event_data.pos_ind.pos.longitude = data->longitude;
89 gps_event.event_data.pos_ind.pos.altitude = data->altitude;
90 gps_event.event_data.pos_ind.pos.speed = data->speed;
91 gps_event.event_data.pos_ind.pos.bearing = data->bearing;
92 gps_event.event_data.pos_ind.pos.hor_accuracy = data->hor_accuracy;
93 gps_event.event_data.pos_ind.pos.ver_accuracy = data->ver_accuracy;
96 //LOG_PLUGIN(DBG_LOW, "%d", gps_event.event_data.pos_ind.pos.timestamp);
98 if (g_gps_event_cb != NULL) {
99 g_gps_event_cb(&gps_event);
103 void gps_plugin_replay_sv_event(sv_data_t * data)
106 gps_event_info_t gps_event;
109 memset(&gps_event, 0, sizeof(gps_event_info_t));
111 gps_event.event_id = GPS_EVENT_REPORT_SATELLITE;
114 LOG_PLUGIN(DBG_ERR, "NULL SV data.");
115 gps_event.event_data.sv_ind.error = GPS_ERR_COMMUNICATION;
117 gps_event.event_data.sv_ind.error = GPS_ERR_NONE;
118 gps_event.event_data.sv_ind.sv.timestamp = timestamp;
119 gps_event.event_data.sv_ind.sv.pos_valid = data->pos_valid;
120 gps_event.event_data.sv_ind.sv.num_of_sat = data->num_of_sat;
121 for (i = 0; i < data->num_of_sat; i++) {
122 gps_event.event_data.sv_ind.sv.sat[i].used = data->sat[i].used;
123 gps_event.event_data.sv_ind.sv.sat[i].prn = data->sat[i].prn;
124 gps_event.event_data.sv_ind.sv.sat[i].snr = data->sat[i].snr;
125 gps_event.event_data.sv_ind.sv.sat[i].elevation = data->sat[i].elevation;
126 gps_event.event_data.sv_ind.sv.sat[i].azimuth = data->sat[i].azimuth;
130 if (g_gps_event_cb != NULL) {
131 g_gps_event_cb(&gps_event);
135 void gps_plugin_replay_nmea_event(nmea_data_t * data)
137 gps_event_info_t gps_event;
140 memset(&gps_event, 0, sizeof(gps_event_info_t));
143 gps_event.event_id = GPS_EVENT_REPORT_NMEA;
146 LOG_PLUGIN(DBG_ERR, "NULL NMEA data.");
147 gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
149 if (data->len > REPLAY_NMEA_SENTENCE_SIZE) {
150 LOG_PLUGIN(DBG_WARN, "The Size of NMEA[ %d ] is larger then max ", data->len);
151 data->len = REPLAY_NMEA_SENTENCE_SIZE;
152 gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
154 gps_event.event_data.nmea_ind.error = GPS_ERR_NONE;
156 gps_event.event_data.nmea_ind.nmea.timestamp = timestamp;
157 gps_event.event_data.nmea_ind.nmea.len = data->len;
158 gps_event.event_data.nmea_ind.nmea.data = (char *)malloc(data->len);
159 memset(gps_event.event_data.nmea_ind.nmea.data, 0x00, data->len);
160 memcpy(gps_event.event_data.nmea_ind.nmea.data, data->data, data->len);
161 //LOG_PLUGIN(DBG_LOW, "NMEA[%d] : %s", gps_event.event_data.nmea_ind.nmea.len, gps_event.event_data.nmea_ind.nmea.data);
164 if (g_gps_event_cb != NULL) {
165 g_gps_event_cb(&gps_event);
168 if (gps_event.event_data.nmea_ind.nmea.data != NULL) {
169 free(gps_event.event_data.nmea_ind.nmea.data);
170 gps_event.event_data.nmea_ind.nmea.data = NULL;
174 void gps_plugin_respond_start_session(gboolean ret)
176 gps_event_info_t gps_event;
177 gps_event.event_id = GPS_EVENT_START_SESSION;
180 gps_event.event_data.start_session_rsp.error = GPS_ERR_NONE;
182 gps_event.event_data.start_session_rsp.error = GPS_ERR_COMMUNICATION;
185 if (g_gps_event_cb != NULL) {
186 g_gps_event_cb(&gps_event);
190 void gps_plugin_respond_stop_session(void)
192 gps_event_info_t gps_event;
194 gps_event.event_id = GPS_EVENT_STOP_SESSION;
195 gps_event.event_data.stop_session_rsp.error = GPS_ERR_NONE;
197 if (g_gps_event_cb != NULL) {
198 g_gps_event_cb(&gps_event);
202 gboolean gps_plugin_replay_read_nmea(replay_timeout * timer, char *nmea_data)
204 gboolean ret = FALSE;
206 char buf[REPLAY_NMEA_SENTENCE_SIZE] = { 0, };
208 if (timer->fd == NULL) {
209 LOG_PLUGIN(DBG_ERR, "nmea fd is NULL");
213 if (nmea_data == NULL) {
214 LOG_PLUGIN(DBG_ERR, "nmea_data is NULL");
220 while (fgets(buf, REPLAY_NMEA_SENTENCE_SIZE, timer->fd) != NULL) {
221 if (strncmp(buf, "$GPGGA", 6) == 0) {
224 fseek(timer->fd, -strlen(buf), SEEK_CUR);
225 LOG_PLUGIN(DBG_LOW, "2nd GPGGA : stop to read nmea data");
228 } else if (ref == 1) {
229 LOG_PLUGIN(DBG_LOW, "1st GPGGA : start to read nmea data");
230 strncpy(nmea_data, buf, strlen(buf));
233 if (strlen(nmea_data) + strlen(buf) > REPLAY_NMEA_SET_SIZE) {
234 LOG_PLUGIN(DBG_ERR, "read nmea data size is too long");
237 strncat(nmea_data, buf, strlen(buf));
240 timer->nmea_data->len = strlen(buf);
241 timer->nmea_data->data = buf;
242 gps_plugin_replay_nmea_event(timer->nmea_data);
245 if (feof(timer->fd)) {
246 LOG_PLUGIN(DBG_ERR, "end of file");
250 LOG_PLUGIN(DBG_LOW, "read nmea data [%s]", nmea_data);
255 gboolean gps_plugin_replay_read_manual(pos_data_t * pos_data)
259 if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LATITUDE, &pos_data->latitude) == FALSE) {
260 LOG_PLUGIN(DBG_ERR, "Fail to get latitude");
263 if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LONGITUDE, &pos_data->longitude) == FALSE) {
264 LOG_PLUGIN(DBG_ERR, "Fail to get longitude");
267 if (setting_get_double(VCONFKEY_LOCATION_MANUAL_ALTITUDE, &pos_data->altitude) == FALSE) {
268 LOG_PLUGIN(DBG_ERR, "Fail to get altitude");
275 gboolean gps_plugin_replay_timeout_cb(gpointer data)
277 gboolean ret = FALSE;
278 read_error_t err = READ_SUCCESS;
279 char nmea_data[REPLAY_NMEA_SET_SIZE] = { 0, };
280 replay_timeout *timer = (replay_timeout *) data;
283 LOG_PLUGIN(DBG_ERR, "replay handel[timer] is NULL");
287 memset(timer->pos_data, 0, sizeof(pos_data_t));
288 memset(timer->sv_data, 0, sizeof(sv_data_t));
290 if (timer->replay_mode == REPLAY_NMEA) {
291 if (gps_plugin_replay_read_nmea(timer, nmea_data) == FALSE) {
292 LOG_PLUGIN(DBG_ERR, "Fail to read nmea data from file");
295 err = nmea_parser(nmea_data, timer->pos_data, timer->sv_data);
296 if (err == READ_ERROR) {
297 LOG_PLUGIN(DBG_ERR, "Fail to parser nmea data from file");
299 } else if (err == READ_NOT_FIXED) {
300 LOG_PLUGIN(DBG_LOW, "GPS position is not fixed");
301 timer->sv_data->pos_valid = FALSE;
304 } else if (timer->replay_mode == REPLAY_MANUAL) {
305 if (gps_plugin_replay_read_manual(timer->pos_data) == FALSE) {
306 LOG_PLUGIN(DBG_ERR, "Fail to read manual data");
310 timer->sv_data->pos_valid = TRUE;
313 } else if (timer->replay_mode == REPLAY_OFF) {
314 LOG_PLUGIN(DBG_WARN, "replay_mode is OFF");
315 err = READ_NOT_FIXED;
316 timer->sv_data->pos_valid = FALSE;
319 if (g_gps_event_cb != NULL) {
320 if (err != READ_NOT_FIXED) {
321 gps_plugin_replay_pos_event(timer->pos_data);
323 gps_plugin_replay_sv_event(timer->sv_data);
329 void gps_plugin_stop_replay_mode(replay_timeout * timer)
331 if (timer->replay_mode == REPLAY_NMEA && fclose(timer->fd) != 0) {
332 LOG_PLUGIN(DBG_ERR, "fclose failed");
336 if (timer->timeout_src != NULL && timer->default_context != NULL && !g_source_is_destroyed(timer->timeout_src)) {
337 if (timer->default_context == g_source_get_context(timer->timeout_src)) {
338 g_source_destroy(timer->timeout_src);
339 LOG_PLUGIN(DBG_LOW, "g_source_destroy timeout_src");
341 LOG_PLUGIN(DBG_WARN, "timer->timeout_src is attatched to 0x%x (actual 0x%x)",
342 g_source_get_context(timer->timeout_src), timer->default_context);
344 timer->timeout_src = NULL;
345 timer->default_context = NULL;
347 LOG_PLUGIN(DBG_WARN, "timeout_src or default_context is NULL or timeout_src is already destroyed");
349 gps_plugin_respond_stop_session();
352 gboolean gps_plugin_get_nmea_fd(replay_timeout * timer)
354 char replay_file_path[256];
356 snprintf(replay_file_path, sizeof(replay_file_path), NMEA_FILE_PATH"%s", setting_get_string(VCONFKEY_LOCATION_NMEA_FILE_NAME));
357 LOG_PLUGIN(DBG_ERR, "replay file name : %s", replay_file_path);
359 timer->fd = fopen(replay_file_path, "r");
360 if (timer->fd == NULL) {
361 LOG_PLUGIN(DBG_ERR, "fopen(%s) failed", replay_file_path);
362 timer->fd = fopen(DEFAULT_NMEA_LOG, "r");
363 if (timer->fd == NULL) {
364 LOG_PLUGIN(DBG_ERR, "fopen(%s) failed", DEFAULT_NMEA_LOG);
371 gboolean gps_plugin_start_replay_mode(replay_timeout * timer)
373 gboolean ret = FALSE;
375 if (timer->replay_mode == REPLAY_NMEA) {
376 if (gps_plugin_get_nmea_fd(timer) == FALSE) {
381 if (timer->default_context == NULL) {
382 timer->default_context = g_main_context_default();
383 if (timer->default_context == NULL) {
388 if (timer->timeout_src != NULL) {
389 LOG_PLUGIN(DBG_ERR, "timeout_src is already existed");
392 timer->timeout_src = g_timeout_source_new_seconds(timer->interval);
393 if (timer->timeout_src != NULL) {
394 g_source_set_callback(timer->timeout_src, &gps_plugin_replay_timeout_cb, timer, NULL);
395 if (g_source_attach(timer->timeout_src, timer->default_context) > 0) {
396 LOG_PLUGIN(DBG_LOW, "timeout_src(0x%x) is created & attatched to 0x%x", timer->timeout_src,
397 timer->default_context);
400 gps_plugin_stop_replay_mode(timer);
405 gps_plugin_respond_start_session(ret);
410 static void replay_mode_changed_cb(keynode_t * key, void *data)
412 if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &g_replay_timer->replay_mode) == FALSE) {
413 g_replay_timer->replay_mode = REPLAY_OFF;
416 if (g_replay_timer->replay_mode == REPLAY_NMEA) {
417 if (gps_plugin_get_nmea_fd(g_replay_timer) == FALSE) {
418 LOG_PLUGIN(DBG_ERR, "Fail to get nmea fd.");
421 if (g_replay_timer->fd != NULL) {
422 fclose(g_replay_timer->fd);
423 g_replay_timer->fd = NULL;
429 replay_timeout *gps_plugin_replay_timer_init()
431 replay_timeout *timer = NULL;
433 timer = (replay_timeout *) malloc(sizeof(replay_timeout));
435 LOG_PLUGIN(DBG_ERR, "replay_timeout allocation is failed.");
441 if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &timer->replay_mode) == FALSE) {
442 timer->replay_mode = REPLAY_OFF;
444 setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
446 timer->pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
447 if (timer->pos_data == NULL) {
448 LOG_PLUGIN(DBG_ERR, "pos_data allocation is failed.");
453 timer->sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
454 if (timer->sv_data == NULL) {
455 LOG_PLUGIN(DBG_ERR, "sv_data allocation is failed.");
456 free(timer->pos_data);
461 timer->nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
462 if (timer->nmea_data == NULL) {
463 LOG_PLUGIN(DBG_ERR, "nmea_data allocation is failed.");
464 free(timer->pos_data);
465 free(timer->sv_data);
470 timer->timeout_src = NULL;
471 timer->default_context = NULL;
476 void gps_plugin_replay_timer_deinit(replay_timeout * timer)
482 if (timer->pos_data != NULL) {
483 free(timer->pos_data);
484 timer->pos_data = NULL;
486 if (timer->sv_data != NULL) {
487 free(timer->sv_data);
488 timer->sv_data = NULL;
490 if (timer->nmea_data != NULL) {
491 free(timer->nmea_data);
492 timer->nmea_data = NULL;
495 setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
501 int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, gps_server_param_t * gps_params)
503 g_gps_event_cb = gps_event_cb;
504 g_replay_timer = gps_plugin_replay_timer_init();
509 int gps_plugin_replay_gps_deinit(gps_failure_reason_t * reason_code)
511 gps_plugin_replay_timer_deinit(g_replay_timer);
516 int gps_plugin_replay_gps_request(gps_action_t gps_action, void *data, gps_failure_reason_t * reason_code)
518 switch (gps_action) {
519 case GPS_ACTION_SEND_PARAMS:
521 case GPS_ACTION_START_SESSION:
522 gps_plugin_start_replay_mode(g_replay_timer);
524 case GPS_ACTION_STOP_SESSION:
525 gps_plugin_stop_replay_mode(g_replay_timer);
527 case GPS_INDI_SUPL_VERIFICATION:
528 case GPS_INDI_SUPL_DNSQUERY:
529 case GPS_ACTION_START_FACTTEST:
530 case GPS_ACTION_STOP_FACTTEST:
531 case GPS_ACTION_REQUEST_SUPL_NI:
532 LOG_PLUGIN(DBG_LOW, "Don't use action type : [ %d ]", gps_action);
541 EXPORT_API const gps_plugin_interface *get_gps_plugin_interface()
543 return &g_gps_plugin_replay_interface;