diff --git a/android/1.0/AGnss.cpp b/android/1.0/AGnss.cpp index faaf75e5..79f665c5 100644 --- a/android/1.0/AGnss.cpp +++ b/android/1.0/AGnss.cpp @@ -105,7 +105,7 @@ Return AGnss::setCallback(const sp& callback) { AgpsCbInfo cbInfo = {}; cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb; - cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW; + cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES; mGnss->getGnssInterface()->agpsInit(cbInfo); return Void(); diff --git a/android/1.1/AGnss.cpp b/android/1.1/AGnss.cpp index fe50c9a0..d8f97065 100644 --- a/android/1.1/AGnss.cpp +++ b/android/1.1/AGnss.cpp @@ -105,7 +105,7 @@ Return AGnss::setCallback(const sp& callback) { AgpsCbInfo cbInfo = {}; cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb; - cbInfo.cbPriority = AGPS_CB_PRIORITY_LOW; + cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES; mGnss->getGnssInterface()->agpsInit(cbInfo); return Void(); diff --git a/android/2.0/AGnss.cpp b/android/2.0/AGnss.cpp index 7bd015e7..a48f1a0d 100644 --- a/android/2.0/AGnss.cpp +++ b/android/2.0/AGnss.cpp @@ -107,7 +107,7 @@ Return AGnss::setCallback(const sp& callback) { AgpsCbInfo cbInfo = {}; cbInfo.statusV4Cb = (void*)agnssStatusIpV4Cb; - cbInfo.cbPriority = AGPS_CB_PRIORITY_HIGH; + cbInfo.atlType = AGPS_ATL_TYPE_SUPL | AGPS_ATL_TYPE_SUPL_ES; mGnss->getGnssInterface()->agpsInit(cbInfo); return Void(); diff --git a/core/EngineHubProxyBase.h b/core/EngineHubProxyBase.h index 4239a508..ec881f69 100644 --- a/core/EngineHubProxyBase.h +++ b/core/EngineHubProxyBase.h @@ -103,12 +103,8 @@ public: } }; -typedef std::function - GnssAdapterReportPositionEventCb; +typedef std::function + GnssAdapterReportEnginePositionsEventCb; typedef std::function @@ -119,11 +115,12 @@ typedef std::function // potential parameters: message queue: MsgTask * msgTask; // callback function to report back dr and ppe position and sv report -typedef EngineHubProxyBase* (getEngHubProxyFn)(const MsgTask * msgTask, - IOsObserver* osObserver, - GnssAdapterReportPositionEventCb positionEventCb, - GnssAdapterReportSvEventCb svEventCb, - GnssAdapterReqAidingDataCb reqAidingDataCb); +typedef EngineHubProxyBase* (getEngHubProxyFn)( + const MsgTask * msgTask, + IOsObserver* osObserver, + GnssAdapterReportEnginePositionsEventCb positionEventCb, + GnssAdapterReportSvEventCb svEventCb, + GnssAdapterReqAidingDataCb reqAidingDataCb); } // namespace loc_core diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index ffd3d5a1..1b844e57 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -81,7 +81,6 @@ void LocAdapterBase:: const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask loc_technology_mask, - bool /*fromEngineHub*/, GnssDataNotification* pDataNotify, int msInWeek) { diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index b9b1f1e8..909b6fea 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -151,9 +151,13 @@ public: const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask loc_technology_mask, - bool fromEngineHub = false, GnssDataNotification* pDataNotify = nullptr, int msInWeek = -1); + virtual void reportEnginePositionsEvent(unsigned int count, + EngineLocationInfo* locationArr) { + (void)count; + (void)locationArr; + } virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromEngineHub=false); virtual void reportDataEvent(const GnssDataNotification& dataNotify, int msInWeek); diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index ef204ec3..8c79cf74 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -148,7 +148,8 @@ struct LocCloseMsg : public LocMsg { } }; -MsgTask* LocApiBase::mMsgTask; +MsgTask* LocApiBase::mMsgTask = nullptr; +volatile int32_t LocApiBase::mMsgTaskRefCount = 0; LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, ContextBase* context) : @@ -157,6 +158,7 @@ LocApiBase::LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, { memset(mLocAdapters, 0, sizeof(mLocAdapters)); + android_atomic_inc(&mMsgTaskRefCount); if (nullptr == mMsgTask) { mMsgTask = new MsgTask("LocApiMsgTask", false); } @@ -230,7 +232,7 @@ void LocApiBase::addAdapter(LocAdapterBase* adapter) for (int i = 0; i < MAX_ADAPTERS && mLocAdapters[i] != adapter; i++) { if (mLocAdapters[i] == NULL) { mLocAdapters[i] = adapter; - mMsgTask->sendMsg(new LocOpenMsg(this, adapter)); + sendMsg(new LocOpenMsg(this, adapter)); break; } } @@ -263,10 +265,10 @@ void LocApiBase::removeAdapter(LocAdapterBase* adapter) // if we have an empty list of adapters if (0 == i) { - mMsgTask->sendMsg(new LocCloseMsg(this)); + sendMsg(new LocCloseMsg(this)); } else { // else we need to remove the bit - mMsgTask->sendMsg(new LocOpenMsg(this)); + sendMsg(new LocOpenMsg(this)); } } } @@ -274,7 +276,7 @@ void LocApiBase::removeAdapter(LocAdapterBase* adapter) void LocApiBase::updateEvtMask() { - mMsgTask->sendMsg(new LocOpenMsg(this)); + sendMsg(new LocOpenMsg(this)); } void LocApiBase::updateNmeaMask(uint32_t mask) @@ -298,7 +300,7 @@ void LocApiBase::updateNmeaMask(uint32_t mask) } }; - mMsgTask->sendMsg(new LocSetNmeaMsg(this, mask)); + sendMsg(new LocSetNmeaMsg(this, mask)); } void LocApiBase::handleEngineUpEvent() @@ -343,7 +345,6 @@ void LocApiBase::reportPosition(UlpLocation& location, TO_ALL_LOCADAPTERS( mLocAdapters[i]->reportPositionEvent(location, locationExtended, status, loc_technology_mask, - false, pDataNotify, msInWeek) ); } diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 8c885f7f..6dac585b 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace loc_core { @@ -107,6 +108,7 @@ class LocApiBase { friend struct LocKillMsg; friend class ContextBase; static MsgTask* mMsgTask; + static volatile int32_t mMsgTaskRefCount; LocAdapterBase* mLocAdapters[MAX_ADAPTERS]; protected: @@ -121,7 +123,8 @@ protected: LocApiBase(LOC_API_ADAPTER_EVENT_MASK_T excludedMask, ContextBase* context = NULL); inline virtual ~LocApiBase() { - if (nullptr != mMsgTask) { + android_atomic_dec(&mMsgTaskRefCount); + if (nullptr != mMsgTask && 0 == mMsgTaskRefCount) { mMsgTask->destroy(); mMsgTask = nullptr; } @@ -132,7 +135,9 @@ protected: public: inline void sendMsg(const LocMsg* msg) const { - mMsgTask->sendMsg(msg); + if (nullptr != mMsgTask) { + mMsgTask->sendMsg(msg); + } } inline void destroy() { close(); diff --git a/etc/gps.conf b/etc/gps.conf index 35a0a7e6..f773e818 100644 --- a/etc/gps.conf +++ b/etc/gps.conf @@ -24,13 +24,6 @@ DEBUG_LEVEL = 3 # Intermediate position report, 1=enable, 0=disable INTERMEDIATE_POS=0 -# Below bit mask configures how GPS functionalities -# should be locked when user turns off GPS on Settings -# Set bit 0x1 if MO GPS functionalities are to be locked -# Set bit 0x2 if NI GPS functionalities are to be locked -# default – both MO and NI locked for maximal privacy -#GPS_LOCK = 3 - # supl version 1.0 SUPL_VER=0x10000 @@ -124,7 +117,7 @@ A_GLONASS_POS_PROTOCOL_SELECT = 0 # 0x2: WLAN AP Measurements for LPPe CP # 0x4: SRN AP measurement for CP # 0x8: Sensor Barometer Measurement LPPe CP -LPPE_CP_TECHNOLOGY = 0 +#LPPE_CP_TECHNOLOGY = 0 ################################################## # Select technology for LPPe User Plane @@ -133,7 +126,7 @@ LPPE_CP_TECHNOLOGY = 0 # 0x2: WLAN AP Measurements for LPPe UP # 0x4: SRN AP measurement for UP # 0x8: Sensor Barometer Measurement LPPe UP -LPPE_UP_TECHNOLOGY = 0 +#LPPE_UP_TECHNOLOGY = 0 ################################################## # AGPS_CONFIG_INJECT diff --git a/gnss/Agps.cpp b/gnss/Agps.cpp index 7931d0c3..9255f88f 100644 --- a/gnss/Agps.cpp +++ b/gnss/Agps.cpp @@ -304,7 +304,7 @@ void AgpsStateMachine::requestOrReleaseDataConn(bool request){ nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN; } - mAgpsManager->mFrameworkStatusV4Cb(nifRequest); + mFrameworkStatusV4Cb(nifRequest); } void AgpsStateMachine::notifyAllSubscribers( @@ -511,7 +511,7 @@ void AgpsStateMachine::dropAllSubscribers(){ /* CREATE AGPS STATE MACHINES * Must be invoked in Msg Handler context */ -void AgpsManager::createAgpsStateMachines() { +void AgpsManager::createAgpsStateMachines(const AgpsCbInfo& cbInfo) { LOC_LOGD("AgpsManager::createAgpsStateMachines"); @@ -519,13 +519,16 @@ void AgpsManager::createAgpsStateMachines() { ((loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA) || (loc_core::ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB)); - if (NULL == mInternetNif) { + if (NULL == mInternetNif && (cbInfo.atlType & AGPS_ATL_TYPE_WWAN)) { mInternetNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_WWAN_ANY); + mInternetNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb); LOC_LOGD("Internet NIF: %p", mInternetNif); } if (agpsCapable) { - if (NULL == mAgnssNif) { + if (NULL == mAgnssNif && (cbInfo.atlType & AGPS_ATL_TYPE_SUPL) && + (cbInfo.atlType & AGPS_ATL_TYPE_SUPL_ES)) { mAgnssNif = new AgpsStateMachine(this, LOC_AGPS_TYPE_SUPL); + mAgnssNif->registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb); LOC_LOGD("AGNSS NIF: %p", mAgnssNif); } } @@ -544,6 +547,11 @@ AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) { LOC_LOGE("NULL AGNSS NIF !"); } return mAgnssNif; + case LOC_AGPS_TYPE_WWAN_ANY: + if (mInternetNif == NULL) { + LOC_LOGE("NULL Internet NIF !"); + } + return mInternetNif; default: return mInternetNif; } diff --git a/gnss/Agps.h b/gnss/Agps.h index 829cbd59..d559377a 100644 --- a/gnss/Agps.h +++ b/gnss/Agps.h @@ -137,6 +137,7 @@ protected: /* Current state for this state machine */ AgpsState mState; + AgnssStatusIpV4Cb mFrameworkStatusV4Cb; private: /* AGPS Type for this state machine LOC_AGPS_TYPE_ANY 0 @@ -154,6 +155,7 @@ private: public: /* CONSTRUCTOR */ AgpsStateMachine(AgpsManager* agpsManager, AGpsExtType agpsType): + mFrameworkStatusV4Cb(NULL), mAgpsManager(agpsManager), mSubscriberList(), mCurrentSubscriber(NULL), mState(AGPS_STATE_RELEASED), mAgpsType(agpsType), mAPN(NULL), mAPNLen(0), @@ -175,6 +177,10 @@ public: inline void setCurrentSubscriber(AgpsSubscriber* subscriber) { mCurrentSubscriber = subscriber; } + inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) { + mFrameworkStatusV4Cb = frameworkStatusV4Cb; + } + /* Fetch subscriber with specified handle */ AgpsSubscriber* getSubscriber(int connHandle); @@ -234,7 +240,6 @@ class AgpsManager { public: /* CONSTRUCTOR */ AgpsManager(): - mFrameworkStatusV4Cb(NULL), mAtlOpenStatusCb(), mAtlCloseStatusCb(), mAgnssNif(NULL), mInternetNif(NULL)/*, mDsNif(NULL)*/ {} @@ -246,12 +251,11 @@ public: mAtlCloseStatusCb = atlCloseStatusCb; } - inline void registerFrameworkStatusCallback(AgnssStatusIpV4Cb frameworkStatusV4Cb) { - mFrameworkStatusV4Cb = frameworkStatusV4Cb; - } + /* Check if AGPS client is registered */ + inline bool isRegistered() { return nullptr != mAgnssNif || nullptr != mInternetNif; } /* Create all AGPS state machines */ - void createAgpsStateMachines(); + void createAgpsStateMachines(const AgpsCbInfo& cbInfo); /* Process incoming ATL requests */ void requestATL(int connHandle, AGpsExtType agpsType, LocApnTypeMask apnTypeMask); @@ -266,7 +270,6 @@ public: void handleModemSSR(); protected: - AgnssStatusIpV4Cb mFrameworkStatusV4Cb; AgpsAtlOpenStatusCb mAtlOpenStatusCb; AgpsAtlCloseStatusCb mAtlCloseStatusCb; diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 47e55270..578953d7 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -80,7 +80,6 @@ GnssAdapter::GnssAdapter() : mGnssSvTypeConfigCb(nullptr), mNiData(), mAgpsManager(), - mAgpsCbInfo(), mOdcpiRequestCb(nullptr), mOdcpiRequestActive(false), mOdcpiTimer(this), @@ -485,6 +484,16 @@ GnssAdapter::convertLocationInfo(GnssLocationInfoNotification& out, out.flags |= GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT; out.calibrationStatus = locationExtended.calibrationStatus; } + + if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & locationExtended.flags) { + out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT; + out.locOutputEngType = locationExtended.locOutputEngType; + } + + if (GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_MASK & locationExtended.flags) { + out.flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT; + out.locOutputEngMask = locationExtended.locOutputEngMask; + } } @@ -722,8 +731,6 @@ GnssAdapter::setConfig() //cache the injected configuration with GnssConfigRequested struct GnssConfig gnssConfigRequested = {}; gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT | - GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT | - GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT | GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT; /* Here we process an SSR. We need to set the GPS_LOCK to the proper values, as follows: 1. Q behavior. This is identified by mSupportNfwControl being 1. In this case @@ -756,10 +763,17 @@ GnssAdapter::setConfig() gnssConfigRequested.aGlonassPositionProtocolMask = gpsConf.A_GLONASS_POS_PROTOCOL_SELECT; } - gnssConfigRequested.lppeControlPlaneMask = - mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY); - gnssConfigRequested.lppeUserPlaneMask = - mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY); + if (gpsConf.LPPE_CP_TECHNOLOGY) { + gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT; + gnssConfigRequested.lppeControlPlaneMask = + mLocApi->convertLppeCp(gpsConf.LPPE_CP_TECHNOLOGY); + } + + if (gpsConf.LPPE_UP_TECHNOLOGY) { + gnssConfigRequested.flags |= GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT; + gnssConfigRequested.lppeUserPlaneMask = + mLocApi->convertLppeUp(gpsConf.LPPE_UP_TECHNOLOGY); + } gnssConfigRequested.blacklistedSvIds.assign(mBlacklistedSvIds.begin(), mBlacklistedSvIds.end()); mLocApi->sendMsg(new LocApiMsg( @@ -2078,10 +2092,9 @@ GnssAdapter::updateClientsEventMask() mask); } - if (mAgpsCbInfo.statusV4Cb != NULL) { + if (mAgpsManager.isRegistered()) { mask |= LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST; } - // Add ODCPI handling if (nullptr != mOdcpiRequestCb) { mask |= LOC_API_ADAPTER_BIT_REQUEST_WIFI; @@ -3051,32 +3064,23 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask techMask, - bool fromEngineHub, GnssDataNotification* pDataNotify, int msInWeek) { - // if this event is called from QMI LOC API, then send report to engine hub + // this position is from QMI LOC API, then send report to engine hub // if sending is successful, we return as we will wait for final report from engine hub // if the position is called from engine hub, then send it out directly - if (!fromEngineHub) { - // report QMI position (both propagated and unpropagated) to engine hub, - // and engine hub will be distributing it to the registered plugins + + if (true == initEngHubProxy()){ mEngHubProxy->gnssReportPosition(ulpLocation, locationExtended, status); - - if (true == ulpLocation.unpropagatedPosition) { - return; - } - - // engine hub is loaded, do not report qmi position to client as - // final position report should come from engine hub - if (true == initEngHubProxy()){ - return; - } + return; } - // for all other cases: - // case 1: fix is from engine hub, queue the msg - // case 2: fix is not from engine hub, e.g. from QMI, and it is not an + if (true == ulpLocation.unpropagatedPosition) { + return; + } + + // Fix is from QMI, and it is not an // unpropagated position and engine hub is not loaded, queue the msg // when message is queued, the position can be dispatched to requesting client struct MsgReportPosition : public LocMsg { @@ -3133,6 +3137,35 @@ GnssAdapter::reportPositionEvent(const UlpLocation& ulpLocation, pDataNotify, msInWeek)); } +void +GnssAdapter::reportEnginePositionsEvent(unsigned int count, + EngineLocationInfo* locationArr) +{ + struct MsgReportEnginePositions : public LocMsg { + GnssAdapter& mAdapter; + unsigned int mCount; + EngineLocationInfo mEngLocInfo[LOC_OUTPUT_ENGINE_COUNT]; + inline MsgReportEnginePositions(GnssAdapter& adapter, + unsigned int count, + EngineLocationInfo* locationArr) : + LocMsg(), + mAdapter(adapter), + mCount(count) { + if (mCount > LOC_OUTPUT_ENGINE_COUNT) { + mCount = LOC_OUTPUT_ENGINE_COUNT; + } + if (mCount > 0) { + memcpy(mEngLocInfo, locationArr, sizeof(EngineLocationInfo)*mCount); + } + } + inline virtual void proc() const { + mAdapter.reportEnginePositions(mCount, mEngLocInfo); + } + }; + + sendMsg(new MsgReportEnginePositions(*this, count, locationArr)); +} + bool GnssAdapter::needReportForGnssClient(const UlpLocation& ulpLocation, enum loc_sess_status status, @@ -3187,9 +3220,20 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { if ((reportToFlpClient && isFlpClient(it->second)) || - (reportToGnssClient && !isFlpClient(it->second))) { + (reportToGnssClient && !isFlpClient(it->second))) { if (nullptr != it->second.gnssLocationInfoCb) { it->second.gnssLocationInfoCb(locationInfo); + } else if ((nullptr != it->second.engineLocationsInfoCb) && + (false == initEngHubProxy())) { + // if engine hub is disabled, this is SPE fix from modem + // we need to mark one copy marked as fused and one copy marked as PPE + // and dispatch it to the engineLocationsInfoCb + GnssLocationInfoNotification engLocationsInfo[2]; + engLocationsInfo[0] = locationInfo; + engLocationsInfo[0].locOutputEngType = LOC_OUTPUT_ENGINE_FUSED; + engLocationsInfo[0].flags |= GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT; + engLocationsInfo[1] = locationInfo; + it->second.engineLocationsInfoCb(2, engLocationsInfo); } else if (nullptr != it->second.trackingCb) { it->second.trackingCb(locationInfo.location); } @@ -3237,6 +3281,48 @@ GnssAdapter::reportPosition(const UlpLocation& ulpLocation, } } +void +GnssAdapter::reportEnginePositions(unsigned int count, + const EngineLocationInfo* locationArr) +{ + bool needReportEnginePositions = false; + for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { + if (nullptr != it->second.engineLocationsInfoCb) { + needReportEnginePositions = true; + break; + } + } + + GnssLocationInfoNotification locationInfo[LOC_OUTPUT_ENGINE_COUNT] = {}; + for (unsigned int i = 0; i < count; i++) { + const EngineLocationInfo* engLocation = (locationArr+i); + // if it is fused/default location, call reportPosition maintain legacy behavior + if ((GPS_LOCATION_EXTENDED_HAS_OUTPUT_ENG_TYPE & engLocation->locationExtended.flags) && + (LOC_OUTPUT_ENGINE_FUSED == engLocation->locationExtended.locOutputEngType)) { + reportPosition(engLocation->location, + engLocation->locationExtended, + engLocation->sessionStatus, + engLocation->location.tech_mask); + } + + if (needReportEnginePositions) { + convertLocationInfo(locationInfo[i], engLocation->locationExtended); + convertLocation(locationInfo[i].location, + engLocation->location, + engLocation->locationExtended, + engLocation->location.tech_mask); + } + } + + if (needReportEnginePositions) { + for (auto it=mClientData.begin(); it != mClientData.end(); ++it) { + if (nullptr != it->second.engineLocationsInfoCb) { + it->second.engineLocationsInfoCb(count, locationInfo); + } + } + } +} + void GnssAdapter::reportSvEvent(const GnssSvNotification& svNotify, bool fromEngineHub) @@ -4111,27 +4197,17 @@ void GnssAdapter::initDefaultAgpsCommand() { /* INIT LOC AGPS MANAGER */ void GnssAdapter::initAgps(const AgpsCbInfo& cbInfo) { - LOC_LOGD("%s]: mAgpsCbInfo.cbPriority - %d; cbInfo.cbPriority - %d", - __func__, mAgpsCbInfo.cbPriority, cbInfo.cbPriority) + LOC_LOGD("%s]:cbInfo.atlType - %d", __func__, cbInfo.atlType); if (!((ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSB) || (ContextBase::mGps_conf.CAPABILITIES & LOC_GPS_CAPABILITY_MSA))) { return; } - if (mAgpsCbInfo.cbPriority > cbInfo.cbPriority) { - return; - } else { - mAgpsCbInfo = cbInfo; - - mAgpsManager.registerFrameworkStatusCallback((AgnssStatusIpV4Cb)cbInfo.statusV4Cb); - - mAgpsManager.createAgpsStateMachines(); - - /* Register for AGPS event mask */ - updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST, - LOC_REGISTRATION_MASK_ENABLED); - } + mAgpsManager.createAgpsStateMachines(cbInfo); + /* Register for AGPS event mask */ + updateEvtMask(LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST, + LOC_REGISTRATION_MASK_ENABLED); } void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ @@ -4920,15 +4996,10 @@ GnssAdapter::initEngHubProxy() { // prepare the callback functions // callback function for engine hub to report back position event - GnssAdapterReportPositionEventCb reportPositionEventCb = - [this](const UlpLocation& ulpLocation, - const GpsLocationExtended& locationExtended, - enum loc_sess_status status, - LocPosTechMask techMask, - bool fromEngineHub) { + GnssAdapterReportEnginePositionsEventCb reportPositionEventCb = + [this](int count, EngineLocationInfo* locationArr) { // report from engine hub on behalf of PPE will be treated as fromUlp - reportPositionEvent(ulpLocation, locationExtended, status, - techMask, fromEngineHub); + reportEnginePositionsEvent(count, locationArr); }; // callback function for engine hub to report back sv event diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index b84c3652..3ccdd96d 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -163,7 +163,6 @@ class GnssAdapter : public LocAdapterBase { /* ==== AGPS =========================================================================== */ // This must be initialized via initAgps() AgpsManager mAgpsManager; - AgpsCbInfo mAgpsCbInfo; void initAgps(const AgpsCbInfo& cbInfo); /* ==== NFW =========================================================================== */ @@ -351,9 +350,11 @@ public: const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask techMask, - bool fromEngineHub = false, GnssDataNotification* pDataNotify = nullptr, int msInWeek = -1); + virtual void reportEnginePositionsEvent(unsigned int count, + EngineLocationInfo* locationArr); + virtual void reportSvEvent(const GnssSvNotification& svNotify, bool fromEngineHub=false); virtual void reportNmeaEvent(const char* nmea, size_t length); @@ -386,6 +387,8 @@ public: const GpsLocationExtended &locationExtended, enum loc_sess_status status, LocPosTechMask techMask); + void reportEnginePositions(unsigned int count, + const EngineLocationInfo* locationArr); void reportSv(GnssSvNotification& svNotify); void reportNmea(const char* nmea, size_t length); void reportData(GnssDataNotification& dataNotify); diff --git a/location/LocationAPI.cpp b/location/LocationAPI.cpp index a43178d1..4348c276 100644 --- a/location/LocationAPI.cpp +++ b/location/LocationAPI.cpp @@ -85,6 +85,7 @@ static bool isGnssClient(LocationCallbacks& locationCallbacks) return (locationCallbacks.gnssNiCb != nullptr || locationCallbacks.trackingCb != nullptr || locationCallbacks.gnssLocationInfoCb != nullptr || + locationCallbacks.engineLocationsInfoCb != nullptr || locationCallbacks.gnssMeasurementsCb != nullptr); } diff --git a/location/LocationDataTypes.h b/location/LocationDataTypes.h index 49822fa5..27c5157b 100644 --- a/location/LocationDataTypes.h +++ b/location/LocationDataTypes.h @@ -175,6 +175,8 @@ typedef enum { GNSS_LOCATION_INFO_NUM_SV_USED_IN_POSITION_BIT = (1<<24), // number of SV used in position GNSS_LOCATION_INFO_CALIBRATION_CONFIDENCE_BIT = (1<<25), // valid sensor cal confidence GNSS_LOCATION_INFO_CALIBRATION_STATUS_BIT = (1<<26), // valid sensor cal status + GNSS_LOCATION_INFO_OUTPUT_ENG_TYPE_BIT = (1<<27), // valid output engine type + GNSS_LOCATION_INFO_OUTPUT_ENG_MASK_BIT = (1<<28), // valid output engine mask } GnssLocationInfoFlagBits; typedef enum { @@ -646,6 +648,13 @@ typedef enum { GNSS_LOC_MAX_NUMBER_OF_SIGNAL_TYPES = 20 /**< Maximum number of signal types */ } Gnss_LocSignalEnumType; +typedef uint32_t PositioningEngineMask; +typedef enum { + STANDARD_POSITIONING_ENGINE = (1 << 0), + DEAD_RECKONING_ENGINE = (1 << 1), + PRECISE_POSITIONING_ENGINE = (1 << 2) +} PositioningEngineBits; + typedef uint64_t GnssDataMask; typedef enum { // Jammer Indicator is available @@ -731,15 +740,35 @@ typedef struct { LocationSpoofMask spoofMask; } Location; +typedef enum { + LOC_REQ_ENGINE_FUSED_BIT = (1<<0), + LOC_REQ_ENGINE_SPE_BIT = (1<<1), + LOC_REQ_ENGINE_PPE_BIT = (1<<2), +} LocReqEngineTypeMask; + +typedef enum { + LOC_OUTPUT_ENGINE_FUSED = 0, + /** This is the GNSS fix from modem */ + LOC_OUTPUT_ENGINE_SPE = 1, + /** This is the GNSS fix with correction PPP/RTK correction */ + LOC_OUTPUT_ENGINE_PPE = 2, + LOC_OUTPUT_ENGINE_COUNT, +} LocOutputEngineType; + struct LocationOptions { uint32_t size; // set to sizeof(LocationOptions) uint32_t minInterval; // in milliseconds uint32_t minDistance; // in meters. if minDistance > 0, gnssSvCallback/gnssNmeaCallback/ // gnssMeasurementsCallback may not be called GnssSuplMode mode; // Standalone/MS-Based/MS-Assisted + // behavior when this field is 0: + // if engine hub is running, this will be fused fix, + // if engine hub is not running, this will be SPE fix + LocReqEngineTypeMask locReqEngTypeMask; inline LocationOptions() : - size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE) {} + size(0), minInterval(0), minDistance(0), mode(GNSS_SUPL_MODE_STANDALONE), + locReqEngTypeMask((LocReqEngineTypeMask)0) {} }; typedef enum { @@ -764,9 +793,11 @@ struct TrackingOptions : LocationOptions { inline TrackingOptions(const LocationOptions& options) : LocationOptions(options), powerMode(GNSS_POWER_MODE_INVALID), tbm(0) {} inline void setLocationOptions(const LocationOptions& options) { + size = sizeof(TrackingOptions); minInterval = options.minInterval; minDistance = options.minDistance; mode = options.mode; + locReqEngTypeMask = options.locReqEngTypeMask; } inline LocationOptions getLocationOptions() { LocationOptions locOption; @@ -774,6 +805,7 @@ struct TrackingOptions : LocationOptions { locOption.minDistance = minDistance; locOption.minInterval = minInterval; locOption.mode = mode; + locOption.locReqEngTypeMask = locReqEngTypeMask; return locOption; } }; @@ -997,6 +1029,16 @@ typedef struct { uint8_t calibrationConfidence; // Sensor calibration confidence percent, // in range of [0, 100] DrCalibrationStatusMask calibrationStatus; // Sensor calibration status + // location engine type. When the fix. when the type is set to + // LOC_ENGINE_SRC_FUSED, the fix is the propagated/aggregated + // reports from all engines running on the system (e.g.: + // DR/SPE/PPE) based proprietary algorithm. To check which + // location engine contributes to the fused output, check for + // locOutputEngMask. + LocOutputEngineType locOutputEngType; + // when loc output eng type is set to fused, this field + // indicates the set of engines contribute to the fix. + PositioningEngineMask locOutputEngMask; } GnssLocationInfoNotification; typedef struct { @@ -1317,6 +1359,20 @@ typedef std::function gnssLocationInfoCallback; +/* Gives default combined location information from all engines and + location information individually from selected engines. + This callback is only used when there are multiple engines + running in the system. + + optional can be NULL + + engineLocationsInfoCallback is called only during a tracking session + broadcasted to all clients, no matter if a session has started by client */ +typedef std::function engineLocationsInfoCallback; + /* Used for addGeofences API, optional can be NULL geofenceBreachCallback is called when any number of geofences have a state change */ typedef std::function