/* Copyright (c) 2011-2014, 2016-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. * */ #define LOG_NDEBUG 0 #define LOG_TAG "LocSvc_LocAdapterBase" #include #include #include #include #include namespace loc_core { // This is the top level class, so the constructor will // always gets called. Here we prepare for the default. // But if getLocApi(targetEnumType target) is overriden, // the right locApi should get created. LocAdapterBase::LocAdapterBase(const LOC_API_ADAPTER_EVENT_MASK_T mask, ContextBase* context, bool isMaster, LocAdapterProxyBase *adapterProxyBase) : mIsMaster(isMaster), mEvtMask(mask), mContext(context), mLocApi(context->getLocApi()), mLocAdapterProxyBase(adapterProxyBase), mMsgTask(context->getMsgTask()), mIsEngineCapabilitiesKnown(ContextBase::sIsEngineCapabilitiesKnown) { mLocApi->addAdapter(this); } uint32_t LocAdapterBase::mSessionIdCounter(1); uint32_t LocAdapterBase::generateSessionId() { if (++mSessionIdCounter == 0xFFFFFFFF) mSessionIdCounter = 1; return mSessionIdCounter; } void LocAdapterBase::handleEngineUpEvent() { if (mLocAdapterProxyBase) { mLocAdapterProxyBase->handleEngineUpEvent(); } } void LocAdapterBase::handleEngineDownEvent() { if (mLocAdapterProxyBase) { mLocAdapterProxyBase->handleEngineDownEvent(); } } void LocAdapterBase:: reportPositionEvent(const UlpLocation& location, const GpsLocationExtended& locationExtended, enum loc_sess_status status, LocPosTechMask loc_technology_mask, bool /*fromEngineHub*/, GnssDataNotification* pDataNotify, int msInWeek) { if (mLocAdapterProxyBase != NULL) { mLocAdapterProxyBase->reportPositionEvent((UlpLocation&)location, (GpsLocationExtended&)locationExtended, status, loc_technology_mask); } else { DEFAULT_IMPL() } } void LocAdapterBase:: reportSvEvent(const GnssSvNotification& /*svNotify*/, bool /*fromEngineHub*/) DEFAULT_IMPL() void LocAdapterBase:: reportSvPolynomialEvent(GnssSvPolynomial &/*svPolynomial*/) DEFAULT_IMPL() void LocAdapterBase:: reportSvEphemerisEvent(GnssSvEphemerisReport &/*svEphemeris*/) DEFAULT_IMPL() void LocAdapterBase:: reportStatus(LocGpsStatusValue /*status*/) DEFAULT_IMPL() void LocAdapterBase:: reportNmeaEvent(const char* /*nmea*/, size_t /*length*/) DEFAULT_IMPL() void LocAdapterBase:: reportDataEvent(const GnssDataNotification& /*dataNotify*/, int /*msInWeek*/) DEFAULT_IMPL() bool LocAdapterBase:: reportXtraServer(const char* /*url1*/, const char* /*url2*/, const char* /*url3*/, const int /*maxlength*/) DEFAULT_IMPL(false) void LocAdapterBase:: reportLocationSystemInfoEvent(const LocationSystemInfo& /*locationSystemInfo*/) DEFAULT_IMPL() bool LocAdapterBase:: requestXtraData() DEFAULT_IMPL(false) bool LocAdapterBase:: requestTime() DEFAULT_IMPL(false) bool LocAdapterBase:: requestLocation() DEFAULT_IMPL(false) bool LocAdapterBase:: requestATL(int /*connHandle*/, LocAGpsType /*agps_type*/, LocApnTypeMask /*apn_type_mask*/) DEFAULT_IMPL(false) bool LocAdapterBase:: releaseATL(int /*connHandle*/) DEFAULT_IMPL(false) bool LocAdapterBase:: requestNiNotifyEvent(const GnssNiNotification &/*notify*/, const void* /*data*/) DEFAULT_IMPL(false) void LocAdapterBase:: reportGnssMeasurementsEvent(const GnssMeasurements& /*gnssMeasurements*/, int /*msInWeek*/) DEFAULT_IMPL() bool LocAdapterBase:: reportWwanZppFix(LocGpsLocation &/*zppLoc*/) DEFAULT_IMPL(false) bool LocAdapterBase:: reportZppBestAvailableFix(LocGpsLocation& /*zppLoc*/, GpsLocationExtended& /*location_extended*/, LocPosTechMask /*tech_mask*/) DEFAULT_IMPL(false) void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/) DEFAULT_IMPL() void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/) DEFAULT_IMPL() bool LocAdapterBase:: requestOdcpiEvent(OdcpiRequestInfo& /*request*/) DEFAULT_IMPL(false) bool LocAdapterBase:: reportGnssEngEnergyConsumedEvent(uint64_t /*energyConsumedSinceFirstBoot*/) DEFAULT_IMPL(false) bool LocAdapterBase:: reportDeleteAidingDataEvent(GnssAidingData & /*aidingData*/) DEFAULT_IMPL(false) bool LocAdapterBase:: reportKlobucharIonoModelEvent(GnssKlobucharIonoModel& /*ionoModel*/) DEFAULT_IMPL(false) bool LocAdapterBase:: reportGnssAdditionalSystemInfoEvent(GnssAdditionalSystemInfo& /*additionalSystemInfo*/) DEFAULT_IMPL(false) void LocAdapterBase:: reportNfwNotificationEvent(GnssNfwNotification& /*notification*/) DEFAULT_IMPL() void LocAdapterBase::geofenceBreachEvent(size_t /*count*/, uint32_t* /*hwIds*/, Location& /*location*/, GeofenceBreachType /*breachType*/, uint64_t /*timestamp*/) DEFAULT_IMPL() void LocAdapterBase::geofenceStatusEvent(GeofenceStatusAvailable /*available*/) DEFAULT_IMPL() void LocAdapterBase::reportLocationsEvent(const Location* /*locations*/, size_t /*count*/, BatchingMode /*batchingMode*/) DEFAULT_IMPL() void LocAdapterBase::reportCompletedTripsEvent(uint32_t /*accumulated_distance*/) DEFAULT_IMPL() void LocAdapterBase::reportBatchStatusChangeEvent(BatchingStatus /*batchStatus*/) DEFAULT_IMPL() void LocAdapterBase::reportPositionEvent(UlpLocation& /*location*/, GpsLocationExtended& /*locationExtended*/, enum loc_sess_status /*status*/, LocPosTechMask /*loc_technology_mask*/) DEFAULT_IMPL() void LocAdapterBase::saveClient(LocationAPI* client, const LocationCallbacks& callbacks) { mClientData[client] = callbacks; updateClientsEventMask(); } void LocAdapterBase::eraseClient(LocationAPI* client) { auto it = mClientData.find(client); if (it != mClientData.end()) { mClientData.erase(it); } updateClientsEventMask(); } LocationCallbacks LocAdapterBase::getClientCallbacks(LocationAPI* client) { LocationCallbacks callbacks = {}; auto it = mClientData.find(client); if (it != mClientData.end()) { callbacks = it->second; } return callbacks; } LocationCapabilitiesMask LocAdapterBase::getCapabilities() { LocationCapabilitiesMask mask = 0; if (isEngineCapabilitiesKnown()) { // time based tracking always supported mask |= LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT; if (ContextBase::isMessageSupported( LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_LOCATION_BATCHING)){ mask |= LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT | LOCATION_CAPABILITIES_DISTANCE_BASED_BATCHING_BIT; } if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_DISTANCE_BASE_TRACKING)) { mask |= LOCATION_CAPABILITIES_DISTANCE_BASED_TRACKING_BIT; } if (ContextBase::isMessageSupported(LOC_API_ADAPTER_MESSAGE_OUTDOOR_TRIP_BATCHING)) { mask |= LOCATION_CAPABILITIES_OUTDOOR_TRIP_BATCHING_BIT; } // geofence always supported mask |= LOCATION_CAPABILITIES_GEOFENCE_BIT; if (ContextBase::gnssConstellationConfig()) { mask |= LOCATION_CAPABILITIES_GNSS_MEASUREMENTS_BIT; } uint32_t carrierCapabilities = ContextBase::getCarrierCapabilities(); if (carrierCapabilities & LOC_GPS_CAPABILITY_MSB) { mask |= LOCATION_CAPABILITIES_GNSS_MSB_BIT; } if (LOC_GPS_CAPABILITY_MSA & carrierCapabilities) { mask |= LOCATION_CAPABILITIES_GNSS_MSA_BIT; } if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02)) { mask |= LOCATION_CAPABILITIES_DEBUG_NMEA_BIT; } if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) { mask |= LOCATION_CAPABILITIES_CONSTELLATION_ENABLEMENT_BIT; } if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_AGPM_V02)) { mask |= LOCATION_CAPABILITIES_AGPM_BIT; } if (ContextBase::isFeatureSupported(LOC_SUPPORTED_FEATURE_LOCATION_PRIVACY)) { mask |= LOCATION_CAPABILITIES_PRIVACY_BIT; } } else { LOC_LOGE("%s]: attempt to get capabilities before they are known.", __func__); } return mask; } void LocAdapterBase::broadcastCapabilities(LocationCapabilitiesMask mask) { for (auto clientData : mClientData) { if (nullptr != clientData.second.capabilitiesCb) { clientData.second.capabilitiesCb(mask); } } } void LocAdapterBase::updateClientsEventMask() DEFAULT_IMPL() void LocAdapterBase::stopClientSessions(LocationAPI* client) DEFAULT_IMPL() void LocAdapterBase::addClientCommand(LocationAPI* client, const LocationCallbacks& callbacks) { LOC_LOGD("%s]: client %p", __func__, client); struct MsgAddClient : public LocMsg { LocAdapterBase& mAdapter; LocationAPI* mClient; const LocationCallbacks mCallbacks; inline MsgAddClient(LocAdapterBase& adapter, LocationAPI* client, const LocationCallbacks& callbacks) : LocMsg(), mAdapter(adapter), mClient(client), mCallbacks(callbacks) {} inline virtual void proc() const { mAdapter.saveClient(mClient, mCallbacks); } }; sendMsg(new MsgAddClient(*this, client, callbacks)); } void LocAdapterBase::removeClientCommand(LocationAPI* client, removeClientCompleteCallback rmClientCb) { LOC_LOGD("%s]: client %p", __func__, client); struct MsgRemoveClient : public LocMsg { LocAdapterBase& mAdapter; LocationAPI* mClient; removeClientCompleteCallback mRmClientCb; inline MsgRemoveClient(LocAdapterBase& adapter, LocationAPI* client, removeClientCompleteCallback rmCb) : LocMsg(), mAdapter(adapter), mClient(client), mRmClientCb(rmCb){} inline virtual void proc() const { mAdapter.stopClientSessions(mClient); mAdapter.eraseClient(mClient); if (nullptr != mRmClientCb) { (mRmClientCb)(mClient); } } }; sendMsg(new MsgRemoveClient(*this, client, rmClientCb)); } void LocAdapterBase::requestCapabilitiesCommand(LocationAPI* client) { LOC_LOGD("%s]: ", __func__); struct MsgRequestCapabilities : public LocMsg { LocAdapterBase& mAdapter; LocationAPI* mClient; inline MsgRequestCapabilities(LocAdapterBase& adapter, LocationAPI* client) : LocMsg(), mAdapter(adapter), mClient(client) {} inline virtual void proc() const { if (!mAdapter.isEngineCapabilitiesKnown()) { mAdapter.mPendingMsgs.push_back(new MsgRequestCapabilities(*this)); return; } LocationCallbacks callbacks = mAdapter.getClientCallbacks(mClient); if (callbacks.capabilitiesCb != nullptr) { callbacks.capabilitiesCb(mAdapter.getCapabilities()); } } }; sendMsg(new MsgRequestCapabilities(*this, client)); } } // namespace loc_core