--- /dev/null
+Youngae Kang <youngae.kang@samsung.com>
+Minjune Kim <sena06.kim@gmail.com>
+Genie Kim <daejins.kim@samsung.com>
--- /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
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = . lbs-server module
--- /dev/null
+aclocal
+libtoolize --copy
+autoheader
+autoconf
+automake --add-missing --copy --foreign
+
--- /dev/null
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.61)
+AC_INIT([lbs-server], [0.1])
+AC_CONFIG_AUX_DIR([build-aux])
+AM_INIT_AUTOMAKE([foreign -Wall -Werror])
+AC_CONFIG_SRCDIR([lbs-server/lbs_server.c])
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+###### Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+AC_PROG_LN_S
+AC_PROG_RANLIB
+
+# PLATFORM configuration
+PLATFORM_INIT
+
+# Add default build options to CFLAGS, LDFLAGS
+if test "x$GCC" = "xyes"; then
+ CFLAGS="$CFLAGS -Wall -Werror"
+ LDFLAGS="$LDFLAGS -Wl,-z,defs -Wl,--as-needed -Wl,--hash-style=both"
+fi
+
+# Add -g option to CFLAGS
+AC_ARG_ENABLE([debug],
+ [AC_HELP_STRING([--enable-debug],[turn on debugging [default=no]])],
+ [case "${enableval}" in
+ yes) enable_dbg=yes ;;
+ no) enable_dbg=no ;;
+ *) AC_MSG_ERROR([Bad value ${enableval} for --enable-debug]) ;;
+ esac],[enable_dbg=no])
+if ([test "x$enable_dbg" = xyes]); then
+ CFLAGS="$CFLAGS -g"
+fi
+
+# Check GCC ELF visibility
+AC_MSG_CHECKING(for ELF visibility)
+AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([[
+ __attribute__((visibility("default")))
+ int var=10;
+ ]])],
+ [has_visibility=yes
+ AC_DEFINE([EXPORT_API], [__attribute__((visibility("default")))], [Symbol visibility prefix])
+ CFLAGS="$CFLAGS -fvisibility=hidden"],
+ [has_visibility=no
+ AC_DEFINE([EXPORT_API], [], [Symbol visibility prefix]) ]
+)
+AC_MSG_RESULT($has_visibility)
+
+# Check required libraries
+#PKG_CHECK_MODULES(PROVIDERS, [glib-2.0 network tapi vconf vconf-internal-keys msg-service gthread-2.0 dlog gio-2.0 gio-unix-2.0 lbs-dbus capi-network-wifi journal libresourced capi-appfw-app-manager deviced])
+PKG_CHECK_MODULES(PROVIDERS, [glib-2.0 network tapi vconf vconf-internal-keys gthread-2.0 dlog gio-2.0 gio-unix-2.0 lbs-dbus capi-network-wifi])
+AC_SUBST(PROVIDERS_CFLAGS)
+AC_SUBST(PROVIDERS_LIBS)
+
+PKG_CHECK_MODULES(MODULE, [glib-2.0 gmodule-2.0 location dlog gio-2.0 lbs-dbus])
+AC_SUBST(MODULE_CFLAGS)
+AC_SUBST(MODULE_LIBS)
+
+AC_HAVE_LIBRARY(pthread, [PTHREAD_LIBS=-lpthread])
+
+# GPS configuration
+AC_ARG_ENABLE([gps],
+ [AC_HELP_STRING([--enable-gps],[enable GPS [default=no]])],
+ [case "${enableval}" in
+ yes) gps=yes ;;
+ no) gps=no ;;
+ *) AC_MSG_ERROR([Bad value ${enableval} for --enable-gps]) ;;
+ esac],[gps=no])
+AM_CONDITIONAL([GPS], [test "x$gps" = xyes])
+AC_MSG_CHECKING([whether host GPS])
+if ([test "x$gps" = xyes])
+then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+AM_CONDITIONAL([HAVE_GPS], [test "x$gps" = xyes])
+
+# WPS configuration
+AC_ARG_ENABLE([wps],
+ [AC_HELP_STRING([--enable-wps],[enable WPS [default=no]])],
+ [case "${enableval}" in
+ yes) wps=yes ;;
+ no) wps=no ;;
+ *) AC_MSG_ERROR([Bad value ${enableval} for --enable-wps]) ;;
+ esac],[wps=no])
+AM_CONDITIONAL([WPS], [test "x$wps" = xyes])
+AC_MSG_CHECKING([whether host WPS])
+if ([test "x$wps" = xyes])
+then
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+AM_CONDITIONAL([HAVE_WPS], [test "x$wps" = xyes])
+
+# Check DBus configuration path
+DBUS_CONF_DIR="${sysconfdir}/dbus-1/system.d"
+AC_SUBST(DBUS_CONF_DIR)
+
+# Check DBus service path
+DBUS_SERVICES_DIR="/usr/share/dbus-1/services"
+AC_SUBST(DBUS_SERVICES_DIR)
+AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBus is])
+
+
+# Config files
+AC_CONFIG_FILES([
+Makefile
+lbs-server/Makefile
+lbs-server/lbs-server-plugin.pc
+module/Makefile
+])
+
+AC_OUTPUT
--- /dev/null
+<manifest>
+ <define>
+ <domain name="location_fw" policy="shared" />
+ <provide>
+ <label name="location_fw::server" />
+ <label name="location_fw::client" />
+ <label name="location_fw::db" />
+ <label name="location_fw::vconf" />
+ <label name="location_fw::maps" />
+ </provide>
+ <request>
+ <smack request="sys-assert::core" type="rwxat"/>
+ <smack request="system::use_internet" type="rwx"/>
+ <smack request="Odnp::dbus-access" type="rw"/>
+ <smack request="Odnp::dbus-access-gw" type="rw"/>
+ <smack request="deviced::display" type="rw"/>
+ <smack request="connman" type="rw"/>
+ <smack request="net-config" type="rw"/>
+ <smack request="location_fw::client" type="rw" />
+ <smack request="telephony_framework::api_gps" type="rw" />
+ <smack request="telephony_framework::api_sim" type="r" />
+ <smack request="system::vconf_setting" type="r" />
+ <smack request="system::vconf" type="r" />
+ </request>
+ <permit>
+ <smack permit="system::use_internet" type="rwx"/>
+ </permit>
+ </define>
+ <assign>
+ <filesystem path="/usr/share/dbus-1/services/org.tizen.lbs.Providers.LbsServer.service" label="_" />
+ <filesystem path="/usr/share/lbs/lbs-server.provider" label="location_fw::server" />
+ <filesystem path="/etc/rc.d/init.d/lbs-server" label="_" exec_label="none" />
+ <filesystem path="/etc/rc.d/rc5.d/S90lbs-server" label="_" exec_label="none" />
+ <dbus name="org.tizen.lbs.Providers.LbsServer" own="location_fw" bus="system">
+ <node name="/org/tizen/lbs/Providers/LbsServer">
+ <interface name="org.tizen.lbs.Manager">
+ <annotation name="com.tizen.smack" value="location_fw::client"/>
+ </interface>
+ <interface name="org.tizen.lbs.Position">
+ <annotation name="com.tizen.smack" value="location_fw::client"/>
+ </interface>
+ <interface name="org.tizen.lbs.Nmea">
+ <annotation name="com.tizen.smack" value="location_fw::client"/>
+ </interface>
+ <interface name="org.tizen.lbs.Satellite">
+ <annotation name="com.tizen.smack" value="location_fw::client"/>
+ </interface>
+ <interface name="org.tizen.lbs.Batch">
+ <annotation name="com.tizen.smack" value="location_fw::client"/>
+ </interface>
+
+ </node>
+ </dbus>
+ </assign>
+ <request>
+ <domain name="location_fw" />
+ </request>
+</manifest>
--- /dev/null
+libexec_PROGRAMS = lbs-server
+
+lbs_server_SOURCES = lbs_server.c \
+ server.c \
+ data_connection.c \
+ nmea_logger.c \
+ gps_plugin_module.c \
+ last_position.c \
+ setting.c \
+ dump_log.c \
+ nps_plugin_module.c
+
+lbs_server_CFLAGS = -Wall -fPIC -fvisibility=hidden \
+ -DEXPORT_API="__attribute__((visibility(\"default\")))" \
+ -I$(srcdir)/include \
+ $(PROVIDERS_CFLAGS)
+
+lbs_server_LDFLAGS = -Wl,--hash-style=both -Wl,--as-needed -Wl,-rpath=/usr/lib
+
+lbs_server_DEPENDENCIES =
+
+lbs_server_LDADD = $(lbs_server_DEPENDENCIES) \
+ $(PROVIDERS_LIBS) \
+ -ldl \
+ -lm \
+ $(NPS_LIBS)
+
+lbs_server_plugin_hdr_intfdir = $(includedir)/lbs-server-plugin
+
+
+lbs_server_plugin_hdr_intf_HEADERS = \
+ include/gps_plugin_intf.h \
+ include/gps_plugin_data_types.h \
+ include/gps_plugin_extra_data_types.h \
+ include/nps_plugin_intf.h
+
+PCFILES = lbs-server-plugin.pc
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = $(PCFILES)
+
+providersdir = $(datadir)/lbs
+providers_DATA = lbs-server.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.tizen.lbs.Providers.LbsServer.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+
+$(conf_DATA): $(conf_in_files)
+ cp $< $@
+
+EXTRA_DIST = $(PCFILES).in \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(conf_in_files)
+
+DISTCLEANFILES = $(service_DATA) \
+ $(conf_DATA)
+
+LBS_SERVER = lbs-server
+bootdir = /etc/rc.d/init.d
+boot_SCRIPTS = script/$(LBS_SERVER)
+
+RC5_SCRIPT = $(DESTDIR)/etc/rc.d/rc5.d/S90lbs-server
+
+install-exec-hook:
+ mkdir -p $(DESTDIR)/etc/rc.d/rc5.d
+ ln -sf ../init.d/$(LBS_SERVER) $(RC3_SCRIPT)
+ ln -sf ../init.d/$(LBS_SERVER) $(RC5_SCRIPT)
+
+uninstall-hook:
+ rm -f $(RC3_SCRIPT) $(RC5_SCRIPT)
+
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <assert.h>
+#include <setjmp.h>
+
+#include "data_connection.h"
+#include <network-cm-intf.h>
+#include "debug_util.h"
+
+int noti_resp_init(int *noti_pipe_fds);
+int noti_resp_wait(int *noti_pipe_fds);
+int noti_resp_check(int *noti_pipe_fds);
+int noti_resp_noti(int *noti_pipe_fds, int result);
+int noti_resp_deinit(int *noti_pipe_fds);
+
+unsigned int g_ipaddr;
+static int pdp_pipe_fds[2];
+
+typedef enum {
+ DEACTIVATED,
+ ACTIVATING,
+ ACTIVATED,
+ DEACTIVATING
+} pdp_status;
+
+char profile_name[NET_PROFILE_NAME_LEN_MAX + 1];
+
+pdp_status act_level;
+
+char *PdpStat[] = { "Deactivated", "Activating", "Activated", "Deactivating" };
+
+static void set_connection_status(pdp_status i)
+{
+ act_level = i;
+ LOG_GPS(DBG_LOW, "==Status: %s\n", PdpStat[i]);
+}
+
+static pdp_status get_connection_status()
+{
+ return act_level;
+}
+
+static void pdp_proxy_conf()
+{
+ net_proxy_t proxy;
+ int ret;
+ ret = net_get_active_proxy(&proxy);
+
+ if (ret == NET_ERR_NONE) {
+ if (strncmp(proxy.proxy_addr, "0.0.0.0", 7)) {
+ char buf[100];
+ snprintf(buf, sizeof(buf), "http://%s/", proxy.proxy_addr);
+ setenv("http_proxy", buf, 1);
+ } else {
+ unsetenv("http_proxy");
+ }
+ } else {
+ LOG_GPS(DBG_ERR, "Fail to get proxy\n");
+ }
+}
+
+void pdp_evt_cb(net_event_info_t * event_cb, void *user_data)
+{
+ switch (event_cb->Event) {
+ case NET_EVENT_OPEN_RSP:{
+ LOG_GPS(DBG_LOW, "event_cb->Error : [%d]\n", event_cb->Error);
+ if (get_connection_status() != ACTIVATING) {
+ LOG_GPS(DBG_LOW, "Not Activating status\n");
+ } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_ACTIVE_CONNECTION_EXISTS) {
+ LOG_GPS(DBG_LOW, "Successful PDP Activation\n");
+ net_profile_info_t *prof_info = NULL;
+ net_dev_info_t *net_info = NULL;
+
+ prof_info = (net_profile_info_t *) event_cb->Data;
+ net_info = &(prof_info->ProfileInfo.Pdp.net_info);
+
+ strncpy(profile_name, net_info->ProfileName, NET_PROFILE_NAME_LEN_MAX);
+
+ set_connection_status(ACTIVATED);
+ pdp_proxy_conf();
+ noti_resp_noti(pdp_pipe_fds, TRUE);
+ } else {
+ LOG_GPS(DBG_ERR, " PDP Activation Failed - PDP Error[%d]\n", event_cb->Error);
+ set_connection_status(DEACTIVATED);
+ noti_resp_noti(pdp_pipe_fds, FALSE);
+ }
+ }
+ break;
+
+ case NET_EVENT_CLOSE_RSP:
+ if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
+ LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
+ } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
+ LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
+ set_connection_status(DEACTIVATED);
+ noti_resp_noti(pdp_pipe_fds, TRUE);
+ } else {
+ LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
+ noti_resp_noti(pdp_pipe_fds, FALSE);
+ }
+ break;
+
+ case NET_EVENT_CLOSE_IND:
+ if (get_connection_status() != ACTIVATED && get_connection_status() != DEACTIVATING) {
+ LOG_GPS(DBG_ERR, "Not Activated && Deactivating status\n");
+ } else if (event_cb->Error == NET_ERR_NONE || event_cb->Error == NET_ERR_UNKNOWN) {
+ LOG_GPS(DBG_LOW, "Successful PDP De-Activation\n");
+ set_connection_status(DEACTIVATED);
+ noti_resp_noti(pdp_pipe_fds, TRUE);
+ } else {
+ LOG_GPS(DBG_ERR, " PDP DeActivation Failed - PDP Error[%d]\n", event_cb->Error);
+ noti_resp_noti(pdp_pipe_fds, FALSE);
+ }
+ break;
+ case NET_EVENT_OPEN_IND:
+ break;
+ default:
+ break;
+ }
+}
+
+unsigned int start_pdp_connection(void)
+{
+ int err = -1;
+
+ set_connection_status(DEACTIVATED);
+ if (noti_resp_init(pdp_pipe_fds))
+ LOG_GPS(DBG_LOW, "Success start_pdp_connection\n");
+ else {
+ LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
+ return FALSE;
+ }
+
+ err = net_register_client((net_event_cb_t) pdp_evt_cb, NULL);
+
+ if (err == NET_ERR_NONE || err == NET_ERR_APP_ALREADY_REGISTERED) {
+ LOG_GPS(DBG_LOW, "Client registration is succeed\n");
+ } else {
+ LOG_GPS(DBG_WARN, "Error in net_register_client [%d]\n", err);
+ noti_resp_deinit(pdp_pipe_fds);
+ return FALSE;
+ }
+
+ set_connection_status(ACTIVATING);
+ err = net_open_connection_with_preference(NET_SERVICE_INTERNET);
+
+ if (err == NET_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Sent PDP Activation.\n");
+ } else {
+ LOG_GPS(DBG_WARN, "Error in net_open_connection_with_preference() [%d]\n", err);
+ set_connection_status(DEACTIVATED);
+ err = net_deregister_client();
+ if (err == NET_ERR_NONE)
+ LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
+ else
+ LOG_GPS(DBG_ERR, "Error deregistering the client\n");
+ noti_resp_deinit(pdp_pipe_fds);
+ return FALSE;
+ }
+
+ if (noti_resp_wait(pdp_pipe_fds) > 0) {
+ if (noti_resp_check(pdp_pipe_fds)) {
+ LOG_GPS(DBG_LOW, "PDP Activation Successful\n");
+ noti_resp_deinit(pdp_pipe_fds);
+ return TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "PDP failed\n");
+ noti_resp_deinit(pdp_pipe_fds);
+
+ err = net_deregister_client();
+ if (err == NET_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
+ } else {
+ LOG_GPS(DBG_ERR, "Error deregistering the client\n");
+ }
+ return FALSE;
+ }
+ } else {
+ LOG_GPS(DBG_ERR, "NO Pdp Act Response or Some error in select.\n");
+ noti_resp_deinit(pdp_pipe_fds);
+
+ err = net_deregister_client();
+ if (err == NET_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
+ } else {
+ LOG_GPS(DBG_ERR, "Error deregistering the client\n");
+ }
+ return FALSE;
+ }
+}
+
+unsigned int stop_pdp_connection(void)
+{
+ int err;
+ pdp_status pStatus = get_connection_status();
+ if (pStatus == DEACTIVATED || pStatus == DEACTIVATING) {
+ LOG_GPS(DBG_ERR, "pdp stop progressing already. pStatus[%d] \n", pStatus);
+ return TRUE;
+ }
+
+ if (noti_resp_init(pdp_pipe_fds))
+ LOG_GPS(DBG_LOW, "Success stop_pdp_connection\n");
+ else {
+ LOG_GPS(DBG_ERR, "ERROR in noti_resp_init()\n");
+ return FALSE;
+ }
+
+ set_connection_status(DEACTIVATING);
+ err = net_close_connection(profile_name);
+ if (err == NET_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Success net_close_connection\n");
+ } else {
+ LOG_GPS(DBG_WARN, "Error in sending net_close_connection error=%d\n", err);
+ set_connection_status(pStatus);
+ noti_resp_deinit(pdp_pipe_fds);
+ return FALSE;
+ }
+ if (noti_resp_wait(pdp_pipe_fds) > 0) {
+ if (noti_resp_check(pdp_pipe_fds))
+ LOG_GPS(DBG_LOW, "Close Connection success\n");
+ else
+ LOG_GPS(DBG_ERR, "Close connection failed\n");
+ }
+
+ noti_resp_deinit(pdp_pipe_fds);
+
+ set_connection_status(DEACTIVATED);
+
+ err = net_deregister_client();
+ if (err == NET_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Client deregistered successfully\n");
+ } else {
+ LOG_GPS(DBG_WARN, "Error deregistering the client\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+unsigned int query_dns(char *pdns_lookup_addr, unsigned int *ipaddr, int *port)
+{
+ FUNC_ENTRANCE_SERVER;
+ //int dns_id;
+ unsigned int ret = 0;
+ struct hostent *he;
+
+ char *colon = strchr(pdns_lookup_addr, ':');
+ char *last = NULL;
+ if (colon != NULL) {
+ char *ptr = (char *)strtok_r(pdns_lookup_addr, ":", &last);
+ pdns_lookup_addr = ptr;
+
+ ptr = (char *)strtok_r(NULL, ":", &last);
+ *port = atoi(ptr);
+ }
+
+ he = gethostbyname(pdns_lookup_addr);
+
+ if (he != NULL) {
+ LOG_GPS(DBG_LOW, "g_agps_ipaddr: %u\n", g_ipaddr);
+ *ipaddr = g_ipaddr;
+
+ ret = TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "//gethostbyname : Error getting host information\n");
+ ret = FALSE;
+ }
+
+ return ret;
+
+}
+
+int noti_resp_init(int *noti_pipe_fds)
+{
+ if (pipe(noti_pipe_fds) < 0)
+ return 0;
+ else
+ return 1;
+}
+
+int noti_resp_wait(int *noti_pipe_fds)
+{
+ fd_set rfds;
+ fd_set wfds;
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+ FD_SET(*noti_pipe_fds, &rfds);
+ return select(*noti_pipe_fds + 1, &rfds, &wfds, NULL, NULL);
+}
+
+int noti_resp_noti(int *noti_pipe_fds, int result)
+{
+ return write(*(noti_pipe_fds + 1), &result, sizeof(int));
+}
+
+int noti_resp_check(int *noti_pipe_fds)
+{
+ int activation = 0;
+ ssize_t ret_val = 0;
+ ret_val = read(*noti_pipe_fds, &activation, sizeof(int));
+ if (ret_val == 0) {
+ LOG_GPS(DBG_ERR, "No data");
+ }
+ return activation;
+}
+
+int noti_resp_deinit(int *noti_pipe_fds)
+{
+ int err;
+ err = close(*noti_pipe_fds);
+ if (err != 0)
+ LOG_GPS(DBG_ERR, "ERROR closing fds1.\n");
+
+ err = close(*(noti_pipe_fds + 1));
+ if (err != 0)
+ LOG_GPS(DBG_ERR, "ERROR closing fds2.\n");
+
+ return err;
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _DATA_CONNECTION_H_
+#define _DATA_CONNECTION_H_
+
+/* Total Number of seconds in years between NTP Reference time(1900) to UTC reference time(1970)*/
+#define UTC_NTP_BIAS 2208988800
+/* Total Number of seconds in years between UTC reference time(1970) to GPS Refernce time(1980)*/
+#define UTC_GPS_BIAS 315964800
+
+#define MAX_NUMBER_OF_URLS 3
+
+#include <glib.h>
+
+unsigned int start_pdp_connection(void);
+unsigned int stop_pdp_connection(void);
+
+unsigned int query_dns(char *pdns_lookup_addr, unsigned int *ipaddr, int *port);
+
+#endif
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _DEBUG_UTIL_H_
+#define _DEBUG_UTIL_H_
+
+#include <glib.h>
+#include <libgen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <dlog.h>
+#define TAG_GPS_MANAGER "LBS_SERVER_GPS"
+#define TAG_NPS_MANAGER "LBS_SERVER_NPS"
+#ifdef TIZEN_WEARABLE
+#define TAG_COMMON_MANAGER "LBS_SERVER"
+#endif
+
+#define DBG_LOW LOG_DEBUG
+#define DBG_INFO LOG_INFO
+#define DBG_WARN LOG_WARN
+#define DBG_ERR LOG_ERROR
+
+#define LOG_GPS(dbg_lvl,fmt,args...) SLOG(dbg_lvl, TAG_GPS_MANAGER, fmt, ##args)
+#define LOG_NPS(dbg_lvl,fmt,args...) SLOG(dbg_lvl, TAG_NPS_MANAGER, fmt,##args)
+#ifdef TIZEN_WEARABLE
+#define LOG_COMMON(dbg_lvl,fmt,args...) SLOG(dbg_lvl, TAG_COMMON_MANAGER, fmt, ##args)
+#endif
+
+#define FUNC_ENTRANCE_SERVER LOG_GPS(DBG_LOW, "[%s] Entered!!", __func__);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _DEBUG_UTIL_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "debug_util.h"
+
+#define GPG_DUMP_LOG "/tmp/dump_gps.log"
+
+int fd = -1;
+
+struct tm * __get_current_time()
+{
+ time_t now;
+ struct tm *cur_time;
+
+ time(&now);
+ cur_time = localtime(&now);
+ return cur_time;
+}
+
+void gps_init_log()
+{
+ LOG_GPS(DBG_ERR, "gps_init_log");
+ int ret = -1;
+ struct tm *cur_time = __get_current_time();
+ char buf[256] = {0, };
+ fd = open(GPG_DUMP_LOG, O_RDWR | O_APPEND | O_CREAT, 0644);
+ if (fd < 0) {
+ LOG_GPS(DBG_ERR, "Fail to open file[%s]", GPG_DUMP_LOG);
+ return;
+ }
+
+ sprintf(buf, "[%02d:%02d:%02d] -- START GPS -- \n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec);
+ ret = write(fd, buf, strlen(buf));
+ if (ret == -1) {
+ LOG_GPS(DBG_ERR, "Fail to write file[%s]", GPG_DUMP_LOG);
+ }
+}
+
+void gps_deinit_log()
+{
+ LOG_GPS(DBG_ERR, "gps_deinit_log");
+ if (fd < 0) return;
+ int ret = -1;
+ struct tm *cur_time = __get_current_time();
+ char buf[256] = {0, };
+
+ sprintf(buf, "[%02d:%02d:%02d] -- END GPS -- \n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec);
+ ret = write(fd, buf, strlen(buf));
+ if (ret == -1) {
+ LOG_GPS(DBG_ERR, "Fail to write file[%s]", GPG_DUMP_LOG);
+ }
+
+ close(fd);
+ fd = -1;
+}
+
+void gps_dump_log(const char *str, const char *app_id)
+{
+ if (fd < 0) {
+ LOG_GPS(DBG_ERR, "Not available fd[%d]", fd);
+ return;
+ }
+ int ret = -1;
+ char buf[256] = {0, };
+ struct tm* cur_time = __get_current_time();
+
+ if (app_id == NULL) {
+ sprintf(buf, "[%02d:%02d:%02d] %s\n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec, str);
+ } else {
+ sprintf(buf, "[%02d:%02d:%02d] %s from [%s]\n", cur_time->tm_hour, cur_time->tm_min, cur_time->tm_sec, str, app_id);
+ }
+ LOG_GPS(DBG_ERR, "Add dump log [%s", buf);
+ ret = write(fd, buf, strlen(buf));
+ if (ret == -1) {
+ LOG_GPS(DBG_ERR, "Fail to write file[%s]", GPG_DUMP_LOG);
+ }
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _DUMP_LOG_H_
+#define _DUMP_LOG_H_
+
+#include <time.h>
+
+void gps_init_log();
+
+void gps_deinit_log();
+
+void gps_dump_log(const char *str, const char *app_id);
+
+#endif /* _DUMP_LOG_H_ */
--- /dev/null
+/*
+ * lbs_server
+ *
+ * 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 <string.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include "gps_plugin_module.h"
+#include "setting.h"
+#include "debug_util.h"
+
+#define SPECIFIC_PLUGIN_PATH_PREFIX "/usr/lib/libSLP-lbs-plugin-"
+#define SPECIFIC_PLUGIN_PATH_POSTFIX ".so"
+
+static const gps_plugin_interface *g_plugin = NULL;
+
+int load_plugin_module(char *specific_name, void **plugin_handle)
+{
+ char plugin_path[256];
+
+ if (specific_name[0] == '\0') {
+ strncpy(plugin_path, GPS_PLUGIN_PATH, sizeof(plugin_path));
+ } else {
+ snprintf(plugin_path, sizeof(plugin_path),
+ SPECIFIC_PLUGIN_PATH_PREFIX
+ "%s"
+ SPECIFIC_PLUGIN_PATH_POSTFIX,
+ specific_name);
+ }
+
+ if (access (plugin_path, R_OK) != 0) {
+ strncpy(plugin_path, GPS_PLUGIN_PATH, sizeof(plugin_path));
+ setting_set_int(VCONFKEY_LOCATION_REPLAY_ENABLED, 1);
+ }
+
+ *plugin_handle = dlopen(plugin_path, RTLD_NOW);
+ if (!*plugin_handle) {
+ LOG_GPS(DBG_ERR, "Failed to load plugin module.");
+ LOG_GPS(DBG_ERR, "%s", dlerror());
+ return FALSE;
+ }
+
+ const gps_plugin_interface *(*get_gps_plugin_interface) ();
+ get_gps_plugin_interface = dlsym(*plugin_handle, "get_gps_plugin_interface");
+ if (!get_gps_plugin_interface) {
+ LOG_GPS(DBG_ERR, "Failed to find entry symbol in plugin module.");
+ dlclose(*plugin_handle);
+ return FALSE;
+ }
+
+ g_plugin = get_gps_plugin_interface();
+
+ if (!g_plugin) {
+ LOG_GPS(DBG_ERR, "Failed to find load symbol in plugin module.");
+ dlclose(*plugin_handle);
+ return FALSE;
+ }
+ LOG_GPS(DBG_LOW, "Success to load plugin module");
+
+ return TRUE;
+}
+
+int unload_plugin_module(void *plugin_handle)
+{
+ if (plugin_handle == NULL) {
+ LOG_GPS(DBG_ERR, "plugin_handle is already NULL.");
+ return FALSE;
+ }
+
+ dlclose(plugin_handle);
+
+ return TRUE;
+}
+
+const gps_plugin_interface *get_plugin_module(void)
+{
+ return g_plugin;
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_MODULE_H_
+#define _GPS_PLUGIN_MODULE_H_
+
+#include "gps_plugin_intf.h"
+
+int load_plugin_module(char *specific_name, void **plugin_handle);
+int unload_plugin_module(void *plugin_handle);
+const gps_plugin_interface *get_plugin_module(void);
+
+#endif /* _GPS_PLUGIN_MODULE_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_DATA_TYPES_H_
+#define _GPS_PLUGIN_DATA_TYPES_H_
+
+#include <stdint.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** Maximum number of satellite which is in used */
+#define MAX_GPS_NUM_SAT_USED (12)
+
+/** Maximum number of satellite which is in view */
+#define MAX_GPS_NUM_SAT_IN_VIEW (32)
+
+/**
+ * This enumeration has error type.
+ */
+typedef enum {
+ GPS_ERR_NONE = 0, /**< Error None */
+ GPS_ERR_TIMEOUT = -100, /**< pos_cb error GPS Timeout */
+ GPS_ERR_OUT_OF_SERVICE = -101, /**< pos_cb error GPS out of service */
+ GPS_ERR_COMMUNICATION = -200, /**< Plugin event callback error */
+} gps_error_t;
+
+/**
+ * This enumeration has geofence service status.
+ */
+typedef enum {
+ GEOFENCE_STATUS_UNAVAILABLE = 0,
+ GEOFENCE_STATUS_AVAILABLE = 1,
+} geofence_status_t;
+
+/**
+ * This enumeration has geofence service error type.
+ */
+typedef enum {
+ GEOFENCE_ERR_NONE = 0,
+ GEOFENCE_ERR_TOO_MANY_GEOFENCE = -100,
+ GEOFENCE_ERR_ID_EXISTS = -101,
+ GEOFENCE_ERR_ID_UNKNOWN = -200,
+ GEOFENCE_ERR_INVALID_TRANSITION = -300,
+ GEOFENCE_ERR_UNKNOWN = -400,
+} geofence_error_t;
+
+#ifdef TIZEN_WEARABLE
+/**
+ * This enumeration has XTRA request error type.
+ */
+typedef enum {
+ XTRA_REQUEST_ERR_NONE = 0,
+ XTRA_REQUEST_ERR_UNKNOWN = -100,
+} xtra_request_error_t;
+#endif
+
+
+/**
+ * This structure defines the GPS position data.
+ */
+typedef struct {
+ time_t timestamp; /**< Timestamp */
+ double latitude; /**< Latitude data (in degree) */
+ double longitude; /**< Longitude data (in degree) */
+ double altitude; /**< Altitude data (in meter) */
+ double speed; /**< Speed (in m/s) */
+ double bearing; /**< Direction from true north(in degree) */
+ double hor_accuracy; /**< Horizontal position error(in meter) */
+ double ver_accuracy; /**< Vertical position error(in meter) */
+} pos_data_t;
+
+/**
+ * This structure defines the GPS batch data.
+ */
+typedef struct {
+ int num_of_location; /**< Number of batch data */
+} batch_data_t;
+
+/**
+ * This structure defines the satellite data.
+ */
+typedef struct {
+ int prn; /**< Pseudo Random Noise code of satellite */
+ int snr; /**< Signal to Noise Ratio */
+ int elevation; /**< Elevation */
+ int azimuth; /**< Degrees from true north */
+ int used; /**< Satellite was used for position fix */
+} sv_info_t;
+
+/**
+ * This structure defines the GPS satellite in view data.
+ */
+typedef struct {
+ time_t timestamp; /**< Timestamp */
+ unsigned char pos_valid; /**< TRUE, if position is valid */
+ int num_of_sat; /**< Number of satellites in view */
+ sv_info_t sat[MAX_GPS_NUM_SAT_IN_VIEW]; /**< Satellite information */
+} sv_data_t;
+
+/**
+ * This structure defines the NMEA data.
+ */
+typedef struct {
+ time_t timestamp; /**< Timestamp */
+ int len; /**< NMEA data length */
+ char *data; /**< Raw NMEA data */
+} nmea_data_t;
+
+/**
+ * This structure defines the geofence data.
+ */
+typedef struct {
+ int geofence_id; /**< Geofence ID */
+ double latitude; /**< Latitude data (in degree) */
+ double longitude; /**< Longitude data (in degree) */
+ int radius; /**< Radius data (in meters) */
+} geofence_data_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GPS_PLUGIN_DATA_TYPES_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_EXTRA_DATA_TYPES_H_
+#define _GPS_PLUGIN_EXTRA_DATA_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * This enumeration has GPS session type.
+ */
+typedef enum {
+ GPS_SESSION_SINGLE_FIX = 0, /**< Single fix starting */
+ GPS_SESSION_TRACKING_MODE /**< Tracking mode starting */
+} gps_session_t;
+
+/**
+ * This enumeration has GPS operation mode.
+ */
+typedef enum {
+ GPS_OPERATION_STANDALONE = 0, /**< GPS standalone (no assistance) */
+ GPS_OPERATION_MS_BASED, /**< MS-Based AGPS */
+ GPS_OPERATION_MS_ASSISTED /**< MS-Assisted AGPS */
+} gps_operation_t;
+
+/**
+ * This enumeration has GPS starting type.
+ */
+typedef enum {
+ GPS_STARTING_HOT_ = 0, /**< Hot start */
+ GPS_STARTING_COLD, /**< Cold start */
+ GPS_STARTING_NONE /**< None */
+} gps_starting_t;
+
+/**
+ * This enumeration has the SSL mode.
+ */
+typedef enum {
+ AGPS_SSL_DISABLE = 0, /**< SSL disable */
+ AGPS_SSL_ENABLE /**< SSL enable */
+} agps_ssl_mode_t;
+
+/**
+ * This enumeration has the SSL certification type.
+ */
+typedef enum {
+ AGPS_CERT_VERISIGN = 0,
+ AGPS_CERT_THAWTE,
+ AGPS_CERT_CMCC,
+ AGPS_CERT_SPIRENT_TEST,
+ AGPS_CERT_THALES_TEST,
+ AGPS_CERT_CMCC_TEST,
+ AGPS_CERT_BMC_TEST,
+ AGPS_CERT_GOOGLE
+} agps_ssl_cert_type_t;
+
+/**
+ * This enumeration has the verification confirm type.
+ */
+typedef enum {
+ AGPS_VER_CNF_YES = 0x00, /**< Specifies Confirmation yes. */
+ AGPS_VER_CNF_NO = 0x01, /**< Specifies Confirmation no. */
+ AGPS_VER_CNF_NORESPONSE = 0x02 /**< Specifies Confirmation no response. */
+} agps_verification_cnf_type_t;
+
+/**
+ * This enumeration has the zone in/out type.
+ */
+typedef enum {
+ GEOFENCE_ZONE_OUT = 0x00,
+ GEOFENCE_ZONE_IN = 0x01,
+ GEOFENCE_ZONE_UNCERTAIN = 0x02
+} geofence_zone_state_t;
+
+/**
+ * This structure is used to get the Extra Fix request parameters.
+ */
+typedef struct {
+ int accuracy; /**< accuracy */
+ int tbf; /**< time between fixes */
+ int num_fixes; /**< num fixes */
+ unsigned char timeout; /**< session timeout */
+} gps_qos_param_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GPS_PLUGIN_EXTRA_DATA_TYPES_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_PLUGIN_INTF_H_
+#define _GPS_PLUGIN_PLUGIN_INTF_H_
+
+#include <gps_plugin_data_types.h>
+#include <gps_plugin_extra_data_types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GPS_PLUGIN_PATH "/usr/lib/libSLP-lbs-plugin.so"
+#define MAX_REQUESTER_ID_LEN (128)
+#define MAX_CLIENT_NAME_LEN (128)
+#define MAX_SUPL_URL_LEN (128)
+
+/**
+ * GPS asynchronous event type
+ */
+typedef enum {
+ GPS_EVENT_START_SESSION = 0x0000, /**< The session is started */
+ GPS_EVENT_STOP_SESSION, /**< The session is stopped */
+ GPS_EVENT_CHANGE_INTERVAL, /**< Change updating interval */
+ GPS_EVENT_REPORT_POSITION = 0x0100, /**< Bring up GPS position data */
+ GPS_EVENT_REPORT_SATELLITE, /**< Bring up GPS SV data */
+ GPS_EVENT_REPORT_NMEA, /**< Bring up GPS NMEA data */
+ GPS_EVENT_REPORT_BATCH, /**< Bring up GPS batch data */
+ GPS_EVENT_SET_OPTION = 0x0200, /**< The option is set */
+ GPS_EVENT_GET_REF_LOCATION = 0x0300, /**< Get the reference location for AGPS */
+ GPS_EVENT_GET_IMSI, /**< Get IMSI for identification */
+ GPS_EVENT_OPEN_DATA_CONNECTION = 0x0400, /**< Request opening data network connection */
+ GPS_EVENT_CLOSE_DATA_CONNECTION, /**< Request closing data network connection */
+ GPS_EVENT_DNS_LOOKUP_IND, /**< Request resolving host name */
+ GPS_EVENT_AGPS_VERIFICATION_INDI, /**< Verification indicator for AGPS is required */
+ GPS_EVENT_FACTORY_TEST = 0x0500, /**< Factory test is done */
+ GPS_EVENT_GEOFENCE_TRANSITION = 0x0600, /**< Geofence transition is occured */
+ GPS_EVENT_GEOFENCE_STATUS, /**< Report geofence serivce status */
+ GPS_EVENT_ADD_GEOFENCE, /**< Geofence is added(Start geofence) */
+ GPS_EVENT_DELETE_GEOFENCE, /**< Geofence is deleted(Stop geofence) */
+ GPS_EVENT_PAUSE_GEOFENCE, /**< Geofence is paused */
+ GPS_EVENT_RESUME_GEOFENCE, /**< Geofence is resumed */
+ #ifdef TIZEN_WEARABLE
+ GPS_EVENT_REQUEST_XTRA = 0x0700, /**< XTRA is requested */
+ #endif
+ GPS_EVENT_ERR_CAUSE = 0xFFFF /**< Some error is occurred */
+} gps_event_id_t;
+
+/**
+ * Start session response event data
+ */
+typedef struct {
+ gps_error_t error;
+} gps_start_session_ev_info_t;
+
+/**
+ * Response of stop session
+ */
+typedef struct {
+ gps_error_t error;
+} gps_stop_session_ev_info_t;
+
+/**
+ * Set option response event data
+ */
+typedef struct {
+ gps_error_t error;
+} gps_set_option_ev_info_t;
+
+typedef struct {
+ gps_error_t error;
+} gps_change_interval_ev_info_t;
+
+/**
+ * Position data from GPS
+ */
+typedef struct {
+ gps_error_t error;
+ pos_data_t pos;
+} gps_pos_ev_info_t;
+
+/**
+ * Batch data from GPS
+ */
+typedef struct {
+ gps_error_t error;
+ batch_data_t batch;
+} gps_batch_ev_info_t;
+
+/**
+ * Satellite data from GPS
+ */
+typedef struct {
+ gps_error_t error;
+ sv_data_t sv;
+} gps_sv_ev_info_t;
+
+/**
+ * NMEA data from GPS
+ */
+typedef struct {
+ gps_error_t error;
+ nmea_data_t nmea;
+} gps_nmea_ev_info_t;
+
+/**
+ * This enumeration defines values for notify type for GPS verification message.
+ */
+typedef enum {
+ AGPS_NOTIFY_NO_VERIFY = 0x00,
+ AGPS_NOTIFY_ONLY = 0x01,
+ AGPS_NOTIFY_ALLOW_NORESPONSE = 0x02,
+ AGPS_NOTIFY_NOTALLOW_NORESPONSE = 0x03,
+ AGPS_NOTIFY_PRIVACY_NEEDED = 0x04,
+ AGPS_NOTIFY_PRIVACY_OVERRIDE = 0x05
+} agps_notify_t;
+
+/**
+ * This enumeration defines values for requester type for GPS verification message
+ */
+typedef enum {
+ AGPS_REQ_LOGICAL_NAME = 0x00, /**< Specifies logical name. */
+ AGPS_REQ_EMAIL_ADDR = 0x01, /**< Specifies e-mail address */
+ AGPS_REQ_MSISDN = 0x02, /**< Specifies MSISDN number */
+ AGPS_REQ_URL = 0x03, /**< Specifies URL */
+ AGPS_REQ_SIPURL = 0x04, /**< Specifies SIPURL */
+ AGPS_REQ_MIN = 0x05, /**< Specifies MIN */
+ AGPS_REQ_MDN = 0x06, /**< Specifies MDN */
+ AGPS_REQ_UNKNOWN = 0x07 /**< Unknown request */
+} agps_supl_format_t;
+
+/**
+ * This enumeration defines values for GPS encoding type for GPS verification message.
+ */
+typedef enum {
+ AGPS_ENCODE_ISO646IRV = 0x00,
+ AGPS_ENCODE_ISO8859 = 0x01,
+ AGPS_ENCODE_UTF8 = 0x02,
+ AGPS_ENCODE_UTF16 = 0x03,
+ AGPS_ENCODE_UCS2 = 0x04,
+ AGPS_ENCODE_GSMDEFAULT = 0x05,
+ AGPS_ENCODE_SHIFT_JIS = 0x06,
+ AGPS_ENCODE_JIS = 0x07,
+ AGPS_ENCODE_EUC = 0x08,
+ AGPS_ENCODE_GB2312 = 0x09,
+ AGPS_ENCODE_CNS11643 = 0x0A,
+ AGPS_ENCODE_KSC1001 = 0x0B,
+ AGPS_ENCODE_GERMAN = 0x0C,
+ AGPS_ENCODE_ENGLISH = 0x0D,
+ AGPS_ENCODE_ITALIAN = 0x0E,
+ AGPS_ENCODE_FRENCH = 0x0F,
+ AGPS_ENCODE_SPANISH = 0x10,
+ AGPS_ENCODE_DUTCH = 0x11,
+ AGPS_ENCODE_SWEDISH = 0x12,
+ AGPS_ENCODE_DANISH = 0x13,
+ AGPS_ENCODE_PORTUGUESE = 0x14,
+ AGPS_ENCODE_FINNISH = 0x15,
+ AGPS_ENCODE_NORWEGIAN = 0x16,
+ AGPS_ENCODE_GREEK = 0x17,
+ AGPS_ENCODE_TURKISH = 0x18,
+ AGPS_ENCODE_HUNGARIAN = 0x19,
+ AGPS_ENCODE_POLISH = 0x1A,
+ AGPS_ENCODE_LANGUAGE_UNSPEC = 0xFF
+} agps_encoding_scheme_t;
+
+/**
+ * This enumeration defines values for GPS encoding type for GPS verification message.
+ */
+typedef enum {
+ AGPS_ID_ENCODE_ISO646IRV = 0x00,
+ AGPS_ID_ENCODE_EXN_PROTOCOL_MSG = 0x01,
+ AGPS_ID_ENCODE_ASCII = 0x02,
+ AGPS_ID_ENCODE_IA5 = 0x03,
+ AGPS_ID_ENCODE_UNICODE = 0x04,
+ AGPS_ID_ENCODE_SHIFT_JIS = 0x05,
+ AGPS_ID_ENCODE_KOREAN = 0x06,
+ AGPS_ID_ENCODE_LATIN_HEBREW = 0x07,
+ AGPS_ID_ENCODE_LATIN = 0x08,
+ AGPS_ID_ENCODE_GSM = 0x09
+} agps_requester_id_encoding_t;
+
+/**
+ * This structure defines the values for GPS Verification message indication.
+ */
+typedef struct {
+ /** Specifies notification type refer enum tapi_gps_notify_type_t */
+ agps_notify_t notify_type;
+
+ /** Specifies encoding type refer enum tapi_gps_encoding_type_t */
+ agps_supl_format_t supl_format;
+
+ /** Specifies requester type */
+ agps_encoding_scheme_t datacoding_scheme;
+
+ agps_requester_id_encoding_t requester_id_encoding;
+
+ /** Specifies requester ID */
+ char requester_id[MAX_REQUESTER_ID_LEN];
+
+ /** Specifies client name */
+ char client_name[MAX_CLIENT_NAME_LEN];
+
+ /** Response timer */
+ int resp_timer;
+} agps_verification_ev_info_t;
+
+/**
+ * Factory test result information
+ */
+typedef struct {
+ gps_error_t error;
+ int prn;
+ double snr;
+} gps_factory_test_ev_info_t;
+
+/**
+ * DNS query request information
+ */
+typedef struct {
+ gps_error_t error;
+ char domain_name[MAX_SUPL_URL_LEN];
+} gps_dns_query_ev_info_t;
+
+/**
+ * Geofecne transition information
+ */
+typedef struct {
+ time_t geofence_timestamp;
+ int geofence_id;
+ pos_data_t pos;
+ geofence_zone_state_t state;
+} geofence_transition_ev_info_t;
+
+/**
+ * Geofecne status information
+ */
+typedef struct {
+ geofence_status_t status;
+ pos_data_t last_pos;
+} geofence_status_ev_info_t;
+
+/**
+ * Geofecne event information
+ */
+typedef struct {
+ int geofence_id;
+ geofence_error_t error;
+} geofence_event_t;
+
+#ifdef TIZEN_WEARABLE
+/**
+ * Type of XTRA request
+ */
+typedef enum {
+ XTRA_REQUEST_TYPE_NONE = 0x00,
+ XTRA_REQUEST_TYPE_QCOM = 0x01,
+ XTRA_REQUEST_TYPE_BRCM = 0x02,
+ XTRA_REQEUST_TYPE_NUM,
+} xtra_request_type_t;
+
+/**
+ * XTRA request information
+ */
+typedef struct {
+ xtra_request_type_t xtra_id;
+ xtra_request_error_t error;
+} xtra_request_info_t;
+#endif
+
+/**
+ * GPS event info
+ */
+typedef union {
+ /** Callback related with Response */
+ gps_start_session_ev_info_t start_session_rsp;
+ gps_stop_session_ev_info_t stop_session_rsp;
+ gps_set_option_ev_info_t set_option_rsp;
+ gps_change_interval_ev_info_t change_interval_rsp;
+
+ /** Callback related with Indication */
+ gps_pos_ev_info_t pos_ind;
+ gps_sv_ev_info_t sv_ind;
+ gps_nmea_ev_info_t nmea_ind;
+ gps_batch_ev_info_t batch_ind;
+ agps_verification_ev_info_t agps_verification_ind;
+
+ gps_factory_test_ev_info_t factory_test_rsp;
+ gps_dns_query_ev_info_t dns_query_ind;
+
+ /** Callback related with Geofence. */
+ geofence_transition_ev_info_t geofence_transition_ind;
+ geofence_status_ev_info_t geofence_status_ind;
+ geofence_event_t geofence_event_rsp;
+
+ #ifdef TIZEN_WEARABLE
+ /** Callback related with XTRA. */
+ xtra_request_info_t xtra_request_ind;
+ #endif
+} gps_event_data_t;
+
+/**
+ * Transport Error Cause
+ */
+typedef enum {
+ GPS_FAILURE_CAUSE_NORMAL = 0x00,
+ GPS_FAILURE_CAUSE_FACTORY_TEST,
+ GPS_FAILURE_CAUSE_DNS_QUERY
+} gps_failure_reason_t;
+
+/**
+ * GPS Event Info
+ */
+typedef struct {
+ gps_event_id_t event_id; /**< GPS asynchronous event id */
+ gps_event_data_t event_data; /**< GPS event information data */
+} gps_event_info_t;
+
+/**
+ * Callback function
+ * LBS server needs to register a callback function with GPS OEM to receive asynchronous events.
+ */
+typedef int (*gps_event_cb) (gps_event_info_t *gps_event_info, void *user_data);
+
+/**
+ * GPS action type
+ */
+typedef enum {
+ GPS_ACTION_SEND_PARAMS = 0x000,
+ GPS_ACTION_START_SESSION,
+ GPS_ACTION_STOP_SESSION,
+ GPS_ACTION_START_BATCH,
+ GPS_ACTION_STOP_BATCH,
+ GPS_ACTION_CHANGE_INTERVAL,
+
+ GPS_INDI_SUPL_VERIFICATION,
+ GPS_INDI_SUPL_DNSQUERY,
+
+ GPS_ACTION_START_FACTTEST,
+ GPS_ACTION_STOP_FACTTEST,
+ GPS_ACTION_REQUEST_SUPL_NI,
+ GPS_ACTION_DELETE_GPS_DATA,
+
+ GPS_ACTION_ADD_GEOFENCE,
+ GPS_ACTION_DELETE_GEOFENCE,
+ GPS_ACTION_PAUSE_GEOFENCE,
+ GPS_ACTION_RESUME_GEOFENCE,
+
+ #ifdef TIZEN_WEARABLE
+ GPS_ACTION_DOWNLOAD_XTRA,
+ GPS_ACTION_CONSUMER_CONNECTED,
+ GPS_ACTION_CONSUMER_DISCONNECTED,
+ #endif
+} gps_action_t;
+
+/**
+ * Cell information type
+ */
+typedef enum {
+ GPS_CELL_INFO_TYPE_aRFCNPresent = 0,
+ GPS_CELL_INFO_TYPE_bSICPresent,
+ GPS_CELL_INFO_TYPE_rxLevPresent,
+ GPS_CELL_INFO_TYPE_frequencyInfoPresent,
+ GPS_CELL_INFO_TYPE_cellMeasuredResultPresent,
+
+ GPS_CELL_INFO_TYPE_refMCC,
+ GPS_CELL_INFO_TYPE_refMNC,
+ GPS_CELL_INFO_TYPE_refLAC,
+ GPS_CELL_INFO_TYPE_refCI,
+ GPS_CELL_INFO_TYPE_refUC,
+ GPS_CELL_INFO_TYPE_aRFCN,
+ GPS_CELL_INFO_TYPE_bSIC,
+ GPS_CELL_INFO_TYPE_rxLev
+} agps_cell_info_t;
+
+/**
+ * Mobile service type
+ */
+typedef enum {
+ SVCTYPE_NONE = 0, /**< Unknown network */
+ SVCTYPE_NOSVC, /**< Network in no service */
+ SVCTYPE_EMERGENCY, /**< Network emergency */
+ SVCTYPE_SEARCH, /**< Network search 1900 */
+ SVCTYPE_2G, /**< Network 2G */
+ SVCTYPE_2_5G, /**< Network 2.5G */
+ SVCTYPE_2_5G_EDGE, /**< Network EDGE */
+ SVCTYPE_3G, /**< Network UMTS */
+ SVCTYPE_HSDPA /**< Network HSDPA */
+} agps_svc_type_t;
+
+/**
+ * SUPL network-initiated information
+ */
+typedef struct {
+ char *msg_body; /**< SUPL NI message body */
+ int msg_size; /**< SUPL NI message size */
+ int status; /**< Return code of Status */
+} agps_supl_ni_info_t;
+
+/**
+ * Geofence action data type
+ */
+typedef struct {
+ geofence_data_t geofence;
+ geofence_zone_state_t last_state;
+ int monitor_states;
+ int notification_responsiveness_ms;
+ int unknown_timer_ms;
+} geofence_action_data_t;
+
+typedef struct {
+ int interval;
+ int period;
+} gps_action_start_data_t;
+
+typedef struct {
+ int interval;
+} gps_action_change_interval_data_t;
+
+/**
+ * gps-plugin plugin interface
+ */
+typedef struct {
+ /** Initialize plugin module and register callback function for event delivery. */
+ int (*init) (gps_event_cb gps_event_cb, void *user_data);
+
+ /** Deinitialize plugin module */
+ int (*deinit) (gps_failure_reason_t *reason_code);
+
+ /** Request specific action to plugin module */
+ int (*request) (gps_action_t gps_action, void *gps_action_data,
+ gps_failure_reason_t *reason_code);
+} gps_plugin_interface;
+
+const gps_plugin_interface *get_gps_plugin_interface();
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _GPS_PLUGIN_INTF_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>,
+ * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>,
+ * Ming Zhu <mingwu.zhu@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 _NPS_PLUGIN_INTF_H_
+#define _NPS_PLUGIN_INTF_H_
+
+#define NPS_UNIQUE_ID_LEN (20)
+#define NPS_PLUGIN_PATH "/usr/lib/libSLP-nps-plugin.so"
+
+typedef struct {
+ double latitude; // decimal degree (WGS84)
+ double longitude; // decimal degree (WGS84)
+ double hpe; // in meters (@ 95% confidence)
+ double altitude; // in meters
+ double speed; // in km/hr (negative value for unknown speed)
+ double bearing; // degree from north clockwise (+90 is East) (negative value for unknown)
+ unsigned long age; // number of milliseconds elapsed since location was calculated
+} Plugin_LocationInfo;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*LocationCallback)(void *arg, const Plugin_LocationInfo *location, const void *reserved);
+typedef void (*OfflineTokenCallback)(void *arg, const unsigned char *token, unsigned tokenSize);
+typedef void (*CancelCallback)(void *arg);
+
+typedef struct {
+ int (*load )(void);
+ int (*unload) (void);
+ int (*start) (unsigned long period, LocationCallback cb, void *arg, void **handle);
+ int (*stop) (void *handle, CancelCallback cb, void *arg);
+ void (*getOfflineToken)(const unsigned char *key,
+ unsigned int keyLengh,
+ OfflineTokenCallback cb,
+ void *arg);
+ int (*offlineLocation) (const unsigned char *key,
+ unsigned int keyLength,
+ const unsigned char *token,
+ unsigned int tokenSize,
+ LocationCallback cb,
+ void *arg);
+ void (*cellLocation) (LocationCallback callback, void* arg);
+} nps_plugin_interface;
+
+const nps_plugin_interface *get_nps_plugin_interface();
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _NPS_PLUGIN_INTF_H_ */
+
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_data_types.h"
+#include "last_position.h"
+#include "debug_util.h"
+#include "setting.h"
+
+#define MAX_GPS_LOC_ITEM 7
+#define UPDATE_INTERVAL 60
+
+void gps_set_last_position(const pos_data_t * pos)
+{
+ if (pos == NULL) return;
+
+ LOG_GPS(DBG_LOW, "set_last_position[%d]", pos->timestamp);
+
+ char location[128] = {0,};
+ snprintf(location, sizeof(location), "%.6lf;%.6lf;%.2lf;%.2lf;%.2lf;%.2lf;%.2lf;", pos->latitude, pos->longitude, pos->altitude, pos->speed, pos->bearing, pos->hor_accuracy, pos->ver_accuracy);
+
+ setting_set_int(VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP, pos->timestamp);
+ setting_set_string(VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION, location);
+}
+
+void gps_set_position(const pos_data_t * pos)
+{
+ if (pos == NULL)
+ return;
+
+ LOG_GPS(DBG_LOW, "set_position[%d]", pos->timestamp);
+ int last_timestamp = 0;
+ int timestamp = pos->timestamp;
+ double lat = pos->latitude;
+ double lon = pos->longitude;
+ double alt = pos->altitude;
+ double spd = pos->speed;
+ double dir = pos->bearing;
+ double h_acc = pos->hor_accuracy;
+ double v_acc = pos->ver_accuracy;
+
+ setting_set_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, timestamp);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, lat);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, lon);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, alt);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_SPEED, spd);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, dir);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, h_acc);
+ setting_set_double(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, v_acc);
+
+ setting_get_int(VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP, &last_timestamp);
+
+ if ((timestamp - last_timestamp) > UPDATE_INTERVAL) {
+ gps_set_last_position(pos);
+ }
+}
+
+void gps_get_last_position(pos_data_t * last_pos)
+{
+ if (last_pos == NULL)
+ return;
+
+ int timestamp;
+ char location[128] = {0,};
+ char *last_location[MAX_GPS_LOC_ITEM] = {0,};
+ char *last = NULL;
+ char *str = NULL;
+ int index = 0;
+
+ setting_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp);
+ str = setting_get_string(VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION);
+ if (str == NULL) {
+ return;
+ }
+ snprintf(location, sizeof(location), "%s", str);
+ free(str);
+
+ last_location[index] = (char *)strtok_r(location, ";", &last);
+ while (last_location[index++] != NULL) {
+ if (index == MAX_GPS_LOC_ITEM)
+ break;
+ last_location[index] = (char *)strtok_r(NULL, ";", &last);
+ }
+ index = 0;
+
+ last_pos->timestamp = timestamp;
+ last_pos->latitude = strtod(last_location[index++], NULL);
+ last_pos->longitude = strtod(last_location[index++], NULL);
+ last_pos->altitude = strtod(last_location[index++], NULL);
+ last_pos->speed = strtod(last_location[index++], NULL);
+ last_pos->bearing = strtod(last_location[index++], NULL);
+ last_pos->hor_accuracy = strtod(last_location[index++], NULL);
+ last_pos->ver_accuracy = strtod(last_location[index], NULL);
+
+ LOG_GPS(DBG_LOW, "get_last_position[%d]", last_pos->timestamp);
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _LAST_POSITON_H_
+#define _LAST_POSITON_H_
+
+#include "gps_plugin_data_types.h"
+
+void gps_set_last_position(const pos_data_t * pos);
+
+void gps_set_position(const pos_data_t * pos);
+
+void gps_get_last_position(pos_data_t * last_pos);
+
+#endif /* _LAST_POSITON_H_ */
--- /dev/null
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include
+
+Name: lbs-server-plugin
+Description: lbs-server plugin
+Requires: dlog
+Version: @VERSION@
+Cflags: -I${includedir} -I${includedir}/lbs-server-plugin
--- /dev/null
+[Gps Manager Provider]
+Name=Agps
+Service=org.tizen.lbs.Providers.LbsServer
+Path=/org/tizen/lbs/Providers/LbsServer
+Requires=RequiresLocation
+Provides=ProvidesUpdates
+Accuracy=Detailed
+Interfaces=org.tizen.lbs.Manager;org.tizen.lbs.Position;org.tizen.lbs.Nmea;org.tizen.lbs.Satellite
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib-object.h>
+
+#include <vconf.h>
+#include "setting.h"
+#include <lbs_dbus_server.h>
+#ifdef TIZEN_WEARABLE
+#include <journal/device.h>
+#include <resourced.h>
+#include <app_manager.h>
+#include <dd-display.h>
+#endif
+
+#include "gps_plugin_data_types.h"
+#include "lbs_server.h"
+
+#include "nps_plugin_module.h"
+#include "nps_plugin_intf.h"
+
+#include "server.h"
+#include "last_position.h"
+#include "debug_util.h"
+#include "dump_log.h"
+
+
+#ifdef TIZEN_WEARABLE
+#define VCONFKEY_CONVERT_GPS_IN_BERLIN "file/private/com.samsung.admin-lbs/GPSOffSet"
+#define CONVERT_OFFSET_LATITUDE (15.304286)
+#define CONVERT_OFFSET_LONGITUDE (-113.690148)
+#endif
+
+typedef struct {
+ // gps variables
+ pos_data_t position;
+ batch_data_t batch;
+ sv_data_t satellite;
+ nmea_data_t nmea;
+ gboolean sv_used;
+ gboolean nmea_used;
+
+ gboolean is_gps_running;
+ #ifdef TIZEN_WEARABLE
+ gboolean prev_setting;
+ #endif
+ gint gps_client_count;
+
+ // nps variables
+ NpsManagerHandle handle;
+ unsigned long period;
+ NpsManagerPositionExt pos;
+ NpsManagerLastPositionExt last_pos;
+ Plugin_LocationInfo location;
+
+ gboolean is_nps_running;
+ gint nps_client_count;
+ unsigned char *token;
+
+ // shared variables
+ GMainLoop *loop;
+ GMutex mutex;
+ GCond *cond;
+ LbsStatus status;
+
+// dynamic interval update
+ GHashTable *dynamic_interval_table;
+ guint *optimized_interval_array;
+ guint temp_minimum_interval;
+ gboolean is_needed_changing_interval;
+
+ lbs_server_dbus_h lbs_dbus_server;
+
+ #ifdef TIZEN_WEARABLE
+ // convert gps position(?)
+ gdouble gps_offset_latitude;
+ gdouble gps_offset_longitude;
+ gboolean is_joined_app_performance;
+ #endif
+} lbs_server_s;
+
+typedef struct {
+ lbs_server_s* lbs_server;
+ int method;
+} dynamic_interval_updator_user_data;
+
+static gboolean gps_remove_all_clients(lbs_server_s *lbs_server);
+#ifdef TIZEN_WEARABLE
+static void nps_set_position(lbs_server_s *lbs_server_nps, NpsManagerPositionExt pos);
+
+static void __join_app_performance_logging()
+{
+ LOG_GPS(DBG_LOW, ">");
+ resourced_ret_c resourced_ret = RESOURCED_ERROR_NONE;
+ int ret = 0;
+ char *app_id = NULL;
+ pid_t pid = getpid();
+
+ ret = app_manager_get_app_id(pid, &app_id);
+ if (ret != APP_MANAGER_ERROR_NONE || app_id == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to app_manager_get_app_id. Error[%d]", ret);
+ return;
+ }
+ LOG_GPS(DBG_LOW, "get appid [%s]", app_id);
+
+ resourced_ret = join_app_performance(app_id, pid);
+ if (resourced_ret != RESOURCED_ERROR_NONE) {
+ LOG_GPS(DBG_ERR, "Failed to start logging through join_app_performance. error code [%d]", ret);
+ }
+
+ g_free(app_id);
+ LOG_GPS(DBG_LOW, "<");
+}
+
+static void __check_gps_offset_mode(lbs_server_s *lbs_server)
+{
+ int set_value = -1;
+ setting_get_int(VCONFKEY_CONVERT_GPS_IN_BERLIN, &set_value);
+
+ if (set_value == 1) {
+ LOG_GPS(DBG_LOW, "converted gps position");
+ lbs_server->gps_offset_latitude = CONVERT_OFFSET_LATITUDE;
+ lbs_server->gps_offset_longitude = CONVERT_OFFSET_LONGITUDE;
+ } else {
+ LOG_GPS(DBG_LOW, "original gps position");
+ lbs_server->gps_offset_latitude = 0.0;
+ lbs_server->gps_offset_longitude = 0.0;
+ }
+}
+
+static void __convert_gps_set_cb(keynode_t *key, gpointer user_data)
+{
+ LOG_GPS(DBG_LOW, "__convert_gps_set_cb");
+ lbs_server_s *lbs_server = (lbs_server_s *)user_data;
+
+ __check_gps_offset_mode(lbs_server);
+}
+#endif
+
+static void __setting_gps_cb (keynode_t *key, gpointer user_data)
+{
+ LOG_GPS(DBG_LOW, "__setting_gps_cb");
+ lbs_server_s *lbs_server = (lbs_server_s *)user_data;
+ int onoff = 0;
+ gboolean ret = FALSE;
+
+ setting_get_int(VCONFKEY_LOCATION_ENABLED, &onoff);
+
+ if (onoff == 0) {
+ ret = gps_remove_all_clients(lbs_server);
+ if (ret == FALSE) {
+ LOG_GPS(DBG_LOW, "already removed.");
+ }
+ }
+}
+
+#ifdef TIZEN_WEARABLE
+static void __setting_pw_saving_cb(keynode_t *key, gpointer user_data)
+{
+ LOG_GPS(DBG_LOW, "__setting_pw_saving_cb");
+ lbs_server_s *lbs_server = (lbs_server_s *)user_data;
+ int mode = 0;
+ int onoff = 0;
+
+ setting_get_int(VCONFKEY_SETAPPL_PSMODE, &mode);
+ if (mode == SETTING_PSMODE_WEARABLE_ENHANCED) {
+ setting_get_int(VCONFKEY_LOCATION_ENABLED, &onoff);
+ if (onoff == 1) {
+ lbs_server->prev_setting = onoff;
+ setting_set_int(VCONFKEY_LOCATION_ENABLED, 0);
+ setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &onoff);
+ if (onoff == 0) {
+ setting_set_int(VCONFKEY_LOCATION_USE_MY_LOCATION, 0);
+ }
+ }
+ } else {
+ if (lbs_server->prev_setting == 1) {
+ setting_get_int(VCONFKEY_LOCATION_USE_MY_LOCATION, &onoff);
+ if(onoff == 0) {
+ setting_set_int(VCONFKEY_LOCATION_USE_MY_LOCATION, 1);
+ }
+ setting_set_int(VCONFKEY_LOCATION_ENABLED, 1);
+ lbs_server->prev_setting = 0;
+ }
+ LOG_GPS(DBG_LOW, "Mode [%d]", mode);
+ }
+}
+#endif
+
+static void nps_set_last_position(NpsManagerPositionExt pos)
+{
+ LOG_NPS(DBG_LOW, "nps_set_last_position[%d]", pos.timestamp);
+
+ char location[128] = {0,};
+ snprintf(location, sizeof(location), "%.6lf;%.6lf;%.2lf;%.2lf;%.2lf;%.2lf;", pos.latitude, pos.longitude, pos.altitude, pos.speed, pos.direction, pos.hor_accuracy);
+
+ setting_set_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, pos.timestamp);
+ setting_set_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION, location);
+}
+
+static void nps_set_position(lbs_server_s *lbs_server_nps, NpsManagerPositionExt pos)
+{
+ LOG_NPS(DBG_LOW, "set position timestamp : %d", pos.timestamp);
+ lbs_server_nps->last_pos.timestamp = pos.timestamp;
+ setting_set_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, lbs_server_nps->last_pos.timestamp);
+
+ if ((lbs_server_nps->last_pos.latitude != pos.latitude) || (lbs_server_nps->last_pos.longitude != pos.longitude)) {
+ lbs_server_nps->last_pos.latitude = pos.latitude;
+ lbs_server_nps->last_pos.longitude = pos.longitude;
+ lbs_server_nps->last_pos.altitude = pos.altitude;
+ lbs_server_nps->last_pos.hor_accuracy = pos.hor_accuracy;
+ lbs_server_nps->last_pos.speed = pos.speed;
+ lbs_server_nps->last_pos.direction = pos.direction;
+
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LATITUDE, lbs_server_nps->last_pos.latitude);
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_LONGITUDE, lbs_server_nps->last_pos.longitude);
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_ALTITUDE, lbs_server_nps->last_pos.altitude);
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_SPEED, lbs_server_nps->last_pos.speed);
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_DIRECTION, lbs_server_nps->last_pos.direction);
+ setting_set_double(VCONFKEY_LOCATION_LAST_WPS_HOR_ACCURACY, lbs_server_nps->last_pos.hor_accuracy);
+ }
+
+ int last_timestamp = 0;
+ setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, &last_timestamp);
+
+ LOG_NPS(DBG_LOW, "last_time stamp: %d, pos.timestamp: %d, UPDATE_INTERVAL: %d ", last_timestamp, pos.timestamp, UPDATE_INTERVAL);
+ if ((pos.timestamp - last_timestamp) > UPDATE_INTERVAL) {
+ nps_set_last_position(pos);
+ }
+
+}
+
+static void nps_set_status(lbs_server_s *lbs_server, LbsStatus status)
+{
+ if (!lbs_server) {
+ LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
+ return;
+ }
+ LOG_NPS(DBG_LOW, "nps_set_status[%d]", status);
+ if (lbs_server->status == status) {
+ LOG_NPS(DBG_ERR, "Donot update NPS status");
+ return;
+ }
+
+ lbs_server->status = status;
+
+ if (lbs_server->status == LBS_STATUS_AVAILABLE) {
+ setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_CONNECTED);
+ } else if (lbs_server->status == LBS_STATUS_ACQUIRING) {
+ setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_SEARCHING);
+ } else {
+ setting_set_int(VCONFKEY_LOCATION_WPS_STATE, POSITION_OFF);
+ }
+
+ if (status != LBS_STATUS_AVAILABLE) {
+ lbs_server->pos.fields = LBS_POSITION_FIELDS_NONE;
+ }
+
+ lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_NPS, status);
+}
+
+static void nps_update_position (lbs_server_s *lbs_server_nps, NpsManagerPositionExt pos)
+{
+ if (!lbs_server_nps) {
+ LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
+ return;
+ }
+
+ GVariant *accuracy = NULL;
+
+ LOG_NPS(DBG_LOW, "nps_update_position");
+ lbs_server_nps->pos.fields = pos.fields;
+ lbs_server_nps->pos.timestamp = pos.timestamp;
+ lbs_server_nps->pos.latitude = pos.latitude;
+ lbs_server_nps->pos.longitude = pos.longitude;
+ lbs_server_nps->pos.altitude = pos.altitude;
+ lbs_server_nps->pos.hor_accuracy = pos.hor_accuracy;
+ lbs_server_nps->pos.ver_accuracy = pos.ver_accuracy;
+
+ accuracy = g_variant_ref_sink (g_variant_new("(idd)", lbs_server_nps->pos.acc_level, lbs_server_nps->pos.hor_accuracy, lbs_server_nps->pos.ver_accuracy));
+
+ LOG_NPS(DBG_LOW, "time:%d", lbs_server_nps->pos.timestamp);
+
+ lbs_server_emit_position_changed(lbs_server_nps->lbs_dbus_server, LBS_SERVER_METHOD_NPS,
+ lbs_server_nps->pos.fields, lbs_server_nps->pos.timestamp, lbs_server_nps->pos.latitude,
+ lbs_server_nps->pos.longitude, lbs_server_nps->pos.altitude, lbs_server_nps->pos.speed,
+ lbs_server_nps->pos.direction, 0.0, accuracy);
+
+ g_variant_unref(accuracy);
+}
+
+static gboolean nps_report_callback(gpointer user_data)
+{
+ LOG_NPS(DBG_LOW, "nps_report_callback");
+ double vertical_accuracy = -1.0; /* vertical accuracy's invalid value is -1 */
+ Plugin_LocationInfo location;
+ memset(&location, 0x00, sizeof(Plugin_LocationInfo));
+ lbs_server_s *lbs_server_nps = (lbs_server_s *) user_data;
+ if(NULL == lbs_server_nps ) {
+ LOG_GPS(DBG_ERR, "lbs_server_s is NULL!!");
+ return FALSE;
+ }
+ time_t timestamp;
+
+ g_mutex_lock(&lbs_server_nps->mutex);
+ memcpy(&location, &lbs_server_nps->location, sizeof(Plugin_LocationInfo));
+ g_mutex_unlock(&lbs_server_nps->mutex);
+
+ time(×tamp);
+ if (timestamp == lbs_server_nps->last_pos.timestamp) {
+ return FALSE;
+ }
+
+ nps_set_status(lbs_server_nps, LBS_STATUS_AVAILABLE);
+
+ NpsManagerPositionExt pos;
+ memset(&pos, 0x00, sizeof(NpsManagerPositionExt));
+
+ pos.timestamp = timestamp;
+
+ if (location.latitude) {
+ pos.fields |= LBS_POSITION_EXT_FIELDS_LATITUDE;
+ pos.latitude = location.latitude;
+ }
+
+ if (location.longitude) {
+ pos.fields |= LBS_POSITION_EXT_FIELDS_LONGITUDE;
+ pos.longitude = location.longitude;
+ }
+
+ if (location.altitude) {
+ pos.fields |= LBS_POSITION_EXT_FIELDS_ALTITUDE;
+ pos.altitude = location.altitude;
+ }
+
+ if (location.speed >= 0) {
+ pos.fields |= LBS_POSITION_EXT_FIELDS_SPEED;
+ pos.speed = location.speed;
+ }
+ if (location.bearing >= 0) {
+ pos.fields |= LBS_POSITION_EXT_FIELDS_DIRECTION;
+ pos.direction = location.bearing;
+ }
+
+ pos.acc_level = LBS_ACCURACY_LEVEL_STREET;
+ pos.hor_accuracy = location.hpe;
+ pos.ver_accuracy = vertical_accuracy;
+
+ nps_update_position(lbs_server_nps, pos);
+
+ nps_set_position(lbs_server_nps, pos);
+
+ return FALSE;
+}
+
+static void __nps_callback(void *arg, const Plugin_LocationInfo *location, const void *reserved)
+{
+ LOG_NPS(DBG_LOW, "__nps_callback");
+ lbs_server_s *lbs_server = (lbs_server_s *)arg;
+ if (!lbs_server) {
+ LOG_NPS(DBG_ERR, "lbs_server is NULL!!");
+ return;
+ }
+
+ if (!location) {
+ LOG_NPS(DBG_LOW, "NULL is returned from plugin...");
+ // sometimes plugin returns NULL even if it is connected...
+ //nps_set_status (lbs_server , LBS_STATUS_ACQUIRING);
+ return;
+ }
+
+ g_mutex_lock(&lbs_server->mutex);
+ memcpy(&lbs_server->location, location, sizeof(Plugin_LocationInfo));
+ g_mutex_unlock(&lbs_server->mutex);
+
+ g_main_context_invoke(NULL, nps_report_callback, arg);
+}
+
+static void _nps_token_callback(void *arg, const unsigned char *token, unsigned tokenSize)
+{
+ LOG_NPS(DBG_LOW, "_nps_token_callback");
+ lbs_server_s *lbs_server_nps = (lbs_server_s *)arg;
+ if (NULL == lbs_server_nps) {
+ LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
+ return;
+ }
+
+ if (token == NULL) {
+ LOG_NPS(DBG_ERR, "*** no token to save\n");
+ } else {
+ // save the token in persistent storage
+ g_mutex_lock(&lbs_server_nps->mutex);
+ lbs_server_nps->token = g_new0(unsigned char, tokenSize);
+ if (lbs_server_nps->token) {
+ memcpy(lbs_server_nps->token, token, tokenSize);
+ }
+ g_mutex_unlock(&lbs_server_nps->mutex);
+ }
+ LOG_NPS(DBG_LOW, "_nps_token_callback ended");
+}
+
+static void _network_enabled_cb(keynode_t *key, void *user_data)
+{
+ LOG_GPS(DBG_LOW, "_network_enabled_cb");
+ int enabled = 0;
+
+ setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
+
+ /* This is vestige of nps-server
+ lbs_server_s *lbs_server_nps = (lbs_server_s *)user_data;
+
+ if (enabled == 0) {
+ if (lbs_server_nps->loop != NULL) {
+ g_main_loop_quit(lbs_server_nps->loop);
+ }
+ }
+ */
+}
+static gboolean nps_offline_location(lbs_server_s * lbs_server)
+{
+ LOG_NPS(DBG_LOW, "nps_offline_location");
+ if (NULL == lbs_server) {
+ LOG_GPS(DBG_ERR, "lbs-server is NULL!!");
+ return FALSE;
+ }
+ char key[NPS_UNIQUE_ID_LEN] = { 0, };
+
+ if (setting_get_unique_id(key)) {
+ LOG_NPS(DBG_LOW, "key = %s", key);
+ get_nps_plugin_module()->getOfflineToken((unsigned char *)key, NPS_UNIQUE_ID_LEN,
+ _nps_token_callback, lbs_server);
+ if (lbs_server->token != NULL) {
+ LOG_NPS(DBG_LOW, "Token = %s", lbs_server->token);
+ int ret = get_nps_plugin_module()->offlineLocation((unsigned char *)key,
+ NPS_UNIQUE_ID_LEN, lbs_server->token, 0,
+ __nps_callback, lbs_server);
+ if (ret) {
+ if (lbs_server->is_nps_running) {
+ LOG_NPS(DBG_LOW, "offlineLocation() called nps_callback successfully.");
+ return TRUE;
+ }
+ }
+ } else {
+ LOG_NPS(DBG_ERR, "getOfflineToken(): Token is NULL");
+ }
+ } else {
+ LOG_NPS(DBG_ERR, "lbs_get_unique_id() failed.");
+ }
+ return TRUE;
+}
+
+static void __nps_cancel_callback(void *arg)
+{
+ LOG_NPS(DBG_LOW, "__nps_cancel_callback");
+ lbs_server_s *lbs_server = (lbs_server_s *) arg;
+ if (!lbs_server) {
+ LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
+ return;
+ }
+
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->is_nps_running = FALSE;
+ g_cond_signal(lbs_server->cond);
+ g_mutex_unlock(&lbs_server->mutex);
+}
+
+static void start_batch_tracking(lbs_server_s * lbs_server, int batch_interval, int batch_period)
+{
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count++;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if(lbs_server->is_gps_running == TRUE){
+ LOG_GPS(DBG_LOW, "Batch: gps is already running");
+ return;
+ }
+ LOG_GPS(DBG_LOW, "Batch: start_tracking GPS");
+ lbs_server->status = LBS_STATUS_ACQUIRING;
+
+ if (request_start_batch_session(batch_interval, batch_period) == TRUE) {
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->is_gps_running = TRUE;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ lbs_server->is_needed_changing_interval = FALSE;
+
+ // ADD notify
+ setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
+ } else {
+ LOG_GPS(DBG_ERR, "Batch: Fail to request_start_batch_session");
+ }
+}
+
+static void stop_batch_tracking(lbs_server_s * lbs_server)
+{
+ LOG_GPS(DBG_LOW, "Batch: stop_tracking GPS");
+
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count--;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if (lbs_server->is_gps_running == FALSE) {
+ LOG_GPS(DBG_LOW, "Batch: gps- is already stopped");
+ return;
+ }
+
+ if (lbs_server->gps_client_count <= 0){
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count = 0;
+
+ if (request_stop_batch_session() == TRUE) {
+ lbs_server->is_gps_running = FALSE;
+ lbs_server->sv_used = FALSE;
+ // remove notify
+ setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
+ g_mutex_unlock(&lbs_server->mutex);
+ }
+ }
+
+ lbs_server->status = LBS_STATUS_UNAVAILABLE;
+ lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_UNAVAILABLE);
+}
+
+static void start_tracking(lbs_server_s * lbs_server, lbs_server_method_e method)
+{
+ switch(method){
+ case LBS_SERVER_METHOD_GPS:
+
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count++;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if(lbs_server->is_gps_running == TRUE){
+ LOG_GPS(DBG_LOW, "gps is already running");
+ return;
+ }
+ LOG_GPS(DBG_LOW, "start_tracking GPS");
+ lbs_server->status = LBS_STATUS_ACQUIRING;
+
+ #ifdef TIZEN_WEARABLE
+ if (lbs_server->is_joined_app_performance == FALSE) {
+ __join_app_performance_logging();
+ lbs_server->is_joined_app_performance = TRUE;
+ }
+ #endif
+
+ if (request_start_session((int)(lbs_server->optimized_interval_array[method])) == TRUE) {
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->is_gps_running = TRUE;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ lbs_server->is_needed_changing_interval = FALSE;
+
+ // ADD notify
+ setting_notify_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb, lbs_server);
+ } else {
+ LOG_GPS(DBG_ERR, "Fail to request_start_session");
+ }
+
+ break;
+
+ case LBS_SERVER_METHOD_NPS:
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->nps_client_count++;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if(lbs_server->is_nps_running == TRUE){
+ LOG_NPS(DBG_LOW, "nps is already running");
+ return;
+ }
+
+ LOG_NPS(DBG_LOW, "start_tracking - LBS_SERVER_METHOD_NPS");
+ nps_set_status(lbs_server, LBS_STATUS_ACQUIRING);
+
+ void *handle_str = NULL;
+ int ret = get_nps_plugin_module()->start(lbs_server->period, __nps_callback, lbs_server, &(handle_str));
+ LOG_NPS(DBG_LOW, "after get_nps_plugin_module()->location");
+
+ if (ret) {
+ lbs_server->handle = handle_str;
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->is_nps_running = TRUE;
+ g_mutex_unlock(&lbs_server->mutex);
+ vconf_ignore_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb);
+ return;
+ }
+
+ if (nps_is_dummy_plugin_module() != TRUE) {
+ nps_offline_location(lbs_server);
+ }
+
+ LOG_NPS(DBG_ERR, "FAILS WPS START");
+ nps_set_status(lbs_server, LBS_STATUS_ERROR);
+ break;
+
+ default:
+ LOG_GPS(DBG_LOW, "start_tracking Invalid");
+ }
+
+}
+
+static gboolean nps_stop(lbs_server_s * lbs_server_nps)
+{
+ LOG_NPS(DBG_LOW, "nps_stop");
+ if (!lbs_server_nps) {
+ LOG_NPS(DBG_ERR, "lbs-server is NULL!!");
+ return FALSE;
+ }
+
+ int ret = get_nps_plugin_module()->stop(lbs_server_nps->handle, __nps_cancel_callback, lbs_server_nps);
+ if (ret) {
+ g_mutex_lock(&lbs_server_nps->mutex);
+ while (lbs_server_nps->is_nps_running) {
+ g_cond_wait(lbs_server_nps->cond, &lbs_server_nps->mutex);
+ }
+ lbs_server_nps->is_nps_running = FALSE;
+ g_mutex_unlock(&lbs_server_nps->mutex);
+ }
+ /* This is vestige of nps-server
+ else {
+ if (lbs_server_nps->loop != NULL) {
+ LOG_NPS(DBG_ERR, "module->stop() is failed. nps is cloesed.");
+ g_main_loop_quit(lbs_server_nps->loop);
+ return FALSE;
+ }
+ }
+ */
+
+ nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
+
+ return TRUE;
+}
+
+static void stop_tracking(lbs_server_s * lbs_server, lbs_server_method_e method)
+{
+ switch(method){
+ case LBS_SERVER_METHOD_GPS:
+ LOG_GPS(DBG_LOW, "stop_tracking GPS");
+
+ gps_set_last_position(&lbs_server->position);
+
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count--;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if (lbs_server->is_gps_running == FALSE) {
+ LOG_GPS(DBG_LOW, "gps- is already stopped");
+ return;
+ }
+
+ if (lbs_server->gps_client_count <= 0){
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->gps_client_count = 0;
+
+ if (request_stop_session() == TRUE) {
+ lbs_server->is_gps_running = FALSE;
+ lbs_server->sv_used = FALSE;
+ // remove notify
+ setting_ignore_key_changed(VCONFKEY_LOCATION_ENABLED, __setting_gps_cb);
+ g_mutex_unlock(&lbs_server->mutex);
+ }
+ }
+
+ lbs_server->status = LBS_STATUS_UNAVAILABLE;
+ lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS,
+ LBS_STATUS_UNAVAILABLE);
+
+ break;
+ case LBS_SERVER_METHOD_NPS:
+ LOG_NPS(DBG_LOW, "stop_tracking NPS");
+
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->nps_client_count--;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ if(lbs_server->is_nps_running == FALSE){
+ LOG_NPS(DBG_LOW, "nps- is already stopped");
+ return;
+ }
+
+ if (lbs_server->nps_client_count <= 0){
+ g_mutex_lock(&lbs_server->mutex);
+ lbs_server->nps_client_count = 0;
+ g_mutex_unlock(&lbs_server->mutex);
+
+ LOG_NPS(DBG_LOW, "lbs_server_nps Normal stop");
+ nps_stop(lbs_server);
+ }
+
+ break;
+ default:
+ LOG_GPS(DBG_LOW, "stop_tracking Invalid");
+ }
+}
+
+static void update_dynamic_interval_table_foreach_cb(gpointer key, gpointer value, gpointer userdata)
+{
+ guint *interval_array = (guint *)value;
+ dynamic_interval_updator_user_data *updator_ud = (dynamic_interval_updator_user_data *)userdata;
+ lbs_server_s *lbs_server = updator_ud->lbs_server;
+ int method = updator_ud->method;
+
+ LOG_GPS(DBG_LOW, "foreach dynamic-interval. method:[%d], key:[%s]-interval:[%u], current optimized interval [%u]", method, (char *)key, interval_array[method], lbs_server->optimized_interval_array[method]);
+ if ((lbs_server->temp_minimum_interval > interval_array[method])) {
+ lbs_server->temp_minimum_interval = interval_array[method];
+ }
+}
+
+static gboolean update_pos_tracking_interval(lbs_server_interval_manipulation_type type, const gchar *client, int method, guint interval, gpointer userdata)
+{
+ LOG_GPS(DBG_INFO, "update_pos_tracking_interval");
+ if (userdata == NULL) return FALSE;
+ if (client == NULL) {
+ LOG_GPS(DBG_ERR, "client is NULL");
+ return FALSE;
+ }
+
+ if (method < LBS_SERVER_METHOD_GPS || method >= LBS_SERVER_METHOD_SIZE) {
+ LOG_GPS(DBG_ERR, "unavailable method [%d]", method);
+ return FALSE;
+ }
+
+ gboolean ret_val = FALSE;
+ lbs_server_s *lbs_server = (lbs_server_s *)userdata;
+
+ /* manipulate logic for dynamic-interval hash table */
+ switch (type) {
+ case LBS_SERVER_INTERVAL_ADD: {
+ LOG_GPS(DBG_LOW, "ADD, client[%s], method[%d], interval[%u]", client, method, interval);
+ gchar *client_cpy = NULL;
+ client_cpy = g_strdup(client);
+
+ guint* interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client_cpy);
+ if (!interval_array) {
+ LOG_GPS(DBG_LOW, "first add key[%s] to interval-table", client);
+ interval_array = (guint *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(guint));
+ g_hash_table_insert(lbs_server->dynamic_interval_table, (gpointer)client_cpy, (gpointer)interval_array);
+ }
+ interval_array[method] = interval;
+ lbs_server->temp_minimum_interval = interval;
+ LOG_GPS(DBG_LOW, "ADD done");
+ break;
+ }
+
+ case LBS_SERVER_INTERVAL_REMOVE: {
+ LOG_GPS(DBG_LOW, "REMOVE, client[%s], method[%d]", client, method);
+ lbs_server->temp_minimum_interval = 120; // interval max value
+ guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
+ if(!interval_array) {
+ LOG_GPS(DBG_INFO, "Client[%s] Method[%d] is already removed from interval-table", client, method);
+ break;
+ }
+ LOG_GPS(DBG_LOW, "Found interval_array[%d](%p):[%u] from interval-table", method, interval_array, interval_array[method]);
+ interval_array[method] = 0;
+
+ int i = 0;
+ guint interval_each = 0;
+ gboolean is_need_remove_client_from_table = TRUE;
+ for(i = 0; i < LBS_SERVER_METHOD_SIZE; i++){
+ interval_each = interval_array[i];
+ if(interval_each != 0){
+ LOG_GPS(DBG_LOW, "[%s] method[%d]'s interval is not zero - interval: %d. It will not be removed.", client, i, interval_each);
+ is_need_remove_client_from_table = FALSE;
+ break;
+ }
+ }
+
+ if (is_need_remove_client_from_table) {
+ LOG_GPS(DBG_LOW, "is_need_remove_client_from_table is TRUE");
+ if (!g_hash_table_remove(lbs_server->dynamic_interval_table, client)) {
+ LOG_GPS(DBG_ERR, "g_hash_table_remove is failed.");
+ }
+ LOG_GPS(DBG_LOW, "REMOVE done.");
+ }
+ break;
+ }
+
+ case LBS_SERVER_INTERVAL_UPDATE:{
+ LOG_GPS(DBG_LOW, "UPDATE client[%s], method[%d], interval[%u]", client, method, interval);
+ guint *interval_array = (guint *) g_hash_table_lookup(lbs_server->dynamic_interval_table, client);
+ if(!interval_array){
+ LOG_GPS(DBG_LOW, "Client[%s] is not exist in interval-table", client, method);
+ break;
+ }
+ interval_array[method] = interval;
+ lbs_server->temp_minimum_interval = interval;
+ LOG_GPS(DBG_LOW, "UPDATE done.");
+ break;
+ }
+
+ default: {
+ LOG_GPS(DBG_ERR, "unhandled interval-update type");
+ return FALSE;
+ }
+ }
+
+ /* update logic for optimized-interval value */
+ if (g_hash_table_size(lbs_server->dynamic_interval_table) == 0) {
+ LOG_GPS(DBG_LOW, "dynamic_interval_table size is zero. It will be updated all value as 0");
+ int i = 0;
+ for (i = 0; i < LBS_SERVER_METHOD_SIZE; i++) {
+ lbs_server->optimized_interval_array[i] = 0;
+ }
+ ret_val = FALSE;
+ } else {
+ LOG_GPS(DBG_LOW, "dynamic_interval_table size is not zero.");
+
+ dynamic_interval_updator_user_data updator_user_data; // temporary struct
+ updator_user_data.lbs_server = lbs_server;
+ updator_user_data.method = method;
+
+ g_hash_table_foreach (lbs_server->dynamic_interval_table, (GHFunc)update_dynamic_interval_table_foreach_cb, (gpointer)&updator_user_data);
+
+ if (lbs_server->optimized_interval_array[method] != lbs_server->temp_minimum_interval) {
+ LOG_GPS(DBG_INFO, "Changing optimized_interval value [%u -> %u] for method [%d]",
+ lbs_server->optimized_interval_array[method], lbs_server->temp_minimum_interval, method);
+ lbs_server->optimized_interval_array[method] = lbs_server->temp_minimum_interval;
+
+ /* need to send message to provider device */
+ lbs_server->is_needed_changing_interval = TRUE;
+ }
+
+ if (lbs_server->is_needed_changing_interval) {
+ ret_val = TRUE;
+ } else {
+ ret_val = FALSE;
+ }
+ }
+ LOG_GPS(DBG_LOW, "update_pos_tracking_interval done.");
+ return ret_val;
+}
+
+static void request_change_pos_update_interval(int method, gpointer userdata)
+{
+ LOG_GPS(DBG_LOW, "request_change_pos_update_interval");
+ if (!userdata) return;
+
+ lbs_server_s *lbs_server = (lbs_server_s *)userdata;
+ switch (method) {
+ case LBS_SERVER_METHOD_GPS:
+ request_change_pos_update_interval_standalone_gps(lbs_server->optimized_interval_array[method]);
+ break;
+ #ifdef TIZEN_WEARABLE
+ case LBS_SERVER_METHOD_COMPANION_GPS:
+ request_change_pos_update_interval_consumer_gps(lbs_server->optimized_interval_array[method]);
+ break;
+ case LBS_SERVER_METHOD_COMPANION_WPS:
+ request_change_pos_update_interval_consumer_wps(lbs_server->optimized_interval_array[method]);
+ break;
+ #endif
+ default:
+ break;
+ }
+}
+
+static void set_options(GVariant *options, const gchar *client, gpointer userdata)
+{
+ LOG_GPS(DBG_LOW, "set_options callback");
+
+ lbs_server_s *lbs_server = (lbs_server_s *)userdata;
+
+ GVariantIter iter;
+ gchar *key = NULL;
+ GVariant *value = NULL;
+ gboolean ret = FALSE;
+#ifdef _TIZEN_PUBLIC_
+ char *msg_header = NULL;
+ char *msg_body = NULL;
+ int size = 0;
+#endif
+ gsize length = 0;
+ char *option = NULL;
+ char *app_id = NULL;
+ guint interval = 0;
+
+ lbs_server_method_e method = 0;
+
+ g_variant_iter_init(&iter, options);
+ ret = g_variant_iter_next(&iter, "{&sv}", &key, &value);
+ if (ret == FALSE) {
+ LOG_GPS(DBG_ERR, "Invalid GVariant");
+ return;
+ }
+ if (!g_strcmp0(key, "CMD")) {
+ LOG_GPS(DBG_LOW, "set_options[%s]", g_variant_get_string(value, &length));
+ if (!g_strcmp0(g_variant_get_string(value, &length), "START")) {
+
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+ if(!g_strcmp0(key, "METHOD")){
+ method = g_variant_get_int32(value);
+ LOG_GPS(DBG_LOW, "METHOD [%d]", method);
+ }
+
+ if (!g_strcmp0(key, "INTERVAL")) {
+ interval = g_variant_get_uint32 (value);
+ LOG_GPS(DBG_LOW, "INTERVAL [%u]", interval);
+ }
+
+ if (!g_strcmp0(key, "APP_ID")) {
+ app_id = g_variant_dup_string(value, &length);
+ LOG_GPS(DBG_LOW, "APP_ID [%s]", app_id);
+ }
+ }
+
+ if (client) {
+ update_pos_tracking_interval (LBS_SERVER_INTERVAL_ADD, client, method, interval, lbs_server);
+ }
+
+ if (app_id) {
+ if (LBS_SERVER_METHOD_GPS == method) {
+ gps_dump_log("START GPS", app_id);
+ }
+ free(app_id);
+ }
+
+ start_tracking(lbs_server, method);
+
+ if (lbs_server->is_needed_changing_interval) {
+ lbs_server->is_needed_changing_interval = FALSE;
+ request_change_pos_update_interval(method, (gpointer)lbs_server);
+ }
+ }
+ else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP")) {
+
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+ if(!g_strcmp0(key, "METHOD")){
+ method = g_variant_get_int32(value);
+ LOG_GPS(DBG_LOW, "METHOD [%d]", method);
+ }
+
+ if (!g_strcmp0(key, "APP_ID")) {
+ app_id = g_variant_dup_string(value, &length);
+ LOG_GPS(DBG_LOW, "APP_ID [%s]", app_id);
+ }
+ }
+
+ if (client) {
+ update_pos_tracking_interval (LBS_SERVER_INTERVAL_REMOVE, client, method, interval, lbs_server);
+ }
+
+ if (app_id) {
+ if (LBS_SERVER_METHOD_GPS == method) {
+ gps_dump_log("STOP GPS", app_id);
+ #ifdef TIZEN_WEARABLE
+ journal_gps_stop(app_id);
+ #endif
+ }
+ free(app_id);
+ }
+
+ stop_tracking(lbs_server, method);
+
+ if (lbs_server->is_needed_changing_interval) {
+ lbs_server->is_needed_changing_interval = FALSE;
+ request_change_pos_update_interval(method, (gpointer)lbs_server);
+ }
+ }
+ else if (!g_strcmp0(g_variant_get_string(value, &length), "START_BATCH")) {
+
+ int batch_interval = 0;
+ int batch_period = 0;
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+
+ if(!g_strcmp0(key, "BATCH_INTERVAL")){
+ batch_interval = g_variant_get_int32(value);
+ LOG_GPS(DBG_LOW, "BATCH_INTERVAL [%d]", batch_interval);
+ } else if(!g_strcmp0(key, "BATCH_PERIOD")){
+ batch_period = g_variant_get_int32(value);
+ LOG_GPS(DBG_LOW, "BATCH_PERIOD [%d]", batch_period);
+ }
+ }
+
+ if (client) {
+ update_pos_tracking_interval (LBS_SERVER_INTERVAL_ADD, client, method, batch_interval, lbs_server);
+ }
+
+ start_batch_tracking(lbs_server, batch_interval, batch_period);
+
+ if (lbs_server->is_needed_changing_interval) {
+ lbs_server->is_needed_changing_interval = FALSE;
+ request_change_pos_update_interval(method, (gpointer)lbs_server);
+ }
+
+ }
+ else if (!g_strcmp0(g_variant_get_string(value, &length), "STOP_BATCH")) {
+
+ if (client) {
+ update_pos_tracking_interval (LBS_SERVER_INTERVAL_REMOVE, client, method, interval, lbs_server);
+ }
+
+ stop_batch_tracking(lbs_server);
+
+ if (lbs_server->is_needed_changing_interval) {
+ lbs_server->is_needed_changing_interval = FALSE;
+ request_change_pos_update_interval(method, (gpointer)lbs_server);
+ }
+ }
+#ifdef _TIZEN_PUBLIC_
+ } else if (!g_strcmp0(g_variant_get_string(value, &length), "SUPLNI")) {
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+ if (!g_strcmp0(key, "HEADER")) {
+ msg_header = g_variant_dup_string(value, &length);
+ } else if (!g_strcmp0(key, "BODY")) {
+ size = (int) g_variant_get_size(value);
+ msg_body = (char *) g_malloc0(sizeof(char) * size);
+ memcpy(msg_body, g_variant_get_data(value), size);
+ } else if (!g_strcmp0(key, "SIZE")) {
+ size = (int) g_variant_get_int32(value);
+ }
+ }
+ request_supl_ni_session(msg_header, msg_body, size);
+ if (msg_header) g_free(msg_header);
+ if (msg_body) g_free(msg_body);
+ }
+#endif
+ else if (!g_strcmp0(g_variant_get_string(value, &length), "SET:OPT")) {
+ LOG_GPS(DBG_LOW, "SET:OPT is called");
+ gboolean is_update_interval = FALSE, is_update_interval_method = FALSE;
+
+ while (g_variant_iter_next(&iter, "{&sv}", &key, &value)) {
+
+ if (!g_strcmp0(key, "OPTION")) {
+ option = g_variant_dup_string(value, &length);
+ LOG_GPS(DBG_ERR, "option [%s]", option);
+
+ if (!g_strcmp0(option, "DELGPS")) {
+ if (request_delete_gps_data() != TRUE) {
+ LOG_GPS(DBG_ERR, "Fail to request_delete_gps_data");
+ }
+ }
+ else if (!g_strcmp0(option, "USE_SV")) {
+ g_mutex_lock(&lbs_server->mutex);
+ if (lbs_server->sv_used == FALSE)
+ lbs_server->sv_used = TRUE;
+ g_mutex_unlock(&lbs_server->mutex);
+ }
+ g_free(option);
+ }
+
+ if(!g_strcmp0(key, "METHOD")){
+ method = g_variant_get_int32(value);
+ LOG_GPS(DBG_LOW, "METHOD [%d]", method);
+ is_update_interval_method = TRUE;
+ }
+
+ if (!g_strcmp0(key, "INTERVAL_UPDATE")) {
+ interval = g_variant_get_uint32 (value);
+ LOG_GPS(DBG_LOW, "INTERVAL_UPDATE [%u]", interval);
+ is_update_interval = TRUE;
+ }
+ }
+
+ if (is_update_interval && is_update_interval_method && client) {
+ update_pos_tracking_interval (LBS_SERVER_INTERVAL_UPDATE, client, method, interval, lbs_server);
+ if (lbs_server->is_needed_changing_interval) {
+ lbs_server->is_needed_changing_interval = FALSE;
+ request_change_pos_update_interval(method, (gpointer)lbs_server);
+ }
+ }
+ }
+ }
+}
+
+static gboolean gps_remove_all_clients(lbs_server_s *lbs_server)
+{
+ LOG_GPS(DBG_LOW, "remove_all_clients GPS");
+ if (lbs_server->gps_client_count <= 0) {
+ lbs_server->gps_client_count = 0;
+ return FALSE;
+ }
+
+ lbs_server->gps_client_count = 0;
+ stop_tracking(lbs_server, LBS_SERVER_METHOD_GPS);
+
+ return TRUE;
+}
+
+static void shutdown(gpointer userdata, gboolean* shutdown_arr)
+{
+ LOG_GPS(DBG_LOW, "shutdown callback gps:%d nps:%d", shutdown_arr[LBS_SERVER_METHOD_GPS], shutdown_arr[LBS_SERVER_METHOD_NPS]);
+ lbs_server_s *lbs_server = (lbs_server_s *)userdata;
+
+ if(shutdown_arr[LBS_SERVER_METHOD_GPS]){
+ LOG_GPS(DBG_LOW, "-> shutdown GPS");
+ if (lbs_server->is_gps_running) {
+ if (gps_remove_all_clients(lbs_server)) {
+ LOG_GPS(DBG_ERR, "<<<< Abnormal shutdown >>>>");
+ }
+ }
+ }
+
+ if(shutdown_arr[LBS_SERVER_METHOD_NPS]){
+ LOG_NPS(DBG_LOW, "-> shutdown NPS");
+ if (lbs_server->is_nps_running) {
+ LOG_NPS(DBG_ERR, "lbs_server_nps is running. nps_stop");
+ nps_stop(lbs_server);
+ }
+ }
+
+ /*
+ int enabled = 0;
+ setting_get_int(VCONFKEY_LOCATION_NETWORK_ENABLED, &enabled);
+ if (enabled == 0) {
+ if (lbs_server->loop != NULL) {
+ g_main_loop_quit(lbs_server->loop);
+ }
+ } else {
+ if (vconf_notify_key_changed(VCONFKEY_LOCATION_NETWORK_ENABLED, _network_enabled_cb, lbs_server)) {
+ LOG_NPS(DBG_ERR, "fail to notify VCONFKEY_LOCATION_NETWORK_ENABLED");
+ }
+ }
+ */
+}
+
+static void gps_update_position_cb(pos_data_t *pos, gps_error_t error, void *user_data)
+{
+ LOG_GPS(DBG_LOW, "gps_update_position_cb");
+
+ GVariant *accuracy = NULL;
+ LbsPositionExtFields fields;
+
+ lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
+
+ memcpy(&lbs_server->position, pos, sizeof(pos_data_t));
+
+ if (lbs_server->status != LBS_STATUS_AVAILABLE) {
+ lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
+ lbs_server->status = LBS_STATUS_AVAILABLE;
+ }
+
+ fields = (LBS_POSITION_EXT_FIELDS_LATITUDE | LBS_POSITION_EXT_FIELDS_LONGITUDE | LBS_POSITION_EXT_FIELDS_ALTITUDE |
+ LBS_POSITION_EXT_FIELDS_SPEED | LBS_POSITION_EXT_FIELDS_DIRECTION);
+
+ accuracy = g_variant_new("(idd)", LBS_ACCURACY_LEVEL_DETAILED, pos->hor_accuracy, pos->ver_accuracy);
+ if (NULL == accuracy) {
+ LOG_GPS(DBG_LOW, "accuracy is NULL");
+ }
+
+ #ifdef TIZEN_WEARABLE
+ lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS,
+ fields, pos->timestamp, (pos->latitude + lbs_server->gps_offset_latitude), (pos->longitude + lbs_server->gps_offset_longitude), pos->altitude,
+ pos->speed, pos->bearing, 0.0, accuracy);
+ #else
+ lbs_server_emit_position_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS,
+ fields, pos->timestamp, pos->latitude, pos->longitude, pos->altitude,
+ pos->speed, pos->bearing, 0.0, accuracy);
+ #endif
+}
+
+static void gps_update_batch_cb(batch_data_t * batch, void *user_data)
+{
+ LOG_GPS(DBG_LOW, "gps_update_batch_cb");
+ lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
+ memcpy(&lbs_server->batch, batch, sizeof(batch_data_t));
+
+ if (lbs_server->status != LBS_STATUS_AVAILABLE) {
+ lbs_server_emit_status_changed(lbs_server->lbs_dbus_server, LBS_SERVER_METHOD_GPS, LBS_STATUS_AVAILABLE);
+ lbs_server->status = LBS_STATUS_AVAILABLE;
+ }
+
+ lbs_server_emit_batch_changed(lbs_server->lbs_dbus_server, batch->num_of_location);
+}
+
+static void gps_update_satellite_cb(sv_data_t * sv, void *user_data)
+{
+ lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
+ if (lbs_server->sv_used == FALSE) {
+ LOG_GPS(DBG_LOW, "sv_used is FALSE");
+ return;
+ }
+
+ LOG_GPS(DBG_LOW, "gps_update_satellite_cb");
+ int index;
+ int timestamp = 0;
+ int satellite_used = 0;
+ GVariant *used_prn = NULL;
+ GVariantBuilder *used_prn_builder = NULL;
+ GVariant *satellite_info = NULL;
+ GVariantBuilder *satellite_info_builder = NULL;
+
+ memcpy(&lbs_server->satellite, sv, sizeof(sv_data_t));
+ timestamp = sv->timestamp;
+
+ used_prn_builder = g_variant_builder_new(G_VARIANT_TYPE ("ai"));
+ for (index = 0; index < sv->num_of_sat; ++index) {
+ if (sv->sat[index].used) {
+ g_variant_builder_add(used_prn_builder, "i", sv->sat[index].prn);
+ ++satellite_used;
+ }
+ }
+ used_prn = g_variant_builder_end(used_prn_builder);
+
+ satellite_info_builder = g_variant_builder_new(G_VARIANT_TYPE ("a(iiii)"));
+ for (index = 0; index < sv->num_of_sat; ++index) {
+ g_variant_builder_add(satellite_info_builder, "(iiii)", sv->sat[index].prn,
+ sv->sat[index].elevation, sv->sat[index].azimuth, sv->sat[index].snr);
+ }
+ satellite_info = g_variant_builder_end(satellite_info_builder);
+
+ lbs_server_emit_satellite_changed(lbs_server->lbs_dbus_server, timestamp, satellite_used, sv->num_of_sat,
+ used_prn, satellite_info);
+}
+
+static void gps_update_nmea_cb(nmea_data_t * nmea, void *user_data)
+{
+ lbs_server_s *lbs_server = (lbs_server_s *)(user_data);
+ if (lbs_server->nmea_used == FALSE) {
+ //LOG_GPS(DBG_LOW, "nmea_used is FALSE");
+ return;
+ }
+
+ LOG_GPS(DBG_LOW, "gps_update_nmea_cb");
+ int timestamp = 0;
+
+ if (lbs_server->nmea.data) {
+ g_free(lbs_server->nmea.data);
+ lbs_server->nmea.len = 0;
+ lbs_server->nmea.data = NULL;
+ }
+ lbs_server->nmea.data = g_malloc(nmea->len + 1);
+ g_memmove(lbs_server->nmea.data, nmea->data, nmea->len);
+ lbs_server->nmea.data[nmea->len] = '\0';
+ lbs_server->nmea.len = nmea->len;
+
+ timestamp = lbs_server->position.timestamp;
+
+ lbs_server_emit_nmea_changed(lbs_server->lbs_dbus_server, timestamp, lbs_server->nmea.data);
+}
+
+int gps_update_geofence_transition(int geofence_id, geofence_zone_state_t transition, double latitude, double longitude, double altitude, double speed, double bearing, double hor_accuracy, void *data)
+{
+ lbs_server_s *lbs_server = (lbs_server_s *)data;
+ lbs_server_emit_gps_geofence_changed(lbs_server->lbs_dbus_server, geofence_id, transition, latitude, longitude, altitude, speed, bearing, hor_accuracy);
+ return 0;
+}
+
+int gps_update_geofence_service_status(int status, void *data)
+{
+ lbs_server_s *lbs_server = (lbs_server_s *)data;
+ lbs_server_emit_gps_geofence_status_changed(lbs_server->lbs_dbus_server, status);
+ return 0;
+}
+
+static void add_fence(gint fence_id, gdouble latitude, gdouble longitude, gint radius, gint last_state, gint monitor_states, gint notification_responsiveness, gint unknown_timer, gpointer userdata)
+{
+ request_add_geofence(fence_id, latitude, longitude, radius, last_state, monitor_states, notification_responsiveness, unknown_timer);
+}
+
+static void remove_fence(gint fence_id, gpointer userdata)
+{
+ request_delete_geofence(fence_id);
+}
+
+static void pause_fence(gint fence_id, gpointer userdata)
+{
+ request_pause_geofence(fence_id);
+}
+
+static void resume_fence(gint fence_id, gint monitor_states, gpointer userdata)
+{
+ request_resume_geofence(fence_id, monitor_states);
+}
+
+static void nps_init(lbs_server_s *lbs_server_nps);
+
+static void lbs_server_init(lbs_server_s * lbs_server)
+{
+ LOG_GPS(DBG_LOW, "lbs_server_init");
+
+ lbs_server->status = LBS_STATUS_UNAVAILABLE;
+ g_mutex_init(&lbs_server->mutex);
+
+ memset(&lbs_server->position, 0x00, sizeof(pos_data_t));
+ memset(&lbs_server->satellite, 0x00, sizeof(sv_data_t));
+ memset(&lbs_server->nmea, 0x00, sizeof(nmea_data_t));
+
+ lbs_server->is_gps_running = FALSE;
+ lbs_server->sv_used = FALSE;
+ lbs_server->nmea_used = FALSE;
+ lbs_server->gps_client_count = 0;
+ #ifdef TIZEN_WEARABLE
+ lbs_server->prev_setting = 0;
+ #endif
+
+ nps_init(lbs_server);
+
+ /* create resource for dynamic-interval */
+ lbs_server->dynamic_interval_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+ lbs_server->optimized_interval_array = (guint *)g_malloc0(LBS_SERVER_METHOD_SIZE * sizeof(guint));
+ lbs_server->is_needed_changing_interval = FALSE;
+}
+
+static void nps_get_last_position(lbs_server_s *lbs_server_nps)
+{
+ int timestamp;
+ char location[128] = {0,};
+ char *last_location[MAX_NPS_LOC_ITEM] = {0,};
+ char *last = NULL;
+ char *str = NULL;
+ int index = 0;
+
+ setting_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, ×tamp);
+ str = setting_get_string(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION);
+ if (str == NULL) {
+ return;
+ }
+ snprintf(location, sizeof(location), "%s", str);
+ free(str);
+
+ last_location[index] = (char *)strtok_r(location, ";", &last);
+ while (last_location[index++] != NULL) {
+ if (index == MAX_NPS_LOC_ITEM)
+ break;
+ last_location[index] = (char *)strtok_r(NULL, ";", &last);
+ }
+ index = 0;
+
+ lbs_server_nps->last_pos.timestamp = timestamp;
+ lbs_server_nps->last_pos.latitude = strtod(last_location[index++], NULL);
+ lbs_server_nps->last_pos.longitude = strtod(last_location[index++], NULL);
+ lbs_server_nps->last_pos.altitude = strtod(last_location[index++], NULL);
+ lbs_server_nps->last_pos.speed = strtod(last_location[index++], NULL);
+ lbs_server_nps->last_pos.direction= strtod(last_location[index++], NULL);
+ lbs_server_nps->last_pos.hor_accuracy = strtod(last_location[index], NULL);
+
+ LOG_NPS(DBG_LOW, "get nps_last_position timestamp : %d", lbs_server_nps->last_pos.timestamp);
+}
+
+static void nps_init(lbs_server_s *lbs_server_nps)
+{
+ LOG_NPS(DBG_LOW, "nps_init");
+
+ lbs_server_nps->handle = NULL;
+ lbs_server_nps->period = 5000;
+ nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
+
+ lbs_server_nps->pos.fields = LBS_POSITION_EXT_FIELDS_NONE;
+ lbs_server_nps->pos.timestamp = 0;
+ lbs_server_nps->pos.latitude = 0.0;
+ lbs_server_nps->pos.longitude = 0.0;
+ lbs_server_nps->pos.altitude = 0.0;
+ lbs_server_nps->pos.acc_level = LBS_POSITION_EXT_FIELDS_NONE;
+ lbs_server_nps->pos.hor_accuracy = -1.0;
+ lbs_server_nps->pos.ver_accuracy = -1.0;
+
+ lbs_server_nps->last_pos.timestamp = 0;
+ lbs_server_nps->last_pos.latitude = 0.0;
+ lbs_server_nps->last_pos.longitude = 0.0;
+ lbs_server_nps->last_pos.altitude = 0.0;
+ lbs_server_nps->last_pos.hor_accuracy = 0.0;
+ lbs_server_nps->last_pos.speed = 0.0;
+ lbs_server_nps->last_pos.direction = 0.0;
+
+ GMutex *mutex_temp = g_mutex_new();
+ lbs_server_nps->mutex = *mutex_temp;
+ lbs_server_nps->cond = g_cond_new();
+ lbs_server_nps->is_nps_running = FALSE;
+ lbs_server_nps->nps_client_count = 0;
+
+ if(!get_nps_plugin_module()->load()) {
+ LOG_NPS(DBG_ERR, "lbs_server_nps plugin load() failed.");
+ return ;
+ }
+
+ nps_get_last_position(lbs_server_nps);
+}
+
+static void nps_deinit(lbs_server_s *lbs_server_nps)
+{
+ LOG_NPS(DBG_LOW, "nps_deinit");
+ if (get_nps_plugin_module()->unload()) {
+ if (lbs_server_nps->is_nps_running) {
+ g_mutex_lock(&lbs_server_nps->mutex);
+ lbs_server_nps->is_nps_running = FALSE;
+ g_cond_signal(lbs_server_nps->cond);
+ g_mutex_unlock(&lbs_server_nps->mutex);
+ }
+
+ if (lbs_server_nps->token) {
+ g_mutex_lock(&lbs_server_nps->mutex);
+ g_free(lbs_server_nps->token);
+ g_mutex_unlock(&lbs_server_nps->mutex);
+ }
+ } else {
+ LOG_NPS(DBG_ERR, "unload() failed.");
+ }
+
+ lbs_server_nps->handle = NULL;
+ lbs_server_nps->is_nps_running = FALSE;
+ lbs_server_nps->nps_client_count = 0;
+ g_cond_free(lbs_server_nps->cond);
+ g_mutex_free(&lbs_server_nps->mutex);
+
+ nps_set_status(lbs_server_nps, LBS_STATUS_UNAVAILABLE);
+}
+
+static void _glib_log (const gchar *log_domain, GLogLevelFlags log_level,
+ const gchar *msg, gpointer user_data)
+{
+ LOG_NPS(DBG_ERR, "GLIB[%d] : %s", log_level, msg);
+}
+
+int main(int argc, char **argv)
+{
+ lbs_server_s *lbs_server = NULL;
+ struct gps_callbacks cb;
+ int ret_code = 0;
+ cb.pos_cb = gps_update_position_cb;
+ cb.batch_cb = gps_update_batch_cb;
+ cb.sv_cb = gps_update_satellite_cb;
+ cb.nmea_cb = gps_update_nmea_cb;
+
+#if !GLIB_CHECK_VERSION (2, 31, 0)
+ if (!g_thread_supported()) {
+ g_thread_init(NULL);
+ }
+#endif
+ g_type_init();
+
+ ret_code = initialize_server(argc, argv);
+ if (ret_code !=0) {
+ LOG_GPS(DBG_ERR, "initialize_server failed");
+ return 1;
+ }
+
+ lbs_server = g_new0(lbs_server_s, 1);
+ if (!lbs_server) {
+ LOG_GPS(DBG_ERR, "lbs_server_s create fail");
+ return 1;
+ }
+ lbs_server_init(lbs_server);
+ gps_init_log();
+
+ register_update_callbacks(&cb, lbs_server);
+
+ g_log_set_default_handler (_glib_log, lbs_server);
+
+ /* create lbs-dbus server */
+ ret_code = lbs_server_create(SERVICE_NAME, SERVICE_PATH, "lbs-server", "lbs-server",
+ &(lbs_server->lbs_dbus_server), set_options, shutdown, update_pos_tracking_interval, request_change_pos_update_interval,
+ add_fence, remove_fence, pause_fence, resume_fence, (gpointer)lbs_server);
+ if (ret_code != LBS_SERVER_ERROR_NONE) {
+ LOG_GPS(DBG_ERR, "lbs_server_create failed");
+ return 1;
+ }
+
+ LOG_GPS(DBG_LOW, "lbs_server_create called");
+
+ #ifdef TIZEN_WEARABLE
+ __check_gps_offset_mode(lbs_server);
+ setting_notify_key_changed(VCONFKEY_SETAPPL_PSMODE, __setting_pw_saving_cb, lbs_server);
+ setting_notify_key_changed(VCONFKEY_CONVERT_GPS_IN_BERLIN, __convert_gps_set_cb, lbs_server);
+ #endif
+
+ lbs_server->loop = g_main_loop_new(NULL, TRUE);
+ g_main_loop_run(lbs_server->loop);
+
+ #ifdef TIZEN_WEARABLE
+ setting_ignore_key_changed(VCONFKEY_CONVERT_GPS_IN_BERLIN, __convert_gps_set_cb);
+ setting_ignore_key_changed(VCONFKEY_SETAPPL_PSMODE, __setting_pw_saving_cb);
+ #endif
+
+ LOG_GPS(DBG_LOW, "lbs_server deamon Stop....");
+
+ gps_deinit_log();
+
+ /* destroy resource for dynamic-interval */
+ g_free(lbs_server->optimized_interval_array);
+ g_hash_table_destroy(lbs_server->dynamic_interval_table);
+
+ /* destroy lbs-dbus server */
+ lbs_server_destroy(lbs_server->lbs_dbus_server);
+ LOG_GPS(DBG_LOW, "lbs_server_destroy called");
+
+ g_main_loop_unref(lbs_server->loop);
+
+ nps_deinit(lbs_server);
+ g_free(lbs_server);
+
+ deinitialize_server();
+
+ return 0;
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _LBS_SERVER_H_
+#define _LBS_SERVER_H_
+
+#include <gps_plugin_data_types.h>
+#include <gps_plugin_extra_data_types.h>
+
+#define SERVICE_NAME "org.tizen.lbs.Providers.LbsServer"
+#define SERVICE_PATH "/org/tizen/lbs/Providers/LbsServer"
+
+#define MAX_NPS_LOC_ITEM 6
+#define MAX_GPS_LOC_ITEM 7
+
+#define UPDATE_INTERVAL 60
+
+typedef enum {
+ LBS_SERVER_METHOD_GPS = 0,
+ LBS_SERVER_METHOD_NPS,
+ LBS_SERVER_METHOD_AGPS,
+ LBS_SERVER_METHOD_GEOFENCE,
+ LBS_SERVER_METHOD_SIZE,
+} lbs_server_method_e;
+
+/**
+ * This callback is called with position data.
+ *
+ * @param[in] pos Position data
+ * @param[in] error Error report
+ * @param[in] user_data User defined data
+ */
+typedef void (*gps_pos_cb) (pos_data_t * pos, gps_error_t error, void *user_data);
+
+/**
+ * This callback is called with batch data.
+ *
+ * @param[in] batch Batch data
+ * @param[in] user_data User defined data
+ */
+typedef void (*gps_batch_cb) (batch_data_t * batch, void *user_data);
+
+/**
+ * This callback is called with satellite data.
+ *
+ * @param[in] sv Satellite data
+ * @param[in] user_data User defined data
+ */
+typedef void (*gps_sv_cb) (sv_data_t * sv, void *user_data);
+
+/**
+ * This callback is called with nmea.
+ *
+ * @param[in] nmea NMEA data
+ * @param[in] user_data User defined data
+ */
+typedef void (*gps_nmea_cb) (nmea_data_t * nmea, void *user_data);
+
+/**
+ * GPS callback structure.
+ */
+struct gps_callbacks {
+ gps_pos_cb pos_cb; /**< Callback function for reporting position data */
+ gps_batch_cb batch_cb; /**< Callback function for reporting batch data */
+ gps_sv_cb sv_cb; /**< Callback function for reporting satellite data */
+ gps_nmea_cb nmea_cb; /**< Callback function for reporting NMEA data */
+};
+typedef struct gps_callbacks gps_callbacks_t;
+
+/**
+ * LbsStatus
+ *
+ * defines the provider status
+ **/
+typedef enum {
+ LBS_STATUS_ERROR,
+ LBS_STATUS_UNAVAILABLE,
+ LBS_STATUS_ACQUIRING,
+ LBS_STATUS_AVAILABLE,
+ LBS_STATUS_BATCH
+} LbsStatus;
+
+/**
+ * LbsPositionExtFields:
+ *
+ * LbsPositionExtFields is a bitfield that defines the validity of
+ * Position & Velocity values.
+ **/
+typedef enum {
+ LBS_POSITION_EXT_FIELDS_NONE = 0,
+ LBS_POSITION_EXT_FIELDS_LATITUDE = 1 << 0,
+ LBS_POSITION_EXT_FIELDS_LONGITUDE = 1 << 1,
+ LBS_POSITION_EXT_FIELDS_ALTITUDE = 1 << 2,
+ LBS_POSITION_EXT_FIELDS_SPEED = 1 << 3,
+ LBS_POSITION_EXT_FIELDS_DIRECTION = 1 << 4,
+ LBS_POSITION_EXT_FIELDS_CLIMB = 1 << 5
+} LbsPositionExtFields;
+
+/**
+ * LbsAccuracyLevel:
+ *
+ * Enum values used to define the approximate accuracy of
+ * Position or Address information.
+ **/
+typedef enum {
+ LBS_ACCURACY_LEVEL_NONE = 0,
+ LBS_ACCURACY_LEVEL_COUNTRY,
+ LBS_ACCURACY_LEVEL_REGION,
+ LBS_ACCURACY_LEVEL_LOCALITY,
+ LBS_ACCURACY_LEVEL_POSTALCODE,
+ LBS_ACCURACY_LEVEL_STREET,
+ LBS_ACCURACY_LEVEL_DETAILED,
+} LbsAccuracyLevel;
+
+typedef enum {
+ GEOFENCE_ADD_FENCE = 0,
+ GEOFENCE_DELETE_FENCE,
+ GEOFENCE_PAUSE_FENCE,
+ GEOFENCE_RESUME_FENCE
+} geofence_event_e;
+
+int gps_update_geofence_transition(int geofence_id, geofence_zone_state_t transition, double latitude, double longitude, double altitude, double speed, double bearing, double hor_accuracy, void *data);
+int gps_update_geofence_service_status(int status, void *data);
+
+// NPS
+
+typedef enum {
+ LBS_POSITION_FIELDS_NONE = 0,
+ LBS_POSITION_FIELDS_LATITUDE = 1 << 0,
+ LBS_POSITION_FIELDS_LONGITUDE = 1 << 1,
+ LBS_POSITION_FIELDS_ALTITUDE = 1 << 2
+} LbsPositionFields; // not used
+
+typedef struct {
+ LbsPositionExtFields fields;
+ int timestamp;
+ double latitude;
+ double longitude;
+ double altitude;
+ double speed;
+ double direction;
+ LbsAccuracyLevel acc_level;
+ double hor_accuracy;
+ double ver_accuracy;
+} NpsManagerPositionExt;
+
+typedef struct {
+ int timestamp;
+ double latitude;
+ double longitude;
+ double altitude;
+ double speed;
+ double direction;
+ double hor_accuracy;
+} NpsManagerLastPositionExt;
+
+typedef void *NpsManagerHandle;
+
+#endif
--- /dev/null
+[Gps Manager Provider]
+Name=Agps
+Service=org.tizen.lbs.Providers.LbsServer
+Path=/org/tizen/lbs/Providers/LbsServer
+Requires=RequiresLocation
+Provides=ProvidesUpdates
+Accuracy=Detailed
+Interfaces=org.tizen.lbs.Manager;org.tizen.lbs.Position;org.tizen.lbs.Nmea;org.tizen.lbs.Satellite
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include "nmea_logger.h"
+#include "debug_util.h"
+
+#define MAX_NMEA_RAW_DATA_LOG_FILE_CNT (999)
+#define MAX_NMEA_LOG_FILE_PATH (100)
+
+#define PHONE_FOLDER "/opt/usr/media"
+#define GPS_FOLDER PHONE_FOLDER"/lbs-server"
+#define NMEA_FOLDER GPS_FOLDER"/NMEA"
+#define NMEA_LOGGING_FILE_PATH NMEA_FOLDER"/nmea_data"
+
+int raw_nmea_fd = -1;
+
+static int generate_nmea_log_file(char *);
+
+void start_nmea_log()
+{
+ char filepath[MAX_NMEA_LOG_FILE_PATH];
+
+ // File Open
+ struct stat st = {0};
+
+ if (stat(GPS_FOLDER, &st) == -1) {
+ if (mkdir(GPS_FOLDER, 0777) == -1) {
+ LOG_GPS(DBG_ERR, "Fail to make lbs-server folder");
+ raw_nmea_fd = -1;
+ return;
+ } else {
+ if (mkdir(NMEA_FOLDER, 0777) == -1) {
+ LOG_GPS(DBG_ERR, "Fail to make NMEA folder");
+ raw_nmea_fd = -1;
+ return;
+ }
+ }
+ } else {
+ if (stat(NMEA_FOLDER, &st) == -1) {
+ if (mkdir(NMEA_FOLDER, 0777) == -1) {
+ LOG_GPS(DBG_ERR, "Fail to make NMEA folder");
+ raw_nmea_fd = -1;
+ return;
+ }
+ }
+ }
+
+ if (generate_nmea_log_file(filepath) == -1) {
+ LOG_GPS(DBG_ERR, "Starting LBS Logging for RAW NMEA data FAILED!");
+ raw_nmea_fd = -1;
+ return;
+ }
+
+ raw_nmea_fd = open(filepath, O_RDWR | O_APPEND | O_CREAT, 0644);
+
+ if (raw_nmea_fd < 0) {
+ LOG_GPS(DBG_ERR, "FAILED to open nmea_data file, error[%d]", errno);
+ } else {
+ LOG_GPS(DBG_LOW, "Success :: raw_nmea_fd [%d]", raw_nmea_fd);
+ }
+
+ return;
+}
+
+void stop_nmea_log()
+{
+ int close_ret_val = 0;
+
+ LOG_GPS(DBG_LOW, "raw_nmea_fd [%d]", raw_nmea_fd);
+
+ if (raw_nmea_fd != -1) {
+ close_ret_val = close(raw_nmea_fd);
+ if (close_ret_val < 0) {
+ LOG_GPS(DBG_ERR, "FAILED to close raw_nmea_fd[%d], error[%d]", raw_nmea_fd, errno);
+ }
+ raw_nmea_fd = -1;
+ }
+ return;
+}
+
+void write_nmea_log(char *data, int len)
+{
+ int write_ret_val = 0;
+
+ if (raw_nmea_fd != -1) {
+ write_ret_val = write(raw_nmea_fd, data, len);
+ if (write_ret_val < 0) {
+ LOG_GPS(DBG_ERR, "FAILED to write[%d], error[%d]", raw_nmea_fd, errno);
+ close(raw_nmea_fd);
+ raw_nmea_fd = -1;
+ }
+ }
+ return;
+}
+
+static int generate_nmea_log_file(char *filepath)
+{
+ int idx = 0;
+ int fd = 0;
+ char fn[MAX_NMEA_LOG_FILE_PATH];
+
+ for (idx = 0; idx < MAX_NMEA_RAW_DATA_LOG_FILE_CNT; idx++) {
+ snprintf(fn, MAX_NMEA_LOG_FILE_PATH, "%s%03d.txt", NMEA_LOGGING_FILE_PATH, idx);
+ if ((fd = access(fn, R_OK)) == -1) {
+ LOG_GPS(DBG_LOW, "Next log file [%s]", fn);
+ strcpy(filepath, fn);
+ return 0;
+ }
+ }
+ LOG_GPS(DBG_LOW, "All NMEA RAW Data logging files are used. New log file can not be created");
+ return -1;
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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_LOGGER_H_
+#define _NMEA_LOGGER_H_
+
+/* Start NMEA logging */
+void start_nmea_log();
+
+/* Stop NMEA logging */
+void stop_nmea_log();
+
+/* Write NMEA data to logging file */
+void write_nmea_log(char *data, int len);
+
+#endif /* _NMEA_LOGGER_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Dong Wei <d.wei@samsung.com>,
+ * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>,
+ * Ming Zhu <mingwu.zhu@samsung.com>, Congyi Shi <congyi.shi@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 <string.h>
+#include <dlfcn.h>
+#include <unistd.h>
+#include "nps_plugin_module.h"
+#include "setting.h"
+#include "debug_util.h"
+
+#define PLUGIN_PATH_POSTFIX ".so"
+
+
+static const nps_plugin_interface *g_plugin = NULL;
+static int g_is_nps_dummy_module = FALSE;
+
+int dummy_load (void);
+int dummy_unload(void);
+int dummy_start(unsigned long period, LocationCallback cb, void *arg, void **handle);
+int dummy_stop(void *handle, CancelCallback cb, void *arg);
+void dummy_get_offline_token(const unsigned char *key, unsigned int keyLengh, OfflineTokenCallback cb, void *arg);
+int dummy_offline_location(const unsigned char *key, unsigned int keyLength, const unsigned char *token, unsigned int tokenSize, LocationCallback cb, void *arg);
+void dummy_cell_location (LocationCallback callback, void* arg);
+
+static nps_plugin_interface g_dummy = {
+ .load = dummy_load,
+ .unload = dummy_unload,
+ .start = dummy_start,
+ .stop = dummy_stop,
+ .getOfflineToken = dummy_get_offline_token,
+ .offlineLocation = dummy_offline_location,
+ .cellLocation = dummy_cell_location
+};
+
+int nps_is_dummy_plugin_module()
+{
+ return g_is_nps_dummy_module;
+}
+
+int nps_load_plugin_module(void **plugin_handle)
+{
+ LOG_NPS(DBG_LOW, "Begin to load plugin module");
+
+ char plugin_path[256] = {0};
+
+ strncpy(plugin_path, NPS_PLUGIN_PATH, sizeof(plugin_path));
+
+ if (access (plugin_path, R_OK) != 0) {
+ LOG_NPS(DBG_ERR, "Failed to access plugin module. [%s]", plugin_path);
+ LOG_NPS(DBG_LOW, "load dummy");
+ g_plugin = &g_dummy;
+ g_is_nps_dummy_module = TRUE;
+ return TRUE;
+ }
+
+ *plugin_handle = dlopen(plugin_path, RTLD_NOW);
+ if (!*plugin_handle) {
+ LOG_NPS(DBG_ERR, "Failed to load plugin module.");
+ LOG_NPS(DBG_ERR, "%s", dlerror());
+ return FALSE;
+ }
+
+ const nps_plugin_interface *(*get_nps_plugin_interface) ();
+ get_nps_plugin_interface = dlsym(*plugin_handle, "get_nps_plugin_interface");
+ if (!get_nps_plugin_interface) {
+ LOG_NPS(DBG_ERR, "Failed to find entry symbol in plugin module.");
+ dlclose(*plugin_handle);
+ return FALSE;
+ }
+
+ g_plugin = get_nps_plugin_interface();
+
+ if (!g_plugin) {
+ LOG_NPS(DBG_ERR, "Failed to find load symbol in plugin module.");
+ dlclose(*plugin_handle);
+ return FALSE;
+ }
+ LOG_NPS(DBG_LOW, "Success to load plugin module (%s).", plugin_path);
+
+ return TRUE;
+}
+
+int nps_unload_plugin_module(void *plugin_handle)
+{
+ if (plugin_handle == NULL) {
+ LOG_NPS(DBG_ERR, "plugin_handle is already NULL.");
+ return FALSE;
+ }
+
+ dlclose(plugin_handle);
+
+ if (g_plugin) {
+ g_plugin = NULL;
+ }
+ return TRUE;
+}
+
+const nps_plugin_interface *get_nps_plugin_module(void)
+{
+ return g_plugin;
+}
+
+int dummy_load (void)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+ return FALSE;
+}
+
+int dummy_unload(void)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+ return FALSE;
+}
+
+int dummy_start(unsigned long period, LocationCallback cb, void *arg, void **handle)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+ return FALSE;
+}
+
+int dummy_stop(void *handle, CancelCallback cb, void *arg)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+ return FALSE;
+}
+
+void dummy_get_offline_token(const unsigned char *key, unsigned int keyLengh, OfflineTokenCallback cb, void *arg)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+}
+
+int dummy_offline_location(const unsigned char *key, unsigned int keyLength, const unsigned char *token, unsigned int tokenSize, LocationCallback cb, void *arg)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+ return FALSE;
+}
+
+void dummy_cell_location (LocationCallback callback, void* arg)
+{
+ LOG_NPS(DBG_ERR, "Dummy func.");
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Dong Wei <d.wei@samsung.com>,
+ * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>,
+ * Ming Zhu <mingwu.zhu@samsung.com>, Congyi Shi <congyi.shi@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 _NPS_PLUGIN_MODULE_H_
+#define _NPS_PLUGIN_MODULE_H_
+
+#include "nps_plugin_intf.h"
+
+int nps_load_plugin_module(void **plugin_handle);
+int nps_unload_plugin_module(void *plugin_handle);
+int nps_is_dummy_plugin_module();
+const nps_plugin_interface *get_nps_plugin_module(void);
+
+#endif /* _NPS_PLUGIN_MODULE_H_ */
--- /dev/null
+[D-BUS Service]
+Name=org.tizen.lbs.Providers.LbsServer
+Exec=@libexecdir@/lbs-server
--- /dev/null
+#!/bin/sh
+
+#--------------------------------------
+# GPS
+#--------------------------------------
+
+GPS_DEBUG_DIR=$1/gps
+mkdir -p ${GPS_DEBUG_DIR}
+
+cp /tmp/dump_gps.log ${GPS_DEBUG_DIR}/
+
+vconftool get memory/location/gps >> ${GPS_DEBUG_DIR}/vconf
+vconftool get memory/location/wps >> ${GPS_DEBUG_DIR}/vconf
+vconftool get db/location/setting >> ${GPS_DEBUG_DIR}/vconf
--- /dev/null
+#!/bin/sh
+
+#--------------------------------------
+# GPS
+#--------------------------------------
+
+GPS_DEBUG_DIR=$1/lbs_server
+mkdir -p ${GPS_DEBUG_DIR}
+
+cp /tmp/dump_lbs.log ${GPS_DEBUG_DIR}/
+
+vconftool get memory/location/gps >> ${GPS_DEBUG_DIR}/vconf
+vconftool get memory/location/wps >> ${GPS_DEBUG_DIR}/vconf
+vconftool get db/location/setting >> ${GPS_DEBUG_DIR}/vconf
--- /dev/null
+#!/bin/sh
+##/etc/init.d/lbs-server Lv : S90
+
+## This file is boot script of /usr/libexec/lbs-server
+
+if [ -x /usr/libexec/lbs-server ]; then
+ if [ ! -z "`pgrep lbs-server`" ]; then
+ /usr/bin/killall lbs-server
+ fi
+ /usr/libexec/lbs-server &
+fi
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <signal.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "server.h"
+#include "gps_plugin_data_types.h"
+#include "gps_plugin_intf.h"
+#include "nmea_logger.h"
+#include "data_connection.h"
+#include "setting.h"
+#include "gps_plugin_module.h"
+#include "debug_util.h"
+#include "last_position.h"
+#include "dump_log.h"
+
+#include "nps_plugin_module.h"
+#include "nps_plugin_intf.h"
+
+#ifdef _TIZEN_PUBLIC_
+#include <msg.h>
+#include <msg_transport.h>
+#include <pmapi.h>
+#endif
+
+#include <vconf.h>
+#include <vconf-keys.h>
+#include <dlog.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#if !GLIB_CHECK_VERSION (2, 31, 0)
+#include <glib/gthread.h>
+#endif
+
+#define REPLAY_MODULE "replay"
+
+#define PLATFORM_PATH "/sys/devices/platform"
+#define BRCM4752_PATH PLATFORM_PATH"/bcm4752"
+#define BRCM47520_PATH PLATFORM_PATH"/bcm47520"
+#define BRCM47511_PATH PLATFORM_PATH"/bcm47511"
+#define CSR_PATH PLATFORM_PATH"/gsd4t"
+#define QCOM8210_PATH PLATFORM_PATH"/msm8210_gps"
+#define QCOM8x30_PATH PLATFORM_PATH"/msm8x30_gps"
+#define QCOM9x15_PATH PLATFORM_PATH"/msm9x15_gps"
+#define QCOM8974_PATH PLATFORM_PATH"/msm8974_gps"
+#define QCOM8226_PATH PLATFORM_PATH"/msm8226_gps"
+
+#define MPS_TO_KMPH 3.6 // 1 m/s = 3.6 km/h
+
+struct gps_callbacks g_update_cb;
+void *g_user_data;
+
+typedef struct {
+ void *handle;
+ char *name;
+} gps_plugin_handler_t;
+
+typedef struct {
+ void *handle;
+} nps_plugin_handler_t;
+
+typedef struct {
+ gps_session_state_t session_state;
+ int dnet_used;
+ gboolean logging_enabled;
+ gboolean replay_enabled;
+
+#ifdef _TIZEN_PUBLIC_
+ pthread_t msg_thread; /* Register SUPL NI cb to msg server Thread */
+ pthread_t popup_thread; /* Register SUPL NI cb to msg server Thread */
+ int msg_thread_status;
+#endif
+
+ gps_plugin_handler_t gps_plugin;
+
+ pos_data_t *pos_data;
+ batch_data_t *batch_data;
+ sv_data_t *sv_data;
+ nmea_data_t *nmea_data;
+} gps_server_t;
+
+gps_server_t *g_gps_server = NULL;
+
+nps_plugin_handler_t g_nps_plugin;
+
+static void __nps_plugin_handler_deinit (void)
+{
+ if (g_nps_plugin.handle != NULL) {
+ g_nps_plugin.handle = NULL;
+ }
+}
+
+static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info, void *user_data);
+
+static void _gps_nmea_changed_cb(keynode_t * key, void *data)
+{
+ gps_server_t *server = (gps_server_t *)data;
+ int int_val;
+ if (setting_get_int(VCONFKEY_LOCATION_NMEA_LOGGING, &int_val) == FALSE) {
+ LOG_GPS(DBG_ERR, "//ERROR!! get VCONFKEY_LOCATION_NMEA_LOGGING setting");
+ int_val = 0;
+ }
+ server->logging_enabled = (int_val == 1) ? TRUE : FALSE;
+ return;
+}
+
+static gboolean get_replay_enabled()
+{
+ int int_val;
+ gboolean ret;
+
+ if (setting_get_int(VCONFKEY_LOCATION_REPLAY_ENABLED, &int_val) == FALSE) {
+ LOG_GPS(DBG_ERR, "//ERROR get VCONFKEY_LOCATION_REPLAY_ENABLED setting");
+ int_val = 0;
+ }
+
+ ret = (int_val == 1) ? TRUE : FALSE;
+
+ return ret;
+}
+
+static void reload_plugin_module(gps_server_t *server)
+{
+ char *module_name;
+ gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL;
+
+ if (server->replay_enabled == TRUE) {
+ module_name = REPLAY_MODULE;
+ } else {
+ module_name = server->gps_plugin.name;
+ }
+
+ LOG_GPS(DBG_LOW, "Loading plugin.name : %s", module_name);
+
+ if (!get_plugin_module()->deinit(&ReasonCode)) {
+ LOG_GPS(DBG_ERR, "Fail to GPS plugin deinit");
+ } else {
+ unload_plugin_module(&server->gps_plugin.handle);
+ if (!load_plugin_module(module_name, &server->gps_plugin.handle)) {
+ LOG_GPS(DBG_ERR, "Fail to load %s plugin", module_name);
+ } else {
+ if (!get_plugin_module()->init(_gps_server_gps_event_cb, (void *)server)) {
+ LOG_GPS(DBG_ERR, "Fail to %s plugin init", module_name);
+ return;
+ }
+ }
+ }
+}
+
+static void _gps_replay_changed_cb(keynode_t * key, void *data)
+{
+ gps_server_t *server = (gps_server_t *)data;
+ server->replay_enabled = get_replay_enabled();
+ reload_plugin_module(server);
+
+ return;
+}
+
+static int _gps_server_get_gps_state()
+{
+ int val;
+
+ if (setting_get_int(VCONFKEY_LOCATION_GPS_STATE, &val) == FALSE) {
+ val = POSITION_OFF;
+ }
+
+ return val;
+}
+
+static void _gps_server_set_gps_state(int gps_state)
+{
+ int ret;
+
+ switch (gps_state) {
+ case POSITION_CONNECTED:
+ ret = setting_set_int(VCONFKEY_LOCATION_GPS_STATE, POSITION_CONNECTED);
+ gps_dump_log("GPS state : POSITION_CONNECTED", NULL);
+ break;
+ case POSITION_SEARCHING:
+ ret = setting_set_int(VCONFKEY_LOCATION_GPS_STATE, POSITION_SEARCHING);
+ gps_dump_log("GPS state : POSITION_SEARCHING", NULL);
+ break;
+ case POSITION_OFF:
+ ret = setting_set_int(VCONFKEY_LOCATION_GPS_STATE, POSITION_OFF);
+ gps_dump_log("GPS state : POSITION_OFF", NULL);
+ break;
+ default:
+ ret = setting_set_int(VCONFKEY_LOCATION_GPS_STATE, POSITION_OFF);
+ break;
+ }
+
+ if (ret == TRUE) {
+ LOG_GPS(DBG_LOW, "Succesee to set VCONFKEY_LOCATION_GPS_STATE");
+ } else {
+ LOG_GPS(DBG_ERR, "Fail to set VCONF_LOCATION_GPS_STATE");
+ }
+}
+
+int request_change_pos_update_interval_standalone_gps(unsigned int interval)
+{
+ LOG_GPS(DBG_INFO, "request_change_pos_update_interval_standalone_gps. interval[%u]", interval);
+ gboolean status = TRUE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ gps_server_t *server = g_gps_server;
+
+ if (server->session_state == GPS_SESSION_STARTING || server->session_state == GPS_SESSION_STARTED) {
+ gps_action_change_interval_data_t gps_change_interval_data;
+ gps_change_interval_data.interval = (int)interval;
+ status = get_plugin_module()->request(GPS_ACTION_CHANGE_INTERVAL, &gps_change_interval_data, &reason_code);
+ LOG_GPS(DBG_INFO, "requested go GPS module done. gps_change_interval_data.interval [%d]", gps_change_interval_data.interval);
+
+ if (status == FALSE) {
+ LOG_GPS(DBG_ERR, "Main: sending GPS_ACTION_CHANGE_INTERVAL Fail !");
+ return FALSE;
+ }
+ LOG_GPS(DBG_INFO, "Main: sending GPS_ACTION_CHANGE_INTERVAL OK !");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int request_start_session(int interval)
+{
+ LOG_GPS(DBG_INFO, "GPS start with interval [%d]", interval);
+
+ gboolean status = TRUE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ gps_server_t *server = g_gps_server;
+ gps_action_start_data_t gps_start_data;
+
+ if (server->session_state != GPS_SESSION_STOPPED && server->session_state != GPS_SESSION_STOPPING) {
+ LOG_GPS(DBG_WARN, "Main: GPS Session Already Started!");
+ return TRUE;
+ }
+
+ server->session_state = GPS_SESSION_STARTING;
+ LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", server->session_state);
+ gps_start_data.interval = interval;
+ status = get_plugin_module()->request(GPS_ACTION_START_SESSION, &gps_start_data, &reason_code);
+
+ if (status == FALSE) {
+ LOG_GPS(DBG_ERR, "Main: sending GPS_ACTION_START_SESSION Fail !");
+ return FALSE;
+ }
+
+ LOG_GPS(DBG_INFO, "Main: sending GPS_ACTION_START_SESSION OK !");
+
+ setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb);
+
+ return TRUE;
+}
+
+int request_stop_session()
+{
+ gboolean status = TRUE;
+ gboolean cur_replay_enabled = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ gps_server_t *server = g_gps_server;
+
+ LOG_GPS(DBG_LOW, "Main: Stop GPS Session, ==GPSSessionState[%d]", server->session_state);
+ if (server->session_state == GPS_SESSION_STARTED || server->session_state == GPS_SESSION_STARTING) {
+ status = get_plugin_module()->request(GPS_ACTION_STOP_SESSION, NULL, &reason_code);
+ if (status) {
+ server->session_state = GPS_SESSION_STOPPING;
+ LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", server->session_state);
+ cur_replay_enabled = get_replay_enabled();
+ if (server->replay_enabled != cur_replay_enabled) {
+ server->replay_enabled = cur_replay_enabled;
+ reload_plugin_module(server);
+ }
+ setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb, (void *)server);
+ } else {
+ LOG_GPS(DBG_ERR, " plugin->request to LBS_GPS_STOP_SESSION Failed, reasonCode =%d", reason_code);
+ }
+ } else {
+ // If request is not sent, keep the client registed
+ LOG_GPS(DBG_LOW,
+ " LBS_GPS_STOP_SESSION is not sent because the GPS state is not started, keep the client registed ");
+ }
+ return status;
+}
+
+int request_start_batch_session(int batch_interval, int batch_period)
+{
+ LOG_GPS(DBG_INFO, "Batch: GPS start with interval[%d]", batch_interval);
+
+ gboolean status = TRUE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ gps_server_t *server = g_gps_server;
+ gps_action_start_data_t gps_start_data;
+
+ if (server->session_state != GPS_SESSION_STOPPED && server->session_state != GPS_SESSION_STOPPING) {
+ LOG_GPS(DBG_WARN, "Batch: GPS Session Already Started!");
+ return TRUE;
+ }
+
+ server->session_state = GPS_SESSION_STARTING;
+ LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", server->session_state);
+ gps_start_data.interval = batch_interval;
+ gps_start_data.period = batch_period;
+ status = get_plugin_module()->request(GPS_ACTION_START_BATCH, &gps_start_data, &reason_code);
+
+ if (status == FALSE) {
+ LOG_GPS(DBG_ERR, "Batch: sending GPS_ACTION_START_SESSION Fail !");
+ return FALSE;
+ }
+
+ LOG_GPS(DBG_INFO, "Batch: sending GPS_ACTION_START_SESSION OK !");
+
+ setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb);
+
+ return TRUE;
+}
+
+int request_stop_batch_session()
+{
+ gboolean status = TRUE;
+ gboolean cur_replay_enabled = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ gps_server_t *server = g_gps_server;
+
+ LOG_GPS(DBG_LOW, "Batch: Stop GPS Session, ==GPSSessionState[%d]", server->session_state);
+ if (server->session_state == GPS_SESSION_STARTED || server->session_state == GPS_SESSION_STARTING) {
+ status = get_plugin_module()->request(GPS_ACTION_STOP_BATCH, NULL, &reason_code);
+ if (status) {
+ server->session_state = GPS_SESSION_STOPPING;
+ LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", server->session_state);
+ cur_replay_enabled = get_replay_enabled();
+ if (server->replay_enabled != cur_replay_enabled) {
+ server->replay_enabled = cur_replay_enabled;
+ reload_plugin_module(server);
+ }
+ setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb, (void *)server);
+ } else {
+ LOG_GPS(DBG_ERR, " plugin->request to LBS_GPS_STOP_SESSION Failed, reasonCode =%d", reason_code);
+ }
+ } else {
+ // If request is not sent, keep the client registed
+ LOG_GPS(DBG_LOW, " LBS_GPS_STOP_SESSION is not sent because the GPS state is not started, keep the client registed ");
+ }
+ return status;
+}
+
+int request_add_geofence(int fence_id, double latitude, double longitude, int radius, int last_state, int monitor_states, int notification_responsiveness, int unknown_timer)
+{
+ gboolean status = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ geofence_action_data_t action_data;
+
+ action_data.geofence.geofence_id = fence_id;
+ action_data.geofence.latitude = latitude;
+ action_data.geofence.longitude = longitude;
+ action_data.geofence.radius = radius;
+ action_data.last_state = last_state;
+ action_data.monitor_states = monitor_states;
+ // Default value : temp
+ action_data.notification_responsiveness_ms = 5000;
+ action_data.unknown_timer_ms = 30000;
+ //action_data.notification_responsiveness_ms = notification_responsiveness;
+ //action_data.unknown_timer_ms = unknown_timer;
+
+ LOG_GPS(DBG_LOW, "request_add_geofence with geofence_id [%d]", fence_id);
+ status = get_plugin_module()->request(GPS_ACTION_ADD_GEOFENCE, &action_data, &reason_code);
+
+ return status;
+}
+
+int request_delete_geofence(int fence_id)
+{
+ gboolean status = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+
+ LOG_GPS(DBG_LOW, "request_delete_geofence with geofence_id [%d]", fence_id);
+ status = get_plugin_module()->request(GPS_ACTION_DELETE_GEOFENCE, &fence_id, &reason_code);
+
+ return status;
+}
+
+int request_pause_geofence(int fence_id)
+{
+ gboolean status = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+
+ LOG_GPS(DBG_LOW, "request_pause_geofence with geofence_id [%d]", fence_id);
+ status = get_plugin_module()->request(GPS_ACTION_PAUSE_GEOFENCE, &fence_id, &reason_code);
+
+ return status;
+}
+
+int request_resume_geofence(int fence_id, int monitor_states)
+{
+ gboolean status = FALSE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ geofence_action_data_t action_data;
+
+ action_data.geofence.geofence_id = fence_id;
+ action_data.monitor_states = monitor_states;
+
+ LOG_GPS(DBG_LOW, "request_resume_geofence with geofence_id [%d]", fence_id);
+ status = get_plugin_module()->request(GPS_ACTION_RESUME_GEOFENCE, &action_data, &reason_code);
+
+ return status;
+}
+
+int request_delete_gps_data()
+{
+ gboolean status = TRUE;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+
+ status = get_plugin_module()->request(GPS_ACTION_DELETE_GPS_DATA, NULL, &reason_code);
+
+ if (status == FALSE) {
+ LOG_GPS(DBG_ERR, "Fail : GPS_ACTION_DELETE_GPS_DATA [%d]", reason_code);
+ return FALSE;
+ }
+
+ LOG_GPS(DBG_LOW, "Success to GPS_ACTION_DELETE_GPS_DATA");
+ return TRUE;
+}
+
+static void _gps_plugin_handler_init(gps_server_t *server, char *module_name)
+{
+ server->gps_plugin.handle = NULL;
+ server->gps_plugin.name = (char *)malloc(strlen(module_name) + 1);
+ snprintf(server->gps_plugin.name, strlen(module_name) + 1, "%s", module_name);
+}
+
+static void _gps_plugin_handler_deinit(gps_server_t *server)
+{
+ if (server->gps_plugin.handle != NULL) {
+ server->gps_plugin.handle = NULL;
+ }
+
+ if (server->gps_plugin.name != NULL) {
+ free(server->gps_plugin.name);
+ server->gps_plugin.name = NULL;
+ }
+}
+
+static void _gps_get_nmea_replay_mode(gps_server_t *server)
+{
+ int int_val = 0;
+
+ if (setting_get_int(VCONFKEY_LOCATION_NMEA_LOGGING, &int_val) == FALSE) {
+ LOG_GPS(DBG_ERR, "//ERROR!! get VCONFKEY_LOCATION_NMEA_LOGGING setting");
+ int_val = 0;
+ }
+ server->logging_enabled = (int_val == 1) ? TRUE : FALSE;
+
+ if (setting_get_int(VCONFKEY_LOCATION_REPLAY_ENABLED, &int_val) == FALSE) {
+ LOG_GPS(DBG_ERR, "//ERROR!! get VCONFKEY_LOCATION_REPLAY_ENABLED setting");
+ int_val = 0;
+ }
+ server->replay_enabled = (int_val == 1) ? TRUE : FALSE;
+}
+
+static void _gps_notify_params(gps_server_t *server)
+{
+ setting_notify_key_changed(VCONFKEY_LOCATION_NMEA_LOGGING, _gps_nmea_changed_cb, (void *)server);
+ setting_notify_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb, (void *)server);
+}
+
+static void _gps_ignore_params()
+{
+ setting_ignore_key_changed(VCONFKEY_LOCATION_NMEA_LOGGING, _gps_nmea_changed_cb);
+ setting_ignore_key_changed(VCONFKEY_LOCATION_REPLAY_ENABLED, _gps_replay_changed_cb);
+}
+
+static void _gps_server_start_event(gps_server_t *server)
+{
+ LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", server->session_state, GPS_SESSION_STARTED);
+ server->session_state = GPS_SESSION_STARTED;
+
+ if (server->logging_enabled) {
+ LOG_GPS(DBG_LOW, "NMEA STARTED");
+ start_nmea_log();
+ }
+
+ if (server->pos_data == NULL) {
+ server->pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
+ if (server->pos_data == NULL) {
+ LOG_GPS(DBG_WARN, "//callback: server->pos_data re-malloc Failed!!");
+ } else {
+ memset(server->pos_data, 0x00, sizeof(pos_data_t));
+ }
+ }
+ if (server->batch_data == NULL) {
+ server->batch_data = (batch_data_t *) malloc(sizeof(batch_data_t));
+ if (server->batch_data == NULL) {
+ LOG_GPS(DBG_WARN, "//callback: server->batch_data re-malloc Failed!!");
+ } else {
+ memset(server->batch_data, 0x00, sizeof(batch_data_t));
+ }
+ }
+ if (server->sv_data == NULL) {
+ server->sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
+ if (server->sv_data == NULL) {
+ LOG_GPS(DBG_WARN, "//callback: server->sv_data re-malloc Failed!!");
+ } else {
+ memset(server->sv_data, 0x00, sizeof(sv_data_t));
+ }
+ }
+ if (server->nmea_data == NULL) {
+ server->nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
+ if (server->nmea_data == NULL) {
+ LOG_GPS(DBG_WARN, "//callback: server->nmea_data re-malloc Failed!!");
+ } else {
+ memset(server->nmea_data, 0x00, sizeof(nmea_data_t));
+ }
+ }
+
+ _gps_server_set_gps_state(POSITION_SEARCHING);
+#ifdef _TIZEN_PUBLIC_
+ pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
+#endif
+}
+
+static void _gps_server_stop_event(gps_server_t *server)
+{
+ LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", server->session_state, GPS_SESSION_STOPPED);
+ server->session_state = GPS_SESSION_STOPPED;
+
+ _gps_server_set_gps_state(POSITION_OFF);
+#ifdef _TIZEN_PUBLIC_
+ pm_unlock_state(LCD_OFF, PM_RESET_TIMER);
+#endif
+
+ if (server->logging_enabled) {
+ LOG_GPS(DBG_LOW, "NMEA STOPPED");
+ stop_nmea_log();
+ }
+}
+
+static void _report_pos_event(gps_server_t *server, gps_event_info_t * gps_event)
+{
+ if (server->pos_data != NULL) {
+ memset(server->pos_data, 0x00, sizeof(pos_data_t)); // Moved: the address of server->pos_data sometimes returns 0 when stopping GPS
+ memcpy(server->pos_data, &(gps_event->event_data.pos_ind.pos), sizeof(pos_data_t));
+ // change m/s to km/h
+ server->pos_data->speed = server->pos_data->speed * MPS_TO_KMPH;
+ gps_set_position(server->pos_data);
+ g_update_cb.pos_cb(server->pos_data, gps_event->event_data.pos_ind.error, g_user_data);
+ } else {
+ LOG_GPS(DBG_ERR, "server->pos_data is NULL");
+ }
+}
+
+static void _report_batch_event(gps_server_t *server, gps_event_info_t * gps_event)
+{
+ if (server->batch_data != NULL) {
+ memset(server->batch_data, 0x00, sizeof(batch_data_t));
+ memcpy(server->batch_data, &(gps_event->event_data.batch_ind.batch), sizeof(batch_data_t));
+ g_update_cb.batch_cb(server->batch_data, g_user_data);
+ } else {
+ LOG_GPS(DBG_ERR, "server->batch_data is NULL");
+ }
+}
+
+static void _report_sv_event(gps_server_t *server, gps_event_info_t * gps_event)
+{
+ if (server->sv_data != NULL) {
+ memset(server->sv_data, 0x00, sizeof(sv_data_t));
+ memcpy(server->sv_data, &(gps_event->event_data.sv_ind.sv), sizeof(sv_data_t));
+ g_update_cb.sv_cb(server->sv_data, g_user_data);
+ } else {
+ LOG_GPS(DBG_ERR, "server->sv_data is NULL");
+ }
+}
+
+static void _report_nmea_event(gps_server_t *server, gps_event_info_t * gps_event)
+{
+ if (server->nmea_data == NULL) {
+ LOG_GPS(DBG_ERR, "server->nmea_data is NULL");
+ return;
+ }
+
+ if (server->nmea_data->data) {
+ free(server->nmea_data->data);
+ server->nmea_data->data = NULL;
+ }
+
+ //LOG_GPS(DBG_LOW, "server->nmea_data->len : [%d]", gps_event->event_data.nmea_ind.nmea.len);
+ server->nmea_data->len = gps_event->event_data.nmea_ind.nmea.len;
+ server->nmea_data->data = (char *)malloc(server->nmea_data->len);
+ if (server->nmea_data->data == NULL) {
+ LOG_GPS(DBG_ERR, "Fail to malloc of server->nmea_data->data");
+ return;
+ }
+ memset(server->nmea_data->data, 0x00, server->nmea_data->len);
+ memcpy(server->nmea_data->data, gps_event->event_data.nmea_ind.nmea.data, server->nmea_data->len);
+ g_update_cb.nmea_cb(server->nmea_data, g_user_data);
+
+ if (server->logging_enabled) {
+ int nmea_len;
+ char *p_nmea_data;
+ nmea_len = gps_event->event_data.nmea_ind.nmea.len;
+ p_nmea_data = gps_event->event_data.nmea_ind.nmea.data;
+ write_nmea_log(p_nmea_data, nmea_len);
+ }
+}
+
+static int _gps_server_open_data_connection(gps_server_t *server)
+{
+ LOG_GPS(DBG_LOW, "Enter _gps_server_open_data_connection");
+
+ server->dnet_used++;
+
+ if (server->dnet_used > 1) {
+ LOG_GPS(DBG_LOW, "dnet_used : count[ %d ]", server->dnet_used);
+ return TRUE;
+ } else {
+ LOG_GPS(DBG_LOW, "First open the data connection");
+ }
+
+ unsigned char result;
+
+ result = start_pdp_connection();
+
+ if (result == TRUE) {
+ LOG_GPS(DBG_LOW, "//Open PDP Conn for SUPL Success.");
+ } else {
+ LOG_GPS(DBG_ERR, "//Open PDP Conn for SUPL Fail.");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int _gps_server_close_data_connection(gps_server_t *server)
+{
+ LOG_GPS(DBG_LOW, "Enter _gps_server_close_data_connection");
+
+ if (server->dnet_used > 0) {
+ server->dnet_used--;
+ }
+
+ if (server->dnet_used != 0) {
+ LOG_GPS(DBG_LOW, "Cannot stop the data connection! [ dnet_used : %d ]", server->dnet_used);
+ return TRUE;
+ } else {
+ LOG_GPS(DBG_LOW, "Close the data connection");
+ }
+
+ unsigned char result;
+
+ result = stop_pdp_connection();
+ if (result == TRUE) {
+ LOG_GPS(DBG_LOW, "Close PDP Conn for SUPL Success.");
+ } else {
+ LOG_GPS(DBG_ERR, "//Close PDP Conn for SUPL Fail.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int _gps_server_resolve_dns(char *domain)
+{
+ LOG_GPS(DBG_LOW, "Enter _gps_server_resolve_dns");
+
+ unsigned char result;
+ gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL;
+ unsigned int ipaddr;
+ int port;
+
+ result = query_dns(domain, &ipaddr, &port);
+ if (result == TRUE) {
+ LOG_GPS(DBG_LOW, "Success to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
+ get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
+ } else {
+ ipaddr = 0;
+ LOG_GPS(DBG_ERR, "Fail to resolve domain name [ %s ] / ipaddr [ %u ]", domain, ipaddr);
+ get_plugin_module()->request(GPS_INDI_SUPL_DNSQUERY, (void *)(&ipaddr), &reason_code);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void _gps_server_send_facttest_result(double snr_data, int prn, unsigned short result)
+{
+}
+
+static void _report_geofence_transition(int geofence_id, geofence_zone_state_t transition, double latitude, double longitude, double altitude, double speed, double bearing, double hor_accuracy)
+{
+ gps_update_geofence_transition(geofence_id, transition, latitude, longitude, altitude, speed, bearing, hor_accuracy, (void *)g_user_data);
+}
+
+static void _report_geofence_service_status(int status)
+{
+ gps_update_geofence_service_status(status, (void *)g_user_data);
+}
+
+static void _gps_server_send_geofence_result(geofence_event_e event, int geofence_id, int result)
+{
+ if (result != 0) {
+ LOG_GPS(DBG_ERR, "result is [%d]", result);
+ return;
+ }
+
+ switch (event) {
+ case GEOFENCE_ADD_FENCE:
+ LOG_GPS(DBG_LOW, "Geofence ID[%d], Success ADD_GEOFENCE", geofence_id);
+ break;
+ case GEOFENCE_DELETE_FENCE:
+ LOG_GPS(DBG_LOW, "Geofence ID[%d], Success DELETE_GEOFENCE", geofence_id);
+ break;
+ case GEOFENCE_PAUSE_FENCE:
+ LOG_GPS(DBG_LOW, "Geofence ID[%d], Success PAUSE_GEOFENCE", geofence_id);
+ break;
+ case GEOFENCE_RESUME_FENCE:
+ LOG_GPS(DBG_LOW, "Geofence ID[%d], Success RESUME_GEOFENCE", geofence_id);
+ break;
+ default:
+ break;
+ }
+}
+
+static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info, void *user_data)
+{
+ //FUNC_ENTRANCE_SERVER;
+ gps_server_t *server = (gps_server_t *)user_data;
+ int result = TRUE;
+ if (gps_event_info == NULL) {
+ LOG_GPS(DBG_WARN, "//NULL pointer variable passed");
+ return result;
+ }
+
+ switch (gps_event_info->event_id) {
+ case GPS_EVENT_START_SESSION:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_START_SESSION :::::::::::::::");
+ if (gps_event_info->event_data.start_session_rsp.error == GPS_ERR_NONE) {
+ _gps_server_start_event(server);
+ } else {
+ LOG_GPS(DBG_ERR, "//Start Session Failed, error : %d",
+ gps_event_info->event_data.start_session_rsp.error);
+ }
+ break;
+ case GPS_EVENT_SET_OPTION:
+ {
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SET_OPTION :::::::::::::::");
+ if (gps_event_info->event_data.set_option_rsp.error != GPS_ERR_NONE) {
+ LOG_GPS(DBG_ERR, "//Set Option Failed, error : %d",
+ gps_event_info->event_data.set_option_rsp.error);
+ }
+ }
+ break;
+
+ case GPS_EVENT_STOP_SESSION:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_STOP_SESSION :::::::::::::::");
+ if (gps_event_info->event_data.stop_session_rsp.error == GPS_ERR_NONE) {
+ _gps_server_close_data_connection(server);
+ _gps_server_stop_event(server);
+ } else {
+ LOG_GPS(DBG_ERR, "//Stop Session Failed, error : %d",
+ gps_event_info->event_data.stop_session_rsp.error);
+ }
+
+ break;
+ case GPS_EVENT_CHANGE_INTERVAL:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_CHANGE_INTERVAL :::::::::::::::");
+ if (gps_event_info->event_data.change_interval_rsp.error == GPS_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "Change interval success.");
+ } else {
+ LOG_GPS(DBG_ERR, "//Change interval Failed, error : %d",
+ gps_event_info->event_data.change_interval_rsp.error);
+ }
+ break;
+ case GPS_EVENT_REPORT_POSITION:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_POSITION :::::::::::::::");
+ if (gps_event_info->event_data.pos_ind.error == GPS_ERR_NONE) {
+ _report_pos_event(server, gps_event_info);
+ } else {
+ LOG_GPS(DBG_ERR, "GPS_EVENT_POSITION Failed, error : %d", gps_event_info->event_data.pos_ind.error);
+ }
+ break;
+ case GPS_EVENT_REPORT_BATCH:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_BATCH :::::::::::::::");
+ if (gps_event_info->event_data.batch_ind.error == GPS_ERR_NONE) {
+ _report_batch_event(server, gps_event_info);
+ } else {
+ LOG_GPS(DBG_ERR, "GPS_EVENT_BATCH Failed, error : %d", gps_event_info->event_data.batch_ind.error);
+ }
+ break;
+ case GPS_EVENT_REPORT_SATELLITE:
+ if (gps_event_info->event_data.sv_ind.error == GPS_ERR_NONE) {
+ if (gps_event_info->event_data.sv_ind.sv.pos_valid) {
+ if (_gps_server_get_gps_state() != POSITION_CONNECTED)
+ _gps_server_set_gps_state(POSITION_CONNECTED);
+ } else {
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SATELLITE :::::::::::::::");
+ if (_gps_server_get_gps_state() != POSITION_SEARCHING)
+ _gps_server_set_gps_state(POSITION_SEARCHING);
+ }
+ _report_sv_event(server, gps_event_info);
+ } else {
+ LOG_GPS(DBG_ERR, "GPS_EVENT_SATELLITE Failed, error : %d", gps_event_info->event_data.sv_ind.error);
+ }
+ break;
+ case GPS_EVENT_REPORT_NMEA:
+ if (_gps_server_get_gps_state() != POSITION_CONNECTED) {
+ //LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_NMEA :::::::::::::::");
+ }
+
+ if (gps_event_info->event_data.nmea_ind.error == GPS_ERR_NONE) {
+ _report_nmea_event(server, gps_event_info);
+ } else {
+ LOG_GPS(DBG_ERR, "GPS_EVENT_NMEA Failed, error : %d", gps_event_info->event_data.nmea_ind.error);
+ }
+ break;
+ case GPS_EVENT_ERR_CAUSE:
+ break;
+ case GPS_EVENT_AGPS_VERIFICATION_INDI:
+ break;
+ case GPS_EVENT_GET_IMSI:
+ break;
+ case GPS_EVENT_GET_REF_LOCATION:
+ break;
+ case GPS_EVENT_OPEN_DATA_CONNECTION:
+ {
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_OPEN_DATA_CONNECTION :::::::::::::::");
+ result = _gps_server_open_data_connection(server);
+ }
+ break;
+ case GPS_EVENT_CLOSE_DATA_CONNECTION:
+ {
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_CLOSE_DATA_CONNECTION :::::::::::::::");
+ result = _gps_server_close_data_connection(server);
+ }
+ break;
+ case GPS_EVENT_DNS_LOOKUP_IND:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_DNS_LOOKUP_IND :::::::::::::::");
+ if (gps_event_info->event_data.dns_query_ind.error == GPS_ERR_NONE) {
+ result = _gps_server_resolve_dns(gps_event_info->event_data.dns_query_ind.domain_name);
+ } else {
+ result = FALSE;
+ }
+ if (result == TRUE) {
+ LOG_GPS(DBG_LOW, "Success to get the DNS Query about [ %s ]",
+ gps_event_info->event_data.dns_query_ind.domain_name);
+ }
+ break;
+ case GPS_EVENT_FACTORY_TEST:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_FACTORY_TEST :::::::::::::::");
+ if (gps_event_info->event_data.factory_test_rsp.error == GPS_ERR_NONE) {
+ LOG_GPS(DBG_LOW, "[LBS server] Response Factory test result success");
+ _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
+ gps_event_info->event_data.factory_test_rsp.prn, TRUE);
+ } else {
+ LOG_GPS(DBG_ERR, "//[LBS server] Response Factory test result ERROR");
+ _gps_server_send_facttest_result(gps_event_info->event_data.factory_test_rsp.snr,
+ gps_event_info->event_data.factory_test_rsp.prn, FALSE);
+ }
+ break;
+ case GPS_EVENT_GEOFENCE_TRANSITION:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_GEOFENCE_TRANSITION :::::::::::::::");
+ _report_geofence_transition(gps_event_info->event_data.geofence_transition_ind.geofence_id,
+ gps_event_info->event_data.geofence_transition_ind.state,
+ gps_event_info->event_data.geofence_transition_ind.pos.latitude,
+ gps_event_info->event_data.geofence_transition_ind.pos.longitude,
+ gps_event_info->event_data.geofence_transition_ind.pos.altitude,
+ gps_event_info->event_data.geofence_transition_ind.pos.speed,
+ gps_event_info->event_data.geofence_transition_ind.pos.bearing,
+ gps_event_info->event_data.geofence_transition_ind.pos.hor_accuracy);
+ break;
+ case GPS_EVENT_GEOFENCE_STATUS:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_GEOFENCE_STATUS :::::::::::::::");
+ _report_geofence_service_status(gps_event_info->event_data.geofence_status_ind.status);
+ break;
+ case GPS_EVENT_ADD_GEOFENCE:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_ADD_GEOFENCE :::::::::::::::");
+ _gps_server_send_geofence_result(GEOFENCE_ADD_FENCE,
+ gps_event_info->event_data.geofence_event_rsp.geofence_id,
+ gps_event_info->event_data.geofence_event_rsp.error);
+ break;
+ case GPS_EVENT_DELETE_GEOFENCE:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_DELETE_GEOFENCE :::::::::::::::");
+ _gps_server_send_geofence_result(GEOFENCE_DELETE_FENCE,
+ gps_event_info->event_data.geofence_event_rsp.geofence_id,
+ gps_event_info->event_data.geofence_event_rsp.error);
+ break;
+ case GPS_EVENT_PAUSE_GEOFENCE:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_PAUSE_GEOFENCE :::::::::::::::");
+ _gps_server_send_geofence_result(GEOFENCE_PAUSE_FENCE,
+ gps_event_info->event_data.geofence_event_rsp.geofence_id,
+ gps_event_info->event_data.geofence_event_rsp.error);
+ break;
+ case GPS_EVENT_RESUME_GEOFENCE:
+ LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_RESUME_GEOFENCE :::::::::::::::");
+ _gps_server_send_geofence_result(GEOFENCE_RESUME_FENCE,
+ gps_event_info->event_data.geofence_event_rsp.geofence_id,
+ gps_event_info->event_data.geofence_event_rsp.error);
+ break;
+ default:
+ LOG_GPS(DBG_WARN, "//Error: Isettingalid Event Type %d", gps_event_info->event_id);
+ break;
+ }
+ return result;
+}
+
+#ifndef _TIZEN_PUBLIC_
+int request_supl_ni_session(const char *header, const char *body, int size)
+{
+ agps_supl_ni_info_t info;
+ gps_failure_reason_t reason_code;
+
+ info.msg_body = (char *)body;
+ info.msg_size = size;
+ info.status = TRUE;
+
+ if (!get_plugin_module()->request(GPS_ACTION_REQUEST_SUPL_NI, &info, &reason_code)) {
+ LOG_GPS(DBG_ERR, "Failed to request SUPL NI (code:%d)", reason_code);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#else
+static void *request_supl_ni_session(void *data)
+{
+ gps_ni_data_t *ni_data= (gps_ni_data_t *) data;
+ agps_supl_ni_info_t info;
+ gps_failure_reason_t reason_code;
+
+ info.msg_body = (char *)ni_data->msg_body;
+ info.msg_size = ni_data->msg_size;
+ info.status = TRUE;
+
+ if (!get_plugin_module()->request(GPS_ACTION_REQUEST_SUPL_NI, &info, &reason_code)) {
+ LOG_GPS(DBG_ERR, "Failed to request SUPL NI (code:%d)", reason_code);
+ }
+
+ free(ni_data);
+
+ return NULL;
+}
+
+static void _gps_supl_networkinit_smscb(msg_handle_t hMsgHandle, msg_struct_t msg, void *user_param)
+{
+ LOG_GPS(DBG_ERR, "_gps_supl_networkinit_smscb is called");
+ gps_server_t *server = (gps_server_t *)user_param;
+
+ gps_ni_data_t *new_message = NULL;
+
+ new_message = (gps_ni_data_t *)malloc(sizeof(gps_ni_data_t));
+ memset(new_message, 0x00, sizeof(gps_ni_data_t));
+ msg_get_int_value(msg, MSG_MESSAGE_DATA_SIZE_INT, &new_message->msg_size);
+ msg_get_str_value(msg, MSG_MESSAGE_SMS_DATA_STR, new_message->msg_body, new_message->msg_size);
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(&server->popup_thread, &attr, request_supl_ni_session, new_message) != 0) {
+ LOG_GPS(DBG_WARN, "Can not make pthread......");
+ }
+}
+
+static void _gps_supl_networkinit_wappushcb(msg_handle_t hMsgHandle, const char *pPushHeader, const char *pPushBody,
+ int pushBodyLen, void *user_param)
+{
+ gps_server_t *server = (gps_server_t *)user_param;
+ char *str;
+
+ LOG_GPS(DBG_ERR, "_gps_supl_networkinit_wappushcb is called");
+
+ if(strstr(pPushHeader, "application/vnd.omaloc-supl-init") != NULL)
+ {
+ str = strstr(pPushHeader, "X-Wap-Application-Id:");
+
+ if( strncmp(str+22,"x-oma-application:ulp.ua",24) != 0 )
+ {
+ LOG_GPS(DBG_ERR, "Wrong Application-ID");
+ return;
+ }
+ }
+
+ gps_ni_data_t *new_message = NULL;
+
+ new_message = (gps_ni_data_t *) malloc(sizeof(gps_ni_data_t));
+ new_message->msg_body = (char *)pPushBody;
+ new_message->msg_size = pushBodyLen;
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if (pthread_create(&server->popup_thread, &attr, request_supl_ni_session, new_message) != 0) {
+ LOG_GPS(DBG_WARN, "Can not make pthread......");
+ }
+}
+
+static void *_gps_register_msgfwcb(void *data)
+{
+ gps_server_t *server = (gps_server_t *)data;
+ msg_handle_t msgHandle = NULL;
+ msg_error_t err = MSG_SUCCESS;
+
+ int setValue = 0;
+ int ret;
+
+ int cnt = 60;
+
+ while (cnt > 0) {
+ ret = vconf_get_bool(VCONFKEY_MSG_SERVER_READY, &setValue);
+
+ if (ret == -1) {
+ LOG_GPS(DBG_WARN, "Fail to get VCONFKEY_MSG_SERVER_READY");
+ return NULL;
+ }
+
+ if (setValue) {
+ LOG_GPS(DBG_LOW, "MSG server is READY!!");
+ cnt = -1;
+ } else {
+ sleep(5);
+ cnt--;
+ if (cnt == 0) {
+ LOG_GPS(DBG_WARN, "Never connect to MSG Server for 300 secs.");
+ return NULL;
+ }
+ }
+ }
+
+ err = msg_open_msg_handle(&msgHandle);
+
+ if (err != MSG_SUCCESS) {
+ LOG_GPS(DBG_WARN, "Fail to MsgOpenMsgHandle. Error type = [ %d ]", err);
+ return NULL;
+ }
+
+ err = msg_reg_sms_message_callback(msgHandle, &_gps_supl_networkinit_smscb, 7275, (void *)server);
+
+ if (err != MSG_SUCCESS) {
+ LOG_GPS(DBG_WARN, "Fail to MsgRegSmsMessageCallback. Error type = [ %d ]", err);
+ return NULL;
+ }
+
+ err = msg_reg_lbs_message_callback(msgHandle, &_gps_supl_networkinit_wappushcb, (void *)server);
+
+ if (err != MSG_SUCCESS) {
+ LOG_GPS(DBG_WARN, "Fail to MsgRegLBSMessageCallback. Error type = [ %d ]", err);
+ return NULL;
+ }
+
+ LOG_GPS(DBG_LOW, "Success to lbs_register_msgfwcb");
+ return NULL;
+
+}
+#endif
+
+void check_plugin_module(char *module_name)
+{
+ if (get_replay_enabled() == TRUE) {
+ strcpy(module_name, "replay");
+ LOG_GPS(DBG_LOW, "REPLAY_ENABELD is TRUE");
+ } else if (access(BRCM4752_PATH, F_OK) == 0 || access(BRCM47520_PATH, F_OK) == 0) {
+ strcpy(module_name, "brcm");
+ } else if (access(BRCM47511_PATH, F_OK) == 0) {
+ strcpy(module_name, "brcm-legacy");
+ } else if (access(CSR_PATH, F_OK) == 0) {
+ strcpy(module_name, "csr");
+ } else if (access(QCOM8x30_PATH, F_OK) == 0 ||
+ access(QCOM9x15_PATH, F_OK) == 0 || access(QCOM8974_PATH, F_OK) == 0 ||
+ access(QCOM8210_PATH, F_OK) == 0 || access(QCOM8226_PATH, F_OK) == 0) {
+ strcpy(module_name, "qcom");
+ } else {
+ strcpy(module_name, "replay");
+ }
+
+ LOG_GPS(DBG_LOW, "module name : %s", module_name);
+}
+
+static gps_server_t *_initialize_gps_data(void)
+{
+ g_gps_server = (gps_server_t *) malloc(sizeof(gps_server_t));
+ if (g_gps_server == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to alloc g_gps_server");
+ return NULL;
+ }
+ memset(g_gps_server, 0x00, sizeof(gps_server_t));
+
+ g_gps_server->session_state = GPS_SESSION_STOPPED;
+ g_gps_server->dnet_used = 0;
+ g_gps_server->logging_enabled = FALSE;
+ g_gps_server->replay_enabled = FALSE;
+#ifdef _TIZEN_PUBLIC_
+ g_gps_server->msg_thread = 0;
+ g_gps_server->popup_thread = 0;
+#endif
+
+ memset(&g_gps_server->gps_plugin, 0x00, sizeof(gps_plugin_handler_t));
+
+ if (g_gps_server->pos_data == NULL) {
+ g_gps_server->pos_data = (pos_data_t *) malloc(sizeof(pos_data_t));
+ if (g_gps_server->pos_data == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to alloc g_gps_server->pos_data");
+ return NULL;
+ } else {
+ memset(g_gps_server->pos_data, 0x00, sizeof(pos_data_t));
+ }
+ }
+
+ if (g_gps_server->batch_data == NULL) {
+ g_gps_server->batch_data = (batch_data_t *) malloc(sizeof(batch_data_t));
+ if (g_gps_server->batch_data == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to alloc g_gps_server->batch_data");
+ return NULL;
+ } else {
+ memset(g_gps_server->batch_data, 0x00, sizeof(batch_data_t));
+ }
+ }
+
+ if (g_gps_server->sv_data == NULL) {
+ g_gps_server->sv_data = (sv_data_t *) malloc(sizeof(sv_data_t));
+ if (g_gps_server->sv_data == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to alloc g_gps_server->sv_data");
+ return NULL;
+ } else {
+ memset(g_gps_server->sv_data, 0x00, sizeof(sv_data_t));
+ }
+ }
+
+ if (g_gps_server->nmea_data == NULL) {
+ g_gps_server->nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t));
+ if (g_gps_server->nmea_data == NULL) {
+ LOG_GPS(DBG_ERR, "Failed to alloc g_gps_server->nmea_data");
+ return NULL;
+ } else {
+ memset(g_gps_server->nmea_data, 0x00, sizeof(nmea_data_t));
+ }
+ }
+
+ return g_gps_server;
+}
+
+static void _deinitialize_gps_data(void)
+{
+ if (g_gps_server->pos_data != NULL) {
+ free(g_gps_server->pos_data);
+ g_gps_server->pos_data = NULL;
+ }
+
+ if (g_gps_server->batch_data != NULL) {
+ free(g_gps_server->batch_data);
+ g_gps_server->batch_data = NULL;
+ }
+
+ if (g_gps_server->sv_data != NULL) {
+ free(g_gps_server->sv_data);
+ g_gps_server->sv_data = NULL;
+ }
+
+ if (g_gps_server->nmea_data != NULL) {
+ if (g_gps_server->nmea_data->data != NULL) {
+ free(g_gps_server->nmea_data->data);
+ g_gps_server->nmea_data->data = NULL;
+ }
+ free(g_gps_server->nmea_data);
+ g_gps_server->nmea_data = NULL;
+ }
+
+ if (g_gps_server != NULL) {
+ free(g_gps_server);
+ g_gps_server = NULL;
+ }
+}
+
+int initialize_server(int argc, char **argv)
+{
+ FUNC_ENTRANCE_SERVER;
+
+ gps_server_t *server;
+ char module_name[16];
+
+ server = _initialize_gps_data();
+ if (server == NULL)
+ return -1;
+ check_plugin_module(module_name);
+ _gps_plugin_handler_init(server, module_name);
+ _gps_get_nmea_replay_mode(server);
+ _gps_notify_params(server);
+
+ if (!load_plugin_module(server->gps_plugin.name, &server->gps_plugin.handle)) {
+ LOG_GPS(DBG_ERR, "Fail to load plugin module.");
+ return -1;
+ }
+
+ if (!get_plugin_module()->init(_gps_server_gps_event_cb, (void *)server)) {
+ LOG_GPS(DBG_WARN, "Fail to gps module initialization");
+ return -1;
+ }
+
+#ifdef _TIZEN_PUBLIC_
+ if (pthread_create(&g_gps_server->msg_thread, NULL, _gps_register_msgfwcb, g_gps_server) != 0) {
+ LOG_GPS(DBG_WARN, "Can not make pthread......");
+ }
+#endif
+
+ LOG_GPS(DBG_LOW, "Initialization-gps is completed.");
+
+ if (!nps_load_plugin_module(&g_nps_plugin.handle)) {
+ LOG_NPS(DBG_ERR, "Fail to load lbs_server_NPS plugin module.");
+ __nps_plugin_handler_deinit();
+ return 0; /* TBD: how to deal with this error situation */
+ }
+
+ LOG_NPS(DBG_LOW, "Initialization-nps is completed.");
+
+ return 0;
+}
+
+int deinitialize_server()
+{
+ gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL;
+
+#ifdef _TIZEN_PUBLIC_
+ pthread_join(g_gps_server->msg_thread, (void *)&g_gps_server->msg_thread_status);
+#endif
+
+ _gps_ignore_params();
+
+ if (!get_plugin_module()->deinit(&ReasonCode)) {
+ LOG_GPS(DBG_WARN, "Fail to gps module de-initialization");
+ }
+ unload_plugin_module(g_gps_server->gps_plugin.handle);
+
+ _gps_plugin_handler_deinit(g_gps_server);
+ _deinitialize_gps_data();
+
+ nps_unload_plugin_module(g_nps_plugin.handle);
+ __nps_plugin_handler_deinit();
+
+ return 0;
+}
+
+int register_update_callbacks(struct gps_callbacks *gps_callback, void *user_data)
+{
+ g_update_cb = *gps_callback;
+ g_user_data = user_data;
+ return 0;
+}
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 _SERVER_H_
+#define _SERVER_H_
+
+#include "lbs_server.h"
+
+#define SUPL_SERVER_URL_DEFAULT "your.supl-server.com"
+#define SUPL_SERVER_PORT_DEFAULT 7275
+
+//This structure must be synchronized with State of mctxlDef.h
+typedef enum {
+ GPS_STATE_AVAILABLE,
+ GPS_STATE_OUT_OF_SERVICE,
+ GPS_STATE_TEMPORARILY_UNAVAILABLE,
+} gps_state_t;
+
+typedef enum {
+ GPS_SESSION_STOPPED,
+ GPS_SESSION_STARTING,
+ GPS_SESSION_STARTED,
+ GPS_SESSION_STOPPING,
+} gps_session_state_t;
+
+typedef enum {
+ AGPS_VERIFICATION_YES = 0x00, /**< Specifies Confirmation yes. */
+ AGPS_VERIFICATION_NO = 0x01, /**< Specifies Confirmation no. */
+ AGPS_VERIFICATION_NORESPONSE = 0x02, /**< Specifies Confirmation no response. */
+} agps_verification_t;
+
+typedef enum {
+ GPS_MAIN_NOTIFY_NO_VERIFY = 0x00,
+ GPS_MAIN_NOTIFY_ONLY = 0x01,
+ GPS_MAIN_NOTIFY_ALLOW_NORESPONSE = 0x02,
+ GPS_MAIN_NOTIFY_NOTALLOW_NORESPONSE = 0x03,
+ GPS_MAIN_NOTIFY_PRIVACY_NEEDED = 0x04,
+ GPS_MAIN_NOTIFY_PRIVACY_OVERRIDE = 0x05,
+} gps_main_notify_type_t;
+
+typedef struct {
+ char requester_name[50]; /**< Specifies Requester name*/
+ char client_name[50]; /**< Specifies Client name */
+} gps_main_verif_info_t;
+
+typedef struct {
+ void *msg_body;
+ int msg_size;
+} gps_ni_data_t;
+
+int initialize_server(int argc, char **argv);
+int deinitialize_server();
+
+int request_change_pos_update_interval_standalone_gps(unsigned int interval);
+int request_start_batch_session(int batch_interval, int batch_period);
+int request_stop_batch_session(void);
+int request_start_session(int interval);
+int request_stop_session(void);
+#ifndef _TIZEN_PUBLIC_
+int request_supl_ni_session(const char *header, const char *body, int size);
+#endif
+int register_update_callbacks(struct gps_callbacks *gps_callback, void *user_data);
+
+int request_add_geofence(int fence_id, double latitude, double longitude, int radius, int last_state, int monitor_states, int notification_responsiveness, int unknown_timer);
+int request_delete_geofence(int fence_id);
+int request_pause_geofence(int fence_id);
+int request_resume_geofence(int fence_id, int monitor_states);
+int request_delete_gps_data(void);
+
+#endif /* _SERVER_H_ */
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 "setting.h"
+#include "debug_util.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <wifi.h>
+#include <unistd.h>
+
+int setting_set_int(const char *path, int val)
+{
+ int ret = vconf_set_int(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "vconf_set_int failed, [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+int setting_get_int(const char *path, int *val)
+{
+ int ret = vconf_get_int(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "vconf_get_int failed, [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+int setting_set_double(const char *path, double val)
+{
+ int ret = vconf_set_dbl(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "vconf_set_dbl 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_GPS(DBG_ERR, "vconf_get_int failed, [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+int setting_set_string(const char *path, const char *val)
+{
+ int ret = vconf_set_str(path, val);
+ if (ret == 0) {
+ ret = TRUE;
+ } else {
+ LOG_GPS(DBG_ERR, "vconf_set_str 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, void *data)
+{
+ int ret = TRUE;
+ if (vconf_notify_key_changed(path, key_changed_cb, data) != 0) {
+ LOG_GPS(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_GPS(DBG_ERR, "Fail to vconf_ignore_key_changed [%s]", path);
+ ret = FALSE;
+ }
+ return ret;
+}
+
+
+static unsigned char _get_mac_address(char *mac)
+{
+ int rv = 0;
+ char *mac_addr = NULL;
+
+ rv = wifi_get_mac_address(&mac_addr);
+ if (rv != WIFI_ERROR_NONE)
+ return FALSE;
+
+ g_strlcpy(mac, mac_addr, NPS_UNIQUE_ID_LEN);
+ g_free(mac_addr);
+
+ return TRUE;
+}
+
+static unsigned char _get_device_name(char *device_name)
+{
+ char *ret_str;
+
+ ret_str = vconf_get_str(VCONFKEY_SETAPPL_DEVICE_NAME_STR);
+ if(ret_str == NULL) {
+ return FALSE;
+ }
+
+ memcpy(device_name, ret_str, strlen(ret_str)+1);
+
+ return TRUE;
+}
+
+/*
+Basic : Use BT address
+BT Address : 12 digits (1234567890AB)
+UNIQUEID : X X X 4 0 X 1 6 X 7 5 X 2 8 X A B 3 9
+X: Model Name
+
+Alternative 1: Use WiFi MAC Address
+Cause : We can get local address and name only when bluetooth is on.
+MAC Address : 17 digits
+UNIQUEID : X X X 4 0 X 1 6 X 7 5 X 2 8 X A B 3 9
+X: Device Name (We can't get the model name, setting is using system string.)
+*/
+unsigned char setting_get_unique_id(char *unique_id)
+{
+ char *mac_addr;
+ char *device_name;
+
+ mac_addr = g_malloc0(NPS_UNIQUE_ID_LEN);
+ if (!_get_mac_address(mac_addr)) {
+ g_free(mac_addr);
+ return FALSE;
+ }
+
+ device_name = g_malloc0(NPS_UNIQUE_ID_LEN);
+ if (!_get_device_name(device_name)) {
+ g_free(mac_addr);
+ g_free(device_name);
+ return FALSE;
+ }
+
+ snprintf(unique_id, NPS_UNIQUE_ID_LEN, "%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X%1.X",
+ device_name[0]&0xF, device_name[1]&0xF, device_name[2]&0xF, mac_addr[3]&0xF,
+ mac_addr[9]&0xF, device_name[3]&0xF, mac_addr[0]&0xF, mac_addr[5]&0xF,
+ device_name[4]&0xF, mac_addr[6]&0xF, mac_addr[4]&0xF, device_name[5]&0xF,
+ mac_addr[1]&0xF, mac_addr[7]&0xF, device_name[6]&0xF, mac_addr[9]&0xF,
+ mac_addr[10]&0xF, mac_addr[2]&0xF, mac_addr[8]&0xF);
+ g_free(mac_addr);
+ g_free(device_name);
+
+ return TRUE;
+}
+
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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>
+
+#include <glib.h>
+
+#define NPS_UNIQUE_ID_LEN (20)
+
+//#define NPS_MANAGER_PLUGIN_PATH "/usr/lib/libSLP-nps-plugin.so"
+
+typedef enum {
+ POSITION_OFF = 0,
+ POSITION_SEARCHING,
+ POSITION_CONNECTED,
+ POSITION_MAX
+} pos_state_t;
+
+int setting_set_int(const char *path, int val);
+int setting_get_int(const char *path, int *val);
+int setting_set_double(const char *path, double val);
+int setting_get_double(const char *path, double *val);
+int setting_set_string(const char *path, const char *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, void *data);
+int setting_ignore_key_changed(const char *path, void *key_changed_cb);
+
+unsigned char setting_get_unique_id(char *unique_id);
+
+#endif /* _SETTING_H_ */
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
--- /dev/null
+pkgdir = $(libdir)/location/module
+if WPS
+pkg_LTLIBRARIES = libgps.la libwps.la
+else
+pkg_LTLIBRARIES = libgps.la
+endif
+
+libgps_la_SOURCES = gps_module.c
+libgps_la_CFLAGS = \
+ -D_GNU_SOURCE \
+ -fPIC\
+ $(MODULE_CFLAGS)
+libgps_la_LIBADD = \
+ -lm\
+ -ldl\
+ $(MODULE_LIBS)
+
+libwps_la_SOURCES = nps_module.c
+libwps_la_CFLAGS = \
+ -D_GNU_SOURCE \
+ -fPIC\
+ $(MODULE_CFLAGS)
+libwps_la_LIBADD = \
+ -lm\
+ -ldl\
+ $(MODULE_LIBS)
+
+
--- /dev/null
+/*
+ * lbs-server
+ *
+ * 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 <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <vconf.h>
+#include <vconf-internal-location-keys.h>
+#include <location-module.h>
+
+#include <dlfcn.h>
+#include <lbs_dbus_client.h>
+#include <lbs_agps.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+
+#define MAX_GPS_LOC_ITEM 7
+
+typedef struct {
+ lbs_client_dbus_h lbs_client;
+ LocModStatusCB status_cb;
+ LocModPositionExtCB pos_cb;
+ LocModBatchExtCB batch_cb;
+ LocModSatelliteCB sat_cb;
+ gpointer userdata;
+ gboolean is_started;
+} GpsManagerData;
+
+static void status_callback(GVariant *param, void *user_data)
+{
+ GpsManagerData *gps_manager = (GpsManagerData *) user_data;
+ g_return_if_fail(param);
+ g_return_if_fail(gps_manager);
+ g_return_if_fail(gps_manager->status_cb);
+
+ int status = 0, method = 0;
+
+ g_variant_get (param, "(ii)", &method, &status);
+
+ MOD_LOGD("method(%d) status(%d)", method, status);
+
+ if (method != LBS_CLIENT_METHOD_GPS) return;
+
+ if (status == 3) { //TODO: LBS_STATUS_AVAILABLE ?
+ MOD_LOGD("LBS_STATUS_AVAILABLE");
+ gps_manager->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gps_manager->userdata);
+ }
+ else {
+ MOD_LOGD("LBS_STATUS_ACQUIRING/ERROR/UNAVAILABLE. Status[%d]", status);
+ gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
+ }
+}
+
+static void satellite_callback(GVariant *param, void *user_data)
+{
+ GpsManagerData *gps_manager = (GpsManagerData *)user_data;
+ g_return_if_fail(gps_manager);
+ g_return_if_fail(gps_manager->sat_cb);
+
+ guint idx;
+ guint used_idx;
+ guint *used_prn_array = NULL;
+ gboolean ret = FALSE;
+ int timestamp = 0, satellite_used = 0, satellite_visible = 0;
+
+ LocationSatellite *sat = NULL;
+ GVariant *used_prn = NULL;
+ GVariantIter *used_prn_iter = NULL;
+ GVariant *sat_info = NULL;
+ GVariantIter *sat_iter = NULL;
+ int prn = 0, elev = 0, azim = 0, snr = 0;
+
+ g_variant_get(param, "(iii@ai@a(iiii))", ×tamp, &satellite_used, &satellite_visible, &used_prn, &sat_info);
+ g_variant_get(used_prn, "ai", &used_prn_iter);
+ g_variant_get(sat_info, "a(iiii)", &sat_iter);
+ MOD_LOGD("timestamp [%d], satellite_used [%d], satellite_visible[%d]", timestamp, satellite_used, satellite_visible);
+ int tmp_prn = 0;
+ int num_of_used_prn = g_variant_iter_n_children (used_prn_iter);
+ if (num_of_used_prn > 0) {
+ used_prn_array = (guint *)g_new0(guint, num_of_used_prn);
+ for (idx = 0; idx < num_of_used_prn; idx++) {
+ ret = g_variant_iter_next(used_prn_iter, "i", &tmp_prn);
+ if (ret == FALSE)
+ break;
+ used_prn_array[idx] = tmp_prn;
+ }
+ }
+ sat = location_satellite_new(satellite_visible);
+
+ sat->timestamp = timestamp;
+ sat->num_of_sat_inview = satellite_visible;
+ sat->num_of_sat_used = satellite_used;
+
+ GVariant *tmp_var = NULL;
+ for (idx = 0; idx < satellite_visible; idx++) {
+ gboolean used = FALSE;
+ tmp_var = g_variant_iter_next_value (sat_iter);
+ g_variant_get (tmp_var, "(iiii)", &prn, &elev, &azim, &snr);
+ if (used_prn_array != NULL) {
+ for (used_idx = 0; used_idx < satellite_used; used_idx++) {
+ if (prn == used_prn_array[used_idx]) {
+ used = TRUE;
+ break;
+ }
+ }
+ }
+ //MOD_LOGD("prn[%d] : used %d elev %d azim %d snr %d", prn, used, elev, azim, snr);
+ location_satellite_set_satellite_details(sat, idx, prn, used, elev, azim, snr);
+ g_variant_unref(tmp_var);
+ }
+
+ gps_manager->sat_cb(TRUE, sat, gps_manager->userdata);
+ location_satellite_free(sat);
+ g_variant_iter_free(used_prn_iter);
+ g_variant_iter_free(sat_iter);
+ g_variant_unref(used_prn);
+ g_variant_unref(sat_info);
+
+
+ if (used_prn_array) {
+ g_free(used_prn_array);
+ used_prn_array = NULL;
+ }
+}
+
+#if 0
+static void nmea_callback(GeoclueNmea * nmea, int timestamp, char *data, gpointer userdata)
+{
+}
+#endif
+
+static void position_callback(GVariant *param, void *user_data)
+{
+ MOD_LOGD("position_callback");
+ GpsManagerData *gps_manager = (GpsManagerData *)user_data;
+ g_return_if_fail(gps_manager);
+ g_return_if_fail(gps_manager->pos_cb);
+
+ int method = 0, fields = 0 ,timestamp = 0 , level = 0;
+ double latitude = 0.0, longitude = 0.0, altitude = 0.0, speed = 0.0, direction = 0.0, climb = 0.0, horizontal = 0.0, vertical = 0.0;
+ GVariant *accuracy = NULL;
+
+ g_variant_get(param, "(iiidddddd@(idd))", &method, &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
+
+ if(method != LBS_CLIENT_METHOD_GPS)
+ return;
+
+ g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
+
+ LocationPosition *pos = NULL;
+ LocationVelocity *vel = NULL;
+ LocationAccuracy *acc = NULL;
+
+ pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
+
+ vel = location_velocity_new(timestamp, speed, direction, climb);
+
+ acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
+
+ gps_manager->pos_cb(TRUE, pos, vel, acc, gps_manager->userdata);
+
+ location_position_free(pos);
+ location_velocity_free(vel);
+ location_accuracy_free(acc);
+ g_variant_unref(accuracy);
+}
+
+static void batch_callback(GVariant *param, void *user_data)
+{
+ MOD_LOGE("batch_callback");
+ GpsManagerData *gps_manager = (GpsManagerData *)user_data;
+ g_return_if_fail(gps_manager);
+ g_return_if_fail(gps_manager->batch_cb);
+
+ int num_of_location = 0;
+ g_variant_get (param, "(i)", &num_of_location);
+
+ gps_manager->batch_cb(TRUE, num_of_location, gps_manager->userdata);
+}
+
+static void on_signal_batch_callback(const gchar *sig, GVariant *param, gpointer user_data)
+{
+ if (!g_strcmp0(sig, "BatchChanged")) {
+ MOD_LOGE("BatchChanged");
+ batch_callback(param, user_data);
+ }
+ else {
+ MOD_LOGD("Invaild signal[%s]", sig);
+ }
+}
+
+static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
+{
+ if (!g_strcmp0(sig, "SatelliteChanged")) {
+ MOD_LOGD("SatelliteChanged");
+ satellite_callback(param, user_data);
+ }
+ else if (!g_strcmp0(sig, "PositionChanged")) {
+ MOD_LOGD("PositionChanged");
+ position_callback(param, user_data);
+ }
+ else if (!g_strcmp0(sig, "StatusChanged")) {
+ MOD_LOGD("StatusChanged");
+ status_callback(param, user_data);
+ }
+ else {
+ MOD_LOGD("Invaild signal[%s]", sig);
+ }
+}
+
+static int start_batch(gpointer handle, LocModBatchExtCB batch_cb, guint batch_interval, guint batch_period, gpointer userdata)
+{
+ MOD_LOGD("start_batch");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(batch_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ gps_manager->batch_cb = batch_cb;
+ gps_manager->userdata = userdata;
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+
+ ret = lbs_client_create (LBS_CLIENT_METHOD_GPS , &(gps_manager->lbs_client));
+ if (ret != LBS_CLIENT_ERROR_NONE || !gps_manager->lbs_client) {
+ MOD_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ MOD_LOGE("gps-manger(%x)", gps_manager);
+ MOD_LOGE("batch (%x), user_data(%x)", gps_manager->batch_cb, gps_manager->userdata);
+
+ ret = lbs_client_start_batch (gps_manager->lbs_client, LBS_CLIENT_BATCH_CB, on_signal_batch_callback, batch_interval, batch_period, gps_manager);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
+ MOD_LOGE("Access denied[%d]", ret);
+ return LOCATION_ERROR_NOT_ALLOWED;
+ }
+ MOD_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
+ lbs_client_destroy(gps_manager->lbs_client);
+ gps_manager->lbs_client = NULL;
+
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int start(gpointer handle, guint pos_update_interval, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
+{
+ MOD_LOGD("start");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ gps_manager->status_cb = status_cb;
+ gps_manager->pos_cb = pos_cb;
+ gps_manager->sat_cb = sat_cb;
+ gps_manager->userdata = userdata;
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+ ret = lbs_client_create (LBS_CLIENT_METHOD_GPS , &(gps_manager->lbs_client));
+ if (ret != LBS_CLIENT_ERROR_NONE || !gps_manager->lbs_client) {
+ MOD_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ MOD_LOGD("gps-manger(%x)", gps_manager);
+ MOD_LOGD("pos_cb (%x), user_data(%x)", gps_manager->pos_cb, gps_manager->userdata);
+
+ ret = lbs_client_start (gps_manager->lbs_client, pos_update_interval, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_LOCATION_STATUS_CB | LBS_CLIENT_SATELLITE_CB, on_signal_callback, gps_manager);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
+ MOD_LOGE("Access denied[%d]", ret);
+ return LOCATION_ERROR_NOT_ALLOWED;
+ }
+ MOD_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
+ lbs_client_destroy(gps_manager->lbs_client);
+ gps_manager->lbs_client = NULL;
+
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int stop_batch(gpointer handle)
+{
+ MOD_LOGD("stop_batch");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+
+ ret = lbs_client_stop_batch (gps_manager->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to stop batch. Error[%d]", ret);
+ lbs_client_destroy(gps_manager->lbs_client);
+ gps_manager->lbs_client = NULL;
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ ret = lbs_client_destroy(gps_manager->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to destroy. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ gps_manager->lbs_client = NULL;
+ gps_manager->batch_cb = NULL;
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int stop(gpointer handle)
+{
+ MOD_LOGD("stop");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gps_manager->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gps_manager->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+
+ ret = lbs_client_stop (gps_manager->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to stop. Error[%d]", ret);
+ lbs_client_destroy(gps_manager->lbs_client);
+ gps_manager->lbs_client = NULL;
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ ret = lbs_client_destroy(gps_manager->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_LOGE("Fail to destroy. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ gps_manager->lbs_client = NULL;
+
+ if (gps_manager->status_cb) {
+ gps_manager->status_cb (FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata);
+ }
+
+ gps_manager->status_cb = NULL;
+ gps_manager->pos_cb = NULL;
+ gps_manager->sat_cb = NULL;
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int get_nmea(gpointer handle, gchar ** nmea_data)
+{
+ MOD_LOGD("get_nmea");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(nmea_data, LOCATION_ERROR_PARAMETER);
+
+ gboolean ret = FALSE;
+ int timestamp = 0;
+ ret = lbs_client_get_nmea(gps_manager->lbs_client, ×tamp, nmea_data);
+ if (ret) {
+ MOD_LOGE("\t Error getting nmea: %d", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int get_last_position(gpointer handle, LocationPosition ** position, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
+{
+ MOD_LOGD("get_last_position");
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
+
+ int timestamp = 0;
+ char location[128] = {0,};
+ char *last_location[MAX_GPS_LOC_ITEM] = {0,};
+ char *last = NULL;
+ char *str = NULL;
+ double longitude = 0.0, latitude = 0.0, altitude = 0.0;
+ double speed = 0.0, direction = 0.0;
+ double hor_accuracy = 0.0, ver_accuracy = 0.0;
+ int index = 0;
+ LocationStatus status = LOCATION_STATUS_NO_FIX;
+ LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
+
+ *position = NULL;
+ *velocity = NULL;
+ *accuracy = NULL;
+
+ if (vconf_get_int(VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP, ×tamp)) {
+ MOD_LOGD("Error to get VCONFKEY_LOCATION_LAST_GPS_TIMESTAMP");
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ } else {
+ if (timestamp != 0) {
+ if (vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LATITUDE, &latitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_LONGITUDE, &longitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_ALTITUDE, &altitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_SPEED, &speed) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_DIRECTION, &direction) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_HOR_ACCURACY, &hor_accuracy) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_GPS_VER_ACCURACY, &ver_accuracy)) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ } else {
+ if (vconf_get_int(VCONFKEY_LOCATION_NV_LAST_GPS_TIMESTAMP, ×tamp)) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ str = vconf_get_str(VCONFKEY_LOCATION_NV_LAST_GPS_LOCATION);
+ if (str == NULL) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ snprintf(location, sizeof(location), "%s", str);
+ free(str);
+
+ last_location[index] = (char *)strtok_r(location, ";", &last);
+ while (last_location[index++] != NULL) {
+ if (index == MAX_GPS_LOC_ITEM)
+ break;
+ last_location[index] = (char *)strtok_r(NULL, ";", &last);
+ }
+ if (index != MAX_GPS_LOC_ITEM) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ index = 0;
+
+ latitude = strtod(last_location[index++], NULL);
+ longitude = strtod(last_location[index++], NULL);
+ altitude = strtod(last_location[index++], NULL);
+ speed = strtod(last_location[index++], NULL);
+ direction = strtod(last_location[index++], NULL);
+ hor_accuracy = strtod(last_location[index++], NULL);
+ ver_accuracy = strtod(last_location[index], NULL);
+ }
+ }
+
+ if (timestamp) {
+ status = LOCATION_STATUS_3D_FIX;
+ } else {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ level = LOCATION_ACCURACY_LEVEL_DETAILED;
+ *position = location_position_new(timestamp, latitude, longitude, altitude, status);
+ *velocity = location_velocity_new ((guint) timestamp, speed, direction, 0.0);
+ *accuracy = location_accuracy_new(level, hor_accuracy, ver_accuracy);
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int set_option(gpointer handle, const char *option)
+{
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(option, LOCATION_ERROR_PARAMETER);
+ MOD_LOGD("set_option : %s", option);
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+ ret = lbs_set_option(option);
+ if (ret != LBS_AGPS_ERROR_NONE) {
+ MOD_LOGE("Fail to lbs_set_option [%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int set_position_update_interval(gpointer handle, guint interval) {
+ MOD_LOGD("set_position_update_interval [%d]", interval);
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(gps_manager->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
+
+ int ret;
+ ret = lbs_client_set_position_update_interval(gps_manager->lbs_client, interval);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
+ MOD_LOGE("Access denied[%d]", ret);
+ return LOCATION_ERROR_NOT_ALLOWED;
+ }
+ MOD_LOGE("Failed lbs_client_set_position_update_interval. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+LOCATION_MODULE_API gpointer init(LocModGpsOps * ops)
+{
+ MOD_LOGD("init");
+
+ g_return_val_if_fail(ops, NULL);
+ ops->start = start;
+ ops->start_batch = start_batch;
+ ops->stop = stop;
+ ops->stop_batch = stop_batch;
+ ops->get_last_position = get_last_position;
+ ops->set_option = set_option;
+ ops->set_position_update_interval = set_position_update_interval;
+
+ Dl_info info;
+ if (dladdr(&get_last_position, &info) == 0) {
+ MOD_LOGD("Failed to get module name");
+ } else if (g_strrstr(info.dli_fname, "gps")) {
+ ops->get_nmea = get_nmea;
+ }
+
+ GpsManagerData *gps_manager = g_new0(GpsManagerData, 1);
+ g_return_val_if_fail(gps_manager, NULL);
+
+ gps_manager->status_cb = NULL;
+ gps_manager->pos_cb = NULL;
+ gps_manager->batch_cb = NULL;
+ gps_manager->userdata = NULL;
+ gps_manager->is_started = FALSE;
+
+ return (gpointer) gps_manager;
+}
+
+LOCATION_MODULE_API void shutdown(gpointer handle)
+{
+ MOD_LOGD("shutdown");
+ g_return_if_fail(handle);
+ GpsManagerData *gps_manager = (GpsManagerData *) handle;
+ if (gps_manager->lbs_client) {
+ lbs_client_stop(gps_manager->lbs_client);
+ lbs_client_destroy(gps_manager->lbs_client);
+ gps_manager->lbs_client = NULL;
+ }
+
+ gps_manager->status_cb = NULL;
+ gps_manager->pos_cb = NULL;
+ gps_manager->batch_cb = NULL;
+ gps_manager->sat_cb = NULL;
+
+ g_free(gps_manager);
+ gps_manager = NULL;
+
+}
--- /dev/null
+/*
+ * gps-manager
+ *
+ * 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 __MOD_LOG_H__
+#define __MOD_LOG_H__
+
+#define TAG_LOCATION "LOCATION_GPS"
+
+#include <dlog.h>
+#define MOD_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_LOCATION, fmt, ##args)
+#define MOD_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_LOCATION, fmt, ##args)
+#define MOD_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_LOCATION, fmt, ##args)
+#define MOD_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_LOCATION, fmt, ##args)
+#define MOD_SECLOG(fmt,args...) SECURE_SLOG(LOG_DEBUG, TAG_LOCATION, fmt, ##args)
+
+#define TAG_MOD_NPS "LOCATION_NPS"
+
+#include <dlog.h>
+#define MOD_NPS_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_MOD_NPS, fmt, ##args)
+#define MOD_NPS_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_MOD_NPS, fmt, ##args)
+#define MOD_NPS_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_MOD_NPS, fmt, ##args)
+#define MOD_NPS_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_MOD_NPS, fmt, ##args)
+#define MOD_NPS_SECLOG(fmt,args...) SECURE_SLOG(LOG_DEBUG, TAG_MOD_NPS, fmt, ##args)
+
+
+#endif
--- /dev/null
+/*
+ * lbs-server
+ *
+ * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Youngae Kang <youngae.kang@samsung.com>, Dong Wei <d.wei@samsung.com>,
+ * Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>,
+ * Ming Zhu <mingwu.zhu@samsung.com>, Congyi Shi <congyi.shi@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 <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <vconf.h>
+#include <location-module.h>
+
+#include <lbs_dbus_client.h>
+#include <vconf-internal-location-keys.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "log.h"
+
+#define MAX_NPS_LOC_ITEM 6
+
+typedef struct {
+ lbs_client_dbus_h lbs_client;
+ gpointer userdata;
+ LocModStatusCB status_cb;
+ LocModPositionExtCB pos_cb;
+ gboolean is_started;
+} ModNpsData;
+
+static void status_callback(GVariant *param, void *user_data)
+{
+ ModNpsData *mod_nps = (ModNpsData *) user_data;
+ g_return_if_fail(mod_nps);
+ g_return_if_fail(param);
+ g_return_if_fail(mod_nps->status_cb);
+
+ int status = 0, method = 0;
+
+ g_variant_get (param, "(ii)", &method, &status);
+
+ MOD_NPS_LOGD("method(%d) status(%d)", method, status);
+
+ if(method != LBS_CLIENT_METHOD_NPS) return;
+
+ if (status == 3) { //TODO: LBS_STATUS_AVAILABLE ?
+ MOD_NPS_LOGD("LBS_STATUS_AVAILABLE");
+ mod_nps->status_cb(TRUE, LOCATION_STATUS_2D_FIX, mod_nps->userdata);
+ }
+ else {
+ MOD_NPS_LOGD("LBS_STATUS_ACQUIRING/ERROR/UNAVAILABLE");
+ mod_nps->status_cb(FALSE, LOCATION_STATUS_NO_FIX, mod_nps->userdata);
+ }
+}
+
+static void position_callback(GVariant *param, void *user_data)
+{
+
+ MOD_NPS_LOGD("position_callback");
+ ModNpsData *mod_nps = (ModNpsData *)user_data;
+ g_return_if_fail(mod_nps);
+ g_return_if_fail(mod_nps->pos_cb);
+
+ int method = 0, fields = 0 ,timestamp = 0 , level = 0;
+ double latitude = 0.0, longitude = 0.0, altitude = 0.0, speed = 0.0, direction = 0.0, climb = 0.0, horizontal = 0.0, vertical = 0.0;
+ GVariant *accuracy = NULL;
+
+ g_variant_get(param, "(iiidddddd@(idd))", &method, &fields, ×tamp, &latitude, &longitude, &altitude, &speed, &direction, &climb, &accuracy);
+
+ if(method != LBS_CLIENT_METHOD_NPS)
+ return;
+
+ g_variant_get(accuracy, "(idd)", &level, &horizontal, &vertical);
+
+ LocationPosition *pos = NULL;
+ LocationVelocity *vel = NULL;
+ LocationAccuracy *acc = NULL;
+
+ if (altitude) {
+ pos = location_position_new(timestamp, latitude, longitude, altitude, LOCATION_STATUS_3D_FIX);
+ } else {
+ pos = location_position_new(timestamp, latitude, longitude, 0.0, LOCATION_STATUS_2D_FIX);
+ }
+
+ vel = location_velocity_new(timestamp, speed, direction, climb);
+ acc = location_accuracy_new(LOCATION_ACCURACY_LEVEL_DETAILED, horizontal, vertical);
+ MOD_NPS_LOGD("time(%d)", pos->timestamp);
+ MOD_NPS_LOGD("method(%d)", method);
+
+ mod_nps->pos_cb(TRUE, pos, vel, acc, mod_nps->userdata);
+
+ location_position_free(pos);
+ location_velocity_free(vel);
+ location_accuracy_free(acc);
+
+}
+
+static void on_signal_callback(const gchar *sig, GVariant *param, gpointer user_data)
+{
+ if (!g_strcmp0(sig, "PositionChanged")) {
+ MOD_NPS_LOGD("PositionChanged");
+ position_callback(param, user_data);
+ }
+ else if (!g_strcmp0(sig, "StatusChanged")) {
+ MOD_NPS_LOGD("StatusChanged");
+ status_callback(param, user_data);
+ }
+ else {
+ MOD_NPS_LOGD("Invaild signal[%s]", sig);
+ }
+
+}
+
+static int start(gpointer handle, LocModStatusCB status_cb, LocModPositionExtCB pos_cb, LocModSatelliteCB sat_cb, gpointer userdata)
+{
+ MOD_NPS_LOGD("start");
+ ModNpsData *mod_nps = (ModNpsData *) handle;
+ g_return_val_if_fail(mod_nps, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(pos_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ mod_nps->status_cb = status_cb;
+ mod_nps->pos_cb = pos_cb;
+ mod_nps->userdata = userdata;
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+ ret = lbs_client_create (LBS_CLIENT_METHOD_NPS, &(mod_nps->lbs_client));
+ if (ret != LBS_CLIENT_ERROR_NONE || !mod_nps->lbs_client) {
+ MOD_NPS_LOGE("Fail to create lbs_client_h. Error[%d]", ret);
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ ret = lbs_client_start (mod_nps->lbs_client, 1, LBS_CLIENT_LOCATION_CB | LBS_CLIENT_LOCATION_STATUS_CB, on_signal_callback, mod_nps);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ if (ret == LBS_CLIENT_ERROR_ACCESS_DENIED) {
+ MOD_NPS_LOGE("Access denied[%d]", ret);
+ return LOCATION_ERROR_NOT_ALLOWED;
+ }
+
+ MOD_NPS_LOGE("Fail to start lbs_client_h. Error[%d]", ret);
+ lbs_client_destroy(mod_nps->lbs_client);
+ mod_nps->lbs_client = NULL;
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int stop(gpointer handle)
+{
+ MOD_NPS_LOGD("stop");
+ ModNpsData *mod_nps = (ModNpsData *) handle;
+ g_return_val_if_fail(mod_nps, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(mod_nps->lbs_client, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(mod_nps->status_cb, LOCATION_ERROR_NOT_AVAILABLE);
+
+ int ret = LBS_CLIENT_ERROR_NONE;
+
+ ret = lbs_client_stop (mod_nps->lbs_client);
+ if (ret != LBS_CLIENT_ERROR_NONE) {
+ MOD_NPS_LOGE("Fail to stop. Error[%d]", ret);
+ lbs_client_destroy(mod_nps->lbs_client);
+ mod_nps->lbs_client = NULL;
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ lbs_client_destroy(mod_nps->lbs_client);
+ mod_nps->lbs_client = NULL;
+
+ if (mod_nps->status_cb) {
+ mod_nps->status_cb (FALSE, LOCATION_STATUS_NO_FIX, mod_nps->userdata);
+ }
+
+ mod_nps->status_cb = NULL;
+ mod_nps->pos_cb = NULL;
+
+ return LOCATION_ERROR_NONE;
+}
+
+static int get_last_position(gpointer handle, LocationPosition ** position, LocationVelocity ** velocity, LocationAccuracy ** accuracy)
+{
+ MOD_NPS_LOGD("get_last_position");
+ ModNpsData *mod_nps = (ModNpsData *) handle;
+ g_return_val_if_fail(mod_nps, LOCATION_ERROR_NOT_AVAILABLE);
+ g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER);
+ g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER);
+
+ int timestamp = 0;
+ char location[128] = {0,};
+ char *last_location[MAX_NPS_LOC_ITEM] = {0,};
+ char *last = NULL;
+ char *str = NULL;
+ double latitude = 0.0, longitude = 0.0, altitude = 0.0;
+ double speed = 0.0, direction = 0.0;
+ double hor_accuracy = 0.0;
+ int index = 0;
+ LocationStatus status = LOCATION_STATUS_NO_FIX;
+ LocationAccuracyLevel level = LOCATION_ACCURACY_LEVEL_NONE;
+
+ *position = NULL;
+ *velocity = NULL;
+ *accuracy = NULL;
+
+ if (vconf_get_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, ×tamp)) {
+ MOD_NPS_LOGD("Error to get VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP");
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ } else {
+ if (timestamp != 0) {
+ if (vconf_get_int(VCONFKEY_LOCATION_LAST_WPS_TIMESTAMP, ×tamp) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_LATITUDE, &latitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_LONGITUDE, &longitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_ALTITUDE, &altitude) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_SPEED, &speed) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_DIRECTION, &direction) ||
+ vconf_get_dbl(VCONFKEY_LOCATION_LAST_WPS_HOR_ACCURACY, &hor_accuracy)) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ } else {
+ if (vconf_get_int(VCONFKEY_LOCATION_NV_LAST_WPS_TIMESTAMP, ×tamp)) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ str = vconf_get_str(VCONFKEY_LOCATION_NV_LAST_WPS_LOCATION);
+ if (str == NULL) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ snprintf(location, sizeof(location), "%s", str);
+ free(str);
+
+ last_location[index] = (char *)strtok_r(location, ";", &last);
+ while (last_location[index++] != NULL) {
+ if (index == MAX_NPS_LOC_ITEM)
+ break;
+ last_location[index] = (char *)strtok_r(NULL, ";", &last);
+ }
+ if (index != MAX_NPS_LOC_ITEM) {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+ index = 0;
+ latitude = strtod(last_location[index++], NULL);
+ longitude = strtod(last_location[index++], NULL);
+ altitude = strtod(last_location[index++], NULL);
+ speed = strtod(last_location[index++], NULL);
+ direction = strtod(last_location[index++], NULL);
+ hor_accuracy = strtod(last_location[index], NULL);
+ }
+ }
+
+ level = LOCATION_ACCURACY_LEVEL_STREET;
+ if (timestamp) {
+ status = LOCATION_STATUS_3D_FIX;
+ } else {
+ return LOCATION_ERROR_NOT_AVAILABLE;
+ }
+
+ *position = location_position_new((guint) timestamp, latitude, longitude, altitude, status);
+ *velocity = location_velocity_new((guint) timestamp, speed, direction, 0.0);
+ *accuracy = location_accuracy_new(level, hor_accuracy, -1.0);
+
+ return LOCATION_ERROR_NONE;
+}
+
+LOCATION_MODULE_API gpointer init(LocModWpsOps * ops)
+{
+ MOD_NPS_LOGD("init");
+ g_return_val_if_fail(ops, NULL);
+ ops->start = start;
+ ops->stop = stop;
+ ops->get_last_position = get_last_position;
+
+ ModNpsData *mod_nps = g_new0(ModNpsData, 1);
+ g_return_val_if_fail(mod_nps, NULL);
+
+ mod_nps->userdata = NULL;
+ mod_nps->status_cb = NULL;
+ mod_nps->pos_cb = NULL;
+ mod_nps->is_started = FALSE;
+
+ return mod_nps;
+}
+
+LOCATION_MODULE_API void shutdown(gpointer handle)
+{
+ MOD_NPS_LOGD("shutdown");
+ ModNpsData *mod_nps = (ModNpsData *) handle;
+ g_return_if_fail(mod_nps);
+
+ if (mod_nps->lbs_client) {
+ if (mod_nps->is_started) {
+ lbs_client_stop(mod_nps->lbs_client);
+ }
+ lbs_client_destroy(mod_nps->lbs_client);
+ mod_nps->lbs_client = NULL;
+ }
+
+ mod_nps->status_cb = NULL;
+ mod_nps->pos_cb = NULL;
+
+ g_free(mod_nps);
+ mod_nps = NULL;
+}
--- /dev/null
+[Unit]
+Description=lbs server daemon
+After=tizen-runtime.target
+Requires=tizen-runtime.target
+
+[Service]
+Type=forking
+ExecStart=/etc/rc.d/rc5.d/S90lbs-server
+MemoryLimit=10M
+
+[Install]
+WantedBy=multi-user.target
--- /dev/null
+Name: lbs-server
+Summary: lbs server for Tizen
+Version: 0.6.0
+Release: 1
+Group: TO_BE/FILLED_IN
+License: TO_BE/FILLED_IN
+Source0: %{name}-%{version}.tar.gz
+Source1: lbs-server.service
+BuildRequires: model-build-features
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(network)
+BuildRequires: pkgconfig(tapi)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(location)
+BuildRequires: pkgconfig(lbs-dbus)
+BuildRequires: pkgconfig(gio-unix-2.0)
+BuildRequires: pkgconfig(capi-network-wifi)
+#%if "%{_repository}" == "wearable“
+#BuildRequires: pkgconfig(journal)
+#BuildRequires: pkgconfig(libresourced)
+#BuildRequires: pkgconfig(capi-appfw-app-manager)
+#BuildRequires: pkgconfig(deviced)
+#%endif
+Requires: sys-assert
+
+%description
+lbs server for Tizen
+
+
+%package -n location-lbs-server
+Summary: lbs server for Tizen
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n location-lbs-server
+lbs server for Tizen
+
+
+%package -n lbs-server-plugin-devel
+Summary: lbs server for Tizen (development files)
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+
+%description -n lbs-server-plugin-devel
+lbs server for Tizen (development files)
+
+
+%prep
+%setup -q
+
+%ifarch %{arm}
+%define GPS_ENABLER --enable-gps
+%define ARCH armel
+%else
+%define GPS_ENABLER --enable-gps
+%define ARCH x86
+%endif
+
+%if 0%{?model_build_feature_location_position_wps}
+%define WPS_ENABLER --enable-wps=yes
+%else
+%define WPS_ENABLER --enable-wps=no
+%endif
+
+%build
+#export CFLAGS="$CFLAGS -D_TIZEN_PUBLIC_"
+
+#%if "%{_repository}" == "wearable“
+#export CFLAGS="$CFLAGS -DTIZEN_WEARABLE"
+#%endif
+
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+
+./autogen.sh
+./configure --prefix=%{_prefix} %{GPS_ENABLER} %{WPS_ENABLER} \
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
+install -m 644 %{SOURCE1} %{buildroot}/usr/lib/systemd/system/lbs-server.service
+ln -s ../lbs-server.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/lbs-server.service
+
+%define GPS_DUMP_DIR /opt/etc/dump.d/module.d
+
+mkdir -p %{buildroot}/%{GPS_DUMP_DIR}
+cp -a lbs-server/script/dump_gps.sh %{buildroot}/%{GPS_DUMP_DIR}/dump_gps.sh
+
+%clean
+rm -rf %{buildroot}
+
+
+%post
+#GPS Indicator value
+vconftool set -t int memory/location/position/state "0" -i -s location_fw::vconf
+vconftool set -t int memory/location/gps/state "0" -i -s location_fw::vconf
+vconftool set -t int memory/location/wps/state "0" -i -s location_fw::vconf
+
+#NMEA_SETTING
+vconftool set -t int db/location/nmea/LoggingEnabled "0" -f -s location_fw::vconf -u 5000
+
+#REPLAY_SETTING
+vconftool set -t string db/location/replay/FileName "nmea_replay.log" -f -s location_fw::vconf -u 5000
+%ifarch %arm
+ vconftool set -t int db/location/replay/ReplayEnabled "0" -f -s location_fw::vconf -u 5000
+ vconftool set -t int db/location/replay/ReplayMode "1" -f -s location_fw::vconf -u 5000
+%else
+ vconftool set -t int db/location/replay/ReplayEnabled "1" -f -s location_fw::vconf -u 5000
+ vconftool set -t int db/location/replay/ReplayMode "0" -f -s location_fw::vconf -u 5000
+%endif
+vconftool set -t double db/location/replay/ManualLatitude "0.0" -f -s location_fw::vconf -u 5000
+vconftool set -t double db/location/replay/ManualLongitude "0.0" -f -s location_fw::vconf -u 5000
+vconftool set -t double db/location/replay/ManualAltitude "0.0" -f -s location_fw::vconf -u 5000
+vconftool set -t double db/location/replay/ManualHAccuracy "0.0" -f -s location_fw::vconf -u 5000
+
+%post -n location-lbs-server
+#%ifnarch %arm
+# cp -f /usr/lib/location/module/libgps.so /usr/lib/location/module/libwps0.so
+#%endif
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest lbs-server.manifest
+%defattr(-,root,root,-)
+/usr/libexec/lbs-server
+/usr/share/dbus-1/services/org.tizen.lbs.Providers.LbsServer.service
+/usr/share/lbs/lbs-server.provider
+/etc/rc.d/init.d/lbs-server
+/etc/rc.d/rc5.d/S90lbs-server
+/usr/lib/systemd/system/lbs-server.service
+/usr/lib/systemd/system/multi-user.target.wants/lbs-server.service
+/opt/etc/dump.d/module.d/dump_gps.sh
+#%if "%{_repository}" == "wearable“
+#/usr/share/packages/com.samsung.lbs-server.xml
+#%endif
+
+%files -n location-lbs-server
+%manifest location-lbs-server.manifest
+%defattr(-,root,root,-)
+%{_libdir}/location/module/libgps.so*
+
+%if 0%{?model_build_feature_location_position_wps}
+%{_libdir}/location/module/libwps.so*
+%endif
+
+%files -n lbs-server-plugin-devel
+%defattr(-,root,root,-)
+#%if "%{_repository}" == "wearable“
+%{_libdir}/location/module/*.so
+#%endif
+%{_libdir}/pkgconfig/lbs-server-plugin.pc
+%{_includedir}/lbs-server-plugin/*.h