From: Kibum Kim Date: Mon, 27 Feb 2012 12:16:14 +0000 (+0900) Subject: tizen beta release X-Git-Tag: 2.0_release~1 X-Git-Url: http://review.tizen.org/git/?p=framework%2Flocation%2Fgps-manager.git;a=commitdiff_plain;h=07f8a3869c835f984c59345da26556755a2825ea tizen beta release --- 07f8a3869c835f984c59345da26556755a2825ea diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..cc7be1c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Youngae Kang +Yunhan 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..c2ed9d0 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,2 @@ +ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = . gps-manager module \ No newline at end of file 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..8d25d28 --- /dev/null +++ b/configure.ac @@ -0,0 +1,103 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.61) +AC_INIT([gps-manager], [0.1]) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE([foreign -Wall -Werror]) +AC_CONFIG_SRCDIR([gps-manager/gps_manager.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 dbus-glib-1 >= 0.60 geoclue network tapi vconf heynoti sysman msg-service gthread-2.0 dlog pmapi]) +AC_SUBST(PRIVIDERS_CFLAGS) +AC_SUBST(PROVIDERS_LIBS) + +PKG_CHECK_MODULES(MODULE, [glib-2.0 gmodule-2.0 geoclue location dlog]) +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]) + +# 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 +gps-manager/Makefile +gps-manager/gps-manager-plugin.pc +module/Makefile +]) + +AC_OUTPUT diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..702cc2b --- /dev/null +++ b/debian/changelog @@ -0,0 +1,63 @@ +gps-manager (0.1.4-2) unstable; urgency=low + + * Fix a crash while init WPS module on emulator + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.4-2 + + -- Minjune Kim Mon, 20 Feb 2012 22:36:47 +0900 + +gps-manager (0.1.4-1) unstable; urgency=low + + * change indicator state to using gps and wps + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.4-1 + + -- Minjune Kim Fri, 17 Feb 2012 17:08:22 +0900 + +gps-manager (0.1.3-2) unstable; urgency=low + + * add qcom plugin in script + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.3-2 + + -- Genie Kim Thu, 16 Feb 2012 11:18:58 +0900 + +gps-manager (0.1.3-1) unstable; urgency=low + + * fixed bug at snprintf + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.3-1 + + -- Genie Kim Mon, 13 Feb 2012 12:37:29 +0900 + +gps-manager (0.1.2-1) unstable; urgency=low + + * adjust replay plugin + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.2-1 + + -- Genie Kim Wed, 01 Feb 2012 16:30:55 +0900 + +gps-manager (0.1.1-0) unstable; urgency=low + + * add last position and change setting key path + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.1-0 + + -- Genie Kim Thu, 26 Jan 2012 17:30:31 +0900 + +gps-manager (0.1.0-1) unstable; urgency=low + + * Refactor source code. + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.0-1 + + -- Yunhan Kim Wed, 21 Dec 2011 17:01:05 +0900 + +gps-manager (0.1.0-0) unstable; urgency=low + + * Initial release + * Git: pkgs/g/gps-manager + * Tag: gps-manager_0.1.0-0 + + -- Yunhan Kim Thu, 06 Oct 2011 14:41:51 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..b9e87fe --- /dev/null +++ b/debian/control @@ -0,0 +1,29 @@ +Source: gps-manager +Section: devel +Priority: extra +Maintainer: Youngae Kang , Yunhan Kim , Minjune Kim , Genie Kim +Build-Depends: debhelper (>= 4.0.0), autotools-dev, libslp-tapi-dev, libnetwork-dev, libslp-setting-dev, libglib2.0-dev, libdbus-glib-1-dev, dlog-dev, libslp-msg-service-dev, libslp-pm-dev, libheynoti-dev, libslp-sysman-dev, libgeoclue-dev, libslp-location-dev + +Package: gps-manager +Section: net +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libslp-tapi-0, libnetwork-0, libslp-setting-0, libglib2.0-0, libdlog-0, libslp-msg-service-0, libslp-pm-0, libheynoti-0, libslp-sysman +Description: GPS Manager for SLP + +Package: location-gps-manager +Section: libs +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gps-manager (= ${binary:Version}) +Description: libslp-location module for gps-manager + +Package: gps-manager-plugin-dev +Section: libdevel +Architecture: any +Depends: dlog-dev +Description: Development packages for gps-manager plugin (Development Headers) + +Package: gps-manager-dbg +Section: debug +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, gps-manager (= ${binary:Version}), location-gps-manager (= ${binary:Version}) +Description: Debug packages for gps-manager, location-gps-manager (Unstripped binary) diff --git a/debian/docs b/debian/docs new file mode 100644 index 0000000..e69de29 diff --git a/debian/gps-manager-plugin-dev.install.in b/debian/gps-manager-plugin-dev.install.in new file mode 100644 index 0000000..4a8577d --- /dev/null +++ b/debian/gps-manager-plugin-dev.install.in @@ -0,0 +1,2 @@ +debian/tmp@PREFIX@/include/gps-manager-plugin/*.h +debian/tmp@PREFIX@/lib/pkgconfig/gps-manager-plugin.pc diff --git a/debian/gps-manager.install.in b/debian/gps-manager.install.in new file mode 100644 index 0000000..fdb41ba --- /dev/null +++ b/debian/gps-manager.install.in @@ -0,0 +1,7 @@ +debian/tmp@PREFIX@/libexec/gps-manager +debian/tmp@PREFIX@/share/dbus-1/services/org.freedesktop.Geoclue.Providers.GpsManager.service +debian/tmp@PREFIX@/share/geoclue-providers/gps-manager.provider +debian/tmp@PREFIX@/etc/dbus-1/system.d/Geoclue.conf +debian/tmp/etc/rc.d/init.d/gps-manager +debian/tmp/etc/rc.d/rc3.d/S90gps-manager +debian/tmp/etc/rc.d/rc5.d/S90gps-manager diff --git a/debian/gps-manager.postinst b/debian/gps-manager.postinst new file mode 100644 index 0000000..fb5a453 --- /dev/null +++ b/debian/gps-manager.postinst @@ -0,0 +1,42 @@ +#!/bin/sh + +if [ "${USER}" = "root" ] +then +#Change File owner + #Executable file + chown root:root /etc/rc.d/init.d/gps-manager + chown root:root /etc/rc.d/rc3.d/S90gps-manager + chown root:root /etc/rc.d/rc5.d/S90gps-manager +#Change File Permission + #Executable file + chmod 700 /etc/rc.d/init.d/gps-manager + chmod 700 /etc/rc.d/rc3.d/S90gps-manager + chmod 700 /etc/rc.d/rc5.d/S90gps-manager +fi + +#GPS Indicator value +vconftool set -t int memory/gps/state 0 -i +vconftool set -t int memory/wps/state 0 -i + +#GPS_SETTING +vconftool set -t int db/location/gps/Operation "1" -f +vconftool set -t int db/location/gps/Starting "0" -f +vconftool set -t int db/location/gps/Session "1" -f + +#SUPL_SETTING +vconftool set -t string db/location/supl/Server "your.supl-server.com" -f +vconftool set -t int db/location/supl/Port "7275" -f +vconftool set -t int db/location/supl/SslEnabled "1" -f + +#NMEA_SETTING +vconftool set -t int db/location/nmea/LoggingEnabled "0" -f + +#REPLAY_SETTING +vconftool set -t string db/location/replay/FileName "nmea_replay.log" -f +vconftool set -t int db/location/replay/ReplayEnabled "0" -f +vconftool set -t int db/location/replay/ReplayMode "1" -f +vconftool set -t double db/location/replay/ManualLatitude "0.0" -f +vconftool set -t double db/location/replay/ManualLongitude "0.0" -f +vconftool set -t double db/location/replay/ManualAltitude "0.0" -f + +sync diff --git a/debian/location-gps-manager.install.in b/debian/location-gps-manager.install.in new file mode 100644 index 0000000..56aef35 --- /dev/null +++ b/debian/location-gps-manager.install.in @@ -0,0 +1 @@ +debian/tmp@PREFIX@/lib/location/module/libgps.so* diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..b84999d --- /dev/null +++ b/debian/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) + +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) +DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH) + +ifneq (,$(findstring armel,$(DEB_HOST_ARCH))) + GPS_ENABLER ?= --enable-gps +else + GPS_ENABLER ?= --disable-gps +endif + +#CFLAGS ?= -Wall -g +#LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /usr/share +DESTDIR ?= $(CURDIR)/debian/tmp + +#CFLAGS += -O0 +CFLAGS += -O0 -fvisibility=hidden -Wall -fPIC -g +CXXFLAGS += -O0 -fvisibility=hidden -Wall -fPIC -g +#LDFLAGS += -Wl,--as-needed -Wl,--hash-style=both + +#ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) +# CFLAGS += -O0 +#else +# CFLAGS += -O2 +#endif +#ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS))) +# CFLAGS += -g +#endif + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + ./autogen.sh + mkdir -p build + cd build && CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" ../configure --prefix=$(PREFIX) --datadir=$(DATADIR) $(GPS_ENABLER) + + touch $@ + +build: build-stamp +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + mkdir -p build + cd build && $(MAKE) + #docbook-to-man debian/ncurses.sgml > ncurses.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + mkdir -p build + cd build + -$(MAKE) clean + -$(MAKE) distclean + cd .. +#ifneq "$(wildcard /usr/share/misc/config.sub)" "" +# cp -f /usr/share/misc/config.sub config.sub +#endif +#ifneq "$(wildcard /usr/share/misc/config.guess)" "" +# cp -f /usr/share/misc/config.guess config.guess +#endif + + for f in `find $(CURDIR)/debian -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + find $(CURDIR) -name "Makefile.in" -exec rm -f {} \; + + rm -rf build build-aux m4 configure config.h.in configure aclocal.m4 + dh_clean + +install: build + dh_testdir + dh_testroot +# dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/ncurses. + mkdir -p build + cd build && $(MAKE) DESTDIR=$(DESTDIR) install + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs + dh_installdocs + dh_installexamples + dh_install #--sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link +# dh_strip + dh_strip --dbg-package=gps-manager-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/gps-manager/Geoclue.conf.in b/gps-manager/Geoclue.conf.in new file mode 100644 index 0000000..1088399 --- /dev/null +++ b/gps-manager/Geoclue.conf.in @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gps-manager/Makefile.am b/gps-manager/Makefile.am new file mode 100644 index 0000000..0574414 --- /dev/null +++ b/gps-manager/Makefile.am @@ -0,0 +1,75 @@ +libexec_PROGRAMS = gps-manager + +gps_manager_SOURCES = gps_manager.c \ + server.c \ + data_connection.c \ + nmea_logger.c \ + plugin_module.c \ + last_position.c \ + setting.c + +gps_manager_CFLAGS = -Wall -fPIC -fvisibility=hidden \ + -DEXPORT_API="__attribute__((visibility(\"default\")))" \ + -I$(srcdir)/include \ + $(PROVIDERS_CFLAGS) + +gps_manager_LDFLAGS = -Wl,--hash-style=both -Wl,--as-needed -Wl,-rpath=/usr/lib + +gps_manager_DEPENDENCIES = + +gps_manager_LDADD = $(gps_manager_DEPENDENCIES) \ + $(PROVIDERS_LIBS) \ + -ldl \ + -lm + +gps_manager_plugin_hdr_intfdir = $(includedir)/gps-manager-plugin + +gps_manager_plugin_hdr_intf_HEADERS = \ + include/gps_manager_plugin_intf.h \ + include/gps_manager_data_types.h \ + include/gps_manager_extra_data_types.h + +PCFILES = gps-manager-plugin.pc +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = $(PCFILES) + +providersdir = $(datadir)/geoclue-providers +providers_DATA = gps-manager.provider + +servicedir = $(DBUS_SERVICES_DIR) +service_in_files = org.freedesktop.Geoclue.Providers.GpsManager.service.in +service_DATA = $(service_in_files:.service.in=.service) + +$(service_DATA): $(service_in_files) Makefile + @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + +confdir = $(DBUS_CONF_DIR) +conf_in_files = Geoclue.conf.in +conf_DATA = $(conf_in_files:.conf.in=.conf) + +$(conf_DATA): $(conf_in_files) + cp $< $@ + +EXTRA_DIST = $(PCFILES).in \ + $(service_in_files) \ + $(providers_DATA) \ + $(conf_in_files) + +DISTCLEANFILES = $(service_DATA) \ + $(conf_DATA) + +GPS_MANAGER = gps-manager +bootdir = /etc/rc.d/init.d +boot_SCRIPTS = script/$(GPS_MANAGER) + +RC3_SCRIPT = $(DESTDIR)/etc/rc.d/rc3.d/S90gps-manager +RC5_SCRIPT = $(DESTDIR)/etc/rc.d/rc5.d/S90gps-manager + +install-exec-hook: + mkdir -p $(DESTDIR)/etc/rc.d/rc3.d + mkdir -p $(DESTDIR)/etc/rc.d/rc5.d + ln -sf ../init.d/$(GPS_MANAGER) $(RC3_SCRIPT) + ln -sf ../init.d/$(GPS_MANAGER) $(RC5_SCRIPT) + +uninstall-hook: + rm -f $(RC3_SCRIPT) $(RC5_SCRIPT) diff --git a/gps-manager/data_connection.c b/gps-manager/data_connection.c new file mode 100644 index 0000000..f02058f --- /dev/null +++ b/gps-manager/data_connection.c @@ -0,0 +1,371 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "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); + + unsigned char *ip = + (unsigned char *)&prof_info->ProfileInfo.Pdp.net_info.IpAddr.Data.Ipv4.s_addr; + unsigned char *dns1 = (unsigned char *)&net_info->DnsAddr[0].Data.Ipv4.s_addr; + unsigned char *dns2 = (unsigned char *)&net_info->DnsAddr[0].Data.Ipv4.s_addr; + + strncpy(profile_name, net_info->ProfileName, NET_PROFILE_NAME_LEN_MAX); + + LOG_GPS(DBG_LOW, "= IP address %d.%d.%d.%d\n", (int)ip[0], ip[1], ip[2], ip[3]); + LOG_GPS(DBG_LOW, "= DNS address %d.%d.%d.%d\n", (int)dns1[0], dns1[1], dns1[2], dns1[3]); + LOG_GPS(DBG_LOW, "= DNS2 address %d.%d.%d.%d\n", (int)dns2[0], dns2[1], dns2[2], dns2[3]); + LOG_GPS(DBG_LOW, "= Device name %s\n", net_info->DevName); + LOG_GPS(DBG_LOW, "= Profile name %s\n", profile_name); + + 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; + char *temp = NULL; + struct hostent *he; + + LOG_GPS(DBG_LOW, "query_dns::url:%s\n", pdns_lookup_addr); + + 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) { + temp = (char *)&g_ipaddr; + temp[0] = he->h_addr_list[0][0]; + temp[1] = he->h_addr_list[0][1]; + temp[2] = he->h_addr_list[0][2]; + temp[3] = he->h_addr_list[0][3]; + + LOG_GPS(DBG_LOW, "-> %u.%u.%u.%u\n", (unsigned char)temp[0], (unsigned char)temp[1], (unsigned char)temp[2], + (unsigned char)temp[3]); + 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; + read(*noti_pipe_fds, &activation, sizeof(int)); + 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/gps-manager/data_connection.h b/gps-manager/data_connection.h new file mode 100644 index 0000000..1aad1e0 --- /dev/null +++ b/gps-manager/data_connection.h @@ -0,0 +1,39 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_DATA_CONNECTION_H_ +#define _GPS_MANAGER_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/gps-manager/debug_util.h b/gps-manager/debug_util.h new file mode 100644 index 0000000..4bc5502 --- /dev/null +++ b/gps-manager/debug_util.h @@ -0,0 +1,59 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_DEBUG_UTIL_H_ +#define _GPS_MANAGER_DEBUG_UTIL_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPS_MANAGER_DLOG +#define LBS_DLOG_DEBUG // filename and line number will be shown + +#ifdef GPS_MANAGER_DLOG +#include +#define TAG_GPS_MANAGER "gps-manager" + +#define DBG_LOW LOG_DEBUG +#define DBG_INFO LOG_INFO +#define DBG_WARN LOG_WARN +#define DBG_ERR LOG_ERROR + +#ifdef LBS_DLOG_DEBUG // Debug mode +#define LOG_GPS(dbg_lvl,fmt,args...) SLOG(dbg_lvl, TAG_GPS_MANAGER, "[%-24s: %-4d] "fmt, basename(__FILE__), __LINE__, ##args) +#define FUNC_ENTRANCE_SERVER LOG_GPS(DBG_LOW, "[%s] Entered!!\n", __func__); +#else // Release(commercial) mode +#define LOG_GPS(dbg_lvl,fmt,args...) SLOG(dbg_lvl, TAG_GPS_MANAGER, fmt, ##args) +#define FUNC_ENTRANCE_SERVER +#endif +#else // No dlog +#define LOG_GPS(dbg_lvl,fmt,args...) g_debug("[%-24s: %-4d] "fmt, basename(__FILE__), __LINE__, ##args) +#define FUNC_ENTRANCE_SERVER g_debug("[%s] Entered!!\n", __func__); +#endif + +#ifdef __cplusplus +} +#endif +#endif /* _GPS_MANAGER_DEBUG_UTIL_H_ */ diff --git a/gps-manager/gps-manager-plugin.pc.in b/gps-manager/gps-manager-plugin.pc.in new file mode 100644 index 0000000..75703e0 --- /dev/null +++ b/gps-manager/gps-manager-plugin.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=${prefix}/lib +includedir=${prefix}/include + +Name: gps-manager-plugin +Description: gps-manager plugin +Requires: vconf dlog +Version: @VERSION@ +Cflags: -I${includedir} -I${includedir}/gps-manager-plugin diff --git a/gps-manager/gps-manager.provider b/gps-manager/gps-manager.provider new file mode 100644 index 0000000..135f857 --- /dev/null +++ b/gps-manager/gps-manager.provider @@ -0,0 +1,8 @@ +[Geoclue Provider] +Name=Agps +Service=org.freedesktop.Geoclue.Providers.GpsManager +Path=/org/freedesktop/Geoclue/Providers/GpsManager +Requires=RequiresGPS +Provides=ProvidesUpdates +Accuracy=Detailed +Interfaces=org.freedesktop.Geoclue.Position;org.freedesktop.Geoclue.Velocity;org.freedesktop.Geoclue.Nmea;org.freedesktop.Geoclue.Satellite diff --git a/gps-manager/gps_manager.c b/gps-manager/gps_manager.c new file mode 100644 index 0000000..4687f4a --- /dev/null +++ b/gps-manager/gps_manager.c @@ -0,0 +1,592 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "gps_manager_data_types.h" +#include "gps_manager.h" + +#include "server.h" + +#define GEOCLUE_GPSMANAGER_DBUS_SERVICE "org.freedesktop.Geoclue.Providers.GpsManager" +#define GEOCLUE_GPSMANAGER_DBUS_PATH "/org/freedesktop/Geoclue/Providers/GpsManager" + +typedef struct { + GcProvider parent; + GMainLoop *loop; + + GeoclueStatus status; + pos_data_t position; + sv_data_t satellite; + nmea_data_t nmea; + + GHashTable *connections; +} GeoclueGpsManager; + +typedef struct { + GcProviderClass parent_class; +} GeoclueGpsManagerClass; + +#define GEOCLUE_TYPE_GPSMANAGER (geoclue_gpsmanager_get_type ()) +#define GEOCLUE_GPSMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSMANAGER, GeoclueGpsManager)) + +static void init_position(GcIfacePositionClass * iface); +static void init_velocity(GcIfaceVelocityClass * iface); +static void init_nmea(GcIfaceNmeaClass * iface); +static void init_satellite(GcIfaceSatelliteClass * iface); +static void init_geoclue(GcIfaceGeoclueClass * iface); + +G_DEFINE_TYPE_WITH_CODE(GeoclueGpsManager, geoclue_gpsmanager, GC_TYPE_PROVIDER, + G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_POSITION, init_position) + G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_VELOCITY, init_velocity) + G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_NMEA, init_nmea) + G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_SATELLITE, init_satellite) + G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE, init_geoclue)); + +static void constructed(GObject * object) +{ + GeoclueGpsManager *gps_manager = GEOCLUE_GPSMANAGER(object); + + gps_manager->connections = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + + gps_manager->status = GEOCLUE_STATUS_UNAVAILABLE; + + memset(&gps_manager->position, 0x00, sizeof(pos_data_t)); + memset(&gps_manager->satellite, 0x00, sizeof(sv_data_t)); + memset(&gps_manager->nmea, 0x00, sizeof(nmea_data_t)); + + ((GObjectClass *) geoclue_gpsmanager_parent_class)->constructed(object); +} + +static void finalize(GObject * object) +{ + ((GObjectClass *) geoclue_gpsmanager_parent_class)->finalize(object); +} + +static void dispose(GObject * object) +{ + GeoclueGpsManager *gpsmanager = GEOCLUE_GPSMANAGER(object); + + g_hash_table_destroy(gpsmanager->connections); + + ((GObjectClass *) geoclue_gpsmanager_parent_class)->dispose(object); +} + +static gboolean get_status(GcIfaceGeoclue * gc, GeoclueStatus * status, GError ** error) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + + *status = gpsmanager->status; + + return TRUE; +} + +static gboolean get_provider_info(GcIfaceGeoclue * geoclue, gchar ** name, gchar ** description, GError ** error) +{ + if (name) { + *name = g_strdup("geoclue-gpsmanager"); + } + if (description) { + *description = g_strdup("Geoclue-gpsmanager"); + } + return TRUE; +} + +static void print_option(gpointer key, gpointer value, gpointer data) +{ + g_print(" %s - %s\n", (char *)key, (char *)value); +} + +static gboolean set_options(GcIfaceGeoclue * gc, GHashTable * options, GError ** error) +{ + g_print("Options received---\n"); + g_hash_table_foreach(options, print_option, NULL); + return TRUE; +} + +static void shutdown(GcProvider * provider) +{ + /* No shutdown!! */ +} + +static void start_tracking(GeoclueGpsManager * gpsmanager) +{ + gpsmanager->status = GEOCLUE_STATUS_ACQUIRING; + request_start_session(); +} + +static void stop_tracking(GeoclueGpsManager * gpsmanager) +{ + request_stop_session(); + gpsmanager->status = GEOCLUE_STATUS_UNAVAILABLE; +} + +static void update_position_cb(pos_data_t * pos, gps_error_t error, void *user_data) +{ + GeocluePositionFields fields; + GeoclueAccuracy *accuracy; + + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data)); + memcpy(&gpsmanager->position, pos, sizeof(pos_data_t)); + + gpsmanager->status = GEOCLUE_STATUS_AVAILABLE; + + fields = (GEOCLUE_POSITION_FIELDS_LATITUDE | GEOCLUE_POSITION_FIELDS_LONGITUDE | GEOCLUE_POSITION_FIELDS_ALTITUDE); + + accuracy = geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_DETAILED, pos->hor_accuracy, pos->ver_accuracy); + + gc_iface_position_emit_position_changed(GC_IFACE_POSITION(gpsmanager), + fields, pos->timestamp, pos->latitude, pos->longitude, pos->altitude, accuracy); + + fields = (GEOCLUE_VELOCITY_FIELDS_SPEED | GEOCLUE_VELOCITY_FIELDS_DIRECTION); + + gc_iface_velocity_emit_velocity_changed(GC_IFACE_VELOCITY(gpsmanager), + fields, pos->timestamp, pos->speed, pos->bearing, 0.0); + + geoclue_accuracy_free(accuracy); + + gc_iface_geoclue_emit_status_changed(GC_IFACE_GEOCLUE(gpsmanager), GEOCLUE_STATUS_AVAILABLE); +} + +static void update_satellite_cb(sv_data_t * sv, void *user_data) +{ + int index; + int timestamp = 0; + int satellite_used = 0; + GArray *used_prn; + GPtrArray *satellite_info; + + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data)); + memcpy(&gpsmanager->satellite, sv, sizeof(sv_data_t)); + + used_prn = g_array_new(FALSE, FALSE, sizeof(guint)); + for (index = 0; index < sv->num_of_sat; ++index) { + if (sv->sat[index].used) { + g_array_append_val(used_prn, sv->sat[index].prn); + ++satellite_used; + } + } + + satellite_info = g_ptr_array_new(); + + for (index = 0; index < sv->num_of_sat; ++index) { + GValue sv_info = { 0, }; + g_value_init(&sv_info, GEOCLUE_SATELLITE_INFO); + g_value_take_boxed(&sv_info, dbus_g_type_specialized_construct(GEOCLUE_SATELLITE_INFO)); + dbus_g_type_struct_set(&sv_info, + 0, sv->sat[index].prn, + 1, sv->sat[index].elevation, + 2, sv->sat[index].azimuth, 3, sv->sat[index].snr, G_MAXUINT); + g_ptr_array_add(satellite_info, g_value_get_boxed(&sv_info)); + } + + gc_iface_satellite_emit_satellite_changed(GC_IFACE_SATELLITE(gpsmanager), + timestamp, satellite_used, sv->num_of_sat, used_prn, satellite_info); + + g_array_free(used_prn, TRUE); + g_ptr_array_free(satellite_info, TRUE); +} + +static void update_nmea_cb(nmea_data_t * nmea, void *user_data) +{ + int timestamp = 0; + + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(user_data)); + + gpsmanager->nmea.data = g_malloc(nmea->len + 1); + g_memmove(gpsmanager->nmea.data, nmea->data, nmea->len); + gpsmanager->nmea.data[nmea->len] = '\0'; + + gc_iface_nmea_emit_nmea_changed(GC_IFACE_NMEA(gpsmanager), timestamp, gpsmanager->nmea.data); + + g_free(gpsmanager->nmea.data); +} + +static void add_reference(GcIfaceGeoclue * gc, DBusGMethodInvocation * context) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + char *sender; + int *pcount; + + sender = dbus_g_method_get_sender(context); + if (g_hash_table_size(gpsmanager->connections) == 0) { + start_tracking(gpsmanager); + } + pcount = g_hash_table_lookup(gpsmanager->connections, sender); + if (!pcount) { + pcount = g_malloc0(sizeof(int)); + g_hash_table_insert(gpsmanager->connections, sender, pcount); + } + (*pcount)++; + + g_debug("add_reference (%s) (%d)", sender, (*pcount)); + + dbus_g_method_return(context); +} + +static gboolean remove_client(GeoclueGpsManager * gpsmanager, const char *client) +{ + int *pcount; + + pcount = g_hash_table_lookup(gpsmanager->connections, client); + if (!pcount) { + return FALSE; + } + (*pcount)--; + if (*pcount == 0) { + g_hash_table_remove(gpsmanager->connections, client); + } + if (g_hash_table_size(gpsmanager->connections) == 0) { + g_debug("There is no connections!"); + stop_tracking(gpsmanager); + } + return TRUE; +} + +static gboolean remove_all_clients(GeoclueGpsManager * gpsmanager, const char *client) +{ + int *pcount; + + pcount = g_hash_table_lookup(gpsmanager->connections, client); + if (!pcount) { + return FALSE; + } + g_hash_table_remove(gpsmanager->connections, client); + if (g_hash_table_size(gpsmanager->connections) == 0) { + g_debug("There is no connections!"); + stop_tracking(gpsmanager); + } + return TRUE; +} + +static void remove_reference(GcIfaceGeoclue * gc, DBusGMethodInvocation * context) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + char *sender; + + sender = dbus_g_method_get_sender(context); + if (!remove_client(gpsmanager, sender)) { + g_warning("Unreffed by client taht has not been referenced"); + } + + g_free(sender); + + dbus_g_method_return(context); +} + +static void name_owner_changed(DBusGProxy * proxy, const char *name, const char *prev_owner, const char *new_owner, void *gc) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + g_debug("name_owner_changed, name:%s, prev_owner:%s, new_owner:%s", name, prev_owner, new_owner); + if (strcmp(new_owner, "") == 0 && strcmp(name, prev_owner) == 0) { + if (remove_all_clients(gpsmanager, prev_owner)) { + g_warning("Impolite client %s disconnected without unreferencing\n", prev_owner); + } + } +} + +static void geoclue_gpsmanager_class_init(GeoclueGpsManagerClass * klass) +{ + GObjectClass *o_class = (GObjectClass *) klass; + GcProviderClass *p_class = (GcProviderClass *) klass; + + o_class->constructed = constructed; + o_class->finalize = finalize; + o_class->dispose = dispose; + p_class->get_status = get_status; + p_class->set_options = set_options; + p_class->shutdown = shutdown; +} + +static void geoclue_gpsmanager_init(GeoclueGpsManager * gpsmanager) +{ + GError *error = NULL; + DBusGProxy *driver; + guint request_ret; + GcProvider *provider; + g_debug("geoclue_gpsmanager_init"); + + g_return_if_fail(GC_IS_PROVIDER(gpsmanager)); + provider = GC_PROVIDER(gpsmanager); + g_return_if_fail(provider->connection != NULL); + + driver = dbus_g_proxy_new_for_name(provider->connection, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + + if (!org_freedesktop_DBus_request_name(driver, GEOCLUE_GPSMANAGER_DBUS_SERVICE, 0, &request_ret, &error)) { + g_warning("%s was unable to register service %s: %s", + G_OBJECT_TYPE_NAME(provider), GEOCLUE_GPSMANAGER_DBUS_SERVICE, error->message); + g_error_free(error); + return; + } + + dbus_g_proxy_add_signal(driver, "NameOwnerChanged", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + + dbus_g_proxy_connect_signal(driver, "NameOwnerChanged", G_CALLBACK(name_owner_changed), provider, NULL); + + dbus_g_connection_register_g_object(provider->connection, GEOCLUE_GPSMANAGER_DBUS_PATH, G_OBJECT(provider)); +} + +static gboolean get_position(GcIfacePosition * gc, + GeocluePositionFields * fields, + int *timestamp, + double *latitude, + double *longitude, double *altitude, GeoclueAccuracy ** accuracy, GError ** error) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + + if (gpsmanager->status == GEOCLUE_STATUS_ACQUIRING) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_NOT_AVAILABLE, "ERROR: Acquiring"); + return FALSE; + } + + if (gpsmanager->status != GEOCLUE_STATUS_AVAILABLE) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available"); + return FALSE; + } + + if (!fields) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters"); + return FALSE; + } + + *fields = GEOCLUE_POSITION_FIELDS_NONE; + + if (timestamp) { + *timestamp = gpsmanager->position.timestamp; + } + + if (latitude) { + *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE; + *latitude = gpsmanager->position.latitude; + } + + if (longitude) { + *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE; + *longitude = gpsmanager->position.longitude; + } + + if (altitude) { + *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE; + *altitude = gpsmanager->position.altitude; + } + + if (accuracy) { + *accuracy = geoclue_accuracy_new(GEOCLUE_ACCURACY_LEVEL_DETAILED, + gpsmanager->position.hor_accuracy, gpsmanager->position.ver_accuracy); + } + + return TRUE; +} + +static gboolean get_velocity(GcIfaceVelocity * gc, + GeoclueVelocityFields * fields, + int *timestamp, double *speed, double *direction, double *climb, GError ** error) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + + if (gpsmanager->status == GEOCLUE_STATUS_ACQUIRING) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_NOT_AVAILABLE, "ERROR: Acquiring"); + return FALSE; + } + + if (gpsmanager->status != GEOCLUE_STATUS_AVAILABLE) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available"); + return FALSE; + } + + if (!fields) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Invalid parameters"); + return FALSE; + } + + *fields = GEOCLUE_VELOCITY_FIELDS_NONE; + + if (timestamp) { + *timestamp = gpsmanager->position.timestamp; + } + + if (speed) { + *fields |= GEOCLUE_VELOCITY_FIELDS_SPEED; + *speed = gpsmanager->position.speed; + } + + if (direction) { + *fields |= GEOCLUE_VELOCITY_FIELDS_DIRECTION; + *direction = gpsmanager->position.bearing; + } + + /* A climb field does not supported because of poor accuracy. */ + + return TRUE; +} + +static gboolean get_nmea(GcIfaceNmea * gc, int *timestamp, char **nmea_data, GError ** error) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + + if (gpsmanager->status == GEOCLUE_STATUS_UNAVAILABLE || gpsmanager->status == GEOCLUE_STATUS_ERROR) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available"); + return FALSE; + } + + if (timestamp) { + *timestamp = gpsmanager->position.timestamp; + } + + if (nmea_data) { + *nmea_data = g_memdup(gpsmanager->nmea.data, gpsmanager->nmea.len); + } + + return TRUE; +} + +static gboolean get_satellite(GcIfaceSatellite * gc, + int *timestamp, + int *satellite_used, + int *satellite_visible, GArray ** used_prn, GPtrArray ** satellite_info, GError ** error) +{ + GeoclueGpsManager *gpsmanager = (GEOCLUE_GPSMANAGER(gc)); + + if (gpsmanager->status == GEOCLUE_STATUS_UNAVAILABLE || gpsmanager->status == GEOCLUE_STATUS_ERROR) { + g_set_error(error, GEOCLUE_ERROR, GEOCLUE_ERROR_FAILED, "ERROR: Not Available"); + return FALSE; + } + + if (timestamp) { + *timestamp = gpsmanager->position.timestamp; + } + + if (satellite_used) { + int index; + int count = 0; + for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) { + count += gpsmanager->satellite.sat[index].used ? 1 : 0; + } + *satellite_used = count; + } + + if (satellite_visible) { + *satellite_visible = gpsmanager->satellite.num_of_sat; + } + + if (used_prn) { + int index; + *used_prn = g_array_new(FALSE, FALSE, sizeof(guint)); + + for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) { + if (gpsmanager->satellite.sat[index].used) { + g_array_append_val(*used_prn, gpsmanager->satellite.sat[index].prn); + } + } + } + + if (satellite_info) { + int index; + *satellite_info = g_ptr_array_new(); + for (index = 0; index < gpsmanager->satellite.num_of_sat; ++index) { + GValue sv_info = { 0, }; + g_value_init(&sv_info, GEOCLUE_SATELLITE_INFO); + g_value_take_boxed(&sv_info, dbus_g_type_specialized_construct(GEOCLUE_SATELLITE_INFO)); + dbus_g_type_struct_set(&sv_info, + 0, gpsmanager->satellite.sat[index].prn, + 1, gpsmanager->satellite.sat[index].elevation, + 2, gpsmanager->satellite.sat[index].azimuth, + 3, gpsmanager->satellite.sat[index].snr, G_MAXUINT); + g_ptr_array_add(*satellite_info, g_value_get_boxed(&sv_info)); + } + + } + return TRUE; +} + +static void init_position(GcIfacePositionClass * iface) +{ + iface->get_position = get_position; +} + +static void init_velocity(GcIfaceVelocityClass * iface) +{ + iface->get_velocity = get_velocity; +} + +static void init_nmea(GcIfaceNmeaClass * iface) +{ + iface->get_nmea = get_nmea; +} + +static void init_satellite(GcIfaceSatelliteClass * iface) +{ + iface->get_satellite = get_satellite; +} + +static void init_geoclue(GcIfaceGeoclueClass * iface) +{ + iface->get_provider_info = get_provider_info; + iface->add_reference = add_reference; + iface->remove_reference = remove_reference; +} + +int main(int argc, char **argv) +{ + GeoclueGpsManager *gpsmanager; + struct gps_callbacks cb; + cb.pos_cb = update_position_cb; + cb.sv_cb = update_satellite_cb; + cb.nmea_cb = update_nmea_cb; + + if (!g_thread_supported()) { + g_thread_init(NULL); + } + dbus_g_thread_init(); + g_type_init(); + + initialize_server(argc, argv); + + gpsmanager = g_object_new(GEOCLUE_TYPE_GPSMANAGER, NULL); + register_update_callbacks(&cb, gpsmanager); + + gpsmanager->loop = g_main_loop_new(NULL, TRUE); + g_main_loop_run(gpsmanager->loop); + + g_main_loop_unref(gpsmanager->loop); + g_object_unref(gpsmanager); + + deinitialize_server(); + + return 0; +} diff --git a/gps-manager/gps_manager.h b/gps-manager/gps_manager.h new file mode 100644 index 0000000..1130ffc --- /dev/null +++ b/gps-manager/gps_manager.h @@ -0,0 +1,62 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_H_ +#define _GPS_MANAGER_H_ + +#include + +/** + * 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 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_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; + +#endif diff --git a/gps-manager/include/gps_manager_data_types.h b/gps-manager/include/gps_manager_data_types.h new file mode 100644 index 0000000..3ae7f13 --- /dev/null +++ b/gps-manager/include/gps_manager_data_types.h @@ -0,0 +1,95 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_DATA_TYPES_H_ +#define _GPS_MANAGER_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 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) */ + int hor_accuracy; /**< Horizontal position error(in meter) */ + int ver_accuracy; /**< Vertical position error(in meter) */ +} pos_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; + +#ifdef __cplusplus +} +#endif +#endif /* _GPS_MANAGER_DATA_TYPES_H_ */ diff --git a/gps-manager/include/gps_manager_extra_data_types.h b/gps-manager/include/gps_manager_extra_data_types.h new file mode 100644 index 0000000..3867ac0 --- /dev/null +++ b/gps-manager/include/gps_manager_extra_data_types.h @@ -0,0 +1,100 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_EXTRA_DATA_TYPES_H_ +#define _GPS_MANAGER_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 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_MANAGER_EXTRA_DATA_TYPES_H_ */ diff --git a/gps-manager/include/gps_manager_plugin_intf.h b/gps-manager/include/gps_manager_plugin_intf.h new file mode 100644 index 0000000..182066a --- /dev/null +++ b/gps-manager/include/gps_manager_plugin_intf.h @@ -0,0 +1,359 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_PLUGIN_INTF_H_ +#define _GPS_MANAGER_PLUGIN_INTF_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define GPS_MANAGER_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 setting parameters + */ +typedef struct { + gps_session_t session_type; /**< Session type */ + gps_operation_t operation_mode; /**< Operation mode */ + gps_starting_t starting_type; /**< Starting type */ + int num_fixes; /**< Total number of fixes to be done */ + int time_bn_fixes; /**< Time between fix */ + char supl_url[MAX_SUPL_URL_LEN];/**< SUPL URL */ + int supl_port; /**< SUPL port number */ + agps_ssl_mode_t ssl_mode; /**< SSL mode */ + agps_ssl_cert_type_t cert_type; /**< SSL certification type */ +} gps_server_param_t; + +/** + * 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_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_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_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; + + +/** + * Position data from GPS + */ +typedef struct { + gps_error_t error; + pos_data_t pos; +} gps_pos_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; + +/** + * 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; + + /** 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; + 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; +} 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); + +/** + * GPS action type + */ +typedef enum { + GPS_ACTION_SEND_PARAMS = 0x00, + GPS_ACTION_START_SESSION, + GPS_ACTION_STOP_SESSION, + + GPS_INDI_SUPL_VERIFICATION, + GPS_INDI_SUPL_DNSQUERY, + + GPS_ACTION_START_FACTTEST, + GPS_ACTION_STOP_FACTTEST, + + GPS_ACTION_REQUEST_SUPL_NI +} 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; + +/** + * gps-manager plugin interface + */ +typedef struct { + /** Initialize plugin module and register callback function for event delivery. */ + int (*init) (gps_event_cb gps_event_cb, gps_server_param_t * gps_params); + + /** 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 *data, + gps_failure_reason_t *reason_code); +} gps_plugin_interface; + +const gps_plugin_interface *get_gps_plugin_interface(); + +#ifdef __cplusplus +} +#endif +#endif /* _GPS_MANAGER_PLUGIN_INTF_H_ */ diff --git a/gps-manager/last_position.c b/gps-manager/last_position.c new file mode 100644 index 0000000..b9202b7 --- /dev/null +++ b/gps-manager/last_position.c @@ -0,0 +1,94 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_manager_data_types.h" +#include "last_position.h" +#include "debug_util.h" +#include "setting.h" + +static void gps_manager_set_last_position(last_pos_t * last_pos) +{ + LOG_GPS(DBG_LOW, "set Last Latitude = %f Longitude = %f Altitude = %f H_Accuracy = %f V_Accuracy = %f", + last_pos->latitude, last_pos->longitude, last_pos->altitude, last_pos->hor_accuracy, last_pos->ver_accuracy); + + setting_set_int(LAST_TIMESTAMP, last_pos->timestamp); + setting_set_double(LAST_LATITUDE, last_pos->latitude); + setting_set_double(LAST_LONGITUDE, last_pos->longitude); + setting_set_double(LAST_ALTITUDE, last_pos->altitude); + setting_set_double(LAST_HOR_ACCURACY, last_pos->hor_accuracy); + setting_set_double(LAST_VER_ACCURACY, last_pos->ver_accuracy); +} + +double deg2rad(double deg) +{ + return (deg * M_PI / 180); +} + +void gps_manager_get_last_position(last_pos_t * last_pos) +{ + setting_get_int(LAST_TIMESTAMP, &last_pos->timestamp); + setting_get_double(LAST_LATITUDE, &last_pos->latitude); + setting_get_double(LAST_LONGITUDE, &last_pos->longitude); + setting_get_double(LAST_ALTITUDE, &last_pos->altitude); + setting_get_double(LAST_HOR_ACCURACY, &last_pos->hor_accuracy); + setting_get_double(LAST_VER_ACCURACY, &last_pos->ver_accuracy); + + LOG_GPS(DBG_LOW, "get Last Latitude = %f Longitude = %f Altitude = %f H_Accuracy = %f V_Accuracy = %f", + last_pos->latitude, last_pos->longitude, last_pos->altitude, last_pos->hor_accuracy, last_pos->ver_accuracy); +} + +int gps_manager_distance_to_last_position(const pos_data_t * pos, const last_pos_t * last_pos) +{ + double delta_lat, delta_long; + double dist; + + delta_lat = pos->latitude - last_pos->latitude; + delta_long = pos->longitude - last_pos->longitude; + + dist = sin(deg2rad(delta_lat) / 2) * sin(deg2rad(delta_lat) / 2) + + cos(deg2rad(pos->latitude)) * cos(deg2rad(last_pos->latitude)) * + sin(deg2rad(delta_long) / 2) * sin(deg2rad(delta_long) / 2); + dist = 2 * atan2(sqrt(dist), sqrt(1 - dist)); + dist = 6371 * dist; // unit: 'km' + + if (dist > 0.3) { + return 0; + } else { + return -1; + } +} + +void gps_manager_update_last_position(const pos_data_t * pos, last_pos_t * last_pos) +{ + last_pos->timestamp = pos->timestamp; + last_pos->latitude = pos->latitude; + last_pos->longitude = pos->longitude; + last_pos->altitude = pos->altitude; + last_pos->hor_accuracy = pos->hor_accuracy; + last_pos->ver_accuracy = pos->ver_accuracy; + + gps_manager_set_last_position(last_pos); +} diff --git a/gps-manager/last_position.h b/gps-manager/last_position.h new file mode 100644 index 0000000..38fb799 --- /dev/null +++ b/gps-manager/last_position.h @@ -0,0 +1,40 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_LAST_POSITON_H_ +#define _GPS_MANAGER_LAST_POSITON_H_ + +#include "gps_manager_data_types.h" + +typedef struct { + int timestamp; + double latitude; + double longitude; + double altitude; + double hor_accuracy; + double ver_accuracy; +} last_pos_t; + +void gps_manager_get_last_position(last_pos_t * last_pos); +int gps_manager_distance_to_last_position(const pos_data_t * pos, const last_pos_t * last_pos); +void gps_manager_update_last_position(const pos_data_t * pos, last_pos_t * last_pos); + +#endif /* _GPS_MANAGER_LAST_POSITON_H_ */ diff --git a/gps-manager/nmea_logger.c b/gps-manager/nmea_logger.c new file mode 100644 index 0000000..d23ff9a --- /dev/null +++ b/gps-manager/nmea_logger.c @@ -0,0 +1,109 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "nmea_logger.h" +#include "debug_util.h" + +#define MAX_NMEA_RAW_DATA_LOG_FILE_CNT (999) +#define MAX_NMEA_LOG_FILE_PATH (100) +#define NMEA_LOGGING_FILE_PATH "/opt/data/gps-manager/res/nmea_data" + +int raw_nmea_fd = -1; + +static int open_nmea_log_file(const char *); + +void start_nmea_log() +{ + char filepath[MAX_NMEA_LOG_FILE_PATH]; + + if (open_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 < -1) { + LOG_GPS(DBG_ERR, "FAILED to open [%s], error[%d]", filepath, errno); + } else { + LOG_GPS(DBG_LOW, "%s raw_nmea_fd [%d]", filepath, 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 open_nmea_log_file(const 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.log", NMEA_LOGGING_FILE_PATH, idx); + fd = open(fn, O_RDONLY); + if (fd == -1) { + LOG_GPS(DBG_LOW, "next log file [%s]", fn); + return 0; + } else { + close(fd); + } + } + LOG_GPS(DBG_LOW, "All NMEA RAW Data logging files are used. New log file can not be created"); + return -1; +} diff --git a/gps-manager/nmea_logger.h b/gps-manager/nmea_logger.h new file mode 100644 index 0000000..c129a95 --- /dev/null +++ b/gps-manager/nmea_logger.h @@ -0,0 +1,34 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 _GEOCLUE_AGPS_NMEA_LOGGER_H_ +#define _GEOCLUE_AGPS_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 /* _GEOCLUE_AGPS_NMEA_LOGGER_H_ */ diff --git a/gps-manager/org.freedesktop.Geoclue.Providers.GpsManager.service.in b/gps-manager/org.freedesktop.Geoclue.Providers.GpsManager.service.in new file mode 100644 index 0000000..6292f66 --- /dev/null +++ b/gps-manager/org.freedesktop.Geoclue.Providers.GpsManager.service.in @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=org.freedesktop.Geoclue.Providers.GpsManager +Exec=@libexecdir@/gps-manager diff --git a/gps-manager/plugin_module.c b/gps-manager/plugin_module.c new file mode 100644 index 0000000..ca36092 --- /dev/null +++ b/gps-manager/plugin_module.c @@ -0,0 +1,94 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "plugin_module.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; + +int load_plugin_module(char *specific_name, void **plugin_handle) +{ + char plugin_path[256]; + + if (specific_name[0] == '\0') { + strncpy(plugin_path, GPS_MANAGER_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_MANAGER_PLUGIN_PATH, sizeof(plugin_path)); + } + + *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 (%s).", plugin_path); + + 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/gps-manager/plugin_module.h b/gps-manager/plugin_module.h new file mode 100644 index 0000000..2f72746 --- /dev/null +++ b/gps-manager/plugin_module.h @@ -0,0 +1,31 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 _GEOCLUE_AGPS_PLUGIN_MODULE_H_ +#define _GEOCLUE_AGPS_PLUGIN_MODULE_H_ + +#include "gps_manager_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 /* _GEOCLUE_AGPS_PLUGIN_MODULE_H_ */ diff --git a/gps-manager/script/gps-manager b/gps-manager/script/gps-manager new file mode 100644 index 0000000..29d3f75 --- /dev/null +++ b/gps-manager/script/gps-manager @@ -0,0 +1,21 @@ +#!/bin/sh +##/etc/init.d/gps-manager Lv : S90 + +## This file is boot script of /usr/libexec/gps-manager +## This script should be run after brcm-gps-daemon + +if [ -x /usr/libexec/gps-manager ]; then + if [ ! -z "`pgrep gps-manager`" ]; then + killall gps-manager + fi + if [ -d /sys/devices/platform/bcm47511 ]; then + /usr/libexec/gps-manager -l brcm & + elif [ -d /sys/devices/platform/gsd4t ]; then + /usr/libexec/gps-manager -l csr & + elif [ -d /sys/devices/platform/msm-cpu-dai.0 ]; then + /usr/libexec/gps-manager -l qcom & + else + vconftool set -t int db/location/replay/ReplayEnabled "1" -f + /usr/libexec/gps-manager -l replay & + fi +fi diff --git a/gps-manager/server.c b/gps-manager/server.c new file mode 100644 index 0000000..4fc3cd4 --- /dev/null +++ b/gps-manager/server.c @@ -0,0 +1,1050 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_manager_data_types.h" +#include "gps_manager_plugin_intf.h" +#include "nmea_logger.h" +#include "data_connection.h" +#include "setting.h" +#include "plugin_module.h" +#include "debug_util.h" +#include "last_position.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define GPS_NI_POPUP "/usr/bin/gps_popup" +#define GPS_NI_BTN "BTN" +#define GPS_NI_WITHOUT_BTN "NONE" +#define YES_EXIT_STATUS 174 +#define NO_EXIT_STATUS 175 + +#define REPLAY_MODULE "replay" + +typedef struct { + void *handle; + char *name; +} gps_plugin_handler_t; + +gps_plugin_handler_t g_gps_plugin; +gps_server_param_t g_gps_params; + +pos_data_t *gps_pos_data = NULL; +sv_data_t *gps_sv_data = NULL; +nmea_data_t *gps_nmea_data = NULL; +last_pos_t *gps_last_pos = NULL; + +int g_dnet_used = 0; + +gboolean logging_enabled = FALSE; +gboolean replay_enabled = FALSE; + +static pthread_t msg_thread = 0; /* Register SUPL NI cb to msg server Thread */ +static pthread_t popup_thread = 0; /* Register SUPL NI cb to msg server Thread */ +static int msg_thread_status; + +gps_session_state_t gps_session_state = GPS_SESSION_STOPPED; + +struct gps_callbacks g_update_cb; +void *g_user_data; + +static int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info); + +static void _gps_mode_changed_cb(keynode_t * key, void *data) +{ + int int_val; + + if (setting_get_int(GPS_SESSION, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! GPS_SESSION setting get failed"); + int_val = GPS_SESSION_TRACKING_MODE; + } + g_gps_params.session_type = int_val; + + if (setting_get_int(GPS_OPERATION, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! GPS_OPERATION setting get failed"); + int_val = GPS_OPERATION_STANDALONE; + } + g_gps_params.operation_mode = int_val; + + if (setting_get_int(GPS_STARTING, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! GPS_STARTING setting get failed"); + int_val = GPS_STARTING_HOT_; + } + g_gps_params.starting_type = int_val; + + return; +} + +static void _gps_supl_changed_cb(keynode_t * key, void *data) +{ + int int_val; + char *str; + + str = setting_get_string(SUPL_SERVER); + + if (str == NULL) { + snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", SUPL_SERVER_URL_DEFAULT); + LOG_GPS(DBG_ERR, "vconf fail to get Server URL [Default URL]"); + } else { + snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", str); + } + + if (setting_get_int(SUPL_PORT, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! SUPL_PORT setting get failed"); + int_val = SUPL_SERVER_PORT_DEFAULT; + } + g_gps_params.supl_port = int_val; + + return; +} + +static void _gps_setting_changed_cb(keynode_t * key, void *data) +{ + int int_val; + + if (setting_get_int(SUPL_SSL, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! SUPL_SSL setting get failed"); + int_val = 0; + } + g_gps_params.ssl_mode = int_val; + return; +} + +static void _gps_nmea_changed_cb(keynode_t * key, void *data) +{ + int int_val; + if (setting_get_int(NMEA_LOGGING, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "NMEA_LOGGING get Failed."); + int_val = 0; + } + logging_enabled = (int_val == 1) ? TRUE : FALSE; + return; +} + +static gboolean get_replay_enabled() +{ + int int_val; + gboolean ret; + + if (setting_get_int(REPLAY_ENABLED, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "REPLAY_ENABLED get Failed."); + int_val = 0; + } + + ret = (int_val == 1) ? TRUE : FALSE; + + return ret; +} + +static void reload_plugin_module() +{ + char *module_name; + gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL; + + if (replay_enabled == TRUE) { + module_name = REPLAY_MODULE; + } else { + module_name = g_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(&g_gps_plugin.handle); + if (!load_plugin_module(module_name, &g_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, &g_gps_params)) { + LOG_GPS(DBG_ERR, "Fail to %s plugin init", module_name); + return; + } + } + } +} + +static void _gps_replay_changed_cb(keynode_t * key, void *data) +{ + + replay_enabled = get_replay_enabled(); + reload_plugin_module(); + + return; +} + +static void _gps_server_set_indicator(int gps_state) +{ + int ret; + int wps_state = 0; + + setting_get_int(VCONFKEY_WPS_STATE, &wps_state); + LOG_GPS(DBG_LOW, "gps state : [%d], wps state : [%d]", gps_state, wps_state); + + if (gps_state == POSITION_CONNECTED || wps_state == POSITION_CONNECTED) { + ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_CONNECTED); + } else { + if (gps_state == POSITION_OFF && wps_state == POSITION_OFF) { + ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_OFF); + } else { + ret = setting_set_int(VCONFKEY_GPS_STATE, POSITION_SEARCHING); + } + } + + if (ret == 1) { + LOG_GPS(DBG_LOW, "Succesee to set indicator"); + } else { + LOG_GPS(DBG_ERR, "Fail to setting_set_int(VCONF_GPS_STATE, ...)"); + } +} + +static gboolean _initialize_data() +{ + gboolean result = TRUE; + if (gps_pos_data == NULL) { + gps_pos_data = (pos_data_t *) malloc(sizeof(pos_data_t)); + if (gps_pos_data == NULL) { + LOG_GPS(DBG_ERR, "Failed to alloc gps_pos_data"); + result = FALSE; + } else { + memset(gps_pos_data, 0x00, sizeof(pos_data_t)); + } + } + + if (gps_sv_data == NULL) { + gps_sv_data = (sv_data_t *) malloc(sizeof(sv_data_t)); + if (gps_sv_data == NULL) { + LOG_GPS(DBG_ERR, "Failed to alloc gps_sv_data"); + result = FALSE; + } else { + memset(gps_sv_data, 0x00, sizeof(sv_data_t)); + } + } + + if (gps_nmea_data == NULL) { + gps_nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t)); + if (gps_nmea_data == NULL) { + LOG_GPS(DBG_ERR, "Failed to alloc gps_nmea_data"); + result = FALSE; + } else { + memset(gps_nmea_data, 0x00, sizeof(nmea_data_t)); + } + } + + if (gps_last_pos == NULL) { + gps_last_pos = (last_pos_t *) malloc(sizeof(last_pos_t)); + if (gps_last_pos == NULL) { + LOG_GPS(DBG_ERR, "Failed to alloc gps_last_pos"); + result = FALSE; + } else { + memset(gps_last_pos, 0x00, sizeof(last_pos_t)); + } + } + return result; +} + +int request_start_session() +{ + int status = TRUE; + gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL; + + if (gps_session_state != GPS_SESSION_STOPPED && gps_session_state != GPS_SESSION_STOPPING) { + LOG_GPS(DBG_LOW, "Main: GPS Session Already Started!"); + return TRUE; + } + + status = get_plugin_module()->request(GPS_ACTION_START_SESSION, &g_gps_params, &reason_code); + + if (status == FALSE) { + LOG_GPS(DBG_ERR, "Main: sending GPS_ACTION_START_SESSION Fail !"); + return FALSE; + } + + LOG_GPS(DBG_LOW, "Main: sending GPS_ACTION_START_SESSION OK !"); + _initialize_data(); + + gps_session_state = GPS_SESSION_STARTING; + LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state); + setting_ignore_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb); + + return TRUE; +} + +int request_stop_session() +{ + unsigned int status = TRUE; + gboolean cur_replay_enabled = FALSE; + gps_failure_reason_t reason_code = GPS_FAILURE_CAUSE_NORMAL; + + LOG_GPS(DBG_LOW, "Main: Stop GPS Session, ==GPSSessionState[%d]", gps_session_state); + if (gps_session_state == GPS_SESSION_STARTED || gps_session_state == GPS_SESSION_STARTING) { + status = get_plugin_module()->request(GPS_ACTION_STOP_SESSION, NULL, &reason_code); + if (status) { + gps_session_state = GPS_SESSION_STOPPING; + LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state); + cur_replay_enabled = get_replay_enabled(); + if (replay_enabled != cur_replay_enabled) { + replay_enabled = cur_replay_enabled; + reload_plugin_module(); + } + setting_notify_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb); + } else { + LOG_GPS(DBG_LOW, " 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; +} + +static void _gps_plugin_handler_init(char *module_name) +{ + g_gps_plugin.handle = NULL; + g_gps_plugin.name = (char *)malloc(strlen(module_name) + 1); + snprintf(g_gps_plugin.name, strlen(module_name) + 1, "%s", module_name); +} + +static void _gps_plugin_handler_deinit() +{ + if (g_gps_plugin.handle != NULL) { + g_gps_plugin.handle = NULL; + } + + if (g_gps_plugin.name != NULL) { + free(g_gps_plugin.name); + g_gps_plugin.name = NULL; + } +} + +static void _gps_read_params() +{ + int int_val = 0; + char *str; + + if (setting_get_int(GPS_SESSION, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! GPS_SESSION setting get failed"); + int_val = GPS_SESSION_TRACKING_MODE; //set to default + } + g_gps_params.session_type = int_val; + + if (setting_get_int(GPS_OPERATION, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! GPS_OPERATION setting get failed"); + int_val = GPS_OPERATION_STANDALONE; //set to default + } + g_gps_params.operation_mode = int_val; + + if (setting_get_int(GPS_STARTING, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! TING_MODE setting get failed"); + int_val = GPS_STARTING_HOT_; + } + g_gps_params.starting_type = int_val; + + g_gps_params.time_bn_fixes = 1; + + str = setting_get_string(SUPL_SERVER); + if (str == NULL) { + snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", SUPL_SERVER_URL_DEFAULT); + LOG_GPS(DBG_ERR, "vconf fail to get Server URL [Default URL]"); + } else { + snprintf(g_gps_params.supl_url, MAX_SUPL_URL_LEN, "%s", str); + } + + if (setting_get_int(SUPL_PORT, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! SUPL_PORT setting get failed"); + int_val = SUPL_SERVER_PORT_DEFAULT; + } + g_gps_params.supl_port = int_val; + + LOG_GPS(DBG_LOW, "First Read!! SUPL server:%s, port:%d", g_gps_params.supl_url, g_gps_params.supl_port); + + if (setting_get_int(SUPL_SSL, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//ERROR!! SUPL_SSL setting get failed"); + int_val = 0; + } + g_gps_params.ssl_mode = int_val; + + if (setting_get_int(NMEA_LOGGING, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//NMEA_LOGGING get Failed."); + int_val = 0; + } + logging_enabled = (int_val == 1) ? TRUE : FALSE; + + if (setting_get_int(REPLAY_ENABLED, &int_val) == FALSE) { + LOG_GPS(DBG_ERR, "//REPLAY_ENABLED get Failed."); + int_val = 0; + } + replay_enabled = (int_val == 1) ? TRUE : FALSE; +} + +static void _gps_notify_params() +{ + setting_notify_key_changed(GPS_SESSION, _gps_mode_changed_cb); + setting_notify_key_changed(GPS_OPERATION, _gps_mode_changed_cb); + setting_notify_key_changed(GPS_STARTING, _gps_mode_changed_cb); + setting_notify_key_changed(SUPL_SERVER, _gps_supl_changed_cb); + setting_notify_key_changed(SUPL_PORT, _gps_supl_changed_cb); + setting_notify_key_changed(SUPL_SSL, _gps_setting_changed_cb); + setting_notify_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb); + setting_notify_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb); +} + +static void _gps_ignore_params() +{ + setting_ignore_key_changed(GPS_SESSION, _gps_mode_changed_cb); + setting_ignore_key_changed(GPS_OPERATION, _gps_mode_changed_cb); + setting_ignore_key_changed(GPS_STARTING, _gps_mode_changed_cb); + setting_ignore_key_changed(SUPL_SERVER, _gps_supl_changed_cb); + setting_ignore_key_changed(SUPL_PORT, _gps_supl_changed_cb); + setting_ignore_key_changed(SUPL_SSL, _gps_setting_changed_cb); + setting_ignore_key_changed(NMEA_LOGGING, _gps_nmea_changed_cb); + setting_ignore_key_changed(REPLAY_ENABLED, _gps_replay_changed_cb); +} + +static void _gps_server_start_event() +{ + LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STARTED); + gps_session_state = GPS_SESSION_STARTED; + + if (logging_enabled) { + start_nmea_log(); + } + + if (gps_pos_data == NULL) { + gps_pos_data = (pos_data_t *) malloc(sizeof(pos_data_t)); + if (gps_pos_data == NULL) { + LOG_GPS(DBG_WARN, "//callback: gps_pos_data re-malloc Failed!!"); + } else { + memset(gps_pos_data, 0x00, sizeof(pos_data_t)); + } + } + if (gps_sv_data == NULL) { + gps_sv_data = (sv_data_t *) malloc(sizeof(sv_data_t)); + if (gps_sv_data == NULL) { + LOG_GPS(DBG_WARN, "//callback: gps_sv_data re-malloc Failed!!"); + } else { + memset(gps_sv_data, 0x00, sizeof(sv_data_t)); + } + } + if (gps_nmea_data == NULL) { + gps_nmea_data = (nmea_data_t *) malloc(sizeof(nmea_data_t)); + if (gps_nmea_data == NULL) { + LOG_GPS(DBG_WARN, "//callback: gps_nmea_data re-malloc Failed!!"); + } else { + memset(gps_nmea_data, 0x00, sizeof(nmea_data_t)); + } + } + + if (gps_last_pos == NULL) { + gps_last_pos = (last_pos_t *) malloc(sizeof(last_pos_t)); + if (gps_last_pos == NULL) { + LOG_GPS(DBG_WARN, "//callback: gps_last_pos re-malloc Failed!!"); + } else { + memset(gps_last_pos, 0x00, sizeof(last_pos_t)); + gps_manager_get_last_position(gps_last_pos); + } + } + + _gps_server_set_indicator(POSITION_SEARCHING); + pm_lock_state(LCD_OFF, STAY_CUR_STATE, 0); +} + +static void _gps_server_stop_event() +{ + LOG_GPS(DBG_LOW, "==GPSSessionState [%d] -> [%d]", gps_session_state, GPS_SESSION_STOPPED); + gps_session_state = GPS_SESSION_STOPPED; + LOG_GPS(DBG_LOW, "==GPSSessionState[%d]", gps_session_state); + + _gps_server_set_indicator(POSITION_OFF); + pm_unlock_state(LCD_NORMAL, PM_RESET_TIMER); + + if (logging_enabled) { + stop_nmea_log(); + } + + if (gps_pos_data != NULL) { + free(gps_pos_data); + gps_pos_data = NULL; + } + if (gps_sv_data != NULL) { + free(gps_sv_data); + gps_sv_data = NULL; + } + if (gps_nmea_data != NULL) { + free(gps_nmea_data); + gps_nmea_data = NULL; + } + if (gps_last_pos != NULL) { + free(gps_last_pos); + gps_last_pos = NULL; + } +} + +static void _report_pos_event(gps_event_info_t * gps_event) +{ + if (gps_pos_data != NULL) { + memcpy(gps_pos_data, &(gps_event->event_data.pos_ind.pos), sizeof(pos_data_t)); + g_update_cb.pos_cb(gps_pos_data, gps_event->event_data.pos_ind.error, g_user_data); + if (gps_manager_distance_to_last_position(gps_pos_data, gps_last_pos) != -1) { + gps_manager_update_last_position(gps_pos_data, gps_last_pos); + } + memset(gps_pos_data, 0x00, sizeof(pos_data_t)); + } else { + LOG_GPS(DBG_ERR, "gps_sv_data is NULL"); + } +} + +static void _report_sv_event(gps_event_info_t * gps_event) +{ + if (gps_sv_data != NULL) { + memcpy(gps_sv_data, &(gps_event->event_data.sv_ind.sv), sizeof(sv_data_t)); + g_update_cb.sv_cb(gps_sv_data, g_user_data); + memset(gps_sv_data, 0x00, sizeof(sv_data_t)); + } else { + LOG_GPS(DBG_ERR, "gps_sv_data is NULL"); + } +} + +static void _report_nmea_event(gps_event_info_t * gps_event) +{ + if (gps_nmea_data == NULL) { + LOG_GPS(DBG_ERR, "gps_nmea_data is NULL"); + return; + } + + gps_nmea_data->len = gps_event->event_data.nmea_ind.nmea.len; + LOG_GPS(DBG_LOW, "gps_nmea_data->len : [%d]", gps_nmea_data->len); + gps_nmea_data->data = (char *)malloc(gps_nmea_data->len); + memset(gps_nmea_data->data, 0x00, gps_nmea_data->len); + memcpy(gps_nmea_data->data, gps_event->event_data.nmea_ind.nmea.data, gps_nmea_data->len); + g_update_cb.nmea_cb(gps_nmea_data, g_user_data); + free(gps_nmea_data->data); + memset(gps_nmea_data, 0x00, sizeof(nmea_data_t)); + + if (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() +{ + LOG_GPS(DBG_LOW, "Enter _gps_server_open_data_connection"); + + g_dnet_used++; + + if (g_dnet_used > 1) { + LOG_GPS(DBG_LOW, "g_dnet_used : [ %d ]", g_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() +{ + LOG_GPS(DBG_LOW, "Enter _gps_server_close_data_connection"); + + if (g_dnet_used > 0) { + g_dnet_used--; + } + + if (g_dnet_used != 0) { + LOG_GPS(DBG_LOW, "Cannot stop the data connection! [ g_dnet_used : %d ]", g_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 int _gps_server_gps_event_cb(gps_event_info_t * gps_event_info) +{ + FUNC_ENTRANCE_SERVER; + 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(); + } 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(); + _gps_server_stop_event(); + } else { + LOG_GPS(DBG_ERR, "//Stop Session Failed, error : %d", + gps_event_info->event_data.stop_session_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(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_SATELLITE: + LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_SATELLITE :::::::::::::::"); + if (gps_event_info->event_data.sv_ind.error == GPS_ERR_NONE) { + if (gps_event_info->event_data.sv_ind.sv.pos_valid) { + _gps_server_set_indicator(POSITION_CONNECTED); + } else { + _gps_server_set_indicator(POSITION_SEARCHING); + } + _report_sv_event(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: + LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_NMEA :::::::::::::::"); + if (gps_event_info->event_data.nmea_ind.error == GPS_ERR_NONE) { + _report_nmea_event(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(); + } + break; + case GPS_EVENT_CLOSE_DATA_CONNECTION: + { + LOG_GPS(DBG_LOW, "<<::::::::::: GPS_EVENT_CLOSE_DATA_CONNECTION :::::::::::::::"); + result = _gps_server_close_data_connection(); + } + 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; + default: + LOG_GPS(DBG_WARN, "//Error: Isettingalid Event Type %d", gps_event_info->event_id); + break; + } + return result; +} + +static void *_gps_launch_popup(void *data) +{ + gps_ni_popup_data_t *msgData = (gps_ni_popup_data_t *) data; + + int status; + char *argv[5]; + char temp[16]; + gps_failure_reason_t reason_code; + + // Max size of SMS message is 255 + // Max size of WAP PUSH is ?????? + snprintf(temp, sizeof(temp), "%d", msgData->msg_size); + + argv[0] = GPS_NI_POPUP; + if (msgData->num_btn == 2) + argv[1] = GPS_NI_BTN; + else + argv[1] = GPS_NI_WITHOUT_BTN; + argv[2] = temp; + argv[3] = msgData->msg_body; + argv[4] = NULL; + + if (msgData->num_btn == 2) { + wait(&status); + if (status != YES_EXIT_STATUS && status != NO_EXIT_STATUS) + status = YES_EXIT_STATUS; + status = status / 256; + } else { + // Popup application Timer is 2 sec + sleep(2); + status = YES_EXIT_STATUS; + } + + status = NO_EXIT_STATUS - status; + LOG_GPS(DBG_LOW, "EXIT_STATUS from the LBS Popup is [ %d ]", status); + + agps_supl_ni_info_t info; + info.msg_body = (char *)msgData->msg_body; + info.msg_size = msgData->msg_size; + info.status = status; + + 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 NULL; + +} + +static void _gps_supl_networkinit_smscb(MSG_HANDLE_T hMsgHandle, msg_message_t msg, void *user_param) +{ + LOG_GPS(DBG_ERR, "_gps_supl_networkinit_smscb is called"); + LOG_GPS(DBG_ERR, "SUPLNI MSG size is [ %d ]", msg_get_message_body_size(msg)); + + gps_ni_popup_data_t new_message; + memset(&new_message, 0x00, sizeof(new_message)); + + new_message.msg_body = (char *)msg_sms_get_message_body(msg); + new_message.msg_size = msg_get_message_body_size(msg); + // TODO: Button number of LBS Popup + new_message.num_btn = 2; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &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) +{ + LOG_GPS(DBG_ERR, "_gps_supl_networkinit_wappushcb is called"); + LOG_GPS(DBG_ERR, "SUPLNI WAPPush MSG size is [ %d ]", pushBodyLen); + + gps_ni_popup_data_t new_message; + memset(&new_message, 0x00, sizeof(new_message)); + + new_message.msg_body = (char *)pPushBody; + new_message.msg_size = pushBodyLen; + // TODO: Button number of LBS Popup + new_message.num_btn = 2; + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if (pthread_create(&popup_thread, &attr, _gps_launch_popup, &new_message) != 0) { + LOG_GPS(DBG_WARN, "Can not make pthread......"); + } + +} + +static void *_gps_register_msgfwcb() +{ + 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, NULL); + + 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, NULL); + + 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; + +} + +static void _gps_hibernation_enter_callback(void *data) +{ + LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_enter_callback"); + + if (msg_thread != 0) { + pthread_cancel(msg_thread); + + pthread_join(msg_thread, (void *)&msg_thread_status); + msg_thread = 0; + } +} + +static void _gps_hibernation_leave_callback(void *data) +{ + LOG_GPS(DBG_LOW, "Enter the _gps_hibernation_leave_callback"); + + if (msg_thread != 0) { + pthread_cancel(msg_thread); + + pthread_join(msg_thread, (void *)&msg_thread_status); + msg_thread = 0; + } + if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) { + LOG_GPS(DBG_WARN, "Can not make pthread......"); + } +} + +static void _print_help() +{ + printf("Usage: gps-manager [OPTION] [NAME]\n" + " -h Help\n" + " -l [NAME] Load a specific plugin module\n"); + exit(0); +} + +static int _parse_argument(const int argc, char **argv, const int buffer_size, char *out_buffer) +{ + int opt; + + memset(out_buffer, 0x00, buffer_size); + while ((opt = getopt(argc, argv, "hl:")) != -1) { + switch (opt) { + case 'l': + snprintf(out_buffer, buffer_size, "%s", optarg); + break; + case 'h': + default: + _print_help(); + break; + } + } + + return 0; +} + +int initialize_server(int argc, char **argv) +{ + char module_name[16]; + + _parse_argument(argc, argv, sizeof(module_name), module_name); + + FUNC_ENTRANCE_SERVER; + + _gps_plugin_handler_init(module_name); + _gps_read_params(); + _gps_notify_params(); + + if (!load_plugin_module(g_gps_plugin.name, &g_gps_plugin.handle)) { + LOG_GPS(DBG_ERR, "Failed to load plugin module."); + return -1; + } + + LOG_GPS(DBG_LOW, "after read parameters......"); + + if (!get_plugin_module()->init(_gps_server_gps_event_cb, &g_gps_params)) { + LOG_GPS(DBG_WARN, "//GPS Initialization failed"); + return -1; + } + // Register SUPL NI cb to MSG server + if (pthread_create(&msg_thread, NULL, _gps_register_msgfwcb, NULL) != 0) { + LOG_GPS(DBG_WARN, "Can not make pthread......"); + } + // Register Hibernation cb to re-connect msg-server + int notifd; + notifd = heynoti_init(); + heynoti_subscribe(notifd, "HIBERNATION_ENTER", _gps_hibernation_enter_callback, NULL); + heynoti_subscribe(notifd, "HIBERNATION_LEAVE", _gps_hibernation_leave_callback, NULL); + heynoti_attach_handler(notifd); + + LOG_GPS(DBG_LOW, "Initialization is completed."); + + return 0; +} + +int deinitialize_server() +{ + gps_failure_reason_t ReasonCode = GPS_FAILURE_CAUSE_NORMAL; + + // Wait termination of msg thread + pthread_join(msg_thread, (void *)&msg_thread_status); + + _gps_ignore_params(); + + if (!get_plugin_module()->deinit(&ReasonCode)) { + LOG_GPS(DBG_WARN, "GPS De-Initialization failed."); + } + + unload_plugin_module(g_gps_plugin.handle); + _gps_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/gps-manager/server.h b/gps-manager/server.h new file mode 100644 index 0000000..17cc417 --- /dev/null +++ b/gps-manager/server.h @@ -0,0 +1,77 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "gps_manager.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; + int num_btn; +} gps_ni_popup_data_t; + +int initialize_server(int argc, char **argv); +int deinitialize_server(); + +int request_start_session(void); +int request_stop_session(void); +int register_update_callbacks(struct gps_callbacks *gps_callback, void *user_data); + +#endif /* _SERVER_H_ */ diff --git a/gps-manager/setting.c b/gps-manager/setting.c new file mode 100644 index 0000000..80c0050 --- /dev/null +++ b/gps-manager/setting.c @@ -0,0 +1,110 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 "setting.h" +#include "debug_util.h" + +int setting_set_int(const char *path, int val) +{ + int ret = vconf_set_int(path, val); + if (ret == 0) { + ret = TRUE; + } else { + LOG_GPS(DBG_ERR, "vconf_set_int failed, [%s]", path); + ret = FALSE; + } + return ret; +} + +int setting_get_int(const char *path, int *val) +{ + int ret = vconf_get_int(path, val); + if (ret == 0) { + ret = TRUE; + } else { + LOG_GPS(DBG_ERR, "vconf_get_int failed, [%s]", path); + ret = FALSE; + } + return ret; +} + +int setting_set_double(const char *path, double val) +{ + int ret = vconf_set_dbl(path, val); + if (ret == 0) { + ret = TRUE; + } else { + LOG_GPS(DBG_ERR, "vconf_set_dbl failed, [%s]", path); + ret = FALSE; + } + return ret; +} + +int setting_get_double(const char *path, double *val) +{ + int ret = vconf_get_dbl(path, val); + if (ret == 0) { + ret = TRUE; + } else { + LOG_GPS(DBG_ERR, "vconf_get_int failed, [%s]", path); + ret = FALSE; + } + return ret; +} + +int setting_set_string(const char *path, const char *val) +{ + int ret = vconf_set_str(path, val); + if (ret == 0) { + ret = TRUE; + } else { + LOG_GPS(DBG_ERR, "vconf_set_str failed, [%s]", path); + ret = FALSE; + } + return ret; +} + +char *setting_get_string(const char *path) +{ + return vconf_get_str(path); +} + +int setting_notify_key_changed(const char *path, void *key_changed_cb) +{ + int ret = TRUE; + if (vconf_notify_key_changed(path, key_changed_cb, NULL) != 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; +} diff --git a/gps-manager/setting.h b/gps-manager/setting.h new file mode 100644 index 0000000..5f2857d --- /dev/null +++ b/gps-manager/setting.h @@ -0,0 +1,76 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_MANAGER_SETTING_H_ +#define _GPS_MANAGER_SETTING_H_ + +#include +#include + +#define VCONFKEY_WPS_STATE "memory/wps/state" + +#define LOCATION_SETTING_PATH "db/location" + +#define GPS_SETTING LOCATION_SETTING_PATH"/gps" +#define GPS_OPERATION GPS_SETTING"/Operation" +#define GPS_STARTING GPS_SETTING"/Starting" +#define GPS_SESSION GPS_SETTING"/Session" + +#define SUPL_SETTING LOCATION_SETTING_PATH"/supl" +#define SUPL_SERVER SUPL_SETTING"/Server" +#define SUPL_PORT SUPL_SETTING"/Port" +#define SUPL_SSL SUPL_SETTING"/SslEnabled" + +#define NMEA_SETTING LOCATION_SETTING_PATH"/nmea" +#define NMEA_LOGGING NMEA_SETTING"/LoggingEnabled" + +#define REPLAY_SETTING LOCATION_SETTING_PATH"/replay" +#define REPLAY_ENABLED REPLAY_SETTING"/ReplayEnabled" + +#define LAST_POSITION LOCATION_SETTING_PATH"/lastposition" +#define METHOD_GPS LAST_POSITION"/gps" + +#define LAST_TIMESTAMP METHOD_GPS"/Timestamp" +#define LAST_LATITUDE METHOD_GPS"/Latitude" +#define LAST_LONGITUDE METHOD_GPS"/Longitude" +#define LAST_ALTITUDE METHOD_GPS"/Altitude" +#define LAST_HOR_ACCURACY METHOD_GPS"/HorAccuracy" +#define LAST_VER_ACCURACY METHOD_GPS"/VerAccuracy" + +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); +int setting_ignore_key_changed(const char *path, void *key_changed_cb); +#endif /* _GPS_MANAGER_SETTING_H_ */ diff --git a/module/Makefile.am b/module/Makefile.am new file mode 100644 index 0000000..692f4cf --- /dev/null +++ b/module/Makefile.am @@ -0,0 +1,12 @@ +pkgdir = $(libdir)/location/module +pkg_LTLIBRARIES = libgps.la + +libgps_la_SOURCES = module_gps_manager.c +libgps_la_CFLAGS = \ + -D_GNU_SOURCE \ + -fPIC\ + $(MODULE_CFLAGS) +libgps_la_LIBADD = \ + -lm\ + -ldl\ + $(MODULE_LIBS) diff --git a/module/log.h b/module/log.h new file mode 100644 index 0000000..2393275 --- /dev/null +++ b/module/log.h @@ -0,0 +1,47 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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_mod" +#define MOD_DLOG_DEBUG + +#ifdef MOD_DLOG_DEBUG // if debug mode, show filename & line number +#include +#define MOD_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_LOCATION, "[%-15s:%-4d:%-20s][MOD]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define MOD_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_LOCATION, "[%-15s:%-4d:%-20s][MOD]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define MOD_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_LOCATION, "[%-15s:%-4d:%-20s][MOD]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#define MOD_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_LOCATION, "[%-15s:%-4d:%-20s][MOD]"fmt"\n", __FILE__, __LINE__, __FUNCTION__, ##args) +#elif MOD_DLOG_RELEASE // if release mode, do not show filename & line number +#include +#define MOD_LOGD(fmt,args...) SLOG(LOG_DEBUG, TAG_LOCATION, "[MOD]"fmt"\n", ##args) +#define MOD_LOGW(fmt,args...) SLOG(LOG_WARN, TAG_LOCATION, "[MOD]"fmt"\n", ##args) +#define MOD_LOGI(fmt,args...) SLOG(LOG_INFO, TAG_LOCATION, "[MOD]"fmt"\n", ##args) +#define MOD_LOGE(fmt,args...) SLOG(LOG_ERROR, TAG_LOCATION, "[MOD]"fmt"\n", ##args) +#else // if do not use dlog +#define MOD_LOGD(...) g_debug(__VA_ARGS__); +#define MOD_LOGW(...) g_warning(__VA_ARGS__); +#define MOD_LOGI(...) g_message(__VA_ARGS__); +#define MOD_LOGE(...) g_error(__VA_ARGS__); +#endif + +#endif diff --git a/module/module_gps_manager.c b/module/module_gps_manager.c new file mode 100644 index 0000000..70e0564 --- /dev/null +++ b/module/module_gps_manager.c @@ -0,0 +1,554 @@ +/* + * gps-manager + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Youngae Kang , Yunhan Kim , + * Genie Kim , Minjune 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 + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "log.h" + +typedef struct{ + char devname[256]; + GeocluePosition *pos; + GeoclueVelocity *vel; + GeoclueNmea *nmea; + GeoclueSatellite *sat; + LocModStatusCB status_cb; + LocModPositionCB pos_cb; + LocModVelocityCB vel_cb; + gpointer userdata; + gboolean is_started; +} GpsManagerData; + +static void +status_callback (GeoclueProvider *provider, + gint status, + gpointer userdata) +{ + GpsManagerData* gps_manager = (GpsManagerData*)userdata; + g_return_if_fail (gps_manager); + g_return_if_fail (gps_manager->status_cb); + + switch(status){ + case GEOCLUE_STATUS_ERROR: + case GEOCLUE_STATUS_UNAVAILABLE: + case GEOCLUE_STATUS_ACQUIRING: + MOD_LOGD("GEOCLUE_STATUS_ACQUIRING/ERROR/UNAVAILABLE"); + gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata); + break; + case GEOCLUE_STATUS_AVAILABLE: + MOD_LOGD("GEOCLUE_STATUS_AVAILABLE"); + gps_manager->status_cb(TRUE, LOCATION_STATUS_3D_FIX, gps_manager->userdata); + break; + default: + break; + } +} + +static void +satellite_callback (GeoclueSatellite *satellite, + int timestamp, + int satellite_used, + int satellite_visible, + GArray *used_prn, + GPtrArray *sat_info, + gpointer userdata) +{ + int idx; + + MOD_LOGD("satellite_callback!!!\n"); + MOD_LOGD("timestamp: %d", timestamp); + MOD_LOGD("satellite_used: %d", satellite_used); + MOD_LOGD("satellite_visible: %d", satellite_visible); + + for (idx = 0; idx < satellite_used; idx++) { + MOD_LOGD ("used_prn[%d] : %d", idx, g_array_index (used_prn, guint, idx)); + } + for (idx = 0; idx < satellite_visible; idx++) { + GValueArray *vals = (GValueArray*)g_ptr_array_index (sat_info, idx); + gint prn = g_value_get_int (g_value_array_get_nth (vals, 0)); + gint elev = g_value_get_int (g_value_array_get_nth (vals, 1)); + gint azim = g_value_get_int (g_value_array_get_nth (vals, 2)); + gint snr = g_value_get_int (g_value_array_get_nth (vals, 3)); + MOD_LOGD ("visible_prn[%d] : elev %d azim %d snr %d", prn, elev, azim, snr); + } +} +static void +nmea_callback (GeoclueNmea *nmea, + int timestamp, + char *data, + gpointer userdata) +{ +} + +static void +position_callback (GeocluePosition *position, + GeocluePositionFields fields, + int timestamp, + double latitude, + double longitude, + double altitude, + GeoclueAccuracy *accuracy, + gpointer userdata) +{ + GpsManagerData* gps_manager = (GpsManagerData*)userdata; + g_return_if_fail (gps_manager); + g_return_if_fail (gps_manager->pos_cb); + + GeoclueAccuracyLevel level; + double horiz_acc; + double vert_acc; + geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, &vert_acc); + + LocationPosition *pos = NULL; + LocationAccuracy *acc = NULL; + + if ((fields & GEOCLUE_POSITION_FIELDS_LATITUDE) && + (fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) { + if (fields & GEOCLUE_POSITION_FIELDS_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); + } + } else { + pos = location_position_new (0.0, + 0.0, + 0.0, + 0.0, + LOCATION_STATUS_NO_FIX); + } + + if (accuracy) { + GeoclueAccuracyLevel level; + double horiz_acc; + double vert_acc; + geoclue_accuracy_get_details (accuracy, &level, &horiz_acc, &vert_acc); + acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc); + } else { + acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, horiz_acc, vert_acc); + } + + MOD_LOGD("time(%d) lat(%f) long(%f) alt(%f) status(%d) acc_level(%d) hoz_acc(%f) vert_acc(%f)", + pos->timestamp, pos->latitude, pos->longitude, pos->altitude, pos->status, + acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); + + gps_manager->pos_cb(TRUE, pos, acc, gps_manager->userdata); + location_position_free (pos); + location_accuracy_free (acc); +} + + +static void +velocity_callback (GeoclueVelocity *velocity, + GeoclueVelocityFields fields, + int timestamp, + double speed, + double direction, + double climb, + gpointer userdata) +{ + GpsManagerData* gps_manager = (GpsManagerData*)userdata; + g_return_if_fail (gps_manager); + g_return_if_fail (gps_manager->vel_cb); + + LocationVelocity *vel = NULL; + LocationAccuracy *acc = NULL; + + if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && + fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) { + if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB) vel = location_velocity_new (timestamp, speed, direction, climb); + else vel = location_velocity_new (timestamp, speed, direction, 0); + acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0); + } else { + vel = location_velocity_new (0, 0, 0, 0); + acc = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0); + } + MOD_LOGD("timestamp(%d) speed(%f) direction(%f) climb(%f) acc_level(%d) hoz_acc(%f) vert_acc(%f)", + vel->timestamp, vel->speed, vel->direction, vel->climb, + acc->level, acc->horizontal_accuracy, acc->vertical_accuracy); + + gps_manager->vel_cb(TRUE, vel, acc, gps_manager->userdata); + location_velocity_free (vel); + location_accuracy_free (acc); +} + +static void +unref_gps_manager(GpsManagerData* gps_manager) +{ + if(gps_manager->pos) { + g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gps_manager->pos)), G_CALLBACK (status_callback), gps_manager); + g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gps_manager->pos)), G_CALLBACK (position_callback), gps_manager); + g_object_unref (gps_manager->pos); + gps_manager->pos = NULL; + } + + if(gps_manager->vel){ + g_signal_handlers_disconnect_by_func(G_OBJECT (GEOCLUE_PROVIDER(gps_manager->vel)), G_CALLBACK (velocity_callback), gps_manager); + g_object_unref (gps_manager->vel); + gps_manager->vel = NULL; + } + + if(gps_manager->nmea) { + g_object_unref (gps_manager->nmea); + gps_manager->nmea = NULL; + } + + if(gps_manager->sat) { + g_object_unref (gps_manager->sat); + gps_manager->sat = NULL; + } + gps_manager->is_started = FALSE; +} + +static gboolean +ref_gps_manager(GpsManagerData* gps_manager) +{ + if(gps_manager->is_started == TRUE){ + MOD_LOGW ("gps-manager is alredy started"); + return TRUE; + } + + gchar *service, *path; + service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.GpsManager"); + path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/GpsManager"); + if(!gps_manager->pos){ + gps_manager->pos = geoclue_position_new (service, path); + } + if(!gps_manager->vel){ + gps_manager->vel = geoclue_velocity_new (service, path); + } + if(!gps_manager->nmea){ + gps_manager->nmea = geoclue_nmea_new (service, path); + } + if(!gps_manager->sat){ + gps_manager->sat = geoclue_satellite_new (service, path); + } + g_free (service); + g_free (path); + if (!gps_manager->pos || !gps_manager->vel || !gps_manager->nmea || !gps_manager->sat) { + MOD_LOGW ("Error while creating Geoclue object."); + unref_gps_manager(gps_manager); + return FALSE; + } + + gps_manager->is_started = TRUE; + int ret; + ret = g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gps_manager->pos)), "status-changed", G_CALLBACK (status_callback), gps_manager); + g_debug ("gsignal_connect status-changed %d", ret); + ret = g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gps_manager->pos)), "position-changed", G_CALLBACK (position_callback), gps_manager); + g_debug ("gsignal_connect position-changed %d", ret); + ret = g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gps_manager->vel)), "velocity-changed", G_CALLBACK (velocity_callback), gps_manager); + g_debug ("gsignal_connect velocity-changed %d", ret); + ret = g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gps_manager->sat)), "satellite-changed", G_CALLBACK (satellite_callback), gps_manager); + g_debug ("gsignal_connect satellite-changed %d", ret); + ret = g_signal_connect (G_OBJECT (GEOCLUE_PROVIDER(gps_manager->nmea)), "nmea-changed", G_CALLBACK (nmea_callback), gps_manager); + g_debug ("gsignal_connect nmea-changed %d", ret); + + return TRUE; +} + +static int +start (gpointer handle, + LocModStatusCB status_cb, + LocModPositionCB pos_cb, + LocModVelocityCB vel_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); + g_return_val_if_fail(vel_cb, LOCATION_ERROR_NOT_AVAILABLE); + + gps_manager->status_cb = status_cb; + gps_manager->pos_cb = pos_cb; + gps_manager->vel_cb = vel_cb; + gps_manager->userdata = userdata; + + if (!ref_gps_manager(gps_manager)) return LOCATION_ERROR_NOT_AVAILABLE; + 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->status_cb, LOCATION_ERROR_NOT_AVAILABLE); + unref_gps_manager(gps_manager); + gps_manager->status_cb (FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata); + return LOCATION_ERROR_NONE; +} + +static int +get_position(gpointer handle, + LocationPosition **position, + LocationAccuracy **accuracy) +{ + MOD_LOGD("get_position"); + GpsManagerData* gps_manager = (GpsManagerData*)handle; + g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(gps_manager->pos, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(position, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER); + + GeocluePositionFields fields; + int timestamp; + double lat, lon, alt; + GeoclueAccuracy *_accuracy = NULL; + GError *error = NULL; + + fields = geoclue_position_get_position (gps_manager->pos, ×tamp, + &lat, &lon, &alt, + &_accuracy, &error); + if (error) { + MOD_LOGD ("Error getting position: %s", error->message); + g_error_free (error); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE && + fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) { + if(fields & GEOCLUE_POSITION_FIELDS_ALTITUDE) *position = location_position_new (timestamp, lat, lon, alt, LOCATION_STATUS_3D_FIX); + else *position = location_position_new (timestamp, lat, lon, 0, LOCATION_STATUS_2D_FIX); + } else *position = location_position_new (0, 0, 0, 0, LOCATION_STATUS_NO_FIX); + + if (_accuracy) { + GeoclueAccuracyLevel level; + double horiz_acc; + double vert_acc; + geoclue_accuracy_get_details (_accuracy, &level, &horiz_acc, &vert_acc); + *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, horiz_acc, vert_acc); + geoclue_accuracy_free (_accuracy); + } else *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0); + + return LOCATION_ERROR_NONE; +} + +static int +get_velocity(gpointer handle, + LocationVelocity **velocity, + LocationAccuracy **accuracy) +{ + MOD_LOGD("get_velocity"); + GpsManagerData* gps_manager = (GpsManagerData*)handle; + g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(gps_manager->vel, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(velocity, LOCATION_ERROR_PARAMETER); + g_return_val_if_fail(accuracy, LOCATION_ERROR_PARAMETER); + + GeoclueVelocityFields fields; + int timestamp; + double spd, dir, climb; + GError *error = NULL; + + fields = geoclue_velocity_get_velocity (gps_manager->vel, ×tamp, + &spd, &dir, &climb, + &error); + if (error) { + MOD_LOGD ("Error getting velocity: %s", error->message); + g_error_free (error); + return LOCATION_ERROR_NOT_AVAILABLE; + } + + if (fields & GEOCLUE_VELOCITY_FIELDS_SPEED && + fields & GEOCLUE_VELOCITY_FIELDS_DIRECTION) { + if (fields & GEOCLUE_VELOCITY_FIELDS_CLIMB) *velocity = location_velocity_new (timestamp, spd, dir, climb); + else *velocity = location_velocity_new (timestamp, spd, dir, 0); + *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_DETAILED, 0, 0); + } else { + *velocity = location_velocity_new (0, 0, 0, 0); + *accuracy = location_accuracy_new (LOCATION_ACCURACY_LEVEL_NONE, 0, 0); + } + 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(gps_manager->nmea, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(nmea_data, LOCATION_ERROR_PARAMETER); + + gboolean ret = FALSE; + int timestamp = 0; + char* _nmea_data = NULL; + GError *error = NULL; + ret = geoclue_nmea_get_nmea (gps_manager->nmea, ×tamp, &_nmea_data, &error); + if( !ret && error) { + MOD_LOGD ("\t Error getting nmea: %s", error->message); + g_error_free (error); + return LOCATION_ERROR_NOT_AVAILABLE; + } + *nmea_data = g_strdup(_nmea_data); + + return LOCATION_ERROR_NONE; +} + +static int +get_satellite(gpointer handle, + LocationSatellite **satellite) +{ + MOD_LOGD("get_satellite"); + GpsManagerData* gps_manager = (GpsManagerData*)handle; + g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(gps_manager->sat, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(satellite, LOCATION_ERROR_PARAMETER); + + int timestamp = 0; + int idx = 0; + int sat_used = 0; + int sat_vis = 0; + GArray *u_prn = NULL; + GPtrArray *sat_info = NULL; + GError *error = NULL; + + geoclue_satellite_get_satellite (gps_manager->sat, ×tamp, &sat_used, &sat_vis, &u_prn, &sat_info, &error); + if (error) { + MOD_LOGW("\t Error getting satellite: %s", error->message); + g_error_free (error); + return LOCATION_ERROR_NOT_AVAILABLE; + } + *satellite = location_satellite_new (sat_vis); + + for (idx=0; idxdevname, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER); + MOD_LOGD("set_devname: %s --> %s", gps_manager->devname, devname); + g_stpcpy(gps_manager->devname, devname); + + return LOCATION_ERROR_NONE; +} + + +static int +get_devname(gpointer handle, + char **devname) +{ + GpsManagerData* gps_manager = (GpsManagerData*)handle; + g_return_val_if_fail(gps_manager, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(gps_manager->devname, LOCATION_ERROR_NOT_AVAILABLE); + g_return_val_if_fail(devname, LOCATION_ERROR_PARAMETER); + *devname = g_strdup(gps_manager->devname); + MOD_LOGD("get_devname: %s", *devname); + + 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->stop = stop ; + ops->get_position = get_position; + ops->get_velocity = get_velocity; + Dl_info info; + if (dladdr(&get_position, &info) == 0) { + MOD_LOGD ("Failed to get module name"); + } else if (g_str_has_prefix(info.dli_fname, "gps")) { + ops->get_nmea = get_nmea; + ops->get_satellite = get_satellite; + ops->set_devname = set_devname; + ops->get_devname = get_devname; + } + + GpsManagerData* gps_manager = g_new0(GpsManagerData, 1); + g_return_val_if_fail(gps_manager, NULL); + + g_stpcpy(gps_manager->devname, "/dev/ttySAC1"); + gps_manager->pos = NULL; + gps_manager->vel = NULL; + gps_manager->nmea = NULL; + gps_manager->sat = NULL; + gps_manager->status_cb= NULL; + gps_manager->pos_cb = NULL; + gps_manager->vel_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; + unref_gps_manager(gps_manager); + if(gps_manager->status_cb) gps_manager->status_cb(FALSE, LOCATION_STATUS_NO_FIX, gps_manager->userdata); + g_free(gps_manager); +} diff --git a/packaging/gps-manager.spec b/packaging/gps-manager.spec new file mode 100644 index 0000000..a541a39 --- /dev/null +++ b/packaging/gps-manager.spec @@ -0,0 +1,95 @@ +%define PREFIX /usr +%define DATADIR /opt + +Name: gps-manager +Summary: Location Based Services server +Version: 0.3.5 +Release: 1 +Group: devel +License: Samsung +Source0: %{name}-%{version}.tar.gz +BuildRequires: pkgconfig(sysman) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(msg-service) +BuildRequires: pkgconfig(pmapi) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(network) +BuildRequires: pkgconfig(tapi) +BuildRequires: pkgconfig(heynoti) +BuildRequires: cmake +Requires(post): /usr/bin/vconftool +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +Location Based Services server binaries and libraries + +%package devel +Summary: LBS Agps Server (devel) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Location Based Services development headers + +%prep +%setup -q + +%build + +%autogen + +mkdir -p build +cd build +%ifarch %{arm} +../configure --prefix=%{_prefix} --datadir=%{DATADIR} --enable-gps +%else +../configure --prefix=%{_prefix} --datadir=%{DATADIR} --disable-gps +%endif + +make + +cd .. + +%install + +rm -rf %{buildroot} +cd build +%make_install +cd .. + + +%post + +/sbin/ldconfig + +vconftool set -t int memory/gps/state 0 -i +vconftool set -t int db/lbs/GpsOperationMode "1" -f +vconftool set -t int db/lbs/GpsStartingMode "0" -f +vconftool set -t int db/lbs/GpsTrackingMode "1" -f +vconftool set -t int db/lbs/GpsPositionMode "1" -f +vconftool set -t string db/lbs/SUPL_SERVER "your.supl-server.com" -f +vconftool set -t int db/lbs/SUPL_PORT "7275" -f +vconftool set -t int db/lbs/AgpsSsl "1" -f +vconftool set -t int db/lbs/AgpsBearer "0" -f +vconftool set -t int db/lbs/NMEALoggingEnable "0" -f +vconftool set -t int db/lbs/NMEAReplayMode "0" -f +vconftool set -t int db/lbs/GpsAccuracy "100" -f + +%postun +/sbin/ldconfig + +%files +%defattr(-,root,root,-) +%attr(0700,root,root) /etc/rc.d/init.d/gps-manager +%attr(0700,root,root) /etc/rc.d/rc3.d/S90gps-manager +%attr(0700,root,root) /etc/rc.d/rc5.d/S90gps-manager +%{_bindir}/gps-manager + +%files devel +%defattr(-,root,root,-) +%{_includedir}/gps-plugin/gps_manager_plugin_intf.h +%{_includedir}/gps-plugin/gps_manager_data_types.h +%{_includedir}/gps-plugin/gps_manager_extra_data_types.h +%{_libdir}/pkgconfig/gps-manager-plugin.pc