diff options
-rw-r--r-- | android/1.0/Android.mk | 1 | ||||
-rw-r--r-- | android/1.0/android.hardware.gnss@1.0-service-qti.xml | 35 | ||||
-rw-r--r-- | android/1.1/Android.mk | 1 | ||||
-rw-r--r-- | android/1.1/android.hardware.gnss@1.1-service-qti.xml | 35 | ||||
-rw-r--r-- | android/2.0/Android.mk | 1 | ||||
-rw-r--r-- | android/2.0/android.hardware.gnss@2.0-service-qti.xml | 36 | ||||
-rw-r--r-- | android/2.0/location_api/LocationUtil.cpp | 3 | ||||
-rw-r--r-- | build/target_specific_features.mk | 1 | ||||
-rw-r--r-- | core/ContextBase.cpp | 4 | ||||
-rw-r--r-- | core/ContextBase.h | 1 | ||||
-rw-r--r-- | core/SystemStatus.cpp | 27 | ||||
-rw-r--r-- | core/SystemStatus.h | 54 | ||||
-rw-r--r-- | etc/gps.conf | 6 | ||||
-rw-r--r-- | gnss/GnssAdapter.cpp | 88 | ||||
-rw-r--r-- | gnss/GnssAdapter.h | 2 | ||||
-rw-r--r-- | gnss/XtraSystemStatusObserver.cpp | 106 | ||||
-rw-r--r-- | gnss/XtraSystemStatusObserver.h | 29 | ||||
-rw-r--r-- | location/LocationDataTypes.h | 51 | ||||
-rw-r--r-- | utils/LocIpc.cpp | 462 | ||||
-rw-r--r-- | utils/LocIpc.h | 186 | ||||
-rw-r--r-- | utils/Makefile.am | 2 | ||||
-rw-r--r-- | utils/gps_extended_c.h | 76 | ||||
-rw-r--r-- | utils/loc_nmea.cpp | 34 |
23 files changed, 870 insertions, 371 deletions
diff --git a/android/1.0/Android.mk b/android/1.0/Android.mk index 122ff8d..5489f86 100644 --- a/android/1.0/Android.mk +++ b/android/1.0/Android.mk @@ -50,6 +50,7 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.gnss@1.0-service-qti +LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.0-service-qti.xml LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc diff --git a/android/1.0/android.hardware.gnss@1.0-service-qti.xml b/android/1.0/android.hardware.gnss@1.0-service-qti.xml new file mode 100644 index 0000000..46bcffb --- /dev/null +++ b/android/1.0/android.hardware.gnss@1.0-service-qti.xml @@ -0,0 +1,35 @@ +<!-- Copyright (c) 2019, 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 Foundation 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. +--> +<manifest version="1.0" type="device"> + <hal format="hidl"> + <name>android.hardware.gnss</name> + <transport>hwbinder</transport> + <fqname>@1.0::IGnss/default</fqname> + </hal> +</manifest> + diff --git a/android/1.1/Android.mk b/android/1.1/Android.mk index 5c97f40..0beaf20 100644 --- a/android/1.1/Android.mk +++ b/android/1.1/Android.mk @@ -51,6 +51,7 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.gnss@1.1-service-qti +LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@1.1-service-qti.xml LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_INIT_RC := android.hardware.gnss@1.1-service-qti.rc diff --git a/android/1.1/android.hardware.gnss@1.1-service-qti.xml b/android/1.1/android.hardware.gnss@1.1-service-qti.xml new file mode 100644 index 0000000..c9c83fb --- /dev/null +++ b/android/1.1/android.hardware.gnss@1.1-service-qti.xml @@ -0,0 +1,35 @@ +<!-- Copyright (c) 2019, 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 Foundation 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. +--> +<manifest version="1.0" type="device"> + <hal format="hidl"> + <name>android.hardware.gnss</name> + <transport>hwbinder</transport> + <fqname>@1.1::IGnss/default</fqname> + </hal> +</manifest> + diff --git a/android/2.0/Android.mk b/android/2.0/Android.mk index 2000bb8..c33a792 100644 --- a/android/2.0/Android.mk +++ b/android/2.0/Android.mk @@ -63,6 +63,7 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.gnss@2.0-service-qti +LOCAL_VINTF_FRAGMENTS := android.hardware.gnss@2.0-service-qti.xml LOCAL_VENDOR_MODULE := true LOCAL_MODULE_RELATIVE_PATH := hw LOCAL_INIT_RC := android.hardware.gnss@2.0-service-qti.rc diff --git a/android/2.0/android.hardware.gnss@2.0-service-qti.xml b/android/2.0/android.hardware.gnss@2.0-service-qti.xml new file mode 100644 index 0000000..ff9fb2c --- /dev/null +++ b/android/2.0/android.hardware.gnss@2.0-service-qti.xml @@ -0,0 +1,36 @@ +<!-- Copyright (c) 2019, 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 Foundation 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. +--> +<manifest version="1.0" type="device"> + <hal format="hidl"> + <name>android.hardware.gnss</name> + <transport>hwbinder</transport> + <fqname>@1.1::IGnss/default</fqname> + <fqname>@2.0::IGnss/default</fqname> + </hal> +</manifest> + diff --git a/android/2.0/location_api/LocationUtil.cpp b/android/2.0/location_api/LocationUtil.cpp index 6bd5084..38a083a 100644 --- a/android/2.0/location_api/LocationUtil.cpp +++ b/android/2.0/location_api/LocationUtil.cpp @@ -209,6 +209,9 @@ void convertGnssConstellationType(GnssSvType& in, V2_0::GnssConstellationType& o case GNSS_SV_TYPE_GALILEO: out = V2_0::GnssConstellationType::GALILEO; break; + case GNSS_SV_TYPE_NAVIC: + out = V2_0::GnssConstellationType::IRNSS; + break; case GNSS_SV_TYPE_UNKNOWN: default: out = V2_0::GnssConstellationType::UNKNOWN; diff --git a/build/target_specific_features.mk b/build/target_specific_features.mk index 83f3cdd..ad7f7e1 100644 --- a/build/target_specific_features.mk +++ b/build/target_specific_features.mk @@ -43,6 +43,7 @@ GNSS_HIDL_2_0_TARGET_LIST += $(MSMSTEPPE) GNSS_HIDL_2_0_TARGET_LIST += $(TRINKET) GNSS_HIDL_2_0_TARGET_LIST += kona GNSS_HIDL_2_0_TARGET_LIST += atoll +GNSS_HIDL_2_0_TARGET_LIST += lito ifneq (,$(filter $(GNSS_HIDL_2_0_TARGET_LIST),$(TARGET_BOARD_PLATFORM))) GNSS_HIDL_VERSION = 2.0 diff --git a/core/ContextBase.cpp b/core/ContextBase.cpp index 12e550f..084b6bf 100644 --- a/core/ContextBase.cpp +++ b/core/ContextBase.cpp @@ -79,6 +79,7 @@ const loc_param_s_type ContextBase::mGps_conf_table[] = {"CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET", &mGps_conf.CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET, NULL, 'n'}, {"POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED", &mGps_conf.POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED, NULL, 'n'}, {"PROXY_APP_PACKAGE_NAME", &mGps_conf.PROXY_APP_PACKAGE_NAME, NULL, 's' }, + {"CP_MTLR_ES", &mGps_conf.CP_MTLR_ES, NULL, 'n' }, }; const loc_param_s_type ContextBase::mSap_conf_table[] = @@ -112,7 +113,8 @@ void ContextBase::readConfig() mGps_conf.GPS_LOCK = GNSS_CONFIG_GPS_LOCK_MO_AND_NI; mGps_conf.SUPL_VER = 0x10000; mGps_conf.SUPL_MODE = 0x1; - mGps_conf.SUPL_ES = 1; + mGps_conf.SUPL_ES = 0; + mGps_conf.CP_MTLR_ES = 0; mGps_conf.SUPL_HOST[0] = 0; mGps_conf.SUPL_PORT = 0; mGps_conf.CAPABILITIES = 0x7; diff --git a/core/ContextBase.h b/core/ContextBase.h index 8fc2bd5..ab61a08 100644 --- a/core/ContextBase.h +++ b/core/ContextBase.h @@ -72,6 +72,7 @@ typedef struct loc_gps_cfg_s uint32_t CONSTRAINED_TIME_UNCERTAINTY_ENERGY_BUDGET; uint32_t POSITION_ASSISTED_CLOCK_ESTIMATOR_ENABLED; char PROXY_APP_PACKAGE_NAME[LOC_MAX_PARAM_STRING]; + uint32_t CP_MTLR_ES; } loc_gps_cfg_s_type; /* NOTE: the implementaiton of the parser casts number diff --git a/core/SystemStatus.cpp b/core/SystemStatus.cpp index 524963b..18cb99c 100644 --- a/core/SystemStatus.cpp +++ b/core/SystemStatus.cpp @@ -382,16 +382,19 @@ public: uint32_t mBdsXtraAge; uint32_t mGalXtraAge; uint32_t mQzssXtraAge; + uint32_t mNavicXtraAge; uint32_t mGpsXtraValid; uint32_t mGloXtraValid; uint64_t mBdsXtraValid; uint64_t mGalXtraValid; uint8_t mQzssXtraValid; + uint32_t mNavicXtraValid; }; class SystemStatusPQWP3parser : public SystemStatusNmeaBase { private: + // todo: update for navic once available enum { eTalker = 0, @@ -418,11 +421,13 @@ public: inline uint32_t getBdsXtraAge() { return mP3.mBdsXtraAge; } inline uint32_t getGalXtraAge() { return mP3.mGalXtraAge; } inline uint32_t getQzssXtraAge() { return mP3.mQzssXtraAge; } + inline uint32_t getNavicXtraAge() { return mP3.mNavicXtraAge; } inline uint32_t getGpsXtraValid() { return mP3.mGpsXtraValid; } inline uint32_t getGloXtraValid() { return mP3.mGloXtraValid; } inline uint64_t getBdsXtraValid() { return mP3.mBdsXtraValid; } inline uint64_t getGalXtraValid() { return mP3.mGalXtraValid; } inline uint8_t getQzssXtraValid() { return mP3.mQzssXtraValid; } + inline uint32_t getNavicXtraValid() { return mP3.mNavicXtraValid; } SystemStatusPQWP3parser(const char *str_in, uint32_t len_in) : SystemStatusNmeaBase(str_in, len_in) @@ -431,6 +436,7 @@ public: return; } memset(&mP3, 0, sizeof(mP3)); + // todo: update for navic once available mP3.mXtraValidMask = strtol(mField[eXtraValidMask].c_str(), NULL, 16); mP3.mGpsXtraAge = atoi(mField[eGpsXtraAge].c_str()); mP3.mGloXtraAge = atoi(mField[eGloXtraAge].c_str()); @@ -511,21 +517,25 @@ public: uint64_t mBdsUnknownMask; uint64_t mGalUnknownMask; uint8_t mQzssUnknownMask; + uint32_t mNavicUnknownMask; uint32_t mGpsGoodMask; uint32_t mGloGoodMask; uint64_t mBdsGoodMask; uint64_t mGalGoodMask; uint8_t mQzssGoodMask; + uint32_t mNavicGoodMask; uint32_t mGpsBadMask; uint32_t mGloBadMask; uint64_t mBdsBadMask; uint64_t mGalBadMask; uint8_t mQzssBadMask; + uint32_t mNavicBadMask; }; class SystemStatusPQWP5parser : public SystemStatusNmeaBase { private: + // todo: update for navic once available enum { eTalker = 0, @@ -555,16 +565,19 @@ public: inline uint64_t getBdsUnknownMask() { return mP5.mBdsUnknownMask; } inline uint64_t getGalUnknownMask() { return mP5.mGalUnknownMask; } inline uint8_t getQzssUnknownMask() { return mP5.mQzssUnknownMask; } + inline uint32_t getNavicUnknownMask() { return mP5.mNavicUnknownMask; } inline uint32_t getGpsGoodMask() { return mP5.mGpsGoodMask; } inline uint32_t getGloGoodMask() { return mP5.mGloGoodMask; } inline uint64_t getBdsGoodMask() { return mP5.mBdsGoodMask; } inline uint64_t getGalGoodMask() { return mP5.mGalGoodMask; } inline uint8_t getQzssGoodMask() { return mP5.mQzssGoodMask; } + inline uint32_t getNavicGoodMask() { return mP5.mNavicGoodMask; } inline uint32_t getGpsBadMask() { return mP5.mGpsBadMask; } inline uint32_t getGloBadMask() { return mP5.mGloBadMask; } inline uint64_t getBdsBadMask() { return mP5.mBdsBadMask; } inline uint64_t getGalBadMask() { return mP5.mGalBadMask; } inline uint8_t getQzssBadMask() { return mP5.mQzssBadMask; } + inline uint32_t getNavicBadMask() { return mP5.mNavicBadMask; } SystemStatusPQWP5parser(const char *str_in, uint32_t len_in) : SystemStatusNmeaBase(str_in, len_in) @@ -573,6 +586,7 @@ public: return; } memset(&mP5, 0, sizeof(mP5)); + // todo: update for navic once available mP5.mGpsUnknownMask = strtol(mField[eGpsUnknownMask].c_str(), NULL, 16); mP5.mGloUnknownMask = strtol(mField[eGloUnknownMask].c_str(), NULL, 16); mP5.mBdsUnknownMask = strtol(mField[eBdsUnknownMask].c_str(), NULL, 16); @@ -971,11 +985,13 @@ SystemStatusXtra::SystemStatusXtra(const SystemStatusPQWP3& nmea) : mBdsXtraAge(nmea.mBdsXtraAge), mGalXtraAge(nmea.mGalXtraAge), mQzssXtraAge(nmea.mQzssXtraAge), + mNavicXtraAge(nmea.mNavicXtraAge), mGpsXtraValid(nmea.mGpsXtraValid), mGloXtraValid(nmea.mGloXtraValid), mBdsXtraValid(nmea.mBdsXtraValid), mGalXtraValid(nmea.mGalXtraValid), - mQzssXtraValid(nmea.mQzssXtraValid) + mQzssXtraValid(nmea.mQzssXtraValid), + mNavicXtraValid(nmea.mNavicXtraValid) { } @@ -987,11 +1003,13 @@ bool SystemStatusXtra::equals(const SystemStatusXtra& peer) (mBdsXtraAge != peer.mBdsXtraAge) || (mGalXtraAge != peer.mGalXtraAge) || (mQzssXtraAge != peer.mQzssXtraAge) || + (mNavicXtraAge != peer.mNavicXtraAge) || (mGpsXtraValid != peer.mGpsXtraValid) || (mGloXtraValid != peer.mGloXtraValid) || (mBdsXtraValid != peer.mBdsXtraValid) || (mGalXtraValid != peer.mGalXtraValid) || - (mQzssXtraValid != peer.mQzssXtraValid)) { + (mQzssXtraValid != peer.mQzssXtraValid) || + (mNavicXtraValid != peer.mNavicXtraValid)) { return false; } return true; @@ -1060,16 +1078,19 @@ SystemStatusSvHealth::SystemStatusSvHealth(const SystemStatusPQWP5& nmea) : mBdsUnknownMask(nmea.mBdsUnknownMask), mGalUnknownMask(nmea.mGalUnknownMask), mQzssUnknownMask(nmea.mQzssUnknownMask), + mNavicUnknownMask(nmea.mNavicUnknownMask), mGpsGoodMask(nmea.mGpsGoodMask), mGloGoodMask(nmea.mGloGoodMask), mBdsGoodMask(nmea.mBdsGoodMask), mGalGoodMask(nmea.mGalGoodMask), mQzssGoodMask(nmea.mQzssGoodMask), + mNavicGoodMask(nmea.mNavicGoodMask), mGpsBadMask(nmea.mGpsBadMask), mGloBadMask(nmea.mGloBadMask), mBdsBadMask(nmea.mBdsBadMask), mGalBadMask(nmea.mGalBadMask), - mQzssBadMask(nmea.mQzssBadMask) + mQzssBadMask(nmea.mQzssBadMask), + mNavicBadMask(nmea.mNavicBadMask) { } diff --git a/core/SystemStatus.h b/core/SystemStatus.h index 399a6c4..f3467e2 100644 --- a/core/SystemStatus.h +++ b/core/SystemStatus.h @@ -44,20 +44,22 @@ #include <gps_extended_c.h> -#define GPS_MIN (1) //1-32 -#define SBAS_MIN (33) -#define GLO_MIN (65) //65-88 -#define QZSS_MIN (193) //193-197 -#define BDS_MIN (201) //201-237 -#define GAL_MIN (301) //301-336 - -#define GPS_NUM (32) -#define SBAS_NUM (32) -#define GLO_NUM (24) -#define QZSS_NUM (5) -#define BDS_NUM (37) -#define GAL_NUM (36) -#define SV_ALL_NUM (GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM) //=134 +#define GPS_MIN (1) //1-32 +#define SBAS_MIN (33) +#define GLO_MIN (65) //65-88 +#define QZSS_MIN (193) //193-197 +#define BDS_MIN (201) //201-237 +#define GAL_MIN (301) //301-336 +#define NAVIC_MIN (401) //401-414 + +#define GPS_NUM (32) +#define SBAS_NUM (32) +#define GLO_NUM (24) +#define QZSS_NUM (5) +#define BDS_NUM (37) +#define GAL_NUM (36) +#define NAVIC_NUM (14) +#define SV_ALL_NUM (GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM+NAVIC_NUM) //=148 namespace loc_core { @@ -68,15 +70,15 @@ namespace loc_core class SystemStatusItemBase { public: - timespec mUtcTime; // UTC timestamp when this info was last updated - timespec mUtcReported; // UTC timestamp when this info was reported + timespec mUtcTime; + timespec mUtcReported; static const uint32_t maxItem = 5; SystemStatusItemBase() { - struct timespec tv; - clock_gettime(CLOCK_MONOTONIC, &tv); + timeval tv; + gettimeofday(&tv, NULL); mUtcTime.tv_sec = tv.tv_sec; - mUtcTime.tv_nsec = tv.tv_nsec; + mUtcTime.tv_nsec = tv.tv_usec*1000ULL; mUtcReported = mUtcTime; }; virtual ~SystemStatusItemBase() {}; @@ -258,11 +260,13 @@ public: uint32_t mBdsXtraAge; uint32_t mGalXtraAge; uint32_t mQzssXtraAge; + uint32_t mNavicXtraAge; uint32_t mGpsXtraValid; uint32_t mGloXtraValid; uint64_t mBdsXtraValid; uint64_t mGalXtraValid; uint8_t mQzssXtraValid; + uint32_t mNavicXtraValid; inline SystemStatusXtra() : mXtraValidMask(0), mGpsXtraAge(0), @@ -270,11 +274,13 @@ public: mBdsXtraAge(0), mGalXtraAge(0), mQzssXtraAge(0), + mNavicXtraAge(0), mGpsXtraValid(0), mGloXtraValid(0), mBdsXtraValid(0ULL), mGalXtraValid(0ULL), - mQzssXtraValid(0) {} + mQzssXtraValid(0), + mNavicXtraValid(0) {} inline SystemStatusXtra(const SystemStatusPQWP3& nmea); bool equals(const SystemStatusXtra& peer); void dump(void); @@ -309,32 +315,38 @@ public: uint64_t mBdsUnknownMask; uint64_t mGalUnknownMask; uint8_t mQzssUnknownMask; + uint32_t mNavicUnknownMask; uint32_t mGpsGoodMask; uint32_t mGloGoodMask; uint64_t mBdsGoodMask; uint64_t mGalGoodMask; uint8_t mQzssGoodMask; + uint32_t mNavicGoodMask; uint32_t mGpsBadMask; uint32_t mGloBadMask; uint64_t mBdsBadMask; uint64_t mGalBadMask; uint8_t mQzssBadMask; + uint32_t mNavicBadMask; inline SystemStatusSvHealth() : mGpsUnknownMask(0), mGloUnknownMask(0), mBdsUnknownMask(0ULL), mGalUnknownMask(0ULL), mQzssUnknownMask(0), + mNavicUnknownMask(0), mGpsGoodMask(0), mGloGoodMask(0), mBdsGoodMask(0ULL), mGalGoodMask(0ULL), mQzssGoodMask(0), + mNavicGoodMask(0), mGpsBadMask(0), mGloBadMask(0), mBdsBadMask(0ULL), mGalBadMask(0ULL), - mQzssBadMask(0) {} + mQzssBadMask(0), + mNavicBadMask(0) {} inline SystemStatusSvHealth(const SystemStatusPQWP5& nmea); bool equals(const SystemStatusSvHealth& peer); void dump(void); diff --git a/etc/gps.conf b/etc/gps.conf index 2ec3f69..35a0a7e 100644 --- a/etc/gps.conf +++ b/etc/gps.conf @@ -288,3 +288,9 @@ MODEM_TYPE = 1 # This is a string that is sent to the framework # in nfwNotifyCb callback PROXY_APP_PACKAGE_NAME = com.google.android.carrierlocation + +##################################### +# CP_MTLR_ES +##################################### +# CP MTLR ES, 1=enable, 0=disable +CP_MTLR_ES=0 diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 1c80443..eaf8878 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -229,6 +229,31 @@ GnssAdapter::convertLocation(Location& out, const UlpLocation& ulpLocation, } } +/* This is utility routine that computes number of SV used + in the fix from the svUsedIdsMask. + */ +#define MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION 64 +uint16_t GnssAdapter::getNumSvUsed(uint64_t svUsedIdsMask, + int totalSvCntInThisConstellation) +{ + if (totalSvCntInThisConstellation > MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION) { + LOC_LOGe ("error: total SV count in this constellation %d exceeded limit of %d", + totalSvCntInThisConstellation, MAX_SV_CNT_SUPPORTED_IN_ONE_CONSTELLATION); + return 0; + } + + uint16_t numSvUsed = 0; + uint64_t mask = 0x1; + for (int i = 0; i < totalSvCntInThisConstellation; i++) { + if (svUsedIdsMask & mask) { + numSvUsed++; + } + mask <<= 1; + } + + return numSvUsed; +} + void GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, const GpsLocationExtended& locationExtended) @@ -238,17 +263,19 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, out.flags |= GNSS_LOCATION_INFO_ALTITUDE_MEAN_SEA_LEVEL_BIT; out.altitudeMeanSeaLevel = locationExtended.altitudeMeanSeaLevel; } - if (GPS_LOCATION_EXTENDED_HAS_DOP & locationExtended.flags) { + if (GPS_LOCATION_EXTENDED_HAS_EXT_DOP & locationExtended.flags) { + out.flags |= (GNSS_LOCATION_INFO_DOP_BIT|GNSS_LOCATION_INFO_EXT_DOP_BIT); + out.pdop = locationExtended.extDOP.PDOP; + out.hdop = locationExtended.extDOP.HDOP; + out.vdop = locationExtended.extDOP.VDOP; + out.gdop = locationExtended.extDOP.GDOP; + out.tdop = locationExtended.extDOP.TDOP; + } else if (GPS_LOCATION_EXTENDED_HAS_DOP & locationExtended.flags) { out.flags |= GNSS_LOCATION_INFO_DOP_BIT; out.pdop = locationExtended.pdop; out.hdop = locationExtended.hdop; out.vdop = locationExtended.vdop; } - if (GPS_LOCATION_EXTENDED_HAS_EXT_DOP & locationExtended.flags) { - out.flags |= GNSS_LOCATION_INFO_EXT_DOP_BIT; - out.gdop = locationExtended.extDOP.GDOP; - out.tdop = locationExtended.extDOP.TDOP; - } if (GPS_LOCATION_EXTENDED_HAS_MAG_DEV & locationExtended.flags) { out.flags |= GNSS_LOCATION_INFO_MAGNETIC_DEVIATION_BIT; out.magneticDeviation = locationExtended.magneticDeviation; @@ -349,8 +376,20 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, locationExtended.gnss_sv_used_ids.bds_sv_used_ids_mask; out.svUsedInPosition.qzssSvUsedIdsMask = locationExtended.gnss_sv_used_ids.qzss_sv_used_ids_mask; - out.numOfMeasReceived = locationExtended.numOfMeasReceived; + out.flags |= GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT; + out.numSvUsedInPosition = getNumSvUsed(out.svUsedInPosition.gpsSvUsedIdsMask, + GPS_SV_PRN_MAX - GPS_SV_PRN_MIN + 1); + out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.gloSvUsedIdsMask, + GLO_SV_PRN_MAX - GLO_SV_PRN_MIN + 1); + out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.qzssSvUsedIdsMask, + QZSS_SV_PRN_MAX - QZSS_SV_PRN_MIN + 1); + out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.bdsSvUsedIdsMask, + BDS_SV_PRN_MAX - BDS_SV_PRN_MIN + 1); + out.numSvUsedInPosition += getNumSvUsed(out.svUsedInPosition.galSvUsedIdsMask, + GAL_SV_PRN_MAX - GAL_SV_PRN_MIN + 1); + + out.numOfMeasReceived = locationExtended.numOfMeasReceived; for (int idx =0; idx < locationExtended.numOfMeasReceived; idx++) { out.measUsageInfo[idx].gnssSignalType = locationExtended.measUsageInfo[idx].gnssSignalType; @@ -3325,6 +3364,11 @@ GnssAdapter::reportSv(GnssSvNotification& svNotify) // SV id passed to here by LocApi is 1-based. svNotify.gnssSvs[i].svId += (QZSS_SV_PRN_MIN - 1); break; + case GNSS_SV_TYPE_NAVIC: + if (mGnssSvIdUsedInPosAvail) { + svUsedIdMask = mGnssSvIdUsedInPosition.navic_sv_used_ids_mask; + } + break; default: svUsedIdMask = 0; break; @@ -3496,16 +3540,20 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* mNotify(notify), mData(data) {} inline virtual void proc() const { - if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type || - GNSS_NI_TYPE_CONTROL_PLANE == mNotify.type) { + if (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type) { if (mAdapter.getE911State() || - ((GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO == ContextBase::mGps_conf.SUPL_ES) && - (GNSS_NI_TYPE_EMERGENCY_SUPL == mNotify.type))) { + (GNSS_CONFIG_SUPL_EMERGENCY_SERVICES_NO == ContextBase::mGps_conf.SUPL_ES)) { mApi.informNiResponse(GNSS_NI_RESPONSE_ACCEPT, mData); - } - else { + } else { mApi.informNiResponse(GNSS_NI_RESPONSE_DENY, mData); } + } else if (GNSS_NI_TYPE_CONTROL_PLANE == mNotify.type) { + if (mAdapter.getE911State() && + (1 == ContextBase::mGps_conf.CP_MTLR_ES)) { + mApi.informNiResponse(GNSS_NI_RESPONSE_ACCEPT, mData); + } else { + mAdapter.requestNiNotify(mNotify, mData); + } } else { mAdapter.requestNiNotify(mNotify, mData); } @@ -4341,6 +4389,19 @@ void GnssAdapter::convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out, server_perdiction_age = (float)(in.mXtra.back().mGalXtraAge); } break; + case GNSS_SV_TYPE_NAVIC: + svid_min = GNSS_BUGREPORT_NAVIC_MIN; + svid_num = NAVIC_NUM; + svid_idx = GPS_NUM+GLO_NUM+QZSS_NUM+BDS_NUM+GAL_NUM; + if (!in.mSvHealth.empty()) { + eph_health_good_mask = in.mSvHealth.back().mNavicGoodMask; + eph_health_bad_mask = in.mSvHealth.back().mNavicBadMask; + } + if (!in.mXtra.empty()) { + server_perdiction_available_mask = in.mXtra.back().mNavicXtraValid; + server_perdiction_age = (float)(in.mXtra.back().mNavicXtraAge); + } + break; default: return; } @@ -4498,6 +4559,7 @@ bool GnssAdapter::getDebugReport(GnssDebugReport& r) convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_QZSS, reports); convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_BEIDOU, reports); convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_GALILEO, reports); + convertSatelliteInfo(r.mSatelliteInfo, GNSS_SV_TYPE_NAVIC, reports); LOC_LOGV("getDebugReport - satellite=%zu", r.mSatelliteInfo.size()); return true; diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 13efab1..1e6d1b8 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -205,6 +205,8 @@ class GnssAdapter : public LocAdapterBase { const LocPosTechMask techMask); static void convertLocationInfo(GnssLocationInfoNotification& out, const GpsLocationExtended& locationExtended); + static uint16_t getNumSvUsed(uint64_t svUsedIdsMask, + int totalSvCntInThisConstellation); /* ======== UTILITIES ================================================================== */ inline void initOdcpi(const OdcpiRequestCallback& callback); diff --git a/gnss/XtraSystemStatusObserver.cpp b/gnss/XtraSystemStatusObserver.cpp index b1c48d7..4cb6f5f 100644 --- a/gnss/XtraSystemStatusObserver.cpp +++ b/gnss/XtraSystemStatusObserver.cpp @@ -49,6 +49,7 @@ #include <DataItemsFactoryProxy.h> #include <DataItemConcreteTypesBase.h> +using namespace loc_util; using namespace loc_core; #ifdef LOG_TAG @@ -56,6 +57,61 @@ using namespace loc_core; #endif #define LOG_TAG "LocSvc_XSSO" +class XtraIpcListener : public ILocIpcListener { + IOsObserver* mSystemStatusObsrvr; + const MsgTask* mMsgTask; + XtraSystemStatusObserver& mXSSO; +public: + inline XtraIpcListener(IOsObserver* observer, const MsgTask* msgTask, + XtraSystemStatusObserver& xsso) : + mSystemStatusObsrvr(observer), mMsgTask(msgTask), mXSSO(xsso) {} + virtual void onReceive(const char* data, uint32_t length) override { +#define STRNCMP(str, constStr) strncmp(str, constStr, sizeof(constStr)-1) + if (!STRNCMP(data, "ping")) { + LOC_LOGd("ping received"); +#ifdef USE_GLIB + } else if (!STRNCMP(data, "connectBackhaul")) { + mSystemStatusObsrvr->connectBackhaul(); + } else if (!STRNCMP(data, "disconnectBackhaul")) { + mSystemStatusObsrvr->disconnectBackhaul(); +#endif + } else if (!STRNCMP(data, "requestStatus")) { + int32_t xtraStatusUpdated = 0; + sscanf(data, "%*s %d", &xtraStatusUpdated); + + struct HandleStatusRequestMsg : public LocMsg { + XtraSystemStatusObserver& mXSSO; + int32_t mXtraStatusUpdated; + inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso, + int32_t xtraStatusUpdated) : + mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {} + inline void proc() const override { + mXSSO.onStatusRequested(mXtraStatusUpdated); + } + }; + mMsgTask->sendMsg(new HandleStatusRequestMsg(mXSSO, xtraStatusUpdated)); + } else { + LOC_LOGw("unknown event: %s", data); + } + } +}; + +XtraSystemStatusObserver::XtraSystemStatusObserver(IOsObserver* sysStatObs, + const MsgTask* msgTask) : + mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask), + mGpsLock(-1), mConnections(~0), mXtraThrottle(true), + mReqStatusReceived(false), + mIsConnectivityStatusKnown(false), + mSender(LocIpc::getLocIpcLocalSender(LOC_IPC_XTRA)), + mDelayLocTimer(*mSender) { + subscribe(true); + auto recver = LocIpc::getLocIpcLocalRecver( + make_shared<XtraIpcListener>(sysStatObs, msgTask, *this), + LOC_IPC_HAL); + mIpc.startNonBlockingListening(recver); + mDelayLocTimer.start(100 /*.1 sec*/, false); +} + bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) { // mask NI(NFW bit) since from XTRA's standpoint GPS is enabled if // MO(AFW bit) is enabled and disabled when MO is disabled @@ -68,7 +124,8 @@ bool XtraSystemStatusObserver::updateLockStatus(GnssConfigGpsLock lock) { stringstream ss; ss << "gpslock"; ss << " " << lock; - return ( send(LOC_IPC_XTRA, ss.str()) ); + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections, @@ -85,8 +142,8 @@ bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections, stringstream ss; ss << "connection" << endl << mConnections << endl << wifiNetworkHandle << endl << mobileNetworkHandle; - - return ( send(LOC_IPC_XTRA, ss.str()) ); + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } bool XtraSystemStatusObserver::updateTac(const string& tac) { @@ -99,7 +156,8 @@ bool XtraSystemStatusObserver::updateTac(const string& tac) { stringstream ss; ss << "tac"; ss << " " << tac.c_str(); - return ( send(LOC_IPC_XTRA, ss.str()) ); + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) { @@ -112,7 +170,8 @@ bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) { stringstream ss; ss << "mncmcc"; ss << " " << mccmnc.c_str(); - return ( send(LOC_IPC_XTRA, ss.str()) ); + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) { @@ -125,7 +184,8 @@ bool XtraSystemStatusObserver::updateXtraThrottle(const bool enabled) { stringstream ss; ss << "xtrathrottle"; ss << " " << (enabled ? 1 : 0); - return ( send(LOC_IPC_XTRA, ss.str()) ); + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdated) { @@ -143,38 +203,8 @@ inline bool XtraSystemStatusObserver::onStatusRequested(int32_t xtraStatusUpdate << mWifiNetworkHandle << endl << mMobileNetworkHandle << endl << mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown; - return ( send(LOC_IPC_XTRA, ss.str()) ); -} - -void XtraSystemStatusObserver::onReceive(const std::string& data) { - if (!strncmp(data.c_str(), "ping", sizeof("ping") - 1)) { - LOC_LOGd("ping received"); - -#ifdef USE_GLIB - } else if (!strncmp(data.c_str(), "connectBackhaul", sizeof("connectBackhaul") - 1)) { - mSystemStatusObsrvr->connectBackhaul(); - - } else if (!strncmp(data.c_str(), "disconnectBackhaul", sizeof("disconnectBackhaul") - 1)) { - mSystemStatusObsrvr->disconnectBackhaul(); -#endif - - } else if (!strncmp(data.c_str(), "requestStatus", sizeof("requestStatus") - 1)) { - int32_t xtraStatusUpdated = 0; - sscanf(data.c_str(), "%*s %d", &xtraStatusUpdated); - - struct HandleStatusRequestMsg : public LocMsg { - XtraSystemStatusObserver& mXSSO; - int32_t mXtraStatusUpdated; - inline HandleStatusRequestMsg(XtraSystemStatusObserver& xsso, - int32_t xtraStatusUpdated) : - mXSSO(xsso), mXtraStatusUpdated(xtraStatusUpdated) {} - inline void proc() const override { mXSSO.onStatusRequested(mXtraStatusUpdated); } - }; - mMsgTask->sendMsg(new (nothrow) HandleStatusRequestMsg(*this, xtraStatusUpdated)); - - } else { - LOC_LOGw("unknown event: %s", data.c_str()); - } + string s = ss.str(); + return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) ); } void XtraSystemStatusObserver::subscribe(bool yes) diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h index b93ecf2..14f9393 100644 --- a/gnss/XtraSystemStatusObserver.h +++ b/gnss/XtraSystemStatusObserver.h @@ -35,25 +35,18 @@ #include <LocTimer.h> using namespace std; +using namespace loc_util; using loc_core::IOsObserver; using loc_core::IDataItemObserver; using loc_core::IDataItemCore; -using loc_util::LocIpc; -class XtraSystemStatusObserver : public IDataItemObserver, public LocIpc{ +class XtraSystemStatusObserver : public IDataItemObserver { public : // constructor & destructor - inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask): - mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask), - mGpsLock(-1), mConnections(~0), mXtraThrottle(true), mReqStatusReceived(false), - mIsConnectivityStatusKnown (false), mDelayLocTimer(*this) { - subscribe(true); - startListeningNonBlocking(LOC_IPC_HAL); - mDelayLocTimer.start(100 /*.1 sec*/, false); - } + XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask); inline virtual ~XtraSystemStatusObserver() { subscribe(false); - stopListening(); + mIpc.stopNonBlockingListening(); } // IDataItemObserver overrides @@ -68,14 +61,13 @@ public : bool updateXtraThrottle(const bool enabled); inline const MsgTask* getMsgTask() { return mMsgTask; } void subscribe(bool yes); - -protected: - void onReceive(const std::string& data) override; + bool onStatusRequested(int32_t xtraStatusUpdated); private: IOsObserver* mSystemStatusObsrvr; const MsgTask* mMsgTask; GnssConfigGpsLock mGpsLock; + LocIpc mIpc; uint64_t mConnections; uint64_t mWifiNetworkHandle; uint64_t mMobileNetworkHandle; @@ -84,17 +76,16 @@ private: bool mXtraThrottle; bool mReqStatusReceived; bool mIsConnectivityStatusKnown; + shared_ptr<LocIpcSender> mSender; class DelayLocTimer : public LocTimer { - XtraSystemStatusObserver& mXSSO; + LocIpcSender& mSender; public: - DelayLocTimer(XtraSystemStatusObserver& xsso) : mXSSO(xsso) {} + DelayLocTimer(LocIpcSender& sender) : mSender(sender) {} void timeOutCallback() override { - mXSSO.send(LOC_IPC_XTRA, "halinit"); + LocIpc::send(mSender, (const uint8_t*)"halinit", sizeof("halinit")); } } mDelayLocTimer; - - bool onStatusRequested(int32_t xtraStatusUpdated); }; #endif diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index 09e243a..d6abda2 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -41,12 +41,13 @@ #define GNSS_MEASUREMENTS_MAX (128) #define GNSS_UTC_TIME_OFFSET (3657) -#define GNSS_BUGREPORT_GPS_MIN (1) -#define GNSS_BUGREPORT_SBAS_MIN (120) -#define GNSS_BUGREPORT_GLO_MIN (1) -#define GNSS_BUGREPORT_QZSS_MIN (193) -#define GNSS_BUGREPORT_BDS_MIN (1) -#define GNSS_BUGREPORT_GAL_MIN (1) +#define GNSS_BUGREPORT_GPS_MIN (1) +#define GNSS_BUGREPORT_SBAS_MIN (120) +#define GNSS_BUGREPORT_GLO_MIN (1) +#define GNSS_BUGREPORT_QZSS_MIN (193) +#define GNSS_BUGREPORT_BDS_MIN (1) +#define GNSS_BUGREPORT_GAL_MIN (1) +#define GNSS_BUGREPORT_NAVIC_MIN (1) #define GNSS_MAX_NAME_LENGTH (8) @@ -153,7 +154,9 @@ typedef enum { GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MAJOR_BIT = (1<<5), // valid elipsode semi major GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_SEMI_MINOR_BIT = (1<<6), // valid elipsode semi minor GNSS_LOCATION_INFO_HOR_ACCURACY_ELIP_AZIMUTH_BIT = (1<<7), // valid accuracy elipsode azimuth - GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT = (1<<8), // valid gnss sv used in pos data + GNSS_LOCATION_INFO_GNSS_SV_USED_DATA_BIT = (1<<8), // valid svUsedInPosition, + // numOfMeasReceived + // and measUsageInfo GNSS_LOCATION_INFO_NAV_SOLUTION_MASK_BIT = (1<<9), // valid navSolutionMask GNSS_LOCATION_INFO_POS_TECH_MASK_BIT = (1<<10),// valid LocPosTechMask GNSS_LOCATION_INFO_SV_SOURCE_INFO_BIT = (1<<11),// valid LocSvInfoSource @@ -168,7 +171,9 @@ typedef enum { GNSS_LOCATION_INFO_EAST_VEL_UNC_BIT = (1<<20),// valid East Velocity Uncertainty GNSS_LOCATION_INFO_UP_VEL_UNC_BIT = (1<<21),// valid Up Velocity Uncertainty GNSS_LOCATION_INFO_LEAP_SECONDS_BIT = (1<<22),// valid leap seconds - GNSS_LOCATION_INFO_TIME_UNC_BIT = (1<<23) // valid time uncertainty + GNSS_LOCATION_INFO_TIME_UNC_BIT = (1<<23),// valid time uncertainty + GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT = (1<<24) // number of SV used in position + } GnssLocationInfoFlagBits; typedef enum { @@ -347,6 +352,7 @@ typedef enum { GNSS_SV_TYPE_QZSS, GNSS_SV_TYPE_BEIDOU, GNSS_SV_TYPE_GALILEO, + GNSS_SV_TYPE_NAVIC, } GnssSvType; typedef enum { @@ -516,6 +522,7 @@ typedef enum { GNSS_AIDING_DATA_SV_TYPE_QZSS_BIT = (1<<2), GNSS_AIDING_DATA_SV_TYPE_BEIDOU_BIT = (1<<3), GNSS_AIDING_DATA_SV_TYPE_GALILEO_BIT = (1<<4), + GNSS_AIDING_DATA_SV_TYPE_NAVIC_BIT = (1<<5), } GnssAidingDataSvTypeBits; /* Gnss constellation type mask */ @@ -526,13 +533,15 @@ typedef enum { GNSS_CONSTELLATION_TYPE_QZSS_BIT = (1<<2), GNSS_CONSTELLATION_TYPE_BEIDOU_BIT = (1<<3), GNSS_CONSTELLATION_TYPE_GALILEO_BIT = (1<<4), - GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5) + GNSS_CONSTELLATION_TYPE_SBAS_BIT = (1<<5), + GNSS_CONSTELLATION_TYPE_NAVIC_BIT = (1<<6) } GnssConstellationTypeBits; #define GNSS_CONSTELLATION_TYPE_MASK_ALL\ (GNSS_CONSTELLATION_TYPE_GPS_BIT | GNSS_CONSTELLATION_TYPE_GLONASS_BIT |\ GNSS_CONSTELLATION_TYPE_QZSS_BIT | GNSS_CONSTELLATION_TYPE_BEIDOU_BIT |\ - GNSS_CONSTELLATION_TYPE_GALILEO_BIT | GNSS_CONSTELLATION_TYPE_SBAS_BIT) + GNSS_CONSTELLATION_TYPE_GALILEO_BIT | GNSS_CONSTELLATION_TYPE_SBAS_BIT |\ + GNSS_CONSTELLATION_TYPE_NAVIC_BIT) /** GNSS Signal Type and RF Band */ typedef uint32_t GnssSignalTypeMask; @@ -572,7 +581,9 @@ typedef enum { /** QZSS L5 RF Band */ GNSS_SIGNAL_QZSS_L5 = (1<<16), /** SBAS L1 RF Band */ - GNSS_SIGNAL_SBAS_L1 = (1<<17) + GNSS_SIGNAL_SBAS_L1 = (1<<17), + /** NAVIC L5 RF Band */ + GNSS_SIGNAL_NAVIC_L5 = (1<<18) } GnssSignalTypeBits; #define GNSS_SIGNAL_TYPE_MASK_ALL\ @@ -581,7 +592,8 @@ typedef enum { GNSS_SIGNAL_GALILEO_E1 | GNSS_SIGNAL_GALILEO_E5A | GNSS_SIGNAL_GALILEO_E5B |\ GNSS_SIGNAL_BEIDOU_B1I | GNSS_SIGNAL_BEIDOU_B1C | GNSS_SIGNAL_BEIDOU_B2I|\ GNSS_SIGNAL_BEIDOU_B2AI | GNSS_SIGNAL_QZSS_L1CA | GNSS_SIGNAL_QZSS_L1S |\ - GNSS_SIGNAL_QZSS_L2| GNSS_SIGNAL_QZSS_L5 | GNSS_SIGNAL_SBAS_L1) + GNSS_SIGNAL_QZSS_L2| GNSS_SIGNAL_QZSS_L5 | GNSS_SIGNAL_SBAS_L1 |\ + GNSS_SIGNAL_NAVIC_L5) typedef enum { @@ -597,7 +609,9 @@ typedef enum /**< GLONASS satellite. */ GNSS_LOC_SV_SYSTEM_BDS = 5, /**< BDS satellite. */ - GNSS_LOC_SV_SYSTEM_QZSS = 6 + GNSS_LOC_SV_SYSTEM_QZSS = 6, + /**< QZSS satellite. */ + GNSS_LOC_SV_SYSTEM_NAVIC = 7 /**< QZSS satellite. */ } Gnss_LocSvSystemEnumType; @@ -620,7 +634,8 @@ typedef enum { GNSS_LOC_SIGNAL_TYPE_QZSS_L2C_L = 15, /**< QZSS L2C_L RF Band */ GNSS_LOC_SIGNAL_TYPE_QZSS_L5_Q = 16, /**< QZSS L5_Q RF Band */ GNSS_LOC_SIGNAL_TYPE_SBAS_L1_CA = 17, /**< SBAS L1_CA RF Band */ - GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES = 18 /**< Maximum number of signal types */ + GNSS_LOC_SIGNAL_TYPE_NAVIC_L5 = 18, /**< NAVIC L5 RF Band */ + GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES = 19 /**< Maximum number of signal types */ } Gnss_LocSignalEnumType; typedef uint64_t GnssDataMask; @@ -797,6 +812,7 @@ typedef struct { uint64_t galSvUsedIdsMask; uint64_t bdsSvUsedIdsMask; uint64_t qzssSvUsedIdsMask; + uint64_t navicSvUsedIdsMask; } GnssLocationSvUsedInPosition; typedef struct { @@ -810,7 +826,8 @@ typedef struct { For SBAS: 120 to 151 For QZSS-L1CA:193 to 197 For BDS: 201 to 237 - For GAL: 301 to 336 */ + For GAL: 301 to 336 + For NAVIC: 401 to 414 */ uint16_t gnssSvId; } GnssMeasUsageInfo; @@ -905,7 +922,8 @@ typedef union { GnssSystemTimeStructType galSystemTime; GnssSystemTimeStructType bdsSystemTime; GnssSystemTimeStructType qzssSystemTime; - GnssGloTimeStructType gloSystemTime; + GnssGloTimeStructType gloSystemTime; + GnssSystemTimeStructType navicSystemTime; } SystemTimeStructUnion; /** Time applicability of PVT report */ typedef struct { @@ -942,6 +960,7 @@ typedef struct { float northVelocityStdDeviation; float eastVelocityStdDeviation; float upVelocityStdDeviation; + uint16_t numSvUsedInPosition; GnssLocationSvUsedInPosition svUsedInPosition;// Gnss sv used in position data GnssLocationNavSolutionMask navSolutionMask; // Nav solution mask to indicate sbas corrections GnssLocationPosTechMask posTechMask; // Position technology used in computing this fix diff --git a/utils/LocIpc.cpp b/utils/LocIpc.cpp index 4178d52..ecaff01 100644 --- a/utils/LocIpc.cpp +++ b/utils/LocIpc.cpp @@ -30,10 +30,14 @@ #include <sys/types.h> #include <sys/stat.h> #include <errno.h> +#include <netinet/in.h> +#include <netdb.h> +#include <loc_misc_utils.h> #include <log_util.h> -#include "LocIpc.h" +#include <LocIpc.h> +#include <algorithm> -using std::string; +using namespace std; namespace loc_util { @@ -42,188 +46,346 @@ namespace loc_util { #endif #define LOG_TAG "LocSvc_LocIpc" -#define LOC_MSG_BUF_LEN 8192 -#define LOC_MSG_HEAD "$MSGLEN$" -#define LOC_MSG_ABORT "LocIpcMsg::ABORT" +#define SOCK_OP_AND_LOG(buf, length, opable, rtv, exe) \ + if (nullptr == (buf) || 0 == (length)) { \ + LOC_LOGe("Invalid inputs: buf - %p, length - %d", (buf), (length)); \ + } else if (!(opable)) { \ + LOC_LOGe("Invalid object: operable - %d", (opable)); \ + } else { \ + rtv = (exe); \ + if (-1 == rtv) { \ + LOC_LOGw("failed reason: %s", strerror(errno)); \ + } \ + } -class LocIpcRunnable : public LocRunnable { -friend LocIpc; -public: - LocIpcRunnable(LocIpc& locIpc, const string& ipcName) - : mLocIpc(locIpc), mIpcName(ipcName) {} - bool run() override { - if (!mLocIpc.startListeningBlocking(mIpcName)) { - LOC_LOGe("listen to socket failed"); +const char Sock::MSG_ABORT[] = "LocIpc::Sock::ABORT"; +const char Sock::LOC_IPC_HEAD[] = "$MSGLEN$"; +ssize_t Sock::send(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const { + ssize_t rtv = -1; + SOCK_OP_AND_LOG(buf, len, isValid(), rtv, sendto(buf, len, flags, destAddr, addrlen)); + return rtv; +} +ssize_t Sock::recv(const shared_ptr<ILocIpcListener>& dataCb, int flags, struct sockaddr *srcAddr, + socklen_t *addrlen, int sid) const { + ssize_t rtv = -1; + if (-1 == sid) { + sid = mSid; + } // else it sid would be connection based socket id for recv + SOCK_OP_AND_LOG(dataCb.get(), mMaxTxSize, isValid(), rtv, + recvfrom(dataCb, sid, flags, srcAddr, addrlen)); + return rtv; +} +ssize_t Sock::sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const { + ssize_t rtv = -1; + if (len <= mMaxTxSize) { + rtv = ::sendto(mSid, buf, len, flags, destAddr, addrlen); + } else { + std::string head(LOC_IPC_HEAD + to_string(len)); + rtv = ::sendto(mSid, head.c_str(), head.length(), flags, destAddr, addrlen); + if (rtv > 0) { + for (size_t offset = 0; offset < len && rtv > 0; offset += rtv) { + rtv = ::sendto(mSid, (char*)buf + offset, min(len - offset, (size_t)mMaxTxSize), + flags, destAddr, addrlen); + } + rtv = (rtv > 0) ? (head.length() + len) : -1; } - - return false; } -private: - LocIpc& mLocIpc; - const string mIpcName; -}; - -bool LocIpc::startListeningNonBlocking(const string& name) { - auto runnable = new LocIpcRunnable(*this, name); - string threadName("LocIpc-"); - threadName.append(name); - return mThread.start(threadName.c_str(), runnable); + return rtv; } +ssize_t Sock::recvfrom(const shared_ptr<ILocIpcListener>& dataCb, int sid, int flags, + struct sockaddr *srcAddr, socklen_t *addrlen) const { + ssize_t nBytes = -1; + std::string msg(mMaxTxSize, 0); + + if ((nBytes = ::recvfrom(sid, (void*)msg.data(), msg.size(), flags, srcAddr, addrlen)) > 0) { + if (strncmp(msg.data(), MSG_ABORT, sizeof(MSG_ABORT)) == 0) { + LOC_LOGi("recvd abort msg.data %s", msg.data()); + nBytes = 0; + } else if (strncmp(msg.data(), LOC_IPC_HEAD, sizeof(LOC_IPC_HEAD) - 1)) { + // short message + msg.resize(nBytes); + dataCb->onReceive(msg.data(), nBytes); + } else { + // long message + size_t msgLen = 0; + sscanf(msg.data() + sizeof(LOC_IPC_HEAD) - 1, "%zu", &msgLen); + msg.resize(msgLen); + for (size_t msgLenReceived = 0; (msgLenReceived < msgLen) && (nBytes > 0); + msgLenReceived += nBytes) { + nBytes = ::recvfrom(sid, &(msg[msgLenReceived]), msg.size() - msgLenReceived, + flags, srcAddr, addrlen); + } + if (nBytes > 0) { + nBytes = msgLen; + dataCb->onReceive(msg.data(), nBytes); + } + } + } -bool LocIpc::startListeningBlocking(const string& name) { - bool stopRequested = false; - int fd = socket(AF_UNIX, SOCK_DGRAM, 0); + return nBytes; +} +ssize_t Sock::sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen) { + return send(MSG_ABORT, sizeof(MSG_ABORT), flags, destAddr, addrlen); +} - if (fd < 0) { - LOC_LOGe("create socket error. reason:%s", strerror(errno)); - return false; +class LocIpcLocalSender : public LocIpcSender { +protected: + shared_ptr<Sock> mSock; + struct sockaddr_un mAddr; + inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const { + return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr)); } - - if ((unlink(name.c_str()) < 0) && (errno != ENOENT)) { - LOC_LOGw("unlink socket error. reason:%s", strerror(errno)); +public: + inline LocIpcLocalSender(const char* name) : LocIpcSender(), + mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_UNIX, SOCK_DGRAM, 0)))), + mAddr({.sun_family = AF_UNIX, {}}) { + if (mSock != nullptr && mSock->isValid()) { + snprintf(mAddr.sun_path, sizeof(mAddr.sun_path), "%s", name); + } } +}; - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name.c_str()); - - umask(0157); +class LocIpcLocalRecver : public LocIpcLocalSender, public LocIpcRecver { +protected: + inline virtual ssize_t recv() const override { + socklen_t size = sizeof(mAddr); + return mSock->recv(mDataCb, 0, (struct sockaddr*)&mAddr, &size); + } +public: + inline LocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener, const char* name) : + LocIpcLocalSender(name), LocIpcRecver(listener, *this) { - if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("bind socket error. reason:%s", strerror(errno)); - } else { - mIpcFd = fd; - mIpcName = name; + if ((unlink(mAddr.sun_path) < 0) && (errno != ENOENT)) { + LOC_LOGw("unlink socket error. reason:%s", strerror(errno)); + } - // inform that the socket is ready to receive message - onListenerReady(); - - ssize_t nBytes = 0; - string msg = ""; - string abort = LOC_MSG_ABORT; - while (1) { - msg.resize(LOC_MSG_BUF_LEN); - nBytes = ::recvfrom(fd, (void*)(msg.data()), msg.size(), 0, NULL, NULL); - if (nBytes < 0) { - LOC_LOGe("cannot read socket. reason:%s", strerror(errno)); - break; - } else if (0 == nBytes) { - continue; - } + umask(0157); + if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) { + LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno)); + mSock->close(); + } + } + inline virtual ~LocIpcLocalRecver() { unlink(mAddr.sun_path); } + inline virtual const char* getName() const override { return mAddr.sun_path; }; + inline virtual void abort() const override { + if (isSendable()) { + mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } + } +}; - if (strncmp(msg.data(), abort.c_str(), abort.length()) == 0) { - LOC_LOGi("recvd abort msg.data %s", msg.data()); - stopRequested = true; - break; +class LocIpcInetTcpSender : public LocIpcSender { +protected: + shared_ptr<Sock> mSock; + const string mName; + sockaddr_in mAddr; + mutable bool mFirstTime; + inline virtual bool isOperable() const override { return mSock != nullptr && mSock->isValid(); } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t /* msgId */) const { + if (mFirstTime) { + mFirstTime = false; + ::connect(mSock->mSid, (const struct sockaddr*)&mAddr, sizeof(mAddr)); + } + return mSock->send(data, length, 0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } +public: + inline LocIpcInetTcpSender(const char* name, int32_t port) : LocIpcSender(), + mSock(make_shared<Sock>((nullptr == name) ? -1 : (::socket(AF_INET, SOCK_STREAM, 0)))), + mName((nullptr == name) ? "" : name), + mAddr({.sin_family=AF_INET, .sin_port=htons(port), .sin_addr={htonl(INADDR_ANY)}}), + mFirstTime(true) { + if (mSock != nullptr && mSock->isValid() && nullptr != name) { + struct hostent* hp = gethostbyname(name); + if (nullptr != hp) { + memcpy((char*)&(mAddr.sin_addr.s_addr), hp->h_addr_list[0], hp->h_length); } + } + } +}; - if (strncmp(msg.data(), LOC_MSG_HEAD, sizeof(LOC_MSG_HEAD) - 1)) { - // short message - msg.resize(nBytes); - onReceive(msg); - } else { - // long message - size_t msgLen = 0; - sscanf(msg.data(), LOC_MSG_HEAD"%zu", &msgLen); - msg.resize(msgLen); - size_t msgLenReceived = 0; - while ((msgLenReceived < msgLen) && (nBytes > 0)) { - nBytes = recvfrom(fd, (void*)&(msg[msgLenReceived]), - msg.size() - msgLenReceived, 0, NULL, NULL); - msgLenReceived += nBytes; - } - if (nBytes > 0) { - onReceive(msg); - } else { - LOC_LOGe("cannot read socket. reason:%s", strerror(errno)); - break; - } +class LocIpcInetTcpRecver : public LocIpcInetTcpSender, public LocIpcRecver { + mutable int32_t mConnFd; +protected: + inline virtual ssize_t recv() const override { + socklen_t size = sizeof(mAddr); + if (-1 == mConnFd && mSock->isValid()) { + if (::listen(mSock->mSid, 3) < 0 || + (mConnFd = accept(mSock->mSid, (struct sockaddr*)&mAddr, &size)) < 0) { + mSock->close(); + mConnFd = -1; } } + return mSock->recv(mDataCb, 0, (struct sockaddr*)&mAddr, &size, mConnFd); } +public: + inline LocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener, const char* name, + int32_t port) : + LocIpcInetTcpSender(name, port), LocIpcRecver(listener, *this), mConnFd(-1) { + if (mSock->isValid() && ::bind(mSock->mSid, (struct sockaddr*)&mAddr, sizeof(mAddr)) < 0) { + LOC_LOGe("bind socket error. sock fd: %d, reason: %s", mSock->mSid, strerror(errno)); + mSock->close(); + } + } + inline virtual ~LocIpcInetTcpRecver() { if (-1 != mConnFd) ::close(mConnFd); } + inline virtual const char* getName() const override { return mName.data(); }; + inline virtual void abort() const override { + if (isSendable()) { + mSock->sendAbort(0, (struct sockaddr*)&mAddr, sizeof(mAddr)); + } + } +}; - if (::close(fd)) { - LOC_LOGe("cannot close socket:%s", strerror(errno)); +#ifdef NOT_DEFINED +class LocIpcQcsiSender : public LocIpcSender { +protected: + inline virtual bool isOperable() const override { + return mService != nullptr && mService->isServiceRegistered(); + } + inline virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t msgId) const override { + return mService->sendIndToClient(msgId, data, length); } - unlink(name.c_str()); + inline LocIpcQcsiSender(shared_ptr<QcsiService>& service) : mService(service) {} +public: + inline virtual ~LocIpcQcsi() {} +}; - return stopRequested; -} +class LocIpcQcsiRecver : public LocIpcQcsiSender, public LocIpcRecver { +protected: + inline virtual ssize_t recv() const override { return mService->recv(); } +public: + inline LocIpcQcsiRecver(unique_ptr<QcsiService>& service) : + LocIpcQcsiSender(service), LocIpcRecver(mService->getDataCallback(), *this) { + } + // only the dele + inline ~LocIpcQcsiRecver() {} + inline virtual const char* getName() const override { return mService->getName().data(); }; + inline virtual void abort() const override { if (isSendable()) mService->abort(); } + shared_ptr<LocIpcQcsiSender> getSender() { return make_pare<LocIpcQcsiSender>(mService); } +}; +#endif -void LocIpc::stopListening() { - if (mIpcFd >= 0) { - string abort = LOC_MSG_ABORT; - if (!mIpcName.empty()) { - send(mIpcName.c_str(), abort); +class LocIpcRunnable : public LocRunnable { + bool mAbortCalled; + LocIpc& mLocIpc; + unique_ptr<LocIpcRecver> mIpcRecver; +public: + inline LocIpcRunnable(LocIpc& locIpc, unique_ptr<LocIpcRecver>& ipcRecver) : + mAbortCalled(false), + mLocIpc(locIpc), + mIpcRecver(move(ipcRecver)) {} + inline bool run() override { + if (mIpcRecver != nullptr) { + mLocIpc.startBlockingListening(*(mIpcRecver.get())); + if (!mAbortCalled) { + LOC_LOGw("startListeningBlocking() returned w/o stopBlockingListening() called"); + } } - mIpcFd = -1; + // return false so the calling thread exits while loop + return false; } - if (!mIpcName.empty()) { - mIpcName.clear(); + inline void abort() { + mAbortCalled = true; + if (mIpcRecver != nullptr) { + mIpcRecver->abort(); + } } -} +}; -bool LocIpc::send(const char name[], const string& data) { - return send(name, (const uint8_t*)data.c_str(), data.length()); +bool LocIpc::startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver) { + if (ipcRecver != nullptr && ipcRecver->isRecvable()) { + std::string threadName("LocIpc-"); + threadName.append(ipcRecver->getName()); + mRunnable = new LocIpcRunnable(*this, ipcRecver); + return mThread.start(threadName.c_str(), mRunnable); + } else { + LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle"); + return false; + } } -bool LocIpc::send(const char name[], const uint8_t data[], uint32_t length) { - - bool result = true; - int fd = ::socket(AF_UNIX, SOCK_DGRAM, 0); - if (fd < 0) { - LOC_LOGe("create socket error. reason:%s", strerror(errno)); +bool LocIpc::startBlockingListening(LocIpcRecver& ipcRecver) { + if (ipcRecver.isRecvable()) { + // inform that the socket is ready to receive message + ipcRecver.onListenerReady(); + while (ipcRecver.recvData()); + return true; + } else { + LOC_LOGe("ipcRecver is null OR ipcRecver->recvable() is fasle"); return false; } - - struct sockaddr_un addr = { .sun_family = AF_UNIX }; - snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", name); - - result = sendData(fd, addr, data, length); - - (void)::close(fd); - return result; } +void LocIpc::stopNonBlockingListening() { + if (mRunnable) { + mRunnable->abort(); + mRunnable = nullptr; + } +} -bool LocIpc::sendData(int fd, const sockaddr_un &addr, const uint8_t data[], uint32_t length) { +void LocIpc::stopBlockingListening(LocIpcRecver& ipcRecver) { + if (ipcRecver.isRecvable()) { + ipcRecver.abort(); + } +} - bool result = true; +bool LocIpc::send(LocIpcSender& sender, const uint8_t data[], uint32_t length, int32_t msgId) { + return sender.sendData(data, length, msgId); +} - if (length <= LOC_MSG_BUF_LEN) { - if (::sendto(fd, data, length, 0, - (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - } - } else { - string head = LOC_MSG_HEAD; - head.append(std::to_string(length)); - if (::sendto(fd, head.c_str(), head.length(), 0, - (struct sockaddr*)&addr, sizeof(addr)) < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - } else { - size_t sentBytes = 0; - while(sentBytes < length) { - size_t partLen = length - sentBytes; - if (partLen > LOC_MSG_BUF_LEN) { - partLen = LOC_MSG_BUF_LEN; - } - ssize_t rv = ::sendto(fd, data + sentBytes, partLen, 0, - (struct sockaddr*)&addr, sizeof(addr)); - if (rv < 0) { - LOC_LOGe("cannot send to socket:%s. reason:%s", - addr.sun_path, strerror(errno)); - result = false; - break; - } - sentBytes += rv; - } - } - } - return result; +shared_ptr<LocIpcSender> LocIpc::getLocIpcLocalSender(const char* localSockName) { + return make_shared<LocIpcLocalSender>(localSockName); +} +unique_ptr<LocIpcRecver> LocIpc::getLocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener, + const char* localSockName) { + return make_unique<LocIpcLocalRecver>(listener, localSockName); +} +static void* sLibQrtrHandle = nullptr; +static const char* sLibQrtrName = "libloc_socket.so"; +shared_ptr<LocIpcSender> LocIpc::getLocIpcQrtrSender(int service, int instance) { + typedef shared_ptr<LocIpcSender> (*creator_t) (int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util22createLocIpcQrtrSenderEii"); + return (nullptr == creator) ? nullptr : creator(service, instance); +} +unique_ptr<LocIpcRecver> LocIpc::getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener, + int service, int instance) { + typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util22createLocIpcQrtrRecverERKNSt3__110shared_ptrINS_15ILocIpcListenerEEEii"); + return (nullptr == creator) ? nullptr : creator(listener, service, instance); +} +shared_ptr<LocIpcSender> LocIpc::getLocIpcQsockSender(int service, int instance) { + typedef shared_ptr<LocIpcSender> (*creator_t) (int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util23createLocIpcQsockSenderEii"); + return (nullptr == creator) ? nullptr : creator(service, instance); +} +unique_ptr<LocIpcRecver> LocIpc::getLocIpcQsockRecver(const shared_ptr<ILocIpcListener>& listener, + int service, int instance) { + typedef unique_ptr<LocIpcRecver> (*creator_t)(const shared_ptr<ILocIpcListener>&, int, int); + static creator_t creator = (creator_t)dlGetSymFromLib(sLibQrtrHandle, sLibQrtrName, + "_ZN8loc_util23createLocIpcQsockRecverERKSt10shared_ptrINS_15ILocIpcListenerEEii"); + return (nullptr == creator) ? nullptr : creator(listener, service, instance); +} +shared_ptr<LocIpcSender> LocIpc::getLocIpcInetTcpSender(const char* serverName, int32_t port) { + return make_shared<LocIpcInetTcpSender>(serverName, port); +} +unique_ptr<LocIpcRecver> LocIpc::getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener, + const char* serverName, int32_t port) { + return make_unique<LocIpcInetTcpRecver>(listener, serverName, port); +} +pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> + LocIpc::getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener, int instance) { + typedef pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> (*creator_t)(const shared_ptr<ILocIpcListener>&, int); + static void* sLibEmuHandle = nullptr; + static creator_t creator = (creator_t)dlGetSymFromLib(sLibEmuHandle, "libloc_emu.so", + "_ZN13QmiLocService41createLocIpcQmiLocServiceSenderRecverPairERKNSt3__110shared_ptrIN8loc_util15ILocIpcListenerEEEi"); + return (nullptr == creator) ? + make_pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>>(nullptr, nullptr) : + creator(listener, instance); } } diff --git a/utils/LocIpc.h b/utils/LocIpc.h index 707df21..20a1c8f 100644 --- a/utils/LocIpc.h +++ b/utils/LocIpc.h @@ -37,35 +37,71 @@ #include <sys/un.h> #include <LocThread.h> -using std::string; +using namespace std; namespace loc_util { + +class LocIpcRecver; class LocIpcSender; +class LocIpcRunnable; + +class ILocIpcListener { +protected: + inline virtual ~ILocIpcListener() {} +public: + // LocIpc client can overwrite this function to get notification + // when the socket for LocIpc is ready to receive messages. + inline virtual void onListenerReady() {} + virtual void onReceive(const char* data, uint32_t length)= 0; +}; + class LocIpc { -friend LocIpcSender; public: - inline LocIpc() : mIpcFd(-1) {} - inline virtual ~LocIpc() { stopListening(); } + inline LocIpc() : mRunnable(nullptr) {} + inline virtual ~LocIpc() { + stopNonBlockingListening(); + } + + static shared_ptr<LocIpcSender> + getLocIpcLocalSender(const char* localSockName); + static shared_ptr<LocIpcSender> + getLocIpcInetTcpSender(const char* serverName, int32_t port); + static shared_ptr<LocIpcSender> + getLocIpcQrtrSender(int service, int instance); + static shared_ptr<LocIpcSender> + getLocIpcQsockSender(int service, int instance); + + static unique_ptr<LocIpcRecver> + getLocIpcLocalRecver(const shared_ptr<ILocIpcListener>& listener, + const char* localSockName); + static unique_ptr<LocIpcRecver> + getLocIpcInetTcpRecver(const shared_ptr<ILocIpcListener>& listener, + const char* serverName, int32_t port); + static unique_ptr<LocIpcRecver> + getLocIpcQrtrRecver(const shared_ptr<ILocIpcListener>& listener, + int service, int instance); + static unique_ptr<LocIpcRecver> + getLocIpcQsockRecver(const shared_ptr<ILocIpcListener>& listener, + int service, int instance); + + static pair<shared_ptr<LocIpcSender>, unique_ptr<LocIpcRecver>> + getLocIpcQmiLocServiceSenderRecverPair(const shared_ptr<ILocIpcListener>& listener, + int instance); // Listen for new messages in current thread. Calling this funciton will - // block current thread. The listening can be stopped by calling stopListening(). - // - // Argument name is the path of the unix local socket to be listened. - // The function will return true on success, and false on failure. - bool startListeningBlocking(const std::string& name); + // block current thread. + // The listening can be stopped by calling stopBlockingListening() passing + // in the same ipcRecver obj handle. + static bool startBlockingListening(LocIpcRecver& ipcRecver); + static void stopBlockingListening(LocIpcRecver& ipcRecver); // Create a new LocThread and listen for new messages in it. // Calling this function will return immediately and won't block current thread. - // The listening can be stopped by calling stopListening(). - // - // Argument name is the path of the unix local socket to be be listened. - // The function will return true on success, and false on failure. - bool startListeningNonBlocking(const std::string& name); - - // Stop listening to new messages. - void stopListening(); + // The listening can be stopped by calling stopNonBlockingListening(). + bool startNonBlockingListening(unique_ptr<LocIpcRecver>& ipcRecver); + void stopNonBlockingListening(); // Send out a message. // Call this function to send a message in argument data to socket in argument name. @@ -73,78 +109,70 @@ public: // Argument name contains the name of the target unix socket. data contains the // message to be sent out. Convert your message to a string before calling this function. // The function will return true on success, and false on failure. - static bool send(const char name[], const std::string& data); - static bool send(const char name[], const uint8_t data[], uint32_t length); - -protected: - // Callback function for receiving incoming messages. - // Override this function in your derived class to process incoming messages. - // For each received message, this callback function will be called once. - // This callback function will be called in the calling thread of startListeningBlocking - // or in the new LocThread created by startListeningNonBlocking. - // - // Argument data contains the received message. You need to parse it. - inline virtual void onReceive(const std::string& /*data*/) {} - - // LocIpc client can overwrite this function to get notification - // when the socket for LocIpc is ready to receive messages. - inline virtual void onListenerReady() {} + static bool send(LocIpcSender& sender, const uint8_t data[], + uint32_t length, int32_t msgId = -1); private: - static bool sendData(int fd, const sockaddr_un& addr, - const uint8_t data[], uint32_t length); - - int mIpcFd; LocThread mThread; - string mIpcName; + LocIpcRunnable *mRunnable; }; +/* this is only when client needs to implement Sender / Recver that are not already provided by + the factor methods prvoided by LocIpc. */ + class LocIpcSender { +protected: + LocIpcSender() = default; + virtual ~LocIpcSender() = default; + virtual bool isOperable() const = 0; + virtual ssize_t send(const uint8_t data[], uint32_t length, int32_t msgId) const = 0; public: - // Constructor of LocIpcSender class - // - // Argument destSocket contains the full path name of destination socket. - // This class hides generated fd and destination address object from user. - inline LocIpcSender(const char* destSocket): - LocIpcSender(std::make_shared<int>(::socket(AF_UNIX, SOCK_DGRAM, 0)), destSocket) { - if (mSocket != nullptr && -1 == *mSocket) { - mSocket = nullptr; - } - } - - // Replicate a new LocIpcSender object with new destination socket. - inline LocIpcSender* replicate(const char* destSocket) { - return (nullptr == mSocket) ? nullptr : new LocIpcSender(mSocket, destSocket); - } - - inline ~LocIpcSender() { - if (nullptr != mSocket && mSocket.unique()) { - ::close(*mSocket); - } + inline bool isSendable() const { return isOperable(); } + inline bool sendData(const uint8_t data[], uint32_t length, int32_t msgId) const { + return isSendable() && (send(data, length, msgId) > 0); } +}; - // Send out a message. - // Call this function to send a message - // - // Argument data and length contains the message to be sent out. - // Return true when succeeded - inline bool send(const uint8_t data[], uint32_t length) { - bool rtv = false; - if (nullptr != mSocket && nullptr != data) { - rtv = LocIpc::sendData(*mSocket, mDestAddr, data, length); - } - return rtv; - } +class LocIpcRecver { + LocIpcSender& mIpcSender; +protected: + const shared_ptr<ILocIpcListener> mDataCb; + inline LocIpcRecver(const shared_ptr<ILocIpcListener>& listener, LocIpcSender& sender) : + mIpcSender(sender), mDataCb(listener) {} + LocIpcRecver(LocIpcRecver const& recver) = delete; + LocIpcRecver& operator=(LocIpcRecver const& recver) = delete; + virtual ssize_t recv() const = 0; +public: + virtual ~LocIpcRecver() = default; + inline bool recvData() const { return isRecvable() && (recv() > 0); } + inline bool isRecvable() const { return mDataCb != nullptr && mIpcSender.isSendable(); } + virtual void onListenerReady() { if (mDataCb != nullptr) mDataCb->onListenerReady(); } + virtual void abort() const = 0; + virtual const char* getName() const = 0; +}; -private: - std::shared_ptr<int> mSocket; - struct sockaddr_un mDestAddr; - - inline LocIpcSender(const std::shared_ptr<int>& mySocket, const char* destSocket) : - mSocket(mySocket), - mDestAddr({.sun_family = AF_UNIX, {}}) { - if ((nullptr != mSocket) && (-1 != *mSocket) && (nullptr != destSocket)) { - snprintf(mDestAddr.sun_path, sizeof(mDestAddr.sun_path), "%s", destSocket); +class Sock { + static const char MSG_ABORT[]; + static const char LOC_IPC_HEAD[]; + const uint32_t mMaxTxSize; + ssize_t sendto(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const; + ssize_t recvfrom(const shared_ptr<ILocIpcListener>& dataCb, int sid, int flags, + struct sockaddr *srcAddr, socklen_t *addrlen) const; +public: + int mSid; + inline Sock(int sid, const uint32_t maxTxSize = 8192) : mMaxTxSize(maxTxSize), mSid(sid) {} + inline ~Sock() { close(); } + inline bool isValid() const { return -1 != mSid; } + ssize_t send(const void *buf, size_t len, int flags, const struct sockaddr *destAddr, + socklen_t addrlen) const; + ssize_t recv(const shared_ptr<ILocIpcListener>& dataCb, int flags, struct sockaddr *srcAddr, + socklen_t *addrlen, int sid = -1) const; + ssize_t sendAbort(int flags, const struct sockaddr *destAddr, socklen_t addrlen); + inline void close() { + if (isValid()) { + ::close(mSid); + mSid = -1; } } }; diff --git a/utils/Makefile.am b/utils/Makefile.am index 50e1e9a..807916d 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -8,7 +8,7 @@ AM_CFLAGS = -Wundef \ -fno-short-enums \ -fpic \ -I./ \ - -std=c++11 \ + -std=c++14 \ $(LOCPLA_CFLAGS) libgps_utils_la_h_sources = \ diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index a3dcbd0..9f4c13c 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -435,6 +435,8 @@ typedef uint32_t GnssAdditionalSystemInfoMask; #define BDS_SV_PRN_MAX 235 #define GAL_SV_PRN_MIN 301 #define GAL_SV_PRN_MAX 336 +#define NAVIC_SV_PRN_MIN 401 +#define NAVIC_SV_PRN_MAX 414 typedef uint32_t LocPosTechMask; #define LOC_POS_TECH_MASK_DEFAULT ((LocPosTechMask)0x00000000) @@ -468,6 +470,7 @@ typedef struct { uint64_t gal_sv_used_ids_mask; uint64_t bds_sv_used_ids_mask; uint64_t qzss_sv_used_ids_mask; + uint64_t navic_sv_used_ids_mask; } GnssSvUsedInPosition; typedef struct { @@ -595,6 +598,8 @@ typedef uint32_t GnssSignalTypeMask; #define GNSS_SIGNAL_QZSS_L5 ((GnssSignalTypeMask)0x00010000ul) /** SBAS L1 RF Band */ #define GNSS_SIGNAL_SBAS_L1 ((GnssSignalTypeMask)0x00020000ul) +/** NAVIC L5 RF Band */ +#define GNSS_SIGNAL_NAVIC_L5 ((GnssSignalTypeMask)0x00040000ul) typedef uint16_t GnssMeasUsageStatusBitMask; /** Used in fix */ @@ -1353,26 +1358,32 @@ typedef struct typedef uint64_t GpsSvMeasHeaderFlags; -#define GNSS_SV_MEAS_HEADER_HAS_LEAP_SECOND 0x00000001 -#define GNSS_SV_MEAS_HEADER_HAS_CLOCK_FREQ 0x00000002 -#define GNSS_SV_MEAS_HEADER_HAS_AP_TIMESTAMP 0x00000004 -#define GNSS_SV_MEAS_HEADER_HAS_GPS_GLO_INTER_SYSTEM_BIAS 0x00000008 -#define GNSS_SV_MEAS_HEADER_HAS_GPS_BDS_INTER_SYSTEM_BIAS 0x00000010 -#define GNSS_SV_MEAS_HEADER_HAS_GPS_GAL_INTER_SYSTEM_BIAS 0x00000020 -#define GNSS_SV_MEAS_HEADER_HAS_BDS_GLO_INTER_SYSTEM_BIAS 0x00000040 -#define GNSS_SV_MEAS_HEADER_HAS_GAL_GLO_INTER_SYSTEM_BIAS 0x00000080 -#define GNSS_SV_MEAS_HEADER_HAS_GAL_BDS_INTER_SYSTEM_BIAS 0x00000100 -#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME 0x00000200 -#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME 0x00000400 -#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME 0x00000800 -#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME 0x00001000 -#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME 0x00002000 -#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME_EXT 0x00004000 -#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME_EXT 0x00008000 -#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME_EXT 0x00010000 -#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME_EXT 0x00020000 -#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x00040000 -#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x00080000 +#define GNSS_SV_MEAS_HEADER_HAS_LEAP_SECOND 0x00000001 +#define GNSS_SV_MEAS_HEADER_HAS_CLOCK_FREQ 0x00000002 +#define GNSS_SV_MEAS_HEADER_HAS_AP_TIMESTAMP 0x00000004 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_GLO_INTER_SYSTEM_BIAS 0x00000008 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_BDS_INTER_SYSTEM_BIAS 0x00000010 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_GAL_INTER_SYSTEM_BIAS 0x00000020 +#define GNSS_SV_MEAS_HEADER_HAS_BDS_GLO_INTER_SYSTEM_BIAS 0x00000040 +#define GNSS_SV_MEAS_HEADER_HAS_GAL_GLO_INTER_SYSTEM_BIAS 0x00000080 +#define GNSS_SV_MEAS_HEADER_HAS_GAL_BDS_INTER_SYSTEM_BIAS 0x00000100 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME 0x00000200 +#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME 0x00000400 +#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME 0x00000800 +#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME 0x00001000 +#define GNSS_SV_MEAS_HEADER_HAS_GLO_SYSTEM_TIME 0x00002000 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_SYSTEM_TIME_EXT 0x00004000 +#define GNSS_SV_MEAS_HEADER_HAS_GAL_SYSTEM_TIME_EXT 0x00008000 +#define GNSS_SV_MEAS_HEADER_HAS_BDS_SYSTEM_TIME_EXT 0x00010000 +#define GNSS_SV_MEAS_HEADER_HAS_QZSS_SYSTEM_TIME_EXT 0x00020000 +#define GNSS_SV_MEAS_HEADER_HAS_GPSL1L5_TIME_BIAS 0x00040000 +#define GNSS_SV_MEAS_HEADER_HAS_GALE1E5A_TIME_BIAS 0x00080000 +#define GNSS_SV_MEAS_HEADER_HAS_GPS_NAVIC_INTER_SYSTEM_BIAS 0x00100000 +#define GNSS_SV_MEAS_HEADER_HAS_GAL_NAVIC_INTER_SYSTEM_BIAS 0x00200000 +#define GNSS_SV_MEAS_HEADER_HAS_GLO_NAVIC_INTER_SYSTEM_BIAS 0x00400000 +#define GNSS_SV_MEAS_HEADER_HAS_BDS_NAVIC_INTER_SYSTEM_BIAS 0x00800000 +#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME 0x01000000 +#define GNSS_SV_MEAS_HEADER_HAS_NAVIC_SYSTEM_TIME_EXT 0x02000000 @@ -1394,6 +1405,10 @@ typedef struct Gnss_InterSystemBiasStructType bdsGloInterSystemBias; Gnss_InterSystemBiasStructType galGloInterSystemBias; Gnss_InterSystemBiasStructType galBdsInterSystemBias; + Gnss_InterSystemBiasStructType gpsNavicInterSystemBias; + Gnss_InterSystemBiasStructType galNavicInterSystemBias; + Gnss_InterSystemBiasStructType gloNavicInterSystemBias; + Gnss_InterSystemBiasStructType bdsNavicInterSystemBias; Gnss_InterSystemBiasStructType gpsL1L5TimeBias; Gnss_InterSystemBiasStructType galE1E5aTimeBias; @@ -1401,6 +1416,7 @@ typedef struct GnssSystemTimeStructType galSystemTime; GnssSystemTimeStructType bdsSystemTime; GnssSystemTimeStructType qzssSystemTime; + GnssSystemTimeStructType navicSystemTime; GnssGloTimeStructType gloSystemTime; /** GPS system RTC time information. */ @@ -1411,6 +1427,8 @@ typedef struct Gnss_LocGnssTimeExtStructType bdsSystemTimeExt; /** QZSS system RTC time information. */ Gnss_LocGnssTimeExtStructType qzssSystemTimeExt; + /** NAVIC system RTC time information. */ + Gnss_LocGnssTimeExtStructType navicSystemTimeExt; } GnssSvMeasurementHeader; @@ -2026,10 +2044,11 @@ typedef struct /* Mask indicating enabled or disabled constellations */ typedef uint64_t GnssSvTypesMask; typedef enum { - GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0), - GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1), - GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2), - GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3), + GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0), + GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1), + GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2), + GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3), + GNSS_SV_TYPES_MASK_NAVIC_BIT = (1<<4), } GnssSvTypesMaskBits; /* This SV Type config is injected directly to GNSS Adapter @@ -2164,11 +2183,10 @@ typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* #define SOCKET_DIR_EHUB "/dev/socket/location/ehub/" #define SOCKET_TO_LOCATION_HAL_DAEMON "/dev/socket/loc_client/hal_daemon" -#define SOCKET_DIR_TO_CLIENT "/dev/socket/loc_client/" -#define SOCKET_TO_LOCATION_CLIENT_BASE "/dev/socket/loc_client/toclient" - -#define DIR_FOR_EXT_AP_LOC_CLIENT "/data/vendor/location/extap_locclient/" -#define FILE_FOR_EXT_AP_LOC_CLIENT_BASE "/data/vendor/location/extap_locclient/client" +#define SOCKET_LOC_CLIENT_DIR "/dev/socket/loc_client/" +#define EAP_LOC_CLIENT_DIR "/data/vendor/location/extap_locclient/" + +#define LOC_CLIENT_NAME_PREFIX "toclient" typedef uint64_t NetworkHandle; #define NETWORK_HANDLE_UNKNOWN ~0 diff --git a/utils/loc_nmea.cpp b/utils/loc_nmea.cpp index 9cd3472..45b4f06 100644 --- a/utils/loc_nmea.cpp +++ b/utils/loc_nmea.cpp @@ -123,6 +123,7 @@ typedef struct loc_sv_cache_info_s uint32_t gal_used_mask; uint32_t qzss_used_mask; uint32_t bds_used_mask; + uint32_t navic_used_mask; uint32_t gps_l1_count; uint32_t gps_l5_count; uint32_t glo_g1_count; @@ -133,6 +134,7 @@ typedef struct loc_sv_cache_info_s uint32_t qzss_l5_count; uint32_t bds_b1_count; uint32_t bds_b2_count; + uint32_t navic_l5_count; float hdop; float pdop; float vdop; @@ -324,6 +326,9 @@ static uint32_t convert_signalType_to_signalId(GnssSignalTypeMask signalType) case GNSS_SIGNAL_BEIDOU_B2AI: signalId = SIGNAL_ID_BDS_B2A; break; + case GNSS_SIGNAL_NAVIC_L5: + signalId = SIGNAL_ID_NAVIC_L5SPS; + break; default: signalId = SIGNAL_ID_ALL_SIGNALS; } @@ -418,6 +423,16 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, sv_meta.svCount = sv_cache_info.bds_b2_count; } break; + case GNSS_SV_TYPE_NAVIC: + sv_meta.talker[0] = 'G'; + sv_meta.talker[1] = 'I'; + sv_meta.mask = sv_cache_info.navic_used_mask; + // NAVIC SV ids are from 401-414. So keep svIdOffset 0 + sv_meta.systemId = SYSTEM_ID_NAVIC; + if (GNSS_SIGNAL_NAVIC_L5 == signalType) { + sv_meta.svCount = sv_cache_info.navic_l5_count; + } + break; default: LOC_LOGE("NMEA Error unknow constellation type: %d", svType); return NULL; @@ -428,7 +443,8 @@ static loc_nmea_sv_meta* loc_nmea_sv_meta_init(loc_nmea_sv_meta& sv_meta, (sv_cache_info.glo_used_mask ? 1 : 0) + (sv_cache_info.gal_used_mask ? 1 : 0) + (sv_cache_info.qzss_used_mask ? 1 : 0) + - (sv_cache_info.bds_used_mask ? 1 : 0) > 1) + (sv_cache_info.bds_used_mask ? 1 : 0) + + (sv_cache_info.navic_used_mask ? 1 : 0) > 1) { // If GPS, GLONASS, Galileo, QZSS, BDS etc. are combined // to obtain the reported position solution, @@ -701,6 +717,9 @@ static void loc_nmea_generate_GSV(const GnssSvNotification &svNotify, case GNSS_SV_TYPE_SBAS: signalType = GNSS_SIGNAL_SBAS_L1; break; + case GNSS_SV_TYPE_NAVIC: + signalType = GNSS_SIGNAL_NAVIC_L5; + break; default: LOC_LOGE("NMEA Error unknow constellation type: %d", svNotify.gnssSvs[svNumber - 1].type); @@ -1815,6 +1834,19 @@ void loc_nmea_generate_sv(const GnssSvNotification &svNotify, sv_cache_info.bds_b1_count++; } } + else if (GNSS_SV_TYPE_NAVIC == svNotify.gnssSvs[svNumber - 1].type) + { + // cache the used in fix mask, as it will be needed to send $PQGSA + // during the position report + if (GNSS_SV_OPTIONS_USED_IN_FIX_BIT == + (svNotify.gnssSvs[svNumber - 1].gnssSvOptionsMask & + GNSS_SV_OPTIONS_USED_IN_FIX_BIT)) + { + sv_cache_info.navic_used_mask |= (1 << (svNotify.gnssSvs[svNumber - 1].svId - 1)); + } + // GNSS_SIGNAL_NAVIC_L5 is the only signal type for NAVIC + sv_cache_info.navic_l5_count++; + } } loc_nmea_sv_meta sv_meta; |