--- /dev/null
+Kyoungjun Sung <kj7.sung@samsung.com>
--- /dev/null
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(lbs-plugin-gps-artik7 C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+#Dependencies
+
+# Set required packages
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED glib-2.0 vconf dlog lbs-server-plugin libtzplatform-config capi-system-peripheral-io)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fvisibility=hidden -fPIC")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS(" -DEXPORT_API=\"__attribute__((visibility(\\\"default\\\")))\" ")
+
+MESSAGE(${CMAKE_C_FLAGS})
+
+ADD_SUBDIRECTORY(gps-plugin)
--- /dev/null
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+ Apache License\r
+ Version 2.0, January 2004\r
+ http://www.apache.org/licenses/\r
+\r
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+ 1. Definitions.\r
+\r
+ "License" shall mean the terms and conditions for use, reproduction,\r
+ and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+ "Licensor" shall mean the copyright owner or entity authorized by\r
+ the copyright owner that is granting the License.\r
+\r
+ "Legal Entity" shall mean the union of the acting entity and all\r
+ other entities that control, are controlled by, or are under common\r
+ control with that entity. For the purposes of this definition,\r
+ "control" means (i) the power, direct or indirect, to cause the\r
+ direction or management of such entity, whether by contract or\r
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+ outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+ "You" (or "Your") shall mean an individual or Legal Entity\r
+ exercising permissions granted by this License.\r
+\r
+ "Source" form shall mean the preferred form for making modifications,\r
+ including but not limited to software source code, documentation\r
+ source, and configuration files.\r
+\r
+ "Object" form shall mean any form resulting from mechanical\r
+ transformation or translation of a Source form, including but\r
+ not limited to compiled object code, generated documentation,\r
+ and conversions to other media types.\r
+\r
+ "Work" shall mean the work of authorship, whether in Source or\r
+ Object form, made available under the License, as indicated by a\r
+ copyright notice that is included in or attached to the work\r
+ (an example is provided in the Appendix below).\r
+\r
+ "Derivative Works" shall mean any work, whether in Source or Object\r
+ form, that is based on (or derived from) the Work and for which the\r
+ editorial revisions, annotations, elaborations, or other modifications\r
+ represent, as a whole, an original work of authorship. For the purposes\r
+ of this License, Derivative Works shall not include works that remain\r
+ separable from, or merely link (or bind by name) to the interfaces of,\r
+ the Work and Derivative Works thereof.\r
+\r
+ "Contribution" shall mean any work of authorship, including\r
+ the original version of the Work and any modifications or additions\r
+ to that Work or Derivative Works thereof, that is intentionally\r
+ submitted to Licensor for inclusion in the Work by the copyright owner\r
+ or by an individual or Legal Entity authorized to submit on behalf of\r
+ the copyright owner. For the purposes of this definition, "submitted"\r
+ means any form of electronic, verbal, or written communication sent\r
+ to the Licensor or its representatives, including but not limited to\r
+ communication on electronic mailing lists, source code control systems,\r
+ and issue tracking systems that are managed by, or on behalf of, the\r
+ Licensor for the purpose of discussing and improving the Work, but\r
+ excluding communication that is conspicuously marked or otherwise\r
+ designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+ "Contributor" shall mean Licensor and any individual or Legal Entity\r
+ on behalf of whom a Contribution has been received by Licensor and\r
+ subsequently incorporated within the Work.\r
+\r
+ 2. Grant of Copyright License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ copyright license to reproduce, prepare Derivative Works of,\r
+ publicly display, publicly perform, sublicense, and distribute the\r
+ Work and such Derivative Works in Source or Object form.\r
+\r
+ 3. Grant of Patent License. Subject to the terms and conditions of\r
+ this License, each Contributor hereby grants to You a perpetual,\r
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+ (except as stated in this section) patent license to make, have made,\r
+ use, offer to sell, sell, import, and otherwise transfer the Work,\r
+ where such license applies only to those patent claims licensable\r
+ by such Contributor that are necessarily infringed by their\r
+ Contribution(s) alone or by combination of their Contribution(s)\r
+ with the Work to which such Contribution(s) was submitted. If You\r
+ institute patent litigation against any entity (including a\r
+ cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+ or a Contribution incorporated within the Work constitutes direct\r
+ or contributory patent infringement, then any patent licenses\r
+ granted to You under this License for that Work shall terminate\r
+ as of the date such litigation is filed.\r
+\r
+ 4. Redistribution. You may reproduce and distribute copies of the\r
+ Work or Derivative Works thereof in any medium, with or without\r
+ modifications, and in Source or Object form, provided that You\r
+ meet the following conditions:\r
+\r
+ (a) You must give any other recipients of the Work or\r
+ Derivative Works a copy of this License; and\r
+\r
+ (b) You must cause any modified files to carry prominent notices\r
+ stating that You changed the files; and\r
+\r
+ (c) You must retain, in the Source form of any Derivative Works\r
+ that You distribute, all copyright, patent, trademark, and\r
+ attribution notices from the Source form of the Work,\r
+ excluding those notices that do not pertain to any part of\r
+ the Derivative Works; and\r
+\r
+ (d) If the Work includes a "NOTICE" text file as part of its\r
+ distribution, then any Derivative Works that You distribute must\r
+ include a readable copy of the attribution notices contained\r
+ within such NOTICE file, excluding those notices that do not\r
+ pertain to any part of the Derivative Works, in at least one\r
+ of the following places: within a NOTICE text file distributed\r
+ as part of the Derivative Works; within the Source form or\r
+ documentation, if provided along with the Derivative Works; or,\r
+ within a display generated by the Derivative Works, if and\r
+ wherever such third-party notices normally appear. The contents\r
+ of the NOTICE file are for informational purposes only and\r
+ do not modify the License. You may add Your own attribution\r
+ notices within Derivative Works that You distribute, alongside\r
+ or as an addendum to the NOTICE text from the Work, provided\r
+ that such additional attribution notices cannot be construed\r
+ as modifying the License.\r
+\r
+ You may add Your own copyright statement to Your modifications and\r
+ may provide additional or different license terms and conditions\r
+ for use, reproduction, or distribution of Your modifications, or\r
+ for any such Derivative Works as a whole, provided Your use,\r
+ reproduction, and distribution of the Work otherwise complies with\r
+ the conditions stated in this License.\r
+\r
+ 5. Submission of Contributions. Unless You explicitly state otherwise,\r
+ any Contribution intentionally submitted for inclusion in the Work\r
+ by You to the Licensor shall be under the terms and conditions of\r
+ this License, without any additional terms or conditions.\r
+ Notwithstanding the above, nothing herein shall supersede or modify\r
+ the terms of any separate license agreement you may have executed\r
+ with Licensor regarding such Contributions.\r
+\r
+ 6. Trademarks. This License does not grant permission to use the trade\r
+ names, trademarks, service marks, or product names of the Licensor,\r
+ except as required for reasonable and customary use in describing the\r
+ origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+ 7. Disclaimer of Warranty. Unless required by applicable law or\r
+ agreed to in writing, Licensor provides the Work (and each\r
+ Contributor provides its Contributions) on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+ implied, including, without limitation, any warranties or conditions\r
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+ PARTICULAR PURPOSE. You are solely responsible for determining the\r
+ appropriateness of using or redistributing the Work and assume any\r
+ risks associated with Your exercise of permissions under this License.\r
+\r
+ 8. Limitation of Liability. In no event and under no legal theory,\r
+ whether in tort (including negligence), contract, or otherwise,\r
+ unless required by applicable law (such as deliberate and grossly\r
+ negligent acts) or agreed to in writing, shall any Contributor be\r
+ liable to You for damages, including any direct, indirect, special,\r
+ incidental, or consequential damages of any character arising as a\r
+ result of this License or out of the use or inability to use the\r
+ Work (including but not limited to damages for loss of goodwill,\r
+ work stoppage, computer failure or malfunction, or any and all\r
+ other commercial damages or losses), even if such Contributor\r
+ has been advised of the possibility of such damages.\r
+\r
+ 9. Accepting Warranty or Additional Liability. While redistributing\r
+ the Work or Derivative Works thereof, You may choose to offer,\r
+ and charge a fee for, acceptance of support, warranty, indemnity,\r
+ or other liability obligations and/or rights consistent with this\r
+ License. However, in accepting such obligations, You may act only\r
+ on Your own behalf and on Your sole responsibility, not on behalf\r
+ of any other Contributor, and only if You agree to indemnify,\r
+ defend, and hold each Contributor harmless for any liability\r
+ incurred by, or claims asserted against, such Contributor by reason\r
+ of your accepting any such warranty or additional liability.\r
+\r
+ END OF TERMS AND CONDITIONS\r
+\r
+ APPENDIX: How to apply the Apache License to your work.\r
+\r
+ To apply the Apache License to your work, attach the following\r
+ boilerplate notice, with the fields enclosed by brackets "[]"\r
+ replaced with your own identifying information. (Don't include\r
+ the brackets!) The text should be enclosed in the appropriate\r
+ comment syntax for the file format. We also recommend that a\r
+ file or class name and description of purpose be included on the\r
+ same "printed page" as the copyright notice for easier\r
+ identification within third-party archives.\r
+\r
+ Copyright [yyyy] [name of copyright owner]\r
+\r
+ Licensed under the Apache License, Version 2.0 (the "License");\r
+ you may not use this file except in compliance with the License.\r
+ You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
--- /dev/null
+aux_source_directory(src SOURCES)
+
+INCLUDE_DIRECTORIES(include)
+
+SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined -Wl,--as-needed")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SOURCES})
+
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME}
+ PROPERTIES
+ VERSION ${FULLVER}
+ SOVERSION ${MAJORVER}
+ CLEAN_DIRECT_OUTPUT 1
+ )
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIB_DIR})
--- /dev/null
+/*
+ * gps-manager replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GPS_PLUGIN_DEBUG_H__
+#define __GPS_PLUGIN_DEBUG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GPS_DLOG
+#define GPS_DLOG_DEBUG /* filename and line number will be shown */
+
+#ifdef GPS_DLOG
+#include <dlog.h>
+#define TAG_GPS_PLUGIN "LBS_REPLAY"
+
+#define DBG_LOW LOG_DEBUG
+#define DBG_INFO LOG_INFO
+#define DBG_WARN LOG_WARN
+#define DBG_ERR LOG_ERROR
+
+#ifdef GPS_DLOG_DEBUG /* Debug mode */
+#define LOG_PLUGIN(dbg_lvl, fmt, args...) SLOG(dbg_lvl, TAG_GPS_PLUGIN, fmt, ##args)
+#define SECLOG_PLUGIN(dbg_lvl, fmt, args...) SECURE_SLOG(dbg_lvl, TAG_GPS_PLUGIN, "[%-40s: %-4d] "fmt, __FILE__, __LINE__, ##args)
+#else /* Release(commercial) mode */
+#define LOG_PLUGIN(dbg_lvl, fmt, args...) SLOG(dbg_lvl, TAG_GPS_PLUGIN, fmt, ##args)
+#define SECLOG_PLUGIN(dbg_lvl, fmt, args...) SECURE_SLOG(dbg_lvl, TAG_GPS_PLUGIN, fmt, ##args)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
+/*
+ * gps-manager replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef NMEA_PARSER_H
+#define NMEA_PARSER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+int nmea_parser(char *data, pos_data_t *pos, sv_data_t *sv);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
--- /dev/null
+/*
+ * gps-manager replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _SETTING_H_
+#define _SETTING_H_
+
+#include <vconf.h>
+#include <vconf-internal-location-keys.h>
+
+
+typedef enum {
+ REPLAY_OFF = 0,
+ REPLAY_NMEA,
+ REPLAY_MANUAL,
+ REPLAY_MODE_MAX
+} replay_mode_t;
+
+typedef enum {
+ BATCH_MODE_OFF = 0,
+ BATCH_MODE_ON
+} batch_mode_t;
+
+typedef enum {
+ READ_ERROR = -1,
+ READ_SUCCESS = 0,
+ READ_NOT_FIXED = 1,
+} read_error_t;
+
+int setting_get_int(const char *path, int *val);
+int setting_get_double(const char *path, double *val);
+char *setting_get_string(const char *path);
+
+typedef void (*key_changed_cb)(keynode_t *key, void *data);
+
+int setting_notify_key_changed(const char *path, void *key_changed_cb);
+int setting_ignore_key_changed(const char *path, void *key_changed_cb);
+#endif /* _SETTING_H_ */
--- /dev/null
+/*
+ * gps replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <gps_plugin_intf.h>
+#include <tzplatform_config.h>
+
+#include "gps_plugin_debug.h"
+#include "nmea_parser.h"
+#include "setting.h"
+
+#include "peripheral_io.h"
+#include "peripheral_gdbus_i2c.h"
+#include "peripheral_common.h"
+#include "peripheral_internal.h"
+
+#define REPLAY_NMEA_SET_SIZE 4096
+#define REPLAY_NMEA_SENTENCE_SIZE 128
+
+/*
+ * NMEA PACKET CMD for BerryGPS-IMU
+ */
+#define PMK_CMD_WAKEUP_MODE "$PMTK161,1*28\r\n"
+#define PMK_CMD_STANDBY_MODE "$PMTK161,0*28\r\n"
+
+/*
+ * ARTIK7 UART PORT has only one.
+ */
+#define GPS_UART_PORT 4
+#define GPS_UART_BUFF_SIZE 1024
+
+gps_event_cb g_gps_event_cb = NULL;
+void *g_user_data = NULL;
+
+peripheral_uart_h uart_hndl = NULL;
+
+typedef struct {
+ FILE *fd;
+ FILE *batch_fd;
+ int interval;
+ int replay_mode;
+ int lcd_mode;
+
+ int batch_mode;
+ int batch_client_count;
+ int batch_interval;
+ int batch_period;
+ int num_of_batch;
+ time_t batch_start_time;
+ gboolean is_flush;
+
+ pos_data_t *pos_data;
+ batch_data_t *batch_data;
+ sv_data_t *sv_data;
+ nmea_data_t *nmea_data;
+
+ GSource *timeout_src;
+ GMainContext *default_context;
+} replay_timeout;
+
+replay_timeout *g_replay_timer = NULL;
+
+int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, void *user_data);
+int gps_plugin_replay_gps_deinit(gps_failure_reason_t *reason_code);
+int gps_plugin_replay_gps_request(gps_action_t gps_action, void *gps_action_data, gps_failure_reason_t *reason_code);
+
+static const gps_plugin_interface g_gps_plugin_replay_interface = {
+ gps_plugin_replay_gps_init,
+ gps_plugin_replay_gps_deinit,
+ gps_plugin_replay_gps_request
+};
+
+static int gps_uart_close()
+{
+ int ret;
+
+ ret = peripheral_uart_close(uart_hndl);
+ if (ret < 0 ) {
+ _E("GPS Uart Port Close failed !!");
+ return FALSE;
+ }
+ uart_hndl = NULL;
+ _D("GPS Uart Port Close Successful !!");
+ return TRUE;
+}
+
+static int gps_uart_open()
+{
+ int ret;
+
+ ret = peripheral_uart_open(GPS_UART_PORT, &uart_hndl);
+ if (ret < 0 ) {
+ _E("GPS Uart Port Open failed !!");
+ return FALSE;
+ }
+ _D("GPS Uart Port Open Successful !!");
+ ret = peripheral_uart_set_baudrate(uart_hndl, PERIPHERAL_UART_BAUDRATE_9600);
+ if (ret < 0) {
+ _E("GPS Uart Port Open failed !!");
+ goto ERROR;
+ }
+ ret = peripheral_uart_set_mode(uart_hndl,
+ PERIPHERAL_UART_BYTESIZE_8BIT,
+ PERIPHERAL_UART_PARITY_NONE,
+ PERIPHERAL_UART_STOPBITS_1BIT);
+ if (ret < 0) {
+ _E("GPS Uart Set Mode failed !!");
+ goto ERROR;
+ }
+ ret = peripheral_uart_set_flowcontrol(uart_hndl, true, false);
+ if (ret < 0) {
+ _E("GPS Uart Set Flow Control Open failed !!");
+ goto ERROR;
+ }
+ ret = peripheral_uart_flush(uart_hndl);
+ if (ret < 0) {
+ _E("GPS Uart Flush failed !!");
+ goto ERROR;
+ }
+ return TRUE;
+ERROR:
+ gps_uart_close();
+ return FALSE;
+}
+
+static int gps_uart_read(char *buf, int len)
+{
+ int length;
+
+ /* ERROR if the length is less than 0 */
+ if ((length = peripheral_uart_read(uart_hndl, (uint8_t *)buf, len)) < PERIPHERAL_ERROR_NONE)
+ _E("GPS Uart Read failed !!");
+
+ return length;
+}
+
+void gps_plugin_replay_pos_event(pos_data_t *data)
+{
+ gps_event_info_t gps_event;
+ time_t timestamp;
+
+ memset(&gps_event, 0, sizeof(gps_event_info_t));
+ time(×tamp);
+
+ gps_event.event_id = GPS_EVENT_REPORT_POSITION;
+
+ if (data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "NULL POS data.");
+ gps_event.event_data.pos_ind.error = GPS_ERR_COMMUNICATION;
+ } else {
+ gps_event.event_data.pos_ind.error = GPS_ERR_NONE;
+ gps_event.event_data.pos_ind.pos.timestamp = timestamp;
+ gps_event.event_data.pos_ind.pos.latitude = data->latitude;
+ gps_event.event_data.pos_ind.pos.longitude = data->longitude;
+ gps_event.event_data.pos_ind.pos.altitude = data->altitude;
+ gps_event.event_data.pos_ind.pos.speed = data->speed;
+ gps_event.event_data.pos_ind.pos.bearing = data->bearing;
+ gps_event.event_data.pos_ind.pos.hor_accuracy = data->hor_accuracy;
+ gps_event.event_data.pos_ind.pos.ver_accuracy = data->ver_accuracy;
+ }
+
+ if (g_gps_event_cb != NULL)
+ g_gps_event_cb(&gps_event, g_user_data);
+}
+
+void gps_plugin_replay_batch_event(pos_data_t *data, replay_timeout *timer)
+{
+ char buf[256] = {0, };
+ time_t timestamp;
+ time(×tamp);
+
+ const char *batch_path = tzplatform_mkpath(TZ_SYS_MEDIA, "lbs-server/location_batch.log");
+ if (timer->batch_fd == NULL) {
+
+ struct stat st = {0};
+ const char *lbs_server_path = tzplatform_mkpath(TZ_SYS_MEDIA, "lbs-server");
+ if (stat(lbs_server_path, &st) == -1) {
+ if (mkdir(lbs_server_path, 0777) == -1) {
+ LOG_PLUGIN(DBG_ERR, "Fail to create lbs-server folder");
+ return ;
+ }
+ }
+
+ timer->batch_fd = fopen(batch_path, "w+");
+ if (timer->batch_fd == NULL) {
+ LOG_PLUGIN(DBG_ERR, "Fail to open file [Not available batch_fd]");
+ return ;
+ }
+ }
+
+ if (data != NULL) {
+
+ g_snprintf(buf, 256, "%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);
+ LOG_PLUGIN(DBG_LOW, "Add location info to batch file [%s]", buf);
+ }
+
+ if (timer->lcd_mode == VCONFKEY_PM_STATE_NORMAL) {
+ fwrite(buf, 1, strlen(buf), timer->batch_fd);
+
+ (timer->num_of_batch)++ ;
+ timer->is_flush = TRUE;
+ } else {
+ if ((timestamp - timer->batch_start_time) % timer->batch_interval == 0) {
+ fwrite(buf, 1, strlen(buf), timer->batch_fd);
+ (timer->num_of_batch)++ ;
+ }
+ if ((timestamp - timer->batch_start_time) >= timer->batch_period)
+ timer->is_flush = TRUE;
+ }
+
+ if (timer->is_flush) {
+ LOG_PLUGIN(DBG_LOW, "Batch invoked, Batch interval is expired or Batch stopped");
+ gps_event_info_t gps_event;
+ memset(&gps_event, 0, sizeof(gps_event_info_t));
+
+ if (timer->batch_fd != NULL) {
+ if (fclose(timer->batch_fd) != 0)
+ LOG_PLUGIN(DBG_ERR, "Fail to close file");
+ timer->batch_fd = NULL;
+ }
+
+ gps_event.event_id = GPS_EVENT_REPORT_BATCH;
+ timer->batch_start_time = timestamp;
+ timer->is_flush = FALSE;
+
+ if (timer->num_of_batch < 1) {
+ LOG_PLUGIN(DBG_ERR, "There is no Batch data");
+ gps_event.event_data.batch_ind.error = GPS_ERR_COMMUNICATION;
+ } else {
+ gps_event.event_data.batch_ind.error = GPS_ERR_NONE;
+ gps_event.event_data.batch_ind.batch.num_of_location = timer->num_of_batch;
+ }
+
+ if (g_gps_event_cb != NULL) {
+ g_gps_event_cb(&gps_event, g_user_data);
+ timer->num_of_batch = 0;
+ }
+ }
+}
+
+void gps_plugin_replay_sv_event(sv_data_t *data)
+{
+ int i;
+ gps_event_info_t gps_event;
+ time_t timestamp;
+
+ memset(&gps_event, 0, sizeof(gps_event_info_t));
+ time(×tamp);
+ gps_event.event_id = GPS_EVENT_REPORT_SATELLITE;
+
+ if (data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "NULL SV data.");
+ gps_event.event_data.sv_ind.error = GPS_ERR_COMMUNICATION;
+ } else {
+ gps_event.event_data.sv_ind.error = GPS_ERR_NONE;
+ gps_event.event_data.sv_ind.sv.timestamp = timestamp;
+ gps_event.event_data.sv_ind.sv.pos_valid = data->pos_valid;
+ gps_event.event_data.sv_ind.sv.num_of_sat = data->num_of_sat;
+ for (i = 0; i < data->num_of_sat; i++) {
+ gps_event.event_data.sv_ind.sv.sat[i].used = data->sat[i].used;
+ gps_event.event_data.sv_ind.sv.sat[i].prn = data->sat[i].prn;
+ gps_event.event_data.sv_ind.sv.sat[i].snr = data->sat[i].snr;
+ gps_event.event_data.sv_ind.sv.sat[i].elevation = data->sat[i].elevation;
+ gps_event.event_data.sv_ind.sv.sat[i].azimuth = data->sat[i].azimuth;
+ }
+ }
+
+ if (g_gps_event_cb != NULL)
+ g_gps_event_cb(&gps_event, g_user_data);
+}
+
+void gps_plugin_replay_nmea_event(nmea_data_t *data)
+{
+ gps_event_info_t gps_event;
+ time_t timestamp;
+
+ memset(&gps_event, 0, sizeof(gps_event_info_t));
+ time(×tamp);
+
+ gps_event.event_id = GPS_EVENT_REPORT_NMEA;
+
+ if (data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "NULL NMEA data.");
+ gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
+ } else {
+ if (data->len > REPLAY_NMEA_SENTENCE_SIZE) {
+ LOG_PLUGIN(DBG_WARN, "The Size of NMEA[ %d ] is larger then max ", data->len);
+ data->len = REPLAY_NMEA_SENTENCE_SIZE;
+ gps_event.event_data.nmea_ind.error = GPS_ERR_COMMUNICATION;
+ } else {
+ gps_event.event_data.nmea_ind.error = GPS_ERR_NONE;
+ }
+ gps_event.event_data.nmea_ind.nmea.timestamp = timestamp;
+ gps_event.event_data.nmea_ind.nmea.len = data->len;
+ gps_event.event_data.nmea_ind.nmea.data = (char *)malloc(data->len);
+ g_return_if_fail(gps_event.event_data.nmea_ind.nmea.data);
+
+ memset(gps_event.event_data.nmea_ind.nmea.data, 0x00, data->len);
+ memcpy(gps_event.event_data.nmea_ind.nmea.data, data->data, data->len);
+ }
+
+ if (g_gps_event_cb != NULL)
+ g_gps_event_cb(&gps_event, g_user_data);
+
+ if (gps_event.event_data.nmea_ind.nmea.data != NULL) {
+ free(gps_event.event_data.nmea_ind.nmea.data);
+ gps_event.event_data.nmea_ind.nmea.data = NULL;
+ }
+}
+
+void gps_plugin_respond_start_session(gboolean ret)
+{
+ gps_event_info_t gps_event;
+ gps_event.event_id = GPS_EVENT_START_SESSION;
+
+ if (ret == TRUE)
+ gps_event.event_data.start_session_rsp.error = GPS_ERR_NONE;
+ else
+ gps_event.event_data.start_session_rsp.error = GPS_ERR_COMMUNICATION;
+
+ if (g_gps_event_cb != NULL)
+ g_gps_event_cb(&gps_event, g_user_data);
+}
+
+void gps_plugin_respond_stop_session(void)
+{
+ gps_event_info_t gps_event;
+
+ gps_event.event_id = GPS_EVENT_STOP_SESSION;
+ gps_event.event_data.stop_session_rsp.error = GPS_ERR_NONE;
+
+ if (g_gps_event_cb != NULL)
+ g_gps_event_cb(&gps_event, g_user_data);
+}
+
+gboolean gps_plugin_read_uart(replay_timeout *timer, char *nmea_data)
+{
+ char buf[GPS_UART_BUFF_SIZE] = { 0, };
+ char *endstr = NULL;
+ int len = 0;
+ char *str = NULL;
+
+ if (uart_hndl == NULL) {
+ LOG_PLUGIN(DBG_ERR, "uart handle is NULL");
+ return FALSE;
+ }
+
+ if (nmea_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "nmea_data is NULL");
+ gps_uart_close();
+ timer->fd = NULL;
+ return FALSE;
+ }
+
+ if ((len = gps_uart_read(buf, GPS_UART_BUFF_SIZE)) < 0) {
+ LOG_PLUGIN(DBG_ERR, "gps_uart_read ERROR");
+ return TRUE;
+ }
+
+ /* remove uncompleted sentences */
+ endstr = rindex(buf, '\n');
+ if (endstr != NULL)
+ *endstr = '\0';
+ else
+ return TRUE;
+
+ str = (char *)strtok(buf, "\n");
+ while (str != NULL) {
+ if (strncmp(str, "$GP", 3) == 0) {
+ if (strlen(nmea_data) + strlen(str) > REPLAY_NMEA_SET_SIZE) {
+ LOG_PLUGIN(DBG_ERR, "read nmea data size is too long");
+ break;
+ } else {
+ strncpy(nmea_data + strlen(nmea_data), str, strlen(str) - 1);
+ }
+ timer->nmea_data->len = strlen(str);
+ timer->nmea_data->data = str;
+ gps_plugin_replay_nmea_event(timer->nmea_data);
+ }
+ str = (char *)strtok(NULL, "\n");
+ }
+ return TRUE;
+}
+
+gboolean gps_plugin_replay_read_nmea(replay_timeout *timer, char *nmea_data)
+{
+ gboolean ret = FALSE;
+ int ref = 0;
+ char buf[REPLAY_NMEA_SENTENCE_SIZE] = { 0, };
+
+ if (timer->fd == NULL) {
+ LOG_PLUGIN(DBG_ERR, "nmea fd is NULL");
+ return FALSE;
+ }
+
+ if (nmea_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "nmea_data is NULL");
+ fclose(timer->fd);
+ timer->fd = NULL;
+ return FALSE;
+ }
+
+ while (fgets(buf, REPLAY_NMEA_SENTENCE_SIZE, timer->fd) != NULL) {
+ if (strncmp(buf, "$GPGGA", 6) == 0) {
+ ref++;
+ if (ref > 1) {
+ fseek(timer->fd, -strlen(buf), SEEK_CUR);
+ /* LOG_PLUGIN(DBG_LOW, "2nd GPGGA : stop to read nmea data"); */
+ ret = TRUE;
+ break;
+ } else if (ref == 1) {
+ /* LOG_PLUGIN(DBG_LOW, "1st GPGGA : start to read nmea data"); */
+ strncpy(nmea_data, buf, strlen(buf) - 1);
+ }
+ } else {
+ if (strlen(nmea_data) + strlen(buf) > REPLAY_NMEA_SET_SIZE) {
+ LOG_PLUGIN(DBG_ERR, "read nmea data size is too long");
+ break;
+ } else {
+ strncpy(nmea_data + strlen(nmea_data), buf, strlen(buf) - 1);
+ }
+ }
+ timer->nmea_data->len = strlen(buf);
+ timer->nmea_data->data = buf;
+ gps_plugin_replay_nmea_event(timer->nmea_data);
+ }
+
+ if (feof(timer->fd)) {
+ LOG_PLUGIN(DBG_ERR, "end of file");
+ rewind(timer->fd);
+ ret = TRUE;
+ } else {
+ /* LOG_PLUGIN(DBG_LOW, "read nmea data [%s]", nmea_data); */
+ }
+ return ret;
+}
+
+gboolean gps_plugin_replay_read_manual(pos_data_t *pos_data)
+{
+ gboolean ret = TRUE;
+
+ if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LATITUDE, &pos_data->latitude) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to get latitude");
+ ret = FALSE;
+ }
+ if (setting_get_double(VCONFKEY_LOCATION_MANUAL_LONGITUDE, &pos_data->longitude) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to get longitude");
+ ret = FALSE;
+ }
+ if (setting_get_double(VCONFKEY_LOCATION_MANUAL_ALTITUDE, &pos_data->altitude) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to get altitude");
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+gboolean gps_plugin_replay_timeout_cb(gpointer data)
+{
+ gboolean ret = FALSE;
+ read_error_t err = READ_SUCCESS;
+ char nmea_data[REPLAY_NMEA_SET_SIZE] = { 0, };
+ replay_timeout *timer = (replay_timeout *) data;
+
+ if (timer == NULL) {
+ LOG_PLUGIN(DBG_ERR, "replay handel[timer] is NULL");
+ return FALSE;
+ }
+
+ memset(timer->pos_data, 0, sizeof(pos_data_t));
+ memset(timer->batch_data, 0, sizeof(batch_data_t));
+ memset(timer->sv_data, 0, sizeof(sv_data_t));
+
+ if (timer->replay_mode == REPLAY_NMEA) {
+ if (gps_plugin_read_uart(timer, nmea_data) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to read nmea data from peripheral uart");
+ return FALSE;
+ } else {
+ err = nmea_parser(nmea_data, timer->pos_data, timer->sv_data);
+ if (err == READ_ERROR) {
+ LOG_PLUGIN(DBG_ERR, "Fail to parser nmea data from peripheral uart");
+ /*return FALSE; */
+ } else if (err == READ_NOT_FIXED) {
+ LOG_PLUGIN(DBG_LOW, "GPS position is not fixed");
+ timer->sv_data->pos_valid = FALSE;
+ }
+ }
+ } else if (timer->replay_mode == REPLAY_MANUAL) {
+ if (gps_plugin_replay_read_manual(timer->pos_data) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to read manual data");
+ err = READ_ERROR;
+ return FALSE;
+ } else {
+ timer->sv_data->pos_valid = TRUE;
+ err = READ_SUCCESS;
+ }
+ } else if (timer->replay_mode == REPLAY_OFF) {
+ if (gps_plugin_replay_read_nmea(timer, nmea_data) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to read nmea data from file");
+ return FALSE;
+ } else {
+ err = nmea_parser(nmea_data, timer->pos_data, timer->sv_data);
+ if (err == READ_ERROR) {
+ LOG_PLUGIN(DBG_ERR, "Fail to parser nmea data from file");
+ /*return FALSE; */
+ } else if (err == READ_NOT_FIXED) {
+ LOG_PLUGIN(DBG_LOW, "GPS position is not fixed");
+ timer->sv_data->pos_valid = FALSE;
+ }
+ }
+ }
+
+ if (g_gps_event_cb != NULL) {
+ if (err != READ_NOT_FIXED) {
+ if (timer->batch_mode == BATCH_MODE_ON) {
+ gps_plugin_replay_batch_event(timer->pos_data, timer);
+ }
+
+ gps_plugin_replay_pos_event(timer->pos_data);
+ }
+
+ gps_plugin_replay_sv_event(timer->sv_data);
+ }
+ ret = TRUE;
+ return ret;
+}
+
+void gps_plugin_stop_replay_mode(replay_timeout *timer)
+{
+ if (timer->replay_mode == REPLAY_NMEA && gps_uart_close() == FALSE)
+ LOG_PLUGIN(DBG_ERR, "peripheral_uart_close failed");
+ else if (timer->replay_mode == REPLAY_OFF && fclose(timer->fd) != 0)
+ LOG_PLUGIN(DBG_ERR, "fclose failed");
+
+ timer->fd = NULL;
+
+ if (timer->timeout_src != NULL && timer->default_context != NULL && !g_source_is_destroyed(timer->timeout_src)) {
+ if (timer->default_context == g_source_get_context(timer->timeout_src)) {
+ g_source_destroy(timer->timeout_src);
+ LOG_PLUGIN(DBG_LOW, "g_source_destroy timeout_src");
+ } else {
+ LOG_PLUGIN(DBG_WARN, "timer->timeout_src is attatched to 0x%x (actual 0x%x)",
+ g_source_get_context(timer->timeout_src), timer->default_context);
+ }
+ timer->timeout_src = NULL;
+ timer->default_context = NULL;
+ } else {
+ LOG_PLUGIN(DBG_WARN, "timeout_src or default_context is NULL or timeout_src is already destroyed");
+ }
+ gps_plugin_respond_stop_session();
+}
+
+gboolean gps_plugin_get_nmea_fd(replay_timeout *timer)
+{
+ char replay_file_path[256];
+ char *str;
+
+ str = setting_get_string(VCONFKEY_LOCATION_NMEA_FILE_NAME);
+ if (str == NULL)
+ return FALSE;
+
+ const char *nmea_file_path = tzplatform_mkpath(TZ_SYS_MEDIA, "lbs-server/replay/");
+ snprintf(replay_file_path, sizeof(replay_file_path), "%s%s", nmea_file_path, str);
+ SECLOG_PLUGIN(DBG_ERR, "replay file name : %s", replay_file_path);
+ free(str);
+
+ timer->fd = fopen(replay_file_path, "r");
+ if (timer->fd == NULL) {
+ SECLOG_PLUGIN(DBG_ERR, "fopen(%s) failed", replay_file_path);
+ const char *default_nmea_log = tzplatform_mkpath(TZ_SYS_RO_ETC, "lbs-server/replay/nmea_replay.log");
+ timer->fd = fopen(default_nmea_log, "r");
+ if (timer->fd == NULL) {
+ SECLOG_PLUGIN(DBG_ERR, "fopen(%s) failed", default_nmea_log);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+gboolean gps_plugin_start_replay_mode(replay_timeout *timer)
+{
+ LOG_PLUGIN(DBG_LOW, "gps_plugin_start replay mode");
+ gboolean ret = FALSE;
+
+ if (timer->replay_mode == REPLAY_NMEA) {
+ if (gps_uart_open() == FALSE)
+ return FALSE;
+ } else if (timer->replay_mode == REPLAY_OFF) {
+ if (gps_plugin_get_nmea_fd(timer) == FALSE)
+ return FALSE;
+ }
+
+ if (timer->default_context == NULL) {
+ timer->default_context = g_main_context_default();
+
+ if (timer->default_context == NULL)
+ return ret;
+ }
+
+ if (timer->timeout_src != NULL) {
+ LOG_PLUGIN(DBG_ERR, "timeout_src is already existed");
+ ret = FALSE;
+ } else {
+ timer->timeout_src = g_timeout_source_new_seconds(timer->interval);
+ if (timer->timeout_src != NULL) {
+ g_source_set_callback(timer->timeout_src, &gps_plugin_replay_timeout_cb, timer, NULL);
+ if (g_source_attach(timer->timeout_src, timer->default_context) > 0) {
+ LOG_PLUGIN(DBG_LOW, "timeout_src(0x%x) is created & attatched to 0x%x", timer->timeout_src, timer->default_context);
+ ret = TRUE;
+ } else {
+ gps_plugin_stop_replay_mode(timer);
+ ret = FALSE;
+ }
+ }
+ }
+
+ gps_plugin_respond_start_session(ret);
+
+ return ret;
+}
+
+gboolean gps_plugin_update_batch_mode(replay_timeout *timer, int batch_interval, int batch_period)
+{
+ gboolean ret = FALSE;
+ time_t timestamp;
+ time(×tamp);
+
+ if (timer->batch_mode == BATCH_MODE_OFF) {
+ timer->batch_mode = BATCH_MODE_ON;
+ timer->batch_client_count = 0;
+ }
+ timer->batch_client_count++;
+
+ timer->batch_interval = batch_interval;
+ timer->batch_period = batch_period;
+ timer->batch_start_time = timestamp;
+
+ LOG_PLUGIN(DBG_LOW, "batch_client_count = %d", timer->batch_client_count);
+ return ret;
+}
+
+void gps_plugin_stop_batch_mode(replay_timeout *timer, int batch_interval, int batch_period)
+{
+ if (timer->batch_client_count > 0)
+ timer->batch_client_count--;
+
+ LOG_PLUGIN(DBG_ERR, "batch_client_count = %d", timer->batch_client_count);
+ if (timer->batch_client_count <= 0) {
+ timer->batch_mode = BATCH_MODE_OFF;
+ timer->batch_interval = 0;
+ timer->batch_period = 0;
+
+ if (timer->batch_fd != NULL) {
+ fclose(timer->batch_fd);
+ timer->batch_fd = NULL;
+ timer->num_of_batch = 0;
+ }
+ } else {
+ timer->batch_interval = batch_interval;
+ timer->batch_period = batch_period;
+ time_t timestamp;
+ time(×tamp);
+ timer->batch_start_time = timestamp;
+ }
+}
+
+static void replay_mode_changed_cb(keynode_t *key, void *data)
+{
+ if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &g_replay_timer->replay_mode) == FALSE)
+ g_replay_timer->replay_mode = REPLAY_OFF;
+
+ if (g_replay_timer->replay_mode == REPLAY_NMEA) {
+ if (gps_plugin_get_nmea_fd(g_replay_timer) == FALSE)
+ LOG_PLUGIN(DBG_ERR, "Fail to get nmea fd.");
+
+ } else {
+ if (g_replay_timer->fd != NULL) {
+ fclose(g_replay_timer->fd);
+ g_replay_timer->fd = NULL;
+ }
+ }
+ return;
+}
+
+static void display_mode_changed_cb(keynode_t * key, void *data)
+{
+ if (setting_get_int(VCONFKEY_PM_STATE, &g_replay_timer->lcd_mode) == FALSE) {
+ LOG_PLUGIN(DBG_ERR, "Fail to get lcd state");
+ g_replay_timer->lcd_mode = VCONFKEY_PM_STATE_LCDOFF;
+ }
+
+ if (g_replay_timer->lcd_mode == VCONFKEY_PM_STATE_NORMAL)
+ g_replay_timer->is_flush = TRUE;
+
+ return;
+}
+
+replay_timeout *gps_plugin_replay_timer_init()
+{
+ replay_timeout *timer = NULL;
+
+ timer = (replay_timeout *) malloc(sizeof(replay_timeout));
+ if (timer == NULL) {
+ LOG_PLUGIN(DBG_ERR, "replay_timeout allocation is failed.");
+ return NULL;
+ }
+
+ timer->fd = NULL;
+ timer->interval = 1;
+
+ timer->batch_fd = NULL;
+ timer->num_of_batch = 0;
+ timer->batch_client_count = 0;
+ timer->batch_mode = BATCH_MODE_OFF;
+ timer->batch_interval = 0;
+ timer->batch_period = 0;
+ timer->is_flush = FALSE;
+
+ if (setting_get_int(VCONFKEY_LOCATION_REPLAY_MODE, &timer->replay_mode) == FALSE)
+ timer->replay_mode = REPLAY_OFF;
+
+ setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
+
+ if (setting_get_int(VCONFKEY_PM_STATE, &timer->lcd_mode) == FALSE)
+ timer->lcd_mode = VCONFKEY_PM_STATE_LCDOFF;
+
+ setting_notify_key_changed(VCONFKEY_PM_STATE, display_mode_changed_cb);
+
+ timer->pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
+ if (timer->pos_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "pos_data allocation is failed.");
+ free(timer);
+ return NULL;
+ }
+
+ timer->batch_data = (batch_data_t *) malloc(sizeof(batch_data_t));
+ if (timer->batch_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "batch_data allocation is failed.");
+ free(timer->pos_data);
+ free(timer);
+ return NULL;
+ }
+
+ timer->sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
+ if (timer->sv_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "sv_data allocation is failed.");
+ free(timer->pos_data);
+ free(timer->batch_data);
+ free(timer);
+ return NULL;
+ }
+
+ timer->nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
+ if (timer->nmea_data == NULL) {
+ LOG_PLUGIN(DBG_ERR, "nmea_data allocation is failed.");
+ free(timer->pos_data);
+ free(timer->batch_data);
+ free(timer->sv_data);
+ free(timer);
+ return NULL;
+ }
+
+ timer->timeout_src = NULL;
+ timer->default_context = NULL;
+
+ return timer;
+}
+
+void gps_plugin_replay_timer_deinit(replay_timeout *timer)
+{
+ if (timer == NULL)
+ return;
+
+ if (timer->pos_data != NULL) {
+ free(timer->pos_data);
+ timer->pos_data = NULL;
+ }
+ if (timer->sv_data != NULL) {
+ free(timer->sv_data);
+ timer->sv_data = NULL;
+ }
+ if (timer->nmea_data != NULL) {
+ free(timer->nmea_data);
+ timer->nmea_data = NULL;
+ }
+
+ setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_MODE, replay_mode_changed_cb);
+
+ free(timer);
+ timer = NULL;
+}
+
+int gps_plugin_replay_gps_init(gps_event_cb gps_event_cb, void *user_data)
+{
+ g_gps_event_cb = gps_event_cb;
+ g_replay_timer = gps_plugin_replay_timer_init();
+ g_user_data = user_data;
+
+ return TRUE;
+}
+
+int gps_plugin_replay_gps_deinit(gps_failure_reason_t *reason_code)
+{
+ gps_plugin_replay_timer_deinit(g_replay_timer);
+ g_gps_event_cb = NULL;
+ g_user_data = NULL;
+
+ peripheral_uart_close(uart_hndl);
+ _D("GPS Uart Port Close Successful !!");
+
+ return TRUE;
+}
+
+int gps_plugin_replay_gps_request(gps_action_t gps_action, void *gps_action_data, gps_failure_reason_t *reason_code)
+{
+ gps_action_start_data_t *gps_start_data = gps_action_data;
+
+ switch (gps_action) {
+ case GPS_ACTION_SEND_PARAMS:
+ break;
+ case GPS_ACTION_START_SESSION:
+ gps_plugin_start_replay_mode(g_replay_timer);
+ break;
+ case GPS_ACTION_STOP_SESSION:
+ gps_plugin_stop_replay_mode(g_replay_timer);
+ break;
+ case GPS_ACTION_START_BATCH:
+ if (!gps_start_data->session_status) /* need to start */
+ gps_plugin_start_replay_mode(g_replay_timer);
+
+ gps_plugin_update_batch_mode(g_replay_timer, gps_start_data->interval, gps_start_data->period);
+ break;
+ case GPS_ACTION_STOP_BATCH:
+ if (!gps_start_data->session_status) /* need to stop */
+ gps_plugin_stop_replay_mode(g_replay_timer);
+
+ gps_plugin_stop_batch_mode(g_replay_timer, gps_start_data->interval, gps_start_data->period);
+ break;
+ case GPS_INDI_SUPL_VERIFICATION:
+ case GPS_INDI_SUPL_DNSQUERY:
+ case GPS_ACTION_START_FACTTEST:
+ case GPS_ACTION_STOP_FACTTEST:
+ case GPS_ACTION_REQUEST_SUPL_NI:
+ LOG_PLUGIN(DBG_LOW, "Don't use action type : [ %d ]", gps_action);
+ break;
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+EXPORT_API const gps_plugin_interface *get_gps_plugin_interface()
+{
+ return &g_gps_plugin_replay_interface;
+}
--- /dev/null
+/*
+ * gps replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <gps_plugin_intf.h>
+
+#include "gps_plugin_debug.h"
+#include "nmea_parser.h"
+#include "setting.h"
+
+#define MAX_NMEA_SENTENCES 32
+#define MAX_TOEKNS 25
+
+#define DECIMAL_TO_DEGREE 60.0
+#define METER_TO_FEET 3.2808399
+#define KNOT_TO_MPS 0.5144444
+#define KMPH_TO_MPS 0.2777778
+
+#define NORTH 1
+#define SOUTH -1
+#define EAST 1
+#define WEST -1
+
+int used_sat[MAX_GPS_NUM_SAT_USED] = { 0, };
+
+static unsigned char nmea_parser_c2n(unsigned char ch)
+{
+ if (ch <= '9')
+ return ch - '0';
+ else
+ return (ch - 'A') + 10;
+}
+
+int nmea_parser_verify_checksum(char *nmea_sen)
+{
+ int ret = -1;
+ int i;
+ int checksum = 0;
+ int sum = 0;
+
+ for (i = 0; i < strlen(nmea_sen) && (nmea_sen[i] != '*'); i++)
+ checksum ^= nmea_sen[i];
+
+ if (++i + 1 < strlen(nmea_sen))
+ sum = (nmea_parser_c2n(nmea_sen[i]) << 4) + nmea_parser_c2n(nmea_sen[i + 1]);
+
+ if (sum == checksum) {
+ ret = 0;
+ } else {
+ LOG_PLUGIN(DBG_LOW, "NMEA checksum is INVALID");
+ ret = -1;
+ }
+ return ret;
+}
+
+int nmea_parser_tokenize(char input[], char *token[])
+{
+ char *s = input;
+ int num_tokens = 0;
+ int state;
+
+ token[num_tokens] = s;
+ num_tokens++;
+ state = 0;
+ /* LOG_PLUGIN(DBG_LOW, "input:%s \n", input); */
+
+ while ((*s != 0) && (num_tokens < MAX_TOEKNS)) {
+ switch (state) {
+ case 0:
+ if (*s == ',') {
+ *s = 0;
+ state = 1;
+ }
+ break;
+ case 1:
+ token[num_tokens++] = s;
+ if (*s == ',')
+ *s = 0;
+ else
+ state = 0;
+
+ break;
+ }
+ s++;
+ }
+ return num_tokens;
+}
+
+static double nmea_parser_get_latitude(const char *lat, const char *bearing)
+{
+ double latitude = 0.0;
+ int ns;
+ int deg;
+ double remainder;
+
+ if ((*lat == 0) || (*bearing == 0))
+ return latitude;
+
+ ns = (*bearing == 'N') ? NORTH : SOUTH;
+
+ latitude = atof(lat);
+ deg = (int)(latitude / 100.0);
+ remainder = latitude - (deg * 100.0);
+ latitude = (deg + (remainder / DECIMAL_TO_DEGREE)) * ns;
+
+ return latitude;
+}
+
+static double nmea_parser_get_longitude(const char *lon, const char *bearing)
+{
+ double longitude = 0.0;
+ int ew;
+ int deg;
+ double remainder;
+
+ if (*lon == 0 || (*bearing == 0))
+ return longitude;
+
+ ew = (*bearing == 'E') ? EAST : WEST;
+
+ longitude = atof(lon);
+ deg = (int)(longitude / 100.0);
+ remainder = longitude - (deg * 100.0);
+ longitude = (deg + (remainder / DECIMAL_TO_DEGREE)) * ew;
+
+ return longitude;
+}
+
+static double nmea_parser_get_altitude(const char *alt, const char *unit)
+{
+ double altitude;
+
+ if (*alt == 0)
+ return 0.0;
+
+ altitude = atof(alt);
+ altitude = (*unit == 'M') ? altitude : altitude * METER_TO_FEET;
+
+ return altitude;
+}
+
+static int nmea_parser_gpgga(char *token[], pos_data_t *pos, sv_data_t *sv)
+{
+ double latitude, longitude, altitude;
+ int quality;
+
+ quality = atoi(token[6]);
+
+ if (quality == 0) {
+ LOG_PLUGIN(DBG_LOW, "Not fixed");
+ sv->pos_valid = FALSE;
+ return READ_NOT_FIXED;
+ }
+
+ /* utctime = atoi(token[1]); */
+ latitude = nmea_parser_get_latitude(token[2], token[3]);
+ longitude = nmea_parser_get_longitude(token[4], token[5]);
+ altitude = nmea_parser_get_altitude(token[9], token[10]);
+ /* num_of_sat_used = atoi(token[7]); */
+ /* eph = atof(token[8]); */
+ /* geoid = nmea_parser_get_altitude(token[11], token[12]); */
+
+ pos->latitude = latitude;
+ pos->longitude = longitude;
+ pos->altitude = altitude;
+
+ sv->pos_valid = TRUE;
+
+ return READ_SUCCESS;
+}
+
+static int nmea_parser_gprmc(char *token[], pos_data_t *pos)
+{
+ char *status;
+ double latitude, longitude, speed, bearing;
+
+ status = token[2]; /*warn = *token[2]; */
+ if (strcmp(status, "V") == 0) {
+ /* LOG_PLUGIN(DBG_LOW, "Not fixed"); */
+ return READ_NOT_FIXED;
+ }
+
+ /* utctime = atoi(token[1]); */
+ latitude = nmea_parser_get_latitude(token[3], token[4]);
+ longitude = nmea_parser_get_longitude(token[5], token[6]);
+ speed = atof(token[7]);
+ bearing = atof(token[8]);
+ /* date = atoi(token[9]); */
+ /* magvar = atof(token[10]); */
+
+ pos->latitude = latitude;
+ pos->longitude = longitude;
+ pos->speed = speed * KNOT_TO_MPS;
+ pos->bearing = bearing;
+
+ return READ_SUCCESS;
+}
+
+static int nmea_parser_gpgll(char *token[], pos_data_t *pos)
+{
+ char *status;
+ double latitude, longitude;
+
+ status = token[6]; /*warn = *token[2]; */
+ if (strcmp(status, "V") == 0) {
+ /* LOG_PLUGIN(DBG_LOW, "Not fixed"); */
+ return READ_NOT_FIXED;
+ }
+
+ latitude = nmea_parser_get_latitude(token[1], token[2]);
+ longitude = nmea_parser_get_longitude(token[3], token[4]);
+
+ pos->latitude = latitude;
+ pos->longitude = longitude;
+
+ return READ_SUCCESS;
+}
+
+static int nmea_parser_gpgsa(char *token[], pos_data_t *pos)
+{
+ int i, fix_type;
+
+ fix_type = atoi(token[2]);
+ if (fix_type == 1) {
+ /* LOG_PLUGIN(DBG_LOW, "Not fixed"); */
+ return READ_NOT_FIXED;
+ }
+
+ /* selection_type = *token[1]; */
+
+ memset(used_sat, 0, sizeof(used_sat));
+ for (i = 0; i < MAX_GPS_NUM_SAT_USED; i++)
+ used_sat[i] = atoi(token[i + 3]);
+
+
+ /* pdop = atof(token[15]); */
+ /* hdop = atof(token[16]); */
+ /* vdop = atof(token[17]); */
+
+ return READ_SUCCESS;
+}
+
+static int nmea_parser_gpvtg(char *token[], pos_data_t *pos)
+{
+ double true_course, kmh_speed;
+
+ true_course = atof(token[1]);
+ /* magnetic_course = atof(token[3]); */
+ /* knot_speed = atof(token[5]); */
+ kmh_speed = atof(token[7]);
+
+ pos->speed = kmh_speed * KMPH_TO_MPS;
+ pos->bearing = true_course;
+
+ return READ_SUCCESS;
+}
+
+static int nmea_parser_gpgsv(char *token[], sv_data_t *sv)
+{
+ int i, j;
+ int p, q, iter;
+ int msg_num, num_sv;
+
+ /* num_sen = atoi(token[1]); */
+ msg_num = atoi(token[2]);
+ if (msg_num < 1) {
+ LOG_PLUGIN(DBG_LOW, "There is not GSV message");
+ return READ_ERROR;
+ }
+
+ num_sv = atoi(token[3]);
+ if (num_sv > MAX_GPS_NUM_SAT_IN_VIEW) {
+ LOG_PLUGIN(DBG_LOW, "num_of_sat(num_sv) size error");
+ return READ_ERROR;
+ }
+
+ sv->num_of_sat = num_sv;
+ iter = ((num_sv < (msg_num * 4)) ? (num_sv - ((msg_num - 1) * 4)) : 4);
+ for (i = 0; i < iter; i++) {
+ q = (i + 1) * 4;
+ p = i + 4 * (msg_num - 1);
+ if (p > 31) {
+ LOG_PLUGIN(DBG_LOW, "Out of bounds");
+ return READ_ERROR;
+ }
+ sv->sat[p].prn = atoi(token[q]);
+ for (j = 0; j < MAX_GPS_NUM_SAT_USED; j++) {
+ if (sv->sat[p].prn == used_sat[j]) {
+ sv->sat[p].used = 1;
+ break;
+ } else {
+ sv->sat[p].used = 0;
+ }
+ }
+ sv->sat[p].elevation = atoi(token[q + 1]);
+ sv->sat[p].azimuth = atoi(token[q + 2]);
+ sv->sat[p].snr = atoi(token[q + 3]);
+ }
+ return READ_SUCCESS;
+}
+
+int nmea_parser_sentence(char *sentence, char *token[], pos_data_t *pos, sv_data_t *sv)
+{
+ int ret = READ_SUCCESS;
+ if (strcmp(sentence, "GPGGA") == 0)
+ ret = nmea_parser_gpgga(token, pos, sv);
+ else if (strcmp(sentence, "GPRMC") == 0)
+ ret = nmea_parser_gprmc(token, pos);
+ else if (strcmp(sentence, "GPGLL") == 0)
+ ret = nmea_parser_gpgll(token, pos);
+ else if (strcmp(sentence, "GPGSA") == 0)
+ ret = nmea_parser_gpgsa(token, pos);
+ else if (strcmp(sentence, "GPVTG") == 0)
+ ret = nmea_parser_gpvtg(token, pos);
+ else if (strcmp(sentence, "GPGSV") == 0)
+ ret = nmea_parser_gpgsv(token, sv);
+ else
+ LOG_PLUGIN(DBG_LOW, "Unsupported sentence : [%s]\n", sentence);
+
+
+ return ret;
+}
+
+int nmea_parser(char *data, pos_data_t *pos, sv_data_t *sv)
+{
+ int ret = READ_SUCCESS;
+ read_error_t err;
+ int num_sen = 0;
+ int count = 0;
+ char *last = NULL;
+ char *nmea_sen[MAX_NMEA_SENTENCES] = { 0, };
+ char *token[MAX_TOEKNS] = { 0, };
+
+ nmea_sen[num_sen] = (char *)strtok_r((char *)data, "$", &last);
+ while (nmea_sen[num_sen] != NULL) {
+ num_sen++;
+ nmea_sen[num_sen] = (char *)strtok_r(NULL, "$", &last);
+ }
+ /* LOG_PLUGIN(DBG_LOW, "Number of NMEA sentences:%d \n", num_sen); */
+
+ while (num_sen > 0) {
+ if (nmea_parser_verify_checksum(nmea_sen[count]) == 0) {
+ nmea_parser_tokenize(nmea_sen[count], token);
+ err = nmea_parser_sentence(token[0], token, pos, sv);
+ if (err == READ_NOT_FIXED) {
+ /* LOG_PLUGIN(DBG_LOW, "NOT Fixed"); */
+ ret = err;
+ } else if (err == READ_ERROR) {
+ ret = err;
+ }
+ } else {
+ LOG_PLUGIN(DBG_ERR, "[NMEA Parser] %dth sentense : Invalid Checksum\n", count);
+ }
+ count++;
+ num_sen--;
+ }
+
+ return ret;
+}
--- /dev/null
+/*
+ * gps-manager replay plugin
+ *
+ * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
+ * Genie Kim <daejins.kim@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <string.h>
+#include <glib.h>
+#include "setting.h"
+#include "gps_plugin_debug.h"
+
+int setting_get_int(const char *path, int *val)
+{
+ int ret = vconf_get_int(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_PLUGIN(DBG_ERR, "vconf_get_int failed, [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+int setting_get_double(const char *path, double *val)
+{
+ int ret = vconf_get_dbl(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_PLUGIN(DBG_ERR, "vconf_get_int failed, [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+char *setting_get_string(const char *path)
+{
+ return vconf_get_str(path);
+}
+
+int setting_notify_key_changed(const char *path, void *key_changed_cb)
+{
+ int ret = TRUE;
+ if (vconf_notify_key_changed(path, key_changed_cb, NULL) != 0) {
+ LOG_PLUGIN(DBG_ERR, "Fail to vconf_notify_key_changed [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+int setting_ignore_key_changed(const char *path, void *key_changed_cb)
+{
+ int ret = TRUE;
+ if (vconf_ignore_key_changed(path, key_changed_cb) != 0) {
+ LOG_PLUGIN(DBG_ERR, "Fail to vconf_ignore_key_changed [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
--- /dev/null
+$GPGGA,054501.326,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,0.0,M,,*6F\r
+$GPRMC,054501.326,V,0000.0000,N,00000.0000,E,0.0,0.0,150911,,,N*79\r
+$GPGLL,0000.0000,N,00000.0000,E,054501.326,V,N*43\r
+$GPGSA,A,1,,,,,,,,,,,,,,0.0,*30\r
+$GPVTG,0.0,T,,M,0.0,N,0.0,K,N*02\r
+$GPGSV,3,1,09,01,00,000,40,07,45,163,36,08,72,186,35,11,40,061,33*77\r
+$GPGSV,3,2,09,19,10,051,33,24,48,105,38,28,57,318,36,17,36,241,2*48\r
+$GPGSV,3,3,09,22,00,025,25*40\r
+$GPGGA,054502.326,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,0.0,M,,*6C\r
+$GPRMC,054502.326,V,0000.0000,N,00000.0000,E,0.0,0.0,150911,,,N*7A\r
+$GPGLL,0000.0000,N,00000.0000,E,054502.326,V,N*40\r
+$GPGSA,A,1,,,,,,,,,,,,,,0.0,*30\r
+$GPVTG,0.0,T,,M,0.0,N,0.0,K,N*02\r
+$GPGSV,3,1,09,01,00,000,40,07,45,163,36,08,72,186,35,11,40,061,33*77\r
+$GPGSV,3,2,09,19,10,051,33,24,48,105,38,28,57,318,36,17,36,241,2*48\r
+$GPGSV,3,3,09,22,00,025,24*41\r
+$GPGGA,054503.326,0000.0000,N,00000.0000,E,0,00,0.0,0.0,M,0.0,M,,*6D\r
+$GPRMC,054503.326,V,0000.0000,N,00000.0000,E,0.0,0.0,150911,,,N*7B\r
+$GPGLL,0000.0000,N,00000.0000,E,054503.326,V,N*41\r
+$GPGSA,A,1,,,,,,,,,,,,,,0.0,*30\r
+$GPVTG,0.0,T,,M,0.0,N,0.0,K,N*02\r
+$GPGSV,3,1,09,01,00,000,40,07,45,163,36,08,72,186,35,11,40,061,33*77\r
+$GPGSV,3,2,09,19,10,051,33,24,48,105,39,28,57,318,36,17,36,241,2*49\r
+$GPGSV,3,3,09,22,00,025,24*41\r
+$GPGGA,054504.324,3715.2199,N,12703.2972,E,1,05,1.6,37.8,M,19.9,M,,*6C\r
+$GPRMC,054504.324,A,3715.2199,N,12703.2972,E,0.5,130.1,150911,,,A*6A\r
+$GPGLL,3715.2199,N,12703.2972,E,054504.324,A,A*56\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.5,N,1.0,K,A*0A\r
+$GPGSV,3,1,09,01,00,000,40,07,44,163,36,08,72,186,35,11,50,073,33*74\r
+$GPGSV,3,2,09,19,14,051,33,24,47,093,39,28,57,318,36,17,36,241,2*4C\r
+$GPGSV,3,3,09,22,00,025,24*41\r
+$GPGGA,054505.324,3715.2202,N,12703.2978,E,1,05,1.6,29.6,M,19.9,M,,*67\r
+$GPRMC,054505.324,A,3715.2202,N,12703.2978,E,0.3,130.1,150911,,,A*66\r
+$GPGLL,3715.2202,N,12703.2978,E,054505.324,A,A*5C\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.3,N,0.5,K,A*08\r
+$GPGSV,3,1,09,01,00,000,40,07,39,219,36,08,48,259,35,11,82,054,33*72\r
+$GPGSV,3,2,09,19,37,058,33,24,78,150,39,28,33,313,36,17,08,268,2*49\r
+$GPGSV,3,3,09,22,07,042,24*47\r
+$GPGGA,054506.000,3715.2201,N,12703.2978,E,1,05,1.6,29.6,M,19.9,M,,*62\r
+$GPRMC,054506.000,A,3715.2201,N,12703.2978,E,0.1,130.1,150911,,,A*61\r
+$GPGLL,3715.2201,N,12703.2978,E,054506.000,A,A*59\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.1,N,0.1,K,A*0E\r
+$GPGSV,3,1,09,01,00,000,40,07,39,219,35,08,48,259,35,11,82,054,33*71\r
+$GPGSV,3,2,09,19,37,058,33,24,78,150,39,28,33,313,37,17,08,268,2*48\r
+$GPGSV,3,3,09,22,07,042,25*46\r
+$GPGGA,054507.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*63\r
+$GPRMC,054507.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*65\r
+$GPGLL,3715.2199,N,12703.2981,E,054507.000,A,A*5C\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,09,01,00,000,40,07,39,219,35,08,48,259,35,11,82,054,33*71\r
+$GPGSV,3,2,09,19,37,058,32,24,78,150,39,28,33,313,37,17,08,268,2*49\r
+$GPGSV,3,3,09,22,07,042,25*46\r
+$GPGGA,054508.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*6C\r
+$GPRMC,054508.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*6A\r
+$GPGLL,3715.2199,N,12703.2981,E,054508.000,A,A*53\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,09,01,00,000,40,07,39,219,35,08,48,259,35,11,82,054,33*71\r
+$GPGSV,3,2,09,19,37,058,32,24,78,150,39,28,33,313,37,17,08,268,2*49\r
+$GPGSV,3,3,09,22,07,042,25*46\r
+$GPGGA,054509.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*6D\r
+$GPRMC,054509.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*6B\r
+$GPGLL,3715.2199,N,12703.2981,E,054509.000,A,A*52\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,1,6,,,,,,,,,,,,,0.0*50\r
+$GPGGA,054510.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*65\r
+$GPRMC,054510.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*63\r
+$GPGLL,3715.2199,N,12703.2981,E,054510.000,A,A*5A\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,09,01,00,000,40,07,39,219,38,08,48,259,35,11,82,054,34*7B\r
+$GPGSV,3,2,09,19,37,058,31,24,78,150,38,28,33,313,38,17,08,268,3*45\r
+$GPGSV,3,3,09,22,07,042,25*46\r
+$GPGGA,054511.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*64\r
+$GPRMC,054511.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*62\r
+$GPGLL,3715.2199,N,12703.2981,E,054511.000,A,A*5B\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,1,6,,,,,,,,,,,,,0.0*50\r
+$GPGGA,054512.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*67\r
+$GPRMC,054512.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*61\r
+$GPGLL,3715.2199,N,12703.2981,E,054512.000,A,A*58\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,34,08,48,259,37,11,82,054,35*7C\r
+$GPGSV,3,2,10,19,37,058,31,24,78,150,37,28,33,313,35,03,11,081,2*46\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,24*7F\r
+$GPGGA,054513.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*66\r
+$GPRMC,054513.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*60\r
+$GPGLL,3715.2199,N,12703.2981,E,054513.000,A,A*59\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,35,08,48,259,36,11,82,054,35*7C\r
+$GPGSV,3,2,10,19,37,058,31,24,78,150,37,28,33,313,34,03,11,081,2*47\r
+$GPGSV,3,3,10,17,08,268,30,22,07,042,25*7F\r
+$GPGGA,054514.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*61\r
+$GPRMC,054514.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*67\r
+$GPGLL,3715.2199,N,12703.2981,E,054514.000,A,A*5E\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,36,08,48,259,36,11,82,054,35*7F\r
+$GPGSV,3,2,10,19,37,058,32,24,78,150,37,28,33,313,35,03,11,081,2*45\r
+$GPGSV,3,3,10,17,08,268,30,22,07,042,26*7C\r
+$GPGGA,054515.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*60\r
+$GPRMC,054515.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*66\r
+$GPGLL,3715.2199,N,12703.2981,E,054515.000,A,A*5F\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,36,08,48,259,36,11,82,054,35*7F\r
+$GPGSV,3,2,10,19,37,058,33,24,78,150,37,28,33,313,35,03,11,081,2*44\r
+$GPGSV,3,3,10,17,08,268,30,22,07,042,27*7D\r
+$GPGGA,054516.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*63\r
+$GPRMC,054516.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*65\r
+$GPGLL,3715.2199,N,12703.2981,E,054516.000,A,A*5C\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,37,08,48,259,36,11,82,054,35*7E\r
+$GPGSV,3,2,10,19,37,058,33,24,78,150,36,28,33,313,35,03,11,081,2*45\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,27*7C\r
+$GPGGA,054517.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*62\r
+$GPRMC,054517.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*64\r
+$GPGLL,3715.2199,N,12703.2981,E,054517.000,A,A*5D\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,37,08,48,259,36,11,82,054,35*7E\r
+$GPGSV,3,2,10,19,37,058,33,24,78,150,36,28,33,313,35,03,11,081,2*45\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,27*7C\r
+$GPGGA,054518.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*6D\r
+$GPRMC,054518.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*6B\r
+$GPGLL,3715.2199,N,12703.2981,E,054518.000,A,A*52\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,37,08,48,259,35,11,82,054,35*7D\r
+$GPGSV,3,2,10,19,37,058,33,24,78,150,36,28,33,313,35,03,11,081,2*45\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,27*7C\r
+$GPGGA,054519.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*6C\r
+$GPRMC,054519.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*6A\r
+$GPGLL,3715.2199,N,12703.2981,E,054519.000,A,A*53\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,37,08,48,259,35,11,82,054,35*7D\r
+$GPGSV,3,2,10,19,37,058,33,24,78,150,36,28,33,313,35,03,11,081,2*45\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,27*7C\r
+$GPGGA,054520.000,3715.2199,N,12703.2981,E,1,05,1.6,28.3,M,19.9,M,,*66\r
+$GPRMC,054520.000,A,3715.2199,N,12703.2981,E,0.0,130.1,150911,,,A*60\r
+$GPGLL,3715.2199,N,12703.2981,E,054520.000,A,A*59\r
+$GPGSA,A,3,07,11,19,24,28,,,,,,,,,1.6,*36\r
+$GPVTG,130.1,T,,M,0.0,N,0.0,K,A*0E\r
+$GPGSV,3,1,10,01,00,000,40,07,39,219,37,08,48,259,35,11,82,054,35*7D\r
+$GPGSV,3,2,10,19,37,058,34,24,78,150,36,28,33,313,35,03,11,081,2*42\r
+$GPGSV,3,3,10,17,08,268,31,22,07,042,27*7C\r
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
--- /dev/null
+Name: lbs-plugin-gps-artik7
+Summary: LBS Server plugin library for replay mode
+Version: 0.1.0
+Release: 1
+Group: Location/Libraries
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Source1: lbs-plugin-gps-artik7.manifest
+BuildRequires: cmake
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(lbs-server-plugin)
+BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(capi-system-peripheral-io)
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+LBS Server plugin library for replay mode
+
+%define DATADIR /etc/lbs-server
+
+%prep
+%setup -q
+cp %{SOURCE1} .
+
+%build
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
+#./autogen.sh
+#./configure --prefix=%{_prefix} --datadir=%{DATADIR}
+
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \
+ -DLIB_DIR=%{_libdir} \
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}%{DATADIR}/replay
+cp -a nmea-log/*.log %{buildroot}%{DATADIR}/replay
+
+%post
+rm -rf %{_libdir}/liblbs-server-plugin.so
+ln -sf %{_libdir}/liblbs-plugin-gps-artik7.so %{_libdir}/liblbs-server-plugin.so
+#for compatible with old version
+ln -sf %{_libdir}/liblbs-plugin-gps-artik7.so %{_libdir}/libSLP-lbs-plugin-replay.so
+ln -sf %{_libdir}/liblbs-plugin-gps-artik7.so %{_libdir}/libSLP-lbs-plugin.so
+/sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest lbs-plugin-gps-artik7.manifest
+%license LICENSE
+%defattr(-,root,root,-)
+%{_libdir}/liblbs-plugin-gps-artik7.so*
+%{DATADIR}/replay/*