diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h index 455c52ea..34af4d06 100644 --- a/core/EngineHubProxyBase.h +++ b/core/EngineHubProxyBase.h @@ -85,6 +85,11 @@ public: (void) svEphemeris; return false; } + + inline virtual bool gnssReportSystemInfo(const LocationSystemInfo& systemInfo) { + (void) systemInfo; + return false; + } }; typedef std::functionreportLocationSystemInfoEvent(locationSystemInfo)); +} + void LocApiBase::requestXtraData() { // loop through adapters, and deliver to the first handling adapter. diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 77c57d98..e5dfebf9 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -171,6 +171,7 @@ public: void reportData(GnssDataNotification& dataNotify, int msInWeek); void reportXtraServer(const char* url1, const char* url2, const char* url3, const int maxlength); + void reportLocationSystemInfo(const LocationSystemInfo& locationSystemInfo); void requestXtraData(); void requestTime(); void requestLocation(); diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 3d3c990d..b7c57e8a 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -87,7 +87,8 @@ GnssAdapter::GnssAdapter() : mSystemStatus(SystemStatus::getInstance(mMsgTask)), mServerUrl(":"), mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask), - mBlockCPIInfo{} + mBlockCPIInfo{}, + mLocSystemInfo{} { LOC_LOGD("%s]: Constructor %p", __func__, this); mLocPositionMode.mode = LOC_POSITION_MODE_INVALID; @@ -1848,6 +1849,8 @@ GnssAdapter::addClientCommand(LocationAPI* client, const LocationCallbacks& call mClient(client), mCallbacks(callbacks) {} inline virtual void proc() const { + // check whether we need to notify client of cached location system info + mAdapter.notifyClientOfCachedLocationSystemInfo(mClient, mCallbacks); mAdapter.saveClient(mClient, mCallbacks); } }; @@ -1917,6 +1920,9 @@ GnssAdapter::updateClientsEventMask() mask |= LOC_API_ADAPTER_BIT_NMEA_1HZ_REPORT; updateNmeaMask(mNmeaMask | LOC_NMEA_MASK_DEBUG_V02); } + if (it->second.locationSystemInfoCb != nullptr) { + mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO; + } } /* @@ -1931,6 +1937,7 @@ GnssAdapter::updateClientsEventMask() mask |= LOC_API_ADAPTER_BIT_GNSS_SV_POLYNOMIAL_REPORT; mask |= LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT; mask |= LOC_API_ADAPTER_BIT_GNSS_SV_EPHEMERIS_REPORT; + mask |= LOC_API_ADAPTER_BIT_LOC_SYSTEM_INFO; LOC_LOGd("Auto usecase, Enable MEAS/POLY/EPHEMERIS - mask 0x%" PRIx64 "", mask); @@ -2106,6 +2113,35 @@ GnssAdapter::saveClient(LocationAPI* client, const LocationCallbacks& callbacks) updateClientsEventMask(); } +void +GnssAdapter::notifyClientOfCachedLocationSystemInfo( + LocationAPI* client, const LocationCallbacks& callbacks) { + + if (mLocSystemInfo.systemInfoMask) { + // client need to be notified if client has not yet previously registered + // for the info but now register for it. + bool notifyClientOfSystemInfo = false; + // check whether we need to notify client of cached location system info + // + // client need to be notified if client has not yet previously registered + // for the info but now register for it. + if (callbacks.locationSystemInfoCb) { + notifyClientOfSystemInfo = true; + auto it = mClientData.find(client); + if (it != mClientData.end()) { + LocationCallbacks oldCallbacks = it->second; + if (oldCallbacks.locationSystemInfoCb) { + notifyClientOfSystemInfo = false; + } + } + } + + if (notifyClientOfSystemInfo) { + callbacks.locationSystemInfoCb(mLocSystemInfo); + } + } +} + void GnssAdapter::eraseClient(LocationAPI* client) { @@ -3228,6 +3264,47 @@ GnssAdapter::requestNiNotifyEvent(const GnssNiNotification ¬ify, const void* return true; } +void +GnssAdapter::reportLocationSystemInfoEvent(const LocationSystemInfo & locationSystemInfo) { + + // send system info to engine hub + mEngHubProxy->gnssReportSystemInfo(locationSystemInfo); + + struct MsgLocationSystemInfo : public LocMsg { + GnssAdapter& mAdapter; + LocationSystemInfo mSystemInfo; + inline MsgLocationSystemInfo(GnssAdapter& adapter, + const LocationSystemInfo& systemInfo) : + LocMsg(), + mAdapter(adapter), + mSystemInfo(systemInfo) {} + inline virtual void proc() const { + mAdapter.reportLocationSystemInfo(mSystemInfo); + } + }; + + sendMsg(new MsgLocationSystemInfo(*this, locationSystemInfo)); +} + +void +GnssAdapter::reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo) { + // save the info into the master copy piece by piece, as other system info + // may come at different time + if (locationSystemInfo.systemInfoMask & LOCATION_SYS_INFO_LEAP_SECOND) { + mLocSystemInfo.systemInfoMask |= LOCATION_SYS_INFO_LEAP_SECOND; + mLocSystemInfo.leapSecondSysInfo = locationSystemInfo.leapSecondSysInfo; + } + + // we received new info, inform client of the newly received info + if (locationSystemInfo.systemInfoMask) { + for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { + if (it->second.locationSystemInfoCb != nullptr) { + it->second.locationSystemInfoCb(locationSystemInfo); + } + } + } +} + static void* niThreadProc(void *args) { NiSession* pSession = (NiSession*)args; diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 21ce787d..f382c6ad 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -172,6 +172,7 @@ class GnssAdapter : public LocAdapterBase { std::string mServerUrl; std::string mMoServerUrl; XtraSystemStatusObserver mXtraObserver; + LocationSystemInfo mLocSystemInfo; /* === Misc ===================================================================== */ BlockCPIInfo mBlockCPIInfo; @@ -210,6 +211,8 @@ public: /* ======== UTILITIES ================================================================== */ void saveClient(LocationAPI* client, const LocationCallbacks& callbacks); void eraseClient(LocationAPI* client); + void notifyClientOfCachedLocationSystemInfo(LocationAPI* client, + const LocationCallbacks& callbacks); void updateClientsEventMask(); void stopClientSessions(LocationAPI* client); LocationCallbacks getClientCallbacks(LocationAPI* client); @@ -344,6 +347,7 @@ public: virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config); virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config); virtual bool reportGnssEngEnergyConsumedEvent(uint64_t energyConsumedSinceFirstBoot); + virtual void reportLocationSystemInfoEvent(const LocationSystemInfo& locationSystemInfo); virtual bool requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask apn_type_mask); virtual bool releaseATL(int connHandle); @@ -367,6 +371,7 @@ public: void requestOdcpi(const OdcpiRequestInfo& request); void invokeGnssEnergyConsumedCallback(uint64_t energyConsumedSinceFirstBoot); void saveGnssEnergyConsumedCallback(GnssEnergyConsumedCallback energyConsumedCb); + void reportLocationSystemInfo(const LocationSystemInfo & locationSystemInfo); /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); diff --git a/location/LocationAPIClientBase.h b/location/LocationAPIClientBase.h index c61e4a83..da87535a 100644 --- a/location/LocationAPIClientBase.h +++ b/location/LocationAPIClientBase.h @@ -281,6 +281,8 @@ public: inline virtual void onGnssNiCb(uint32_t /*id*/, GnssNiNotification /*gnssNiNotification*/) {} inline virtual void onGnssNiResponseCb(LocationError /*error*/) {} + inline virtual void onLocationSystemInfoCb(LocationSystemInfo /*locationSystemInfo*/) {} + private: // private inner classes typedef struct { diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index aae6dcf9..f35b2200 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -1113,6 +1113,58 @@ typedef struct { std::vector mSatelliteInfo; } GnssDebugReport; +typedef uint32_t LeapSecondSysInfoMask; +typedef enum { + // current leap second info is available. This info will only + // be available if the leap second change info is not available. + // + // If leap second change info is avaiable, to figure out + // the current leap second info, compare current gps time with + // the gps timestamp of leap second change to know whether to choose + // leapSecondBefore or leapSecondAfter as current leap second. + LEAP_SECOND_SYS_INFO_CURRENT_LEAP_SECONDS_BIT = (1ULL << 0), + // the last known leap change event is available. + // The info can be available on two scenario: + // 1: this leap second change event has been scheduled and yet to happen + // 2: this leap second change event has already happened and next + // leap second change event has not yet been scheduled. + LEAP_SECOND_SYS_INFO_LEAP_SECOND_CHANGE_BIT = (1ULL << 1), +} LeapSecondSysInfoDataBits; + +struct LeapSecondChangeInfo { + // GPS timestamp that corrresponds to the last known + // leap second change event. + // + // The info can be available on two scenario: + // 1: this leap second change event has been scheduled and yet to happen + // 2: this leap second change event has already happened and next + // leap second change event has not yet been scheduled. + GnssSystemTimeStructType gpsTimestampLsChange; + // Number of leap seconds prior to the leap second change event + // that corresponds to the timestamp at gpsTimestampLsChange. + uint8_t leapSecondsBeforeChange; + // Number of leap seconds after the leap second change event + // that corresponds to the timestamp at gpsTimestampLsChange. + uint8_t leapSecondsAfterChange; +}; + +struct LeapSecondSystemInfo { + LeapSecondSysInfoMask leapSecondInfoMask; + uint8_t leapSecondCurrent; + LeapSecondChangeInfo leapSecondChangeInfo; +}; + +typedef uint32_t LocationSystemInfoMask; +typedef enum { + // contains current leap second or leap second change info + LOCATION_SYS_INFO_LEAP_SECOND = (1ULL << 0), +} LocationSystemInfoDataBits; + +struct LocationSystemInfo { + LocationSystemInfoMask systemInfoMask; + LeapSecondSystemInfo leapSecondSysInfo; +}; + /* Provides the capabilities of the system capabilities callback is called once soon after createInstance is called */ typedef std::function gnssConfigCallback; +/* LocationSystemInfoCb is for receiving rare occuring location + system information update. optional, can be NULL. +*/ +typedef std::function locationSystemInfoCallback; + typedef struct { size_t size; // set to sizeof(LocationCallbacks) capabilitiesCallback capabilitiesCb; // mandatory @@ -1231,6 +1290,7 @@ typedef struct { gnssDataCallback gnssDataCb; // optional gnssMeasurementsCallback gnssMeasurementsCb; // optional batchingStatusCallback batchingStatusCb; // optional + locationSystemInfoCallback locationSystemInfoCb; // optional } LocationCallbacks; #endif /* LOCATIONDATATYPES_H */ diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index 146b2f4e..8ddf488a 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -852,6 +852,7 @@ enum loc_api_adapter_event_index { LOC_API_ADAPTER_REPORT_UNPROPAGATED_POSITION, // Unpropagated Position report LOC_API_ADAPTER_BS_OBS_DATA_SERVICE_REQ, // BS observation data request LOC_API_ADAPTER_GNSS_SV_EPHEMERIS_REPORT, // GNSS SV Ephemeris Report + LOC_API_ADAPTER_LOC_SYSTEM_INFO, // Location system info event LOC_API_ADAPTER_EVENT_MAX }; @@ -891,6 +892,7 @@ enum loc_api_adapter_event_index { #define LOC_API_ADAPTER_BIT_PARSED_UNPROPAGATED_POSITION_REPORT (1ULL<