diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 8b6713c1..65d2c8d9 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -126,7 +126,7 @@ struct LocOpenMsg : public LocMsg { LocApiBase::LocApiBase(const MsgTask* msgTask, LOC_API_ADAPTER_EVENT_MASK_T excludedMask) : - mExcludedMask(excludedMask), mMsgTask(msgTask), mMask(0) + mMsgTask(msgTask), mExcludedMask(excludedMask), mMask(0) { memset(mLocAdapters, 0, sizeof(mLocAdapters)); } diff --git a/loc_api/libloc_api_50001/LocEngAdapter.cpp b/loc_api/libloc_api_50001/LocEngAdapter.cpp index ba9ee5ec..44000816 100644 --- a/loc_api/libloc_api_50001/LocEngAdapter.cpp +++ b/loc_api/libloc_api_50001/LocEngAdapter.cpp @@ -65,7 +65,8 @@ LocEngAdapter::LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, :context), mOwner(owner), mInternalAdapter(new LocInternalAdapter(this)), mUlp(new UlpProxyBase()), mNavigating(false), - mSupportsAgpsExtendedCapabilities(false), mSupportsCPIExtendedCapabilities(false) + mSupportsAgpsExtendedCapabilities(false), + mSupportsCPIExtendedCapabilities(false), mPowerVote(0) { memset(&mFixCriteria, 0, sizeof(mFixCriteria)); mFixCriteria.mode = LOC_POSITION_MODE_INVALID; @@ -123,6 +124,40 @@ void LocEngAdapter::setUlpProxy(UlpProxyBase* ulp) mUlp = ulp; } +void LocEngAdapter::requestPowerVote() +{ + struct LocEngAdapterVotePower : public LocMsg { + LocEngAdapter* mAdapter; + const bool mPowerUp; + inline LocEngAdapterVotePower(LocEngAdapter* adapter, bool powerUp) : + LocMsg(), mAdapter(adapter), mPowerUp(powerUp) + { + locallog(); + } + inline virtual void proc() const { + /* Power voting without engine lock: + * 101: vote down, 102-104 - vote up + * These codes are used not to confuse with actual engine lock + * functionality, that can't be used in SSR scenario, as it + * conflicts with initialization sequence. + */ + int mode = mPowerUp ? 103 : 101; + mAdapter->setGpsLock(mode); + } + inline void locallog() const { + LOC_LOGV("LocEngAdapterVotePower - Vote Power: %d", + (int)mPowerUp); + } + inline virtual void log() const { + locallog(); + } + }; + + if (getPowerVoteRight()) { + sendMsg(new LocEngAdapterVotePower(this, getPowerVote())); + } +} + void LocInternalAdapter::reportPosition(UlpLocation &location, GpsLocationExtended &locationExtended, void* locationExt, diff --git a/loc_api/libloc_api_50001/LocEngAdapter.h b/loc_api/libloc_api_50001/LocEngAdapter.h index fdc4c778..2c6e22d5 100644 --- a/loc_api/libloc_api_50001/LocEngAdapter.h +++ b/loc_api/libloc_api_50001/LocEngAdapter.h @@ -74,13 +74,19 @@ class LocEngAdapter : public LocAdapterBase { UlpProxyBase* mUlp; LocPosMode mFixCriteria; bool mNavigating; + // mPowerVote is encoded as + // mPowerVote & 0x20 -- powerVoteRight + // mPowerVote & 0x10 -- power On / Off + unsigned int mPowerVote; + static const unsigned int POWER_VOTE_RIGHT = 0x20; + static const unsigned int POWER_VOTE_VALUE = 0x10; public: bool mSupportsAgpsExtendedCapabilities; bool mSupportsCPIExtendedCapabilities; LocEngAdapter(LOC_API_ADAPTER_EVENT_MASK_T mask, - void* owner,ContextBase* context, + void* owner, ContextBase* context, MsgTask::tCreate tCreator); virtual ~LocEngAdapter(); @@ -279,6 +285,26 @@ public: { return mNavigating; } void setInSession(bool inSession); + // Permit/prohibit power voting + inline void setPowerVoteRight(bool powerVoteRight) { + mPowerVote = powerVoteRight ? (mPowerVote | POWER_VOTE_RIGHT) : + (mPowerVote & ~POWER_VOTE_RIGHT); + } + inline bool getPowerVoteRight() const { + return (mPowerVote & POWER_VOTE_RIGHT) != 0 ; + } + // Set the power voting up/down and do actual operation if permitted + inline void setPowerVote(bool powerOn) { + mPowerVote = powerOn ? (mPowerVote | POWER_VOTE_VALUE) : + (mPowerVote & ~POWER_VOTE_VALUE); + requestPowerVote(); + } + inline bool getPowerVote() const { + return (mPowerVote & POWER_VOTE_VALUE) != 0 ; + } + // Do power voting according to last settings if permitted + void requestPowerVote(); + /*Values for lock 1 = Do not lock any position sessions 2 = Lock MI position sessions diff --git a/loc_api/libloc_api_50001/loc.cpp b/loc_api/libloc_api_50001/loc.cpp index d98a80fa..8c5ce033 100644 --- a/loc_api/libloc_api_50001/loc.cpp +++ b/loc_api/libloc_api_50001/loc.cpp @@ -294,6 +294,9 @@ static int loc_init(GpsCallbacks* callbacks) goto err; } + loc_afw_data.adapter->setPowerVoteRight(loc_get_target() == TARGET_QCA1530); + loc_afw_data.adapter->setPowerVote(true); + LOC_LOGD("loc_eng_init() success!"); if (mdm_fd < 0) { struct dev_info modem_info; @@ -349,6 +352,9 @@ SIDE EFFECTS static void loc_cleanup() { ENTRY_LOG(); + + loc_afw_data.adapter->setPowerVote(false); + loc_eng_cleanup(loc_afw_data); gps_loc_cb = NULL; gps_sv_cb = NULL; diff --git a/loc_api/libloc_api_50001/loc_eng.cpp b/loc_api/libloc_api_50001/loc_eng.cpp index 28b0874b..cb3c4961 100644 --- a/loc_api/libloc_api_50001/loc_eng.cpp +++ b/loc_api/libloc_api_50001/loc_eng.cpp @@ -2525,6 +2525,8 @@ void loc_eng_handle_engine_up(loc_eng_data_s_type &loc_eng_data) ENTRY_LOG(); loc_eng_reinit(loc_eng_data); + loc_eng_data.adapter->requestPowerVote(); + if (loc_eng_data.agps_status_cb != NULL) { if (loc_eng_data.agnss_nif) loc_eng_data.agnss_nif->dropAllSubscribers();