diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 43b7e598..87565d73 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -81,7 +81,8 @@ GnssAdapter::GnssAdapter() : mAgpsCbInfo(), mOdcpiRequestCb(nullptr), mOdcpiRequestActive(false), - mOdcpiInjectedPositionCount(0), + mOdcpiTimer(this), + mOdcpiRequest(), mSystemStatus(SystemStatus::getInstance(mMsgTask)), mServerUrl(":"), mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask), @@ -1943,6 +1944,9 @@ GnssAdapter::restartSessions() { LOC_LOGD("%s]: ", __func__); + // odcpi session is no longer active after restart + mOdcpiRequestActive = false; + if (mTrackingSessions.empty()) { return; } @@ -3297,9 +3301,6 @@ GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial) bool GnssAdapter::requestOdcpiEvent(OdcpiRequestInfo& request) { - LOC_LOGd("ODCPI request: type %d, tbf %d, isEmergency %d", request.type, - request.tbfMillis, request.isEmergencyMode); - struct MsgRequestOdcpi : public LocMsg { GnssAdapter& mAdapter; OdcpiRequestInfo mOdcpiRequest; @@ -3319,15 +3320,45 @@ GnssAdapter::requestOdcpiEvent(OdcpiRequestInfo& request) void GnssAdapter::requestOdcpi(const OdcpiRequestInfo& request) { if (nullptr != mOdcpiRequestCb) { - mOdcpiInjectedPositionCount = 0; + LOC_LOGd("request: type %d, tbf %d, isEmergency %d" + " requestActive: %d timerActive: %d", + request.type, request.tbfMillis, request.isEmergencyMode, + mOdcpiRequestActive, mOdcpiTimer.isActive()); + // ODCPI START and ODCPI STOP from modem can come in quick succession + // so the mOdcpiTimer helps avoid spamming the framework as well as + // extending the odcpi session past 30 seconds if needed if (ODCPI_REQUEST_TYPE_START == request.type) { - mOdcpiRequestCb(request); - mOdcpiRequestActive = true; + if (false == mOdcpiRequestActive && false == mOdcpiTimer.isActive()) { + mOdcpiRequestCb(request); + mOdcpiRequestActive = true; + mOdcpiTimer.start(); + // if the current active odcpi session is non-emergency, and the new + // odcpi request is emergency, replace the odcpi request with new request + // and restart the timer + } else if (false == mOdcpiRequest.isEmergencyMode && + true == request.isEmergencyMode) { + mOdcpiRequestCb(request); + mOdcpiRequestActive = true; + if (true == mOdcpiTimer.isActive()) { + mOdcpiTimer.restart(); + } else { + mOdcpiTimer.start(); + } + // if ODCPI request is not active but the timer is active, then + // just update the active state and wait for timer to expire + // before requesting new ODCPI to avoid spamming ODCPI requests + } else if (false == mOdcpiRequestActive && true == mOdcpiTimer.isActive()) { + mOdcpiRequestActive = true; + } + mOdcpiRequest = request; + // the request is being stopped, but allow timer to expire first + // before stopping the timer just in case more ODCPI requests come + // to avoid spamming more odcpi requests to the framework } else { mOdcpiRequestActive = false; } } else { - LOC_LOGe("ODCPI request not supported"); + LOC_LOGw("ODCPI request not supported"); } } @@ -3377,26 +3408,48 @@ void GnssAdapter::injectOdcpiCommand(const Location& location) void GnssAdapter::injectOdcpi(const Location& location) { - if (LOCATION_HAS_LAT_LONG_BIT & location.flags) { - if ((uptimeMillis() <= mBlockCPIInfo.blockedTillTsMs) && - (fabs(location.latitude-mBlockCPIInfo.latitude) <= - mBlockCPIInfo.latLonDiffThreshold) && - (fabs(location.longitude-mBlockCPIInfo.longitude) <= - mBlockCPIInfo.latLonDiffThreshold)) { + LOC_LOGd("ODCPI Injection: requestActive: %d timerActive: %d" + "lat %.7f long %.7f", + mOdcpiRequestActive, mOdcpiTimer.isActive(), + location.latitude, location.longitude); - LOC_LOGD("%s]: positon injeciton blocked: lat: %f, lon: %f, accuracy: %f", - __func__, location.latitude, location.longitude, location.accuracy); - } else { - mLocApi->injectPosition(location, true); - if (mOdcpiRequestActive) { - mOdcpiInjectedPositionCount++; - if (mOdcpiInjectedPositionCount >= - ODCPI_INJECTED_POSITION_COUNT_PER_REQUEST) { - mOdcpiRequestActive = false; - mOdcpiInjectedPositionCount = 0; - } - } + mLocApi->injectPosition(location, true); +} + +// Called in the context of LocTimer thread +void OdcpiTimer::timeOutCallback() +{ + if (nullptr != mAdapter) { + mAdapter->odcpiTimerExpireEvent(); + } +} + +// Called in the context of LocTimer thread +void GnssAdapter::odcpiTimerExpireEvent() +{ + struct MsgOdcpiTimerExpire : public LocMsg { + GnssAdapter& mAdapter; + inline MsgOdcpiTimerExpire(GnssAdapter& adapter) : + LocMsg(), + mAdapter(adapter) {} + inline virtual void proc() const { + mAdapter.odcpiTimerExpire(); } + }; + sendMsg(new MsgOdcpiTimerExpire(*this)); +} +void GnssAdapter::odcpiTimerExpire() +{ + LOC_LOGd("requestActive: %d timerActive: %d", + mOdcpiRequestActive, mOdcpiTimer.isActive()); + + // if ODCPI request is still active after timer + // expires, request again and restart timer + if (mOdcpiRequestActive) { + mOdcpiRequestCb(mOdcpiRequest); + mOdcpiTimer.restart(); + } else { + mOdcpiTimer.stop(); } } diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index 6ed96552..7ca605af 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -44,10 +44,39 @@ #define MAX_SATELLITES_IN_USE 12 #define LOC_NI_NO_RESPONSE_TIME 20 #define LOC_GPS_NI_RESPONSE_IGNORE 4 -#define ODCPI_INJECTED_POSITION_COUNT_PER_REQUEST 30 +#define ODCPI_EXPECTED_INJECTION_TIME_MS 30000 class GnssAdapter; +class OdcpiTimer : public LocTimer { +public: + OdcpiTimer(GnssAdapter* adapter) : + LocTimer(), mAdapter(adapter), mActive(false) {} + + inline void start() { + mActive = true; + LocTimer::start(ODCPI_EXPECTED_INJECTION_TIME_MS, false); + } + inline void stop() { + mActive = false; + LocTimer::stop(); + } + inline void restart() { + stop(); + start(); + } + inline bool isActive() { + return mActive; + } + +private: + // Override + virtual void timeOutCallback() override; + + GnssAdapter* mAdapter; + bool mActive; +}; + typedef struct { pthread_t thread; /* NI thread */ uint32_t respTimeLeft; /* examine time for NI response */ @@ -130,7 +159,9 @@ class GnssAdapter : public LocAdapterBase { /* ==== ODCPI ========================================================================== */ OdcpiRequestCallback mOdcpiRequestCb; bool mOdcpiRequestActive; - uint32_t mOdcpiInjectedPositionCount; + OdcpiTimer mOdcpiTimer; + OdcpiRequestInfo mOdcpiRequest; + void odcpiTimerExpire(); /* === SystemStatus ===================================================================== */ SystemStatus* mSystemStatus; @@ -268,7 +299,6 @@ public: /* ======== COMMANDS ====(Called from Client Thread)==================================== */ void initOdcpiCommand(const OdcpiRequestCallback& callback); void injectOdcpiCommand(const Location& location); - /* ======== RESPONSES ================================================================== */ void reportResponse(LocationError err, uint32_t sessionId); void reportResponse(size_t count, LocationError* errs, uint32_t* ids); @@ -281,6 +311,7 @@ public: virtual bool isInSession() { return !mTrackingSessions.empty(); } void initDefaultAgps(); bool initEngHubProxy(); + void odcpiTimerExpireEvent(); /* ==== REPORTS ======================================================================== */ /* ======== EVENTS ====(Called from QMI/EngineHub Thread)===================================== */