diff options
author | Raghuram Subramani <raghus2247@gmail.com> | 2024-10-17 09:31:12 +0530 |
---|---|---|
committer | Raghuram Subramani <raghus2247@gmail.com> | 2024-10-17 11:53:26 +0530 |
commit | baa3641d5f8e64288f45432d6e4989701dbbcc0f (patch) | |
tree | 1ba8efafae76794db4d0853462f04c71d1f2e3e6 /gps/gnsspps | |
parent | 360bc96adec406327820363cd5f79d3d0edbddf7 (diff) |
msm8996-common: Import newer GPS stack from xiaomi_msm8996-common
Change-Id: I5afe78048c4af3648b2d267d71a58b63b9decbc9
Diffstat (limited to 'gps/gnsspps')
-rw-r--r-- | gps/gnsspps/Android.mk | 3 | ||||
-rw-r--r-- | gps/gnsspps/Makefile.am | 37 | ||||
-rw-r--r-- | gps/gnsspps/configure.ac | 70 | ||||
-rw-r--r-- | gps/gnsspps/gnsspps.c | 231 | ||||
-rw-r--r-- | gps/gnsspps/gnsspps.pc.in | 10 |
5 files changed, 217 insertions, 134 deletions
diff --git a/gps/gnsspps/Android.mk b/gps/gnsspps/Android.mk index f87b674..ef43979 100644 --- a/gps/gnsspps/Android.mk +++ b/gps/gnsspps/Android.mk @@ -4,6 +4,9 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := libgnsspps +LOCAL_SANITIZE += $(GNSS_SANITIZE) +# activate the following line for debug purposes only, comment out for production +#LOCAL_SANITIZE_DIAG += $(GNSS_SANITIZE_DIAG) LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 LOCAL_MODULE_TAGS := optional diff --git a/gps/gnsspps/Makefile.am b/gps/gnsspps/Makefile.am deleted file mode 100644 index c990be0..0000000 --- a/gps/gnsspps/Makefile.am +++ /dev/null @@ -1,37 +0,0 @@ -AM_CFLAGS = \ - $(LOCPLA_CFLAGS) \ - $(GPSUTILS_CFLAGS) \ - -I$(WORKSPACE)/system/core/include \ - -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 deleted file mode 100644 index eb87bc1..0000000 --- a/gps/gnsspps/configure.ac +++ /dev/null @@ -1,70 +0,0 @@ -# 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([GPSUTILS], [gps-utils]) -AC_SUBST([GPSUTILS_CFLAGS]) -AC_SUBST([GPSUTILS_LIBS]) - -AC_ARG_WITH([locpla_includes], - AC_HELP_STRING([--with-locpla-includes=@<:@dir@:>@], - [Specify the path to locpla-includes in loc-pla_git.bb]), - [locpla_incdir=$withval], - with_locpla_includes=no) - -if test "x${with_locpla_includes}" != "xno"; then - AC_SUBST(LOCPLA_CFLAGS, "-I${locpla_incdir}") -fi - -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 index 70b23f5..b27fd77 100644 --- a/gps/gnsspps/gnsspps.c +++ b/gps/gnsspps/gnsspps.c @@ -35,16 +35,42 @@ #include <pthread.h> #include <timepps.h> #include <linux/types.h> +#include <stdbool.h> +#include "loc_cfg.h" +#include <inttypes.h> +#include <time.h> +#include <math.h> + +#define BILLION_NSEC (1E9) + +typedef struct timespec pps_sync_time; //DRsync kernel timestamp static struct timespec drsyncKernelTs = {0,0}; //DRsync userspace timestamp static struct timespec drsyncUserTs = {0,0}; + +static struct timespec prevDrsyncKernelTs = {0,0}; + //flag to stop fetching timestamp static int isActive = 0; static pps_handle handle; static pthread_mutex_t ts_lock; +static int skipPPSPulseCnt = 0; +static int gnssOutageInSec = 1; +static loc_param_s_type gps_conf_param_table[] = +{ + {"IGNORE_PPS_PULSE_COUNT", &skipPPSPulseCnt, NULL, 'n'}, + {"GNSS_OUTAGE_DURATION", &gnssOutageInSec, NULL, 'n'} +}; + +typedef enum { + KERNEL_REPORTED_CLOCK_BOOTTIME = 0, + KERNEL_REPORTED_CLOCK_REALTIME, + KERNEL_REPORTED_CLOCK_UNKNOWN = 0xfe, + KERNEL_REPORTED_CLOCK_MAX = 0xff +} kernel_reported_time_e; /* checks the PPS source and opens it */ int check_device(char *path, pps_handle *handle) @@ -52,7 +78,7 @@ 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); + ret = open(path, O_RDONLY); if (ret < 0) { LOC_LOGV("%s:%d unable to open device %s", __func__, __LINE__, path); @@ -69,34 +95,205 @@ int check_device(char *path, pps_handle *handle) return 0; } + +/* calculate the time difference between two given times in argument - +** returns the result in timeDifference parametter*/ +static inline void calculate_time_difference(pps_sync_time time1, + pps_sync_time time2, pps_sync_time* timeDifference) +{ + if (time2.tv_nsec < time1.tv_nsec) { + timeDifference->tv_sec = time2.tv_sec - 1 - time1.tv_sec; + timeDifference->tv_nsec = BILLION_NSEC + time2.tv_nsec - time1.tv_nsec; + } else { + timeDifference->tv_sec = time2.tv_sec - time1.tv_sec; + timeDifference->tv_nsec = time2.tv_nsec - time1.tv_nsec; + } +} + +/*add two timespec values and return the result in third resultTime parameter*/ +static inline void pps_sync_time_add(pps_sync_time time1, + pps_sync_time time2, pps_sync_time* resultTime) +{ + if (time2.tv_nsec + time1.tv_nsec >= BILLION_NSEC) { + resultTime->tv_sec = time2.tv_sec + time1.tv_sec + 1; + resultTime->tv_nsec = time2.tv_nsec + time1.tv_nsec - BILLION_NSEC; + } else { + resultTime->tv_sec = time2.tv_sec + time1.tv_sec; + resultTime->tv_nsec = time2.tv_nsec + time1.tv_nsec; + } +} + +#define MAX_REALTIME_OFFSET_DELTA_DIFFERENCE 10 +#define MAX_PPS_KERNEL_TO_USERSPACE_LATENCY 100 /*in milli-second*/ + +static inline double convertTimeToMilliSec(pps_sync_time timeToConvert) +{ + return ((double)(timeToConvert.tv_sec * 1000) + (double)(timeToConvert.tv_nsec * 0.000001)); +} + +/*returnValue: 1 = offsetTime OK, 0 = offsetTime NOT OK*/ +static inline bool isTimeOffsetOk(pps_sync_time offsetTime) +{ + double offsetInMillis = convertTimeToMilliSec(offsetTime); + return (fabs(offsetInMillis) <= MAX_REALTIME_OFFSET_DELTA_DIFFERENCE)? true: false; +} + +/*check whether kernel PPS timestamp is a CLOCK_BOOTTIME or CLOCK_REALTIME*/ +static kernel_reported_time_e get_reported_time_type(pps_sync_time userBootTs, + pps_sync_time userRealTs, + pps_sync_time kernelTs) +{ + double userRealMs, userBootMs, kernelTsMs; + kernel_reported_time_e reportedTime = KERNEL_REPORTED_CLOCK_UNKNOWN; + + userRealMs = convertTimeToMilliSec(userRealTs); + userBootMs = convertTimeToMilliSec(userBootTs); + kernelTsMs = convertTimeToMilliSec(kernelTs); + + if(fabs(userBootMs - kernelTsMs) <= MAX_PPS_KERNEL_TO_USERSPACE_LATENCY) { + reportedTime = KERNEL_REPORTED_CLOCK_BOOTTIME; + } else if (fabs(userRealMs - kernelTsMs) <= MAX_PPS_KERNEL_TO_USERSPACE_LATENCY) { + reportedTime = KERNEL_REPORTED_CLOCK_REALTIME; + } else { + reportedTime = KERNEL_REPORTED_CLOCK_UNKNOWN; + } + + LOC_LOGV("[%s] Detected PPS timestamp type (0:Boot, 1:Real, 0xfe:Unknown):0x%x", + __func__, reportedTime); + + return reportedTime; +} + +/*compute_real_to_boot_time - converts the kernel real time stamp to boot time reference*/ +static int compute_real_to_boot_time(pps_info ppsFetchTime) +{ + int retVal = 0; + /*Offset between REAL_TIME to BOOT_TIME*/ + static pps_sync_time time_offset = {0, 0}; + pps_sync_time drSyncUserRealTs, drSyncUserBootTs; + pps_sync_time deltaRealToBootTime = {0, 0}; + pps_sync_time deltaOffsetTime = {0, 0}; + kernel_reported_time_e ppsTimeType; + + retVal = clock_gettime(CLOCK_BOOTTIME,&drSyncUserBootTs); + if (retVal != 0) { + LOC_LOGE("[%s]Error Reading CLOCK_BOOTTIME", __func__); + retVal = -1; + goto exit0; + } + retVal = clock_gettime(CLOCK_REALTIME,&drSyncUserRealTs); + if (retVal != 0){ + LOC_LOGE("[%s]Error Reading CLOCK_REALTIME", __func__); + retVal = -1; + goto exit0; + } + + ppsTimeType = get_reported_time_type(drSyncUserBootTs, drSyncUserRealTs, ppsFetchTime); + + if (KERNEL_REPORTED_CLOCK_BOOTTIME == ppsTimeType) { + + /*Store PPS kernel time*/ + drsyncKernelTs.tv_sec = ppsFetchTime.tv_sec; + drsyncKernelTs.tv_nsec = ppsFetchTime.tv_nsec; + /*Store User PPS fetch time*/ + drsyncUserTs.tv_sec = drSyncUserBootTs.tv_sec; + drsyncUserTs.tv_nsec = drSyncUserBootTs.tv_nsec; + + LOC_LOGV("[compute_real_to_boot] PPS TimeType CLOCK_BOOTTIME -- report as is"); + retVal = 0; + } else if (KERNEL_REPORTED_CLOCK_REALTIME == ppsTimeType) { + + /* Calculate time difference between REALTIME to BOOT_TIME*/ + calculate_time_difference(drSyncUserRealTs, drSyncUserBootTs, &deltaRealToBootTime); + + /* Calculate the time difference between stored offset and computed one now*/ + calculate_time_difference(time_offset, deltaRealToBootTime, &deltaOffsetTime); + + if ((0 == time_offset.tv_sec && 0 == time_offset.tv_nsec) || + (isTimeOffsetOk(deltaOffsetTime))) { + /* if Time Offset does not change beyond threshold then + ** convert to boot time*/ + drsyncUserTs.tv_sec = drSyncUserBootTs.tv_sec; + drsyncUserTs.tv_nsec = drSyncUserBootTs.tv_nsec; + pps_sync_time_add(ppsFetchTime, deltaRealToBootTime, &drsyncKernelTs); + retVal = 0; + } else { + /*The offset is too high, jump detected in realTime tick, either + ** wall clock changed by user of NTP, skip PPS, re-sync @ next tick + */ + LOC_LOGE("[%s] Jump detected in CLOCK_REALTIME - Offset %ld:%ld", __func__, + deltaOffsetTime.tv_sec, deltaOffsetTime.tv_nsec); + retVal = -1; + } + time_offset.tv_sec = deltaRealToBootTime.tv_sec; + time_offset.tv_nsec = deltaRealToBootTime.tv_nsec; + + LOC_LOGV("[compute_real_to_boot] KernelRealTs %ld:%ld ComputedTs %ld:%ld RealTs %ld:%ld BootTs %ld:%ld Offset %ld:%ld retVal %d ", + ppsFetchTime.tv_sec, ppsFetchTime.tv_nsec, + drsyncKernelTs.tv_sec, drsyncKernelTs.tv_nsec, drSyncUserRealTs.tv_sec, + drSyncUserRealTs.tv_nsec, drsyncUserTs.tv_sec, drsyncUserTs.tv_nsec, + time_offset.tv_sec, time_offset.tv_nsec, retVal); + } else { + LOC_LOGV("[compute_real_to_boot] PPS TimeType Unknown -- KernelTs %ld:%ld userRealTs %ld:%ld userBootTs %ld:%ld", + ppsFetchTime.tv_sec, ppsFetchTime.tv_nsec, + drSyncUserRealTs.tv_sec, drSyncUserRealTs.tv_nsec, + drsyncUserTs.tv_sec, drsyncUserTs.tv_nsec); + retVal = -1; + } + +exit0: + return retVal; + +} + + /* fetches the timestamp from the PPS source */ int read_pps(pps_handle *handle) { struct timespec timeout; pps_info infobuf; int ret; + static bool isFirstPulseReceived = false; + static unsigned int skipPulseCnt = 0; // 3sec timeout timeout.tv_sec = 3; timeout.tv_nsec = 0; - ret = pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,&timeout); + 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; - } + if (ret < 0 && ret !=-EINTR) + { + LOC_LOGV("%s:%d pps_fetch() error %d", __func__, __LINE__, ret); + return -1; + } + if (!isFirstPulseReceived && (skipPPSPulseCnt > 0)) { + skipPulseCnt = skipPPSPulseCnt; + isFirstPulseReceived = true; + LOC_LOGV("%s:%d first pps pulse received %ld (sec) %ld (nsec)", + __func__, __LINE__, infobuf.tv_sec, infobuf.tv_nsec) + }else if (isFirstPulseReceived && (skipPPSPulseCnt > 0) && + ((infobuf.tv_sec - prevDrsyncKernelTs.tv_sec) > gnssOutageInSec)) { + LOC_LOGV("%s:%d long RF outage detected, ignore next %d PPS Pulses", + __func__, __LINE__, skipPPSPulseCnt) + skipPulseCnt = skipPPSPulseCnt; + } + prevDrsyncKernelTs.tv_sec = infobuf.tv_sec; + prevDrsyncKernelTs.tv_nsec = infobuf.tv_nsec; + /* check if this dr sync pulse need to be ignored or not*/ + if (skipPulseCnt > 0) { + LOC_LOGV("%s:%d skip pps count %d, ignoring this pps pulse %ld (sec) %ld (nsec)", + __func__,__LINE__, skipPulseCnt, infobuf.tv_sec, infobuf.tv_nsec); + skipPulseCnt--; + return 0; + } + /* update dr syncpulse time*/ - 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); + pthread_mutex_lock(&ts_lock); + + ret = compute_real_to_boot_time(infobuf); + + pthread_mutex_unlock(&ts_lock); - if(ret != 0) - { - LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__); - } return 0; } @@ -136,7 +333,7 @@ int initPPS(char *devname) LOC_LOGV("%s:%d Could not find PPS source", __func__, __LINE__); return 0; } - + UTIL_READ_CONF(LOC_PATH_GPS_CONF, gps_conf_param_table); pthread_mutex_init(&ts_lock,NULL); pid = pthread_create(&thread,NULL,&thread_handle,NULL); diff --git a/gps/gnsspps/gnsspps.pc.in b/gps/gnsspps/gnsspps.pc.in deleted file mode 100644 index 8931ebd..0000000 --- a/gps/gnsspps/gnsspps.pc.in +++ /dev/null @@ -1,10 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: gnsspps -Description: QTI GPS gnsspps -Version: @VERSION -Libs: -L${libdir} -lgnsspps -Cflags: -I${includedir}/gnsspps |