From: jk7744.park Date: Sat, 31 Jan 2015 07:34:46 +0000 (+0900) Subject: tizen 2.3 release X-Git-Tag: submit/tizen_2.3/20150202.062329^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1597971403006a96f8abe1791207d5228b729f4;p=framework%2Flocation%2Flbs-server.git tizen 2.3 release --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..01fda69 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Youngae Kang +Minjune Kim +Genie Kim diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9c13a9b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..5b90d7d --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = . lbs-server module diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..798eba2 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,6 @@ +aclocal +libtoolize --copy +autoheader +autoconf +automake --add-missing --copy --foreign + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..328f058 --- /dev/null +++ b/configure.ac @@ -0,0 +1,123 @@ +# -*- 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 diff --git a/lbs-server.manifest b/lbs-server.manifest new file mode 100644 index 0000000..b1aa770 --- /dev/null +++ b/lbs-server.manifest @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lbs-server/Makefile.am b/lbs-server/Makefile.am new file mode 100644 index 0000000..38cb077 --- /dev/null +++ b/lbs-server/Makefile.am @@ -0,0 +1,76 @@ +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) + diff --git a/lbs-server/data_connection.c b/lbs-server/data_connection.c new file mode 100644 index 0000000..f4cfddd --- /dev/null +++ b/lbs-server/data_connection.c @@ -0,0 +1,354 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "data_connection.h" +#include +#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; +} diff --git a/lbs-server/data_connection.h b/lbs-server/data_connection.h new file mode 100644 index 0000000..a98f6f6 --- /dev/null +++ b/lbs-server/data_connection.h @@ -0,0 +1,39 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 + +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 diff --git a/lbs-server/debug_util.h b/lbs-server/debug_util.h new file mode 100644 index 0000000..cd3b059 --- /dev/null +++ b/lbs-server/debug_util.h @@ -0,0 +1,55 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#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_ */ diff --git a/lbs-server/dump_log.c b/lbs-server/dump_log.c new file mode 100644 index 0000000..6f171c4 --- /dev/null +++ b/lbs-server/dump_log.c @@ -0,0 +1,102 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include +#include +#include + +#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); + } +} diff --git a/lbs-server/dump_log.h b/lbs-server/dump_log.h new file mode 100644 index 0000000..1bc5fa9 --- /dev/null +++ b/lbs-server/dump_log.h @@ -0,0 +1,33 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 + +void gps_init_log(); + +void gps_deinit_log(); + +void gps_dump_log(const char *str, const char *app_id); + +#endif /* _DUMP_LOG_H_ */ diff --git a/lbs-server/gps_plugin_module.c b/lbs-server/gps_plugin_module.c new file mode 100644 index 0000000..0217f9e --- /dev/null +++ b/lbs-server/gps_plugin_module.c @@ -0,0 +1,96 @@ +/* + * lbs_server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include +#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; +} diff --git a/lbs-server/gps_plugin_module.h b/lbs-server/gps_plugin_module.h new file mode 100644 index 0000000..62a675c --- /dev/null +++ b/lbs-server/gps_plugin_module.h @@ -0,0 +1,31 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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_ */ diff --git a/lbs-server/include/gps_plugin_data_types.h b/lbs-server/include/gps_plugin_data_types.h new file mode 100644 index 0000000..b3f5013 --- /dev/null +++ b/lbs-server/include/gps_plugin_data_types.h @@ -0,0 +1,145 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include + +#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_ */ diff --git a/lbs-server/include/gps_plugin_extra_data_types.h b/lbs-server/include/gps_plugin_extra_data_types.h new file mode 100644 index 0000000..f815489 --- /dev/null +++ b/lbs-server/include/gps_plugin_extra_data_types.h @@ -0,0 +1,109 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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_ */ diff --git a/lbs-server/include/gps_plugin_intf.h b/lbs-server/include/gps_plugin_intf.h new file mode 100644 index 0000000..9b8dd3a --- /dev/null +++ b/lbs-server/include/gps_plugin_intf.h @@ -0,0 +1,458 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include + +#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_ */ diff --git a/lbs-server/include/nps_plugin_intf.h b/lbs-server/include/nps_plugin_intf.h new file mode 100644 index 0000000..8344fce --- /dev/null +++ b/lbs-server/include/nps_plugin_intf.h @@ -0,0 +1,72 @@ +/* + * lbs-server + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Youngae Kang , + * Genie Kim , Minjune Kim , + * Ming Zhu + * + * 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_ */ + diff --git a/lbs-server/last_position.c b/lbs-server/last_position.c new file mode 100644 index 0000000..442d76c --- /dev/null +++ b/lbs-server/last_position.c @@ -0,0 +1,118 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include + +#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); +} diff --git a/lbs-server/last_position.h b/lbs-server/last_position.h new file mode 100644 index 0000000..b0ff36c --- /dev/null +++ b/lbs-server/last_position.h @@ -0,0 +1,33 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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_ */ diff --git a/lbs-server/lbs-server-plugin.pc.in b/lbs-server/lbs-server-plugin.pc.in new file mode 100644 index 0000000..d0a6940 --- /dev/null +++ b/lbs-server/lbs-server-plugin.pc.in @@ -0,0 +1,10 @@ +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 diff --git a/lbs-server/lbs-server.provider b/lbs-server/lbs-server.provider new file mode 100644 index 0000000..82bd337 --- /dev/null +++ b/lbs-server/lbs-server.provider @@ -0,0 +1,8 @@ +[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 diff --git a/lbs-server/lbs_server.c b/lbs-server/lbs_server.c new file mode 100755 index 0000000..1d86e2c --- /dev/null +++ b/lbs-server/lbs_server.c @@ -0,0 +1,1507 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include "setting.h" +#include +#ifdef TIZEN_WEARABLE +#include +#include +#include +#include +#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; +} diff --git a/lbs-server/lbs_server.h b/lbs-server/lbs_server.h new file mode 100755 index 0000000..4984e91 --- /dev/null +++ b/lbs-server/lbs_server.h @@ -0,0 +1,177 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include + +#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 diff --git a/lbs-server/lbs_server.provider b/lbs-server/lbs_server.provider new file mode 100644 index 0000000..82bd337 --- /dev/null +++ b/lbs-server/lbs_server.provider @@ -0,0 +1,8 @@ +[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 diff --git a/lbs-server/nmea_logger.c b/lbs-server/nmea_logger.c new file mode 100644 index 0000000..51b960f --- /dev/null +++ b/lbs-server/nmea_logger.c @@ -0,0 +1,138 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#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; +} diff --git a/lbs-server/nmea_logger.h b/lbs-server/nmea_logger.h new file mode 100644 index 0000000..f9132c8 --- /dev/null +++ b/lbs-server/nmea_logger.h @@ -0,0 +1,34 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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_ */ diff --git a/lbs-server/nps_plugin_module.c b/lbs-server/nps_plugin_module.c new file mode 100644 index 0000000..9d6f372 --- /dev/null +++ b/lbs-server/nps_plugin_module.c @@ -0,0 +1,161 @@ +/* + * lbs-server + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Youngae Kang , Dong Wei , + * Genie Kim , Minjune Kim , + * Ming Zhu , Congyi Shi + * + * 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 +#include +#include +#include +#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."); +} diff --git a/lbs-server/nps_plugin_module.h b/lbs-server/nps_plugin_module.h new file mode 100644 index 0000000..3428a9b --- /dev/null +++ b/lbs-server/nps_plugin_module.h @@ -0,0 +1,34 @@ +/* + * lbs-server + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Youngae Kang , Dong Wei , + * Genie Kim , Minjune Kim , + * Ming Zhu , Congyi Shi + * + * 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_ */ diff --git a/lbs-server/org.tizen.lbs.Providers.LbsServer.service.in b/lbs-server/org.tizen.lbs.Providers.LbsServer.service.in new file mode 100644 index 0000000..8e70293 --- /dev/null +++ b/lbs-server/org.tizen.lbs.Providers.LbsServer.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.tizen.lbs.Providers.LbsServer +Exec=@libexecdir@/lbs-server diff --git a/lbs-server/script/dump_gps.sh b/lbs-server/script/dump_gps.sh new file mode 100755 index 0000000..ee1b6c9 --- /dev/null +++ b/lbs-server/script/dump_gps.sh @@ -0,0 +1,14 @@ +#!/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 diff --git a/lbs-server/script/dump_lbs.sh b/lbs-server/script/dump_lbs.sh new file mode 100755 index 0000000..b49613c --- /dev/null +++ b/lbs-server/script/dump_lbs.sh @@ -0,0 +1,14 @@ +#!/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 diff --git a/lbs-server/script/lbs-server b/lbs-server/script/lbs-server new file mode 100644 index 0000000..c262f88 --- /dev/null +++ b/lbs-server/script/lbs-server @@ -0,0 +1,11 @@ +#!/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 diff --git a/lbs-server/server.c b/lbs-server/server.c new file mode 100644 index 0000000..68dc399 --- /dev/null +++ b/lbs-server/server.c @@ -0,0 +1,1270 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#endif + +#include +#include +#include + +#include +#include +#if !GLIB_CHECK_VERSION (2, 31, 0) +#include +#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; +} diff --git a/lbs-server/server.h b/lbs-server/server.h new file mode 100644 index 0000000..c5a6272 --- /dev/null +++ b/lbs-server/server.h @@ -0,0 +1,88 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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_ */ diff --git a/lbs-server/setting.c b/lbs-server/setting.c new file mode 100644 index 0000000..24ea520 --- /dev/null +++ b/lbs-server/setting.c @@ -0,0 +1,187 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include "setting.h" +#include "debug_util.h" + +#include +#include +#include +#include + +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; +} + diff --git a/lbs-server/setting.h b/lbs-server/setting.h new file mode 100644 index 0000000..4f4991a --- /dev/null +++ b/lbs-server/setting.h @@ -0,0 +1,55 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include + +#include + +#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_ */ diff --git a/location-lbs-server.manifest b/location-lbs-server.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/location-lbs-server.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/module/Makefile.am b/module/Makefile.am new file mode 100644 index 0000000..e2548ed --- /dev/null +++ b/module/Makefile.am @@ -0,0 +1,28 @@ +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) + + diff --git a/module/gps_module.c b/module/gps_module.c new file mode 100755 index 0000000..3b5832a --- /dev/null +++ b/module/gps_module.c @@ -0,0 +1,563 @@ +/* + * lbs-server + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#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; + +} diff --git a/module/log.h b/module/log.h new file mode 100644 index 0000000..c3c3df0 --- /dev/null +++ b/module/log.h @@ -0,0 +1,44 @@ +/* + * gps-manager + * + * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Minjune Kim + * Genie Kim + * + * 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 +#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 +#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 diff --git a/module/nps_module.c b/module/nps_module.c new file mode 100644 index 0000000..1273e5e --- /dev/null +++ b/module/nps_module.c @@ -0,0 +1,319 @@ +/* + * lbs-server + * + * Copyright (c) 2010-2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Youngae Kang , Dong Wei , + * Genie Kim , Minjune Kim , + * Ming Zhu , Congyi Shi + * + * 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 +#include +#include + +#include +#include + +#include +#include + +#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; +} diff --git a/packaging/lbs-server.service b/packaging/lbs-server.service new file mode 100644 index 0000000..e99c8f5 --- /dev/null +++ b/packaging/lbs-server.service @@ -0,0 +1,12 @@ +[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 diff --git a/packaging/lbs-server.spec b/packaging/lbs-server.spec new file mode 100644 index 0000000..8cb84df --- /dev/null +++ b/packaging/lbs-server.spec @@ -0,0 +1,159 @@ +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