diff --git a/device.mk b/device.mk index 95b00be..b4bdb94 100644 --- a/device.mk +++ b/device.mk @@ -182,19 +182,15 @@ PRODUCT_PACKAGES += \ android.hardware.gatekeeper@1.0-impl \ android.hardware.gatekeeper@1.0-service -# GNSS HAL -PRODUCT_PACKAGES += \ - android.hardware.gnss@1.0-impl - # GPS PRODUCT_PACKAGES += \ - libgps.utils \ - gps.default \ libgnss \ - liblocation_api \ + libgnsspps \ android.hardware.gnss@1.0-impl-qti \ - libloc_api-rpc-qc \ - libshims_get_process_name + android.hardware.gnss@1.0-impl \ + android.hardware.gnss@1.0-service-qti \ + libqsap_sdk \ + libqsap_shim # health PRODUCT_PACKAGES += \ diff --git a/gps/android/AGnss.cpp b/gps/android/AGnss.cpp index e76671c..6213a08 100644 --- a/gps/android/AGnss.cpp +++ b/gps/android/AGnss.cpp @@ -72,7 +72,10 @@ void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status){ } st.ipV4Addr = status.ipV4Addr; - sAGnssCbIface->agnssStatusIpV4Cb(st); + auto r = sAGnssCbIface->agnssStatusIpV4Cb(st); + if (!r.isOk()) { + LOC_LOGE("Error invoking AGNSS status cb %s", r.description().c_str()); + } } Return AGnss::setCallback(const sp& callback) { diff --git a/gps/android/Android.mk b/gps/android/Android.mk index 03ea1f3..5f17415 100644 --- a/gps/android/Android.mk +++ b/gps/android/Android.mk @@ -52,7 +52,9 @@ include $(BUILD_SHARED_LIBRARY) BUILD_GNSS_HIDL_SERVICE := true ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true) ifneq ($(LW_FEATURE_SET),true) +ifneq ($(TARGET_HAS_LOW_RAM),true) BUILD_GNSS_HIDL_SERVICE := false +endif # TARGET_HAS_LOW_RAM endif # LW_FEATURE_SET endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET @@ -61,6 +63,8 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.gnss@1.0-service-qti LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES) LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_VENDOR_MODULE := true +LOCAL_MODULE_OWNER := qti LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc LOCAL_SRC_FILES := \ service.cpp \ diff --git a/gps/android/location_api/GnssAPIClient.cpp b/gps/android/location_api/GnssAPIClient.cpp index 0cccb27..2745f56 100644 --- a/gps/android/location_api/GnssAPIClient.cpp +++ b/gps/android/location_api/GnssAPIClient.cpp @@ -278,7 +278,9 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; - if (mGnssCbIface != nullptr) { + sp gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { uint32_t data = 0; if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || @@ -293,13 +295,13 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) data |= IGnssCallback::Capabilities::MSB; if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) data |= IGnssCallback::Capabilities::MSA; - auto r = mGnssCbIface->gnssSetCapabilitesCb(data); + auto r = gnssCbIface->gnssSetCapabilitesCb(data); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s", __func__, r.description().c_str()); } } - if (mGnssCbIface != nullptr) { + if (gnssCbIface != nullptr) { IGnssCallback::GnssSystemInfo gnssInfo; if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) { gnssInfo.yearOfHw = 2017; @@ -309,7 +311,7 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) gnssInfo.yearOfHw = 2015; } LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); - auto r = mGnssCbIface->gnssSetSystemInfoCb(gnssInfo); + auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s", __func__, r.description().c_str()); @@ -320,10 +322,12 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) void GnssAPIClient::onTrackingCb(Location location) { LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); - if (mGnssCbIface != nullptr) { + sp gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { GnssLocation gnssLocation; convertGnssLocation(location, gnssLocation); - auto r = mGnssCbIface->gnssLocationCb(gnssLocation); + auto r = gnssCbIface->gnssLocationCb(gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssLocationCb description=%s", __func__, r.description().c_str()); @@ -334,8 +338,9 @@ void GnssAPIClient::onTrackingCb(Location location) void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) { LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); + sp gnssNiCbIface = mGnssNiCbIface; - if (mGnssNiCbIface == nullptr) { + if (gnssNiCbIface == nullptr) { LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); return; } @@ -400,16 +405,18 @@ void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotificatio notificationGnss.notificationIdEncoding = IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; - mGnssNiCbIface->niNotifyCb(notificationGnss); + gnssNiCbIface->niNotifyCb(notificationGnss); } void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) { LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); - if (mGnssCbIface != nullptr) { + sp gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { IGnssCallback::GnssSvStatus svStatus; convertGnssSvStatus(gnssSvNotification, svStatus); - auto r = mGnssCbIface->gnssSvStatusCb(svStatus); + auto r = gnssCbIface->gnssSvStatusCb(svStatus); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSvStatusCb description=%s", __func__, r.description().c_str()); @@ -419,10 +426,12 @@ void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) { - if (mGnssCbIface != nullptr) { + sp gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { android::hardware::hidl_string nmeaString; nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); - auto r = mGnssCbIface->gnssNmeaCb( + auto r = gnssCbIface->gnssNmeaCb( static_cast(gnssNmeaNotification.timestamp), nmeaString); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__, @@ -434,13 +443,15 @@ void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) void GnssAPIClient::onStartTrackingCb(LocationError error) { LOC_LOGD("%s]: (%d)", __FUNCTION__, error); - if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { - auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); + sp gnssCbIface = mGnssCbIface; + + if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { + auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s", __func__, r.description().c_str()); } - r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); + r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s", __func__, r.description().c_str()); @@ -451,13 +462,15 @@ void GnssAPIClient::onStartTrackingCb(LocationError error) void GnssAPIClient::onStopTrackingCb(LocationError error) { LOC_LOGD("%s]: (%d)", __FUNCTION__, error); - if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { - auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); + sp gnssCbIface = mGnssCbIface; + + if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { + auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s", __func__, r.description().c_str()); } - r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); + r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s", __func__, r.description().c_str()); diff --git a/gps/gnsspps/Android.mk b/gps/gnsspps/Android.mk new file mode 100644 index 0000000..f87b674 --- /dev/null +++ b/gps/gnsspps/Android.mk @@ -0,0 +1,36 @@ +ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),) +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libgnsspps +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 +LOCAL_MODULE_TAGS := optional + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libgps.utils \ + liblog + +LOCAL_SRC_FILES += \ + gnsspps.c + +LOCAL_CFLAGS += \ + -fno-short-enums \ + -D_ANDROID_ + +## Includes +LOCAL_HEADER_LIBRARIES := \ + libgps.utils_headers \ + libloc_pla_headers +LOCAL_CFLAGS += $(GNSS_CFLAGS) +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libgnsspps_headers +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +include $(BUILD_HEADER_LIBRARY) + +endif diff --git a/gps/gnsspps/Makefile.am b/gps/gnsspps/Makefile.am new file mode 100644 index 0000000..390c1cc --- /dev/null +++ b/gps/gnsspps/Makefile.am @@ -0,0 +1,36 @@ +AM_CFLAGS = \ + $(LOCPLA_CFLAGS) \ + $(GPSUTILS_CFLAGS) \ + -I./ + +ACLOCAL_AMFLAGS = -I m4 + +libgnsspps_la_SOURCES = \ + gnsspps.c + +if USE_GLIB +libgnsspps_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ +libgnsspps_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 +libgnsspps_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ +else +libgnsspps_la_CFLAGS = $(AM_CFLAGS) +libgnsspps_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0 +libgnsspps_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) +endif + +libgnsspps_la_LIBADD = -lstdc++ $(GPSUTILS_LIBS) + +library_include_HEADERS = \ + gnsspps.h + +#Create and Install libraries +lib_LTLIBRARIES = libgnsspps.la + +library_includedir = $(pkgincludedir) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gnsspps.pc +EXTRA_DIST = $(pkgconfig_DATA) + + + + diff --git a/gps/gnsspps/configure.ac b/gps/gnsspps/configure.ac new file mode 100644 index 0000000..b0ffa77 --- /dev/null +++ b/gps/gnsspps/configure.ac @@ -0,0 +1,64 @@ +# configure.ac -- Autoconf script for gps lbs-core +# +# Process this file with autoconf to produce a configure script + +# Requires autoconf tool later than 2.61 +AC_PREREQ(2.61) +# Initialize the gps lbs-core package version 1.0.0 +AC_INIT([gnsspps],1.0.0) +# Does not strictly follow GNU Coding standards +AM_INIT_AUTOMAKE([foreign]) +# Disables auto rebuilding of configure, Makefile.ins +AM_MAINTAINER_MODE +# Verifies the --srcdir is correct by checking for the path +AC_CONFIG_SRCDIR([Makefile.am]) +# defines some macros variable to be included by source +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. +AC_PROG_LIBTOOL +AC_PROG_CXX +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_AWK +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +PKG_PROG_PKG_CONFIG + +# Checks for libraries. +PKG_CHECK_MODULES([LOCPLA], [loc-pla]) +AC_SUBST([LOCPLA_CFLAGS]) +AC_SUBST([LOCPLA_LIBS]) + +PKG_CHECK_MODULES([GPSUTILS], [gps-utils]) +AC_SUBST([GPSUTILS_CFLAGS]) +AC_SUBST([GPSUTILS_LIBS]) + +AC_ARG_WITH([glib], + AC_HELP_STRING([--with-glib], + [enable glib, building HLOS systems which use glib])) + +if (test "x${with_glib}" = "xyes"); then + AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib]) + PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GThread >= 2.16 is required)) + PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GLib >= 2.16 is required)) + GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" + GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS" + + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) +fi + +AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes") + +AC_CONFIG_FILES([ \ + Makefile \ + gnsspps.pc + ]) + +AC_OUTPUT diff --git a/gps/gnsspps/gnsspps.c b/gps/gnsspps/gnsspps.c new file mode 100644 index 0000000..f92a862 --- /dev/null +++ b/gps/gnsspps/gnsspps.c @@ -0,0 +1,194 @@ +/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundatoin, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//DRsync kernel timestamp +static struct timespec drsyncKernelTs = {0,0}; +//DRsync userspace timestamp +static struct timespec drsyncUserTs = {0,0}; +//flag to stop fetching timestamp +static int isActive = 0; +static pps_handle handle; + +static pthread_mutex_t ts_lock; + + /* checks the PPS source and opens it */ +int check_device(char *path, pps_handle *handle) +{ + int ret; + + /* Try to find the source by using the supplied "path" name */ + ret = open(path, O_RDWR); + if (ret < 0) + { + LOC_LOGV("%s:%d unable to open device %s", __func__, __LINE__, path); + return ret; + } + + /* Open the PPS source */ + ret = pps_create(ret, handle); + if (ret < 0) + { + LOC_LOGV( "%s:%d cannot create a PPS source from device %s", __func__, __LINE__, path); + return -1; + } + return 0; +} + +/* fetches the timestamp from the PPS source */ +int read_pps(pps_handle *handle) +{ + struct timespec timeout; + pps_info infobuf; + int ret; + // 3sec timeout + timeout.tv_sec = 3; + timeout.tv_nsec = 0; + + ret = pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,&timeout); + + if (ret < 0 && ret !=-EINTR) + { + LOC_LOGV("%s:%d pps_fetch() error %d", __func__, __LINE__, ret); + return -1; + } + + pthread_mutex_lock(&ts_lock); + drsyncKernelTs.tv_sec = infobuf.tv_sec; + drsyncKernelTs.tv_nsec = infobuf.tv_nsec; + ret = clock_gettime(CLOCK_BOOTTIME,&drsyncUserTs); + pthread_mutex_unlock(&ts_lock); + + if(ret != 0) + { + LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__); + } + return 0; +} + +#ifdef __cplusplus +extern "C" { +#endif +/* infinitely calls read_pps() */ +void *thread_handle(void *input) +{ + int ret; + if(input != NULL) + { + LOC_LOGV("%s:%d Thread Input is present", __func__, __LINE__); + } + while(isActive) + { + ret = read_pps(&handle); + + if (ret == -1 && errno != ETIMEDOUT ) + { + LOC_LOGV("%s:%d Could not fetch PPS source", __func__, __LINE__); + } + } + return NULL; +} + +/* opens the device and fetches from PPS source */ +int initPPS(char *devname) +{ + int ret,pid; + pthread_t thread; + isActive = 1; + + ret = check_device(devname, &handle); + if (ret < 0) + { + LOC_LOGV("%s:%d Could not find PPS source", __func__, __LINE__); + return 0; + } + + pthread_mutex_init(&ts_lock,NULL); + + pid = pthread_create(&thread,NULL,&thread_handle,NULL); + if(pid != 0) + { + LOC_LOGV("%s:%d Could not create thread in InitPPS", __func__, __LINE__); + return 0; + } + return 1; +} + +/* stops fetching and closes the device */ +void deInitPPS() +{ + pthread_mutex_lock(&ts_lock); + isActive = 0; + pthread_mutex_unlock(&ts_lock); + + pthread_mutex_destroy(&ts_lock); + pps_destroy(handle); +} + +/* retrieves DRsync kernel timestamp,DRsync userspace timestamp + and updates current timestamp */ +/* Returns: + * 1. @Param out DRsync kernel timestamp + * 2. @Param out DRsync userspace timestamp + * 3. @Param out current timestamp + */ +int getPPS(struct timespec *fineKernelTs ,struct timespec *currentTs, + struct timespec *fineUserTs) +{ + int ret; + + pthread_mutex_lock(&ts_lock); + fineKernelTs->tv_sec = drsyncKernelTs.tv_sec; + fineKernelTs->tv_nsec = drsyncKernelTs.tv_nsec; + + fineUserTs->tv_sec = drsyncUserTs.tv_sec; + fineUserTs->tv_nsec = drsyncUserTs.tv_nsec; + + ret = clock_gettime(CLOCK_BOOTTIME,currentTs); + pthread_mutex_unlock(&ts_lock); + if(ret != 0) + { + LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__); + return 0; + } + return 1; +} + +#ifdef __cplusplus +} +#endif + diff --git a/gps/gnsspps/gnsspps.h b/gps/gnsspps/gnsspps.h new file mode 100644 index 0000000..3642f3b --- /dev/null +++ b/gps/gnsspps/gnsspps.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundatoin, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _GNSSPPS_H +#define _GNSSPPS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* opens the device and fetches from PPS source */ +int initPPS(char *devname); +/* updates the fine time stamp */ +int getPPS(struct timespec *current_ts, struct timespec *current_boottime, struct timespec *last_boottime); +/* stops fetching and closes the device */ +void deInitPPS(); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/gps/gnsspps/gnsspps.pc.in b/gps/gnsspps/gnsspps.pc.in new file mode 100644 index 0000000..604eedd --- /dev/null +++ b/gps/gnsspps/gnsspps.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnsspps +Description: QTI GPS drplugin-client +Version: @VERSION +Libs: -L${libdir} -lgnsspps +Cflags: -I${includedir}/gnsspps diff --git a/gps/gnsspps/timepps.h b/gps/gnsspps/timepps.h new file mode 100644 index 0000000..fe0d8f0 --- /dev/null +++ b/gps/gnsspps/timepps.h @@ -0,0 +1,106 @@ +/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundatoin, nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +#ifndef _TIMEPPS_H +#define _TIMEPPS_H + +#ifdef __cplusplus +extern "C" { +#endif +/* time of assert event */ +typedef struct timespec pps_info; +/* represents pps source */ +typedef int pps_handle; + + /* Open the PPS source */ +static __inline int pps_create(int source, pps_handle *handle) +{ + int ret; + struct pps_kparams dummy; + + if (!handle) + { + errno = EINVAL; + return -1; + } + /* check if current device is valid pps */ + ret = ioctl(source, PPS_GETPARAMS, &dummy); + if (ret) + { + errno = EOPNOTSUPP; + return -1; + } + *handle = source; + + return 0; +} +/* close the pps source */ +static __inline int pps_destroy(pps_handle handle) +{ + return close(handle); +} +/*reads timestamp from pps device*/ +static __inline int pps_fetch(pps_handle handle, const int tsformat, + pps_info *ppsinfobuf, + const struct timespec *timeout) +{ + struct pps_fdata fdata; + int ret; + + if (tsformat != PPS_TSFMT_TSPEC) + { + errno = EINVAL; + return -1; + } + if (timeout) + { + fdata.timeout.sec = timeout->tv_sec; + fdata.timeout.nsec = timeout->tv_nsec; + fdata.timeout.flags = ~PPS_TIME_INVALID; + } + else + { + fdata.timeout.flags = PPS_TIME_INVALID; + } + ret = ioctl(handle, PPS_FETCH, &fdata); + + ppsinfobuf->tv_sec = fdata.info.assert_tu.sec; + ppsinfobuf->tv_nsec = fdata.info.assert_tu.nsec; + + return ret; +} + +#ifdef __cplusplus +} +#endif +#endif