diff options
author | dianlujitao <dianlujitao@lineageos.org> | 2018-01-20 10:25:47 +0800 |
---|---|---|
committer | Davide Garberi <dade.garberi@gmail.com> | 2018-01-27 23:40:16 +0100 |
commit | 596fd461f0a603c861ca9df4076f24a66e732cb5 (patch) | |
tree | 6eaf2d1255b13d5dcc14e938eed2f1321d4ba309 /gps | |
parent | 18fc14ac0a3a0e622d679e7a6f708b4e468e1cfb (diff) |
msm8996: gps: Squashed update to LA.UM.6.5.r1-05300-8x96.0
Change-Id: I76b39dd5329a050d44f126c684edb44b0184f0fc
Signed-off-by: Davide Garberi <dade.garberi@gmail.com>
Diffstat (limited to 'gps')
28 files changed, 1813 insertions, 1076 deletions
diff --git a/gps/android/AGnss.cpp b/gps/android/AGnss.cpp index b5f76bb..6213a08 100644 --- a/gps/android/AGnss.cpp +++ b/gps/android/AGnss.cpp @@ -23,7 +23,6 @@ #include <log_util.h> #include "Gnss.h" #include "AGnss.h" -#include <gps_extended_c.h> namespace android { namespace hardware { @@ -36,9 +35,47 @@ sp<IAGnssCallback> AGnss::sAGnssCbIface = nullptr; AGnss::AGnss(Gnss* gnss) : mGnss(gnss) { } -void AGnss::agnssStatusIpV4Cb(IAGnssCallback::AGnssStatusIpV4 status){ +void AGnss::agnssStatusIpV4Cb(AGnssExtStatusIpV4 status){ + IAGnssCallback::AGnssStatusIpV4 st = {}; + + switch (status.type) { + case LOC_AGPS_TYPE_SUPL: + st.type = IAGnssCallback::AGnssType::TYPE_SUPL; + break; + case LOC_AGPS_TYPE_C2K: + st.type = IAGnssCallback::AGnssType::TYPE_C2K; + break; + default: + LOC_LOGE("invalid type: %d", status.type); + return; + } + + switch (status.status) { + case LOC_GPS_REQUEST_AGPS_DATA_CONN: + st.status = IAGnssCallback::AGnssStatusValue::REQUEST_AGNSS_DATA_CONN; + break; + case LOC_GPS_RELEASE_AGPS_DATA_CONN: + st.status = IAGnssCallback::AGnssStatusValue::RELEASE_AGNSS_DATA_CONN; + break; + case LOC_GPS_AGPS_DATA_CONNECTED: + st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONNECTED; + break; + case LOC_GPS_AGPS_DATA_CONN_DONE: + st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_DONE; + break; + case LOC_GPS_AGPS_DATA_CONN_FAILED: + st.status = IAGnssCallback::AGnssStatusValue::AGNSS_DATA_CONN_FAILED; + break; + default: + LOC_LOGE("invalid status: %d", status.status); + return; + } + st.ipV4Addr = status.ipV4Addr; - sAGnssCbIface->agnssStatusIpV4Cb(status); + auto r = sAGnssCbIface->agnssStatusIpV4Cb(st); + if (!r.isOk()) { + LOC_LOGE("Error invoking AGNSS status cb %s", r.description().c_str()); + } } Return<void> AGnss::setCallback(const sp<IAGnssCallback>& callback) { @@ -97,8 +134,24 @@ Return<bool> AGnss::dataConnOpen(const hidl_string& apn, LOC_LOGD("dataConnOpen APN name = [%s]", apn.c_str()); + AGpsBearerType bearerType; + switch (apnIpType) { + case IAGnss::ApnIpType::IPV4: + bearerType = AGPS_APN_BEARER_IPV4; + break; + case IAGnss::ApnIpType::IPV6: + bearerType = AGPS_APN_BEARER_IPV6; + break; + case IAGnss::ApnIpType::IPV4V6: + bearerType = AGPS_APN_BEARER_IPV4V6; + break; + default: + bearerType = AGPS_APN_BEARER_IPV4; + break; + } + mGnss->getGnssInterface()->agpsDataConnOpen( - LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)apnIpType); + LOC_AGPS_TYPE_SUPL, apn.c_str(), apn.size(), (int)bearerType); return true; } diff --git a/gps/android/AGnss.h b/gps/android/AGnss.h index f4216b0..a3f4a87 100644 --- a/gps/android/AGnss.h +++ b/gps/android/AGnss.h @@ -23,6 +23,7 @@ #include <android/hardware/gnss/1.0/IAGnss.h> #include <hidl/Status.h> +#include <gps_extended_c.h> namespace android { namespace hardware { @@ -60,7 +61,7 @@ struct AGnss : public IAGnss { const hidl_string& hostname, int32_t port) override; /* Data call setup callback passed down to GNSS HAL implementation */ - static void agnssStatusIpV4Cb(IAGnssCallback::AGnssStatusIpV4 status); + static void agnssStatusIpV4Cb(AGnssExtStatusIpV4 status); private: Gnss* mGnss = nullptr; diff --git a/gps/android/Android.mk b/gps/android/Android.mk index 03ea1f3..5f17415 100644 --- a/gps/android/Android.mk +++ b/gps/android/Android.mk @@ -52,7 +52,9 @@ include $(BUILD_SHARED_LIBRARY) BUILD_GNSS_HIDL_SERVICE := true ifneq ($(BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET), true) ifneq ($(LW_FEATURE_SET),true) +ifneq ($(TARGET_HAS_LOW_RAM),true) BUILD_GNSS_HIDL_SERVICE := false +endif # TARGET_HAS_LOW_RAM endif # LW_FEATURE_SET endif # BOARD_VENDOR_QCOM_LOC_PDK_FEATURE_SET @@ -61,6 +63,8 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.gnss@1.0-service-qti LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_EXECUTABLES) LOCAL_MODULE_RELATIVE_PATH := hw +LOCAL_VENDOR_MODULE := true +LOCAL_MODULE_OWNER := qti LOCAL_INIT_RC := android.hardware.gnss@1.0-service-qti.rc LOCAL_SRC_FILES := \ service.cpp \ diff --git a/gps/android/location_api/GnssAPIClient.cpp b/gps/android/location_api/GnssAPIClient.cpp index 0cccb27..2745f56 100644 --- a/gps/android/location_api/GnssAPIClient.cpp +++ b/gps/android/location_api/GnssAPIClient.cpp @@ -278,7 +278,9 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) LOC_LOGD("%s]: (%02x)", __FUNCTION__, capabilitiesMask); mLocationCapabilitiesMask = capabilitiesMask; mLocationCapabilitiesCached = true; - if (mGnssCbIface != nullptr) { + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { uint32_t data = 0; if ((capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_TRACKING_BIT) || (capabilitiesMask & LOCATION_CAPABILITIES_TIME_BASED_BATCHING_BIT) || @@ -293,13 +295,13 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) data |= IGnssCallback::Capabilities::MSB; if (capabilitiesMask & LOCATION_CAPABILITIES_GNSS_MSA_BIT) data |= IGnssCallback::Capabilities::MSA; - auto r = mGnssCbIface->gnssSetCapabilitesCb(data); + auto r = gnssCbIface->gnssSetCapabilitesCb(data); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSetCapabilitesCb description=%s", __func__, r.description().c_str()); } } - if (mGnssCbIface != nullptr) { + if (gnssCbIface != nullptr) { IGnssCallback::GnssSystemInfo gnssInfo; if (capabilitiesMask & LOCATION_CAPABILITIES_DEBUG_NMEA_BIT) { gnssInfo.yearOfHw = 2017; @@ -309,7 +311,7 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) gnssInfo.yearOfHw = 2015; } LOC_LOGV("%s:%d] set_system_info_cb (%d)", __FUNCTION__, __LINE__, gnssInfo.yearOfHw); - auto r = mGnssCbIface->gnssSetSystemInfoCb(gnssInfo); + auto r = gnssCbIface->gnssSetSystemInfoCb(gnssInfo); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSetSystemInfoCb description=%s", __func__, r.description().c_str()); @@ -320,10 +322,12 @@ void GnssAPIClient::onCapabilitiesCb(LocationCapabilitiesMask capabilitiesMask) void GnssAPIClient::onTrackingCb(Location location) { LOC_LOGD("%s]: (flags: %02x)", __FUNCTION__, location.flags); - if (mGnssCbIface != nullptr) { + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { GnssLocation gnssLocation; convertGnssLocation(location, gnssLocation); - auto r = mGnssCbIface->gnssLocationCb(gnssLocation); + auto r = gnssCbIface->gnssLocationCb(gnssLocation); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssLocationCb description=%s", __func__, r.description().c_str()); @@ -334,8 +338,9 @@ void GnssAPIClient::onTrackingCb(Location location) void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotification) { LOC_LOGD("%s]: (id: %d)", __FUNCTION__, id); + sp<IGnssNiCallback> gnssNiCbIface = mGnssNiCbIface; - if (mGnssNiCbIface == nullptr) { + if (gnssNiCbIface == nullptr) { LOC_LOGE("%s]: mGnssNiCbIface is nullptr", __FUNCTION__); return; } @@ -400,16 +405,18 @@ void GnssAPIClient::onGnssNiCb(uint32_t id, GnssNiNotification gnssNiNotificatio notificationGnss.notificationIdEncoding = IGnssNiCallback::GnssNiEncodingType::ENC_SUPL_UCS2; - mGnssNiCbIface->niNotifyCb(notificationGnss); + gnssNiCbIface->niNotifyCb(notificationGnss); } void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) { LOC_LOGD("%s]: (count: %zu)", __FUNCTION__, gnssSvNotification.count); - if (mGnssCbIface != nullptr) { + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { IGnssCallback::GnssSvStatus svStatus; convertGnssSvStatus(gnssSvNotification, svStatus); - auto r = mGnssCbIface->gnssSvStatusCb(svStatus); + auto r = gnssCbIface->gnssSvStatusCb(svStatus); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssSvStatusCb description=%s", __func__, r.description().c_str()); @@ -419,10 +426,12 @@ void GnssAPIClient::onGnssSvCb(GnssSvNotification gnssSvNotification) void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) { - if (mGnssCbIface != nullptr) { + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (gnssCbIface != nullptr) { android::hardware::hidl_string nmeaString; nmeaString.setToExternal(gnssNmeaNotification.nmea, gnssNmeaNotification.length); - auto r = mGnssCbIface->gnssNmeaCb( + auto r = gnssCbIface->gnssNmeaCb( static_cast<GnssUtcTime>(gnssNmeaNotification.timestamp), nmeaString); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssNmeaCb nmea=%s length=%zu description=%s", __func__, @@ -434,13 +443,15 @@ void GnssAPIClient::onGnssNmeaCb(GnssNmeaNotification gnssNmeaNotification) void GnssAPIClient::onStartTrackingCb(LocationError error) { LOC_LOGD("%s]: (%d)", __FUNCTION__, error); - if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { - auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { + auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_ON); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb ENGINE_ON description=%s", __func__, r.description().c_str()); } - r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); + r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_BEGIN); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb SESSION_BEGIN description=%s", __func__, r.description().c_str()); @@ -451,13 +462,15 @@ void GnssAPIClient::onStartTrackingCb(LocationError error) void GnssAPIClient::onStopTrackingCb(LocationError error) { LOC_LOGD("%s]: (%d)", __FUNCTION__, error); - if (error == LOCATION_ERROR_SUCCESS && mGnssCbIface != nullptr) { - auto r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); + sp<IGnssCallback> gnssCbIface = mGnssCbIface; + + if (error == LOCATION_ERROR_SUCCESS && gnssCbIface != nullptr) { + auto r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::SESSION_END); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb SESSION_END description=%s", __func__, r.description().c_str()); } - r = mGnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); + r = gnssCbIface->gnssStatusCb(IGnssCallback::GnssStatusValue::ENGINE_OFF); if (!r.isOk()) { LOC_LOGE("%s] Error from gnssStatusCb ENGINE_OFF description=%s", __func__, r.description().c_str()); diff --git a/gps/core/SystemStatus.cpp b/gps/core/SystemStatus.cpp index dc03604..52d28c7 100644 --- a/gps/core/SystemStatus.cpp +++ b/gps/core/SystemStatus.cpp @@ -37,6 +37,7 @@ #include <platform_lib_log_util.h> #include <MsgTask.h> #include <loc_nmea.h> +#include <DataItemsFactoryProxy.h> #include <SystemStatus.h> #include <SystemStatusOsObserver.h> @@ -1212,7 +1213,8 @@ IOsObserver* SystemStatus::getOsObserver() } SystemStatus::SystemStatus(const MsgTask* msgTask) : - mSysStatusObsvr(msgTask) + mSysStatusObsvr(msgTask), + mConnected(false) { int result = 0; ENTRY_LOG (); @@ -1414,6 +1416,28 @@ bool SystemStatus::setPositionFailure(const SystemStatusPQWS1& nmea) } /****************************************************************************** + SystemStatus - storing dataitems +******************************************************************************/ +bool SystemStatus::setNetworkInfo(IDataItemCore* dataitem) +{ + SystemStatusNetworkInfo* data = reinterpret_cast<SystemStatusNetworkInfo*>(dataitem); + SystemStatusNetworkInfo s(data->mType,data->mTypeName,data->mSubTypeName, + data->mAvailable,data->mConnected,data->mRoaming); + s.dump(); + mConnected = data->mConnected; + + if (!mCache.mNetworkInfo.empty() && mCache.mNetworkInfo.back().equals(s)) { + mCache.mNetworkInfo.back().mUtcReported = s.mUtcReported; + } else { + mCache.mNetworkInfo.push_back(s); + if (mCache.mNetworkInfo.size() > maxNetworkInfo) { + mCache.mNetworkInfo.erase(mCache.mNetworkInfo.begin()); + } + } + return true; +} + +/****************************************************************************** @brief API to set report data into internal buffer @param[In] data pointer to the NMEA string @@ -1534,6 +1558,26 @@ bool SystemStatus::eventPosition(const UlpLocation& location, } /****************************************************************************** +@brief API to set report DataItem event into internal buffer + +@param[In] DataItem + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::eventDataItemNotify(IDataItemCore* dataitem) +{ + pthread_mutex_lock(&mMutexSystemStatus); + switch(dataitem->getId()) + { + case NETWORKINFO_DATA_ITEM_ID: + setNetworkInfo(dataitem); + break; + } + pthread_mutex_unlock(&mMutexSystemStatus); + return true; +} + +/****************************************************************************** @brief API to get report data into a given buffer @param[In] reference to report buffer @@ -1712,5 +1756,33 @@ bool SystemStatus::setDefaultReport(void) return true; } +/****************************************************************************** +@brief API to handle connection status update event from GnssRil + +@param[In] Connection status + +@return true when successfully done +******************************************************************************/ +bool SystemStatus::eventConnectionStatus(bool connected, uint8_t type) +{ + if (connected != mConnected) { + mConnected = connected; + + // send networkinof dataitem to systemstatus observer clients + SystemStatusNetworkInfo s(type, "", "", false, connected, false); + IDataItemCore *networkinfo = + DataItemsFactoryProxy::createNewDataItem(NETWORKINFO_DATA_ITEM_ID); + if (nullptr == networkinfo) { + LOC_LOGE("Unable to create dataitemd"); + return false; + } + networkinfo->copy(&s); + list<IDataItemCore*> dl(0); + dl.push_back(networkinfo); + mSysStatusObsvr.notify(dl); + } + return true; +} + } // namespace loc_core diff --git a/gps/core/SystemStatus.h b/gps/core/SystemStatus.h index 8cf75b5..5dc2d9f 100644 --- a/gps/core/SystemStatus.h +++ b/gps/core/SystemStatus.h @@ -34,6 +34,7 @@ #include <vector> #include <platform_lib_log_util.h> #include <MsgTask.h> +#include <IDataItemCore.h> #include <IOsObserver.h> #include <SystemStatusOsObserver.h> @@ -368,18 +369,182 @@ public: }; /****************************************************************************** + SystemStatus report data structure - from DataItem observer +******************************************************************************/ +class SystemStatusGpsState : public SystemStatusItemBase, public IDataItemCore +{ +public: + inline SystemStatusGpsState() : + mEnabled(false) {} + inline SystemStatusGpsState(bool enabled) : + mEnabled(enabled) {} + + bool mEnabled; + + inline bool equals(SystemStatusGpsState& peer) { + return (mEnabled == peer.mEnabled); + } + inline void dump(void) { + LOC_LOGD("GpsState: state=%u", mEnabled); + } + inline DataItemId getId() { + return GPSSTATE_DATA_ITEM_ID; + } + inline void stringify(string& valueStr) { + valueStr.clear(); + valueStr += "GpsState: enabled="; + valueStr += to_string(mEnabled); + } + inline int32_t copy(IDataItemCore* src, bool* dataItemCopied = nullptr) { + SystemStatusGpsState* gpsstate = static_cast<SystemStatusGpsState*>(src); + mEnabled = gpsstate->mEnabled; + if (dataItemCopied) { + *dataItemCopied = true; + } + return 1; + } +}; + +class SystemStatusNetworkInfo : public SystemStatusItemBase, public IDataItemCore +{ +public: + inline SystemStatusNetworkInfo() : + mType(0), + mTypeName(""), + mSubTypeName(""), + mAvailable(false), + mConnected(false), + mRoaming(false) {} + inline SystemStatusNetworkInfo( + uint32_t type, + std::string typeName, + std::string subTypeName, + bool available, + bool connected, + bool roaming) : + mType(type), + mTypeName(typeName), + mSubTypeName(subTypeName), + mAvailable(available), + mConnected(connected), + mRoaming(roaming) {} + + uint32_t mType; + std::string mTypeName; + std::string mSubTypeName; + bool mAvailable; + bool mConnected; + bool mRoaming; + + inline bool equals(SystemStatusNetworkInfo& peer) { + if ((mType != peer.mType) || + (mTypeName != peer.mTypeName) || + (mSubTypeName != peer.mSubTypeName) || + (mAvailable != peer.mAvailable) || + (mConnected != peer.mConnected) || + (mRoaming != peer.mRoaming)) { + return false; + } + return true; + } + inline void dump(void) { + LOC_LOGD("NetworkInfo: type=%u connected=%u", mType, mConnected); + } + inline DataItemId getId() { + return NETWORKINFO_DATA_ITEM_ID; + } + inline void stringify(string& /*valueStr*/) { } + inline int32_t copy(IDataItemCore* src, bool* dataItemCopied = nullptr) { + SystemStatusNetworkInfo* networkinfo = static_cast<SystemStatusNetworkInfo*>(src); + mType = networkinfo->mType; + mTypeName = networkinfo->mTypeName; + mSubTypeName = networkinfo->mSubTypeName; + mAvailable = networkinfo->mAvailable; + mConnected = networkinfo->mConnected; + mRoaming = networkinfo->mRoaming; + if (dataItemCopied) { + *dataItemCopied = true; + } + return 1; + } +}; + +class SystemStatusTac : public SystemStatusItemBase, public IDataItemCore +{ +public: + inline SystemStatusTac() : + mValue("") {} + inline SystemStatusTac(std::string value) : + mValue(value) {} + + std::string mValue; + + inline bool equals(SystemStatusTac& peer) { + return (mValue == peer.mValue); + } + inline void dump(void) { + LOC_LOGD("Tac: value=%s", mValue.c_str()); + } + inline DataItemId getId() { + return TAC_DATA_ITEM_ID; + } + inline void stringify(string& /*valueStr*/) { } + inline int32_t copy(IDataItemCore* src, bool* dataItemCopied = nullptr) { + SystemStatusTac* tac = static_cast<SystemStatusTac*>(src); + mValue = tac->mValue; + if (dataItemCopied) { + *dataItemCopied = true; + } + return 1; + } +}; + +class SystemStatusMccMnc : public SystemStatusItemBase, public IDataItemCore +{ +public: + inline SystemStatusMccMnc() : + mValue("") {} + inline SystemStatusMccMnc(std::string value) : + mValue(value) {} + + std::string mValue; + + inline bool equals(SystemStatusMccMnc& peer) { + return (mValue == peer.mValue); + } + inline void dump(void) { + LOC_LOGD("TacMccMnc value=%s", mValue.c_str()); + } + inline DataItemId getId() { + return MCCMNC_DATA_ITEM_ID; + } + inline void stringify(string& /*valueStr*/) { } + inline int32_t copy(IDataItemCore* src, bool* dataItemCopied = nullptr) { + SystemStatusMccMnc* mccmnc = static_cast<SystemStatusMccMnc*>(src); + mValue = mccmnc->mValue; + if (dataItemCopied) { + *dataItemCopied = true; + } + return 1; + } +}; + +/****************************************************************************** SystemStatusReports ******************************************************************************/ class SystemStatusReports { public: + // from QMI_LOC indication std::vector<SystemStatusLocation> mLocation; + // from ME debug NMEA std::vector<SystemStatusTimeAndClock> mTimeAndClock; std::vector<SystemStatusXoState> mXoState; std::vector<SystemStatusRfAndParams> mRfAndParams; std::vector<SystemStatusErrRecovery> mErrRecovery; + // from PE debug NMEA std::vector<SystemStatusInjectedPosition> mInjectedPosition; std::vector<SystemStatusBestPosition> mBestPosition; std::vector<SystemStatusXtra> mXtra; @@ -388,7 +553,14 @@ public: std::vector<SystemStatusPdr> mPdr; std::vector<SystemStatusNavData> mNavData; + // from SM debug NMEA std::vector<SystemStatusPositionFailure> mPositionFailure; + + // from dataitems observer + std::vector<SystemStatusGpsState> mGpsState; + std::vector<SystemStatusNetworkInfo> mNetworkInfo; + std::vector<SystemStatusTac> mTac; + std::vector<SystemStatusMccMnc> mMccMnc; }; /****************************************************************************** @@ -424,7 +596,13 @@ private: static const uint32_t maxPositionFailure = 5; + static const uint32_t maxGpsState = 5; + static const uint32_t maxNetworkInfo = 5; + static const uint32_t maxTac = 5; + static const uint32_t maxMccMnc = 5; + SystemStatusReports mCache; + bool mConnected; bool setLocation(const UlpLocation& location); @@ -443,6 +621,8 @@ private: bool setPositionFailure(const SystemStatusPQWS1& nmea); + bool setNetworkInfo(IDataItemCore* dataitem); + public: // Static methods static SystemStatus* getInstance(const MsgTask* msgTask); @@ -451,9 +631,11 @@ public: // Helpers bool eventPosition(const UlpLocation& location,const GpsLocationExtended& locationEx); + bool eventDataItemNotify(IDataItemCore* dataitem); bool setNmeaString(const char *data, uint32_t len); bool getReport(SystemStatusReports& reports, bool isLatestonly = false) const; bool setDefaultReport(void); + bool eventConnectionStatus(bool connected, uint8_t type); }; } // namespace loc_core diff --git a/gps/core/SystemStatusOsObserver.cpp b/gps/core/SystemStatusOsObserver.cpp index e327f93..319f1d7 100644 --- a/gps/core/SystemStatusOsObserver.cpp +++ b/gps/core/SystemStatusOsObserver.cpp @@ -28,618 +28,565 @@ */ #define LOG_TAG "LocSvc_SystemStatusOsObserver" -#include <string> -#include <cinttypes> -#include <stdlib.h> -#include <string.h> -#include <sys/time.h> -#include <pthread.h> -#include <iterator> #include <algorithm> - -#include <MsgTask.h> +#include <SystemStatus.h> #include <SystemStatusOsObserver.h> - -#include <DataItemId.h> #include <IDataItemCore.h> #include <IClientIndex.h> #include <IDataItemIndex.h> #include <IndexFactory.h> - #include <DataItemsFactoryProxy.h> -#include <platform_lib_log_util.h> - namespace loc_core { -#define BREAK_IF_ZERO(ERR,X) if(0==(X)) {result = (ERR); break;} -#define BREAK_IF_NON_ZERO(ERR,X) if(0!=(X)) {result = (ERR); break;} - SystemStatusOsObserver::SystemStatusOsObserver(const MsgTask* msgTask) : - mAddress ("SystemStatusOsObserver"), - mClientIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createClientIndex ()), - mDataItemIndex(IndexFactory <IDataItemObserver *, DataItemId> :: createDataItemIndex ()) + mAddress("SystemStatusOsObserver"), + mClientIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createClientIndex()), + mDataItemIndex(IndexFactory<IDataItemObserver*, DataItemId> :: createDataItemIndex()) { - int result = -1; - ENTRY_LOG (); - do { - BREAK_IF_ZERO (1, mClientIndex); - BREAK_IF_ZERO (2, mDataItemIndex); - mContext.mMsgTask = msgTask; - result = 0; - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + mContext.mMsgTask = msgTask; } -SystemStatusOsObserver :: ~SystemStatusOsObserver () +SystemStatusOsObserver::~SystemStatusOsObserver() { // Close data-item library handle DataItemsFactoryProxy::closeDataItemLibraryHandle(); // Destroy cache - map <DataItemId, IDataItemCore *> :: iterator citer = mDataItemCache.begin (); - for (; citer != mDataItemCache.end (); ++citer) { - if (citer->second != NULL) { delete citer->second; } + for (auto each : mDataItemCache) { + if (nullptr != each.second) { + delete each.second; + } } - mDataItemCache.clear (); + + mDataItemCache.clear(); delete mClientIndex; delete mDataItemIndex; - mClientIndex = NULL; - mDataItemIndex = NULL; } -/****************************************************************************** - Message proc -******************************************************************************/ -void SystemStatusOsObserver :: HandleSubscribeReq :: proc () const { - - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - // Handle First Response - list <DataItemId> pendingFirstResponseList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList); - - // Do not send first response for only pendingFirstResponseList, - // instead send for all the data items (present in the cache) that - // have been subscribed for each time. - this->mParent->sendFirstResponse (mDataItemList, this->mClient); - - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty ()) { - this->mParent->mContext.mSubscriptionObj->subscribe - ( - yetToSubscribeDataItemsList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); - } +void SystemStatusOsObserver::setSubscriptionObj(IDataItemSubscription* subscriptionObj) +{ + mContext.mSubscriptionObj = subscriptionObj; + + LOC_LOGD("Request cache size - Subscribe:%zu RequestData:%zu", + mSubscribeReqCache.size(), mReqDataCache.size()); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return; + // we have received the subscription object. process cached requests + // process - subscribe request cache + for (auto each : mSubscribeReqCache) { + subscribe(each.second, each.first); + } + // process - requestData request cache + for (auto each : mReqDataCache) { + requestData(each.second, each.first); + } } -void SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> currentlySubscribedList; - this->mParent->mClientIndex->getSubscribedList (this->mClient, currentlySubscribedList); - list <DataItemId> removeDataItemList; - set_difference (currentlySubscribedList.begin (), currentlySubscribedList.end (), - mDataItemList.begin (), mDataItemList.end (), - inserter (removeDataItemList,removeDataItemList.begin ())); - // Handle First Response - list <DataItemId> pendingFirstResponseList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, pendingFirstResponseList); - // Send First Response - this->mParent->sendFirstResponse (pendingFirstResponseList, this->mClient); - - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!yetToSubscribeDataItemsList.empty ()) { - this->mParent->mContext.mSubscriptionObj->subscribe - ( - yetToSubscribeDataItemsList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); +// Helper to cache requests subscribe and requestData till subscription obj is obtained +void SystemStatusOsObserver::cacheObserverRequest(ObserverReqCache& reqCache, + const list<DataItemId>& l, IDataItemObserver* client) +{ + ObserverReqCache::iterator dicIter = reqCache.find(client); + if (dicIter != reqCache.end()) { + // found + list<DataItemId> difference(0); + set_difference(l.begin(), l.end(), + dicIter->second.begin(), dicIter->second.end(), + inserter(difference, difference.begin())); + if (!difference.empty()) { + difference.sort(); + dicIter->second.merge(difference); + dicIter->second.unique(); } + } + else { + // not found + reqCache[client] = l; + } +} - list <DataItemId> unsubscribeList; - list <DataItemId> unused; - this->mParent->mClientIndex->remove (this->mClient, removeDataItemList, unused); +/****************************************************************************** + IDataItemSubscription Overrides +******************************************************************************/ +void SystemStatusOsObserver::subscribe( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); + cacheObserverRequest(mSubscribeReqCache, l, client); + return; + } - if (!this->mParent->mClientIndex->isSubscribedClient (this->mClient)) { - this->mParent->mDataItemIndex->remove (list <IDataItemObserver *> (1,this->mClient), unsubscribeList); - } - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + struct HandleSubscribeReq : public LocMsg { + HandleSubscribeReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleSubscribeReq() {} + void proc() const { -void SystemStatusOsObserver :: HandleRequestData :: proc () const { - int result = 0; - ENTRY_LOG (); + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> yetToSubscribeDataItemsList; - this->mParent->mClientIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - this->mParent->mDataItemIndex->add (this->mClient, mDataItemList, yetToSubscribeDataItemsList); - // Send subscription list to framework - if (!mDataItemList.empty ()) { - this->mParent->mContext.mSubscriptionObj->requestData - ( - mDataItemList, - this->mParent - ); - LOC_LOGD ("Subscribe Request sent to framework for the following data items"); - this->mParent->logMe (yetToSubscribeDataItemsList); - } + // Handle First Response + list<DataItemId> pendingFirstResponseList(0); + mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + // Do not send first response for only pendingFirstResponseList, + // instead send for all the data items (present in the cache) that + // have been subscribed for each time. + mParent->sendFirstResponse(mDataItemList, mClient); -void SystemStatusOsObserver :: HandleUnsubscribeReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - if (mDataItemList.empty ()) { - LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); - result = 0; - break; - } - //mDataItemList.sort (); - list <DataItemId> unsubscribeList; - list <DataItemId> unused; - this->mParent->mClientIndex->remove (this->mClient, mDataItemList, unused); - - list <DataItemId> :: const_iterator it = mDataItemList.begin (); - for (; it != mDataItemList.end (); ++it) { - list <IDataItemObserver *> clientListSubs; - list <IDataItemObserver *> clientListOut; - this->mParent->mDataItemIndex->remove ((*it), - list <IDataItemObserver *> (1,this->mClient), clientListOut); - // check if there are any other subscribed client for this data item id - this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientListSubs); - if (clientListSubs.empty()) - { - LOC_LOGD ("Client list subscribed is empty for dataitem - %d",(*it)); - unsubscribeList.push_back((*it)); - } - } - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mDataItemIndex->add(mClient, mDataItemList, yetToSubscribeDataItemsList); -void SystemStatusOsObserver :: HandleUnsubscribeAllReq :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemObserver *> clients (1, this->mClient); - list <DataItemId> unsubscribeList; - BREAK_IF_NON_ZERO (2, this->mParent->mClientIndex->remove (this->mClient)); - - - this->mParent->mDataItemIndex->remove (clients, unsubscribeList); - if (!unsubscribeList.empty ()) { - // Send unsubscribe to framework - this->mParent->mContext.mSubscriptionObj->unsubscribe - ( - unsubscribeList, - this->mParent - ); - LOC_LOGD ("Unsubscribe Request sent to framework for the following data items"); - this->mParent->logMe (unsubscribeList); + // Send subscription list to framework + if (!yetToSubscribeDataItemsList.empty()) { + mParent->mContext.mSubscriptionObj->subscribe(yetToSubscribeDataItemsList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleSubscribeReq(this, l, client)); } -void SystemStatusOsObserver :: HandleNotify :: getListOfClients - (const list <DataItemId> & dlist, list <IDataItemObserver *> & clients ) const { - - list <DataItemId> :: const_iterator it = dlist.begin (); - for (; it != dlist.end (); ++it) { - list <IDataItemObserver *> clientList; - this->mParent->mDataItemIndex->getListOfSubscribedClients ( (*it), clientList); - list <IDataItemObserver *> :: iterator citer = clientList.begin (); - for (; citer != clientList.end (); ++citer) { - clients.push_back (*citer); - } - clientList.clear (); - } - // remove duplicates - clients.unique (); -} +void SystemStatusOsObserver::updateSubscription( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } -void SystemStatusOsObserver :: HandleNotify :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Update Cache with received data items and prepare - // list of data items to be sent. - list <IDataItemCore *> :: const_iterator it = mDList.begin (); - list <DataItemId> dataItemIdsToBeSent; - for (; it != mDList.end (); ++it) { - bool dataItemUpdated = false; - this->mParent->updateCache (*it, dataItemUpdated); - if (dataItemUpdated) { - dataItemIdsToBeSent.push_back ( (*it)->getId ()); + struct HandleUpdateSubscriptionReq : public LocMsg { + HandleUpdateSubscriptionReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleUpdateSubscriptionReq() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; } - } - list <IDataItemObserver *> clientList; - this->getListOfClients (dataItemIdsToBeSent, clientList); - list <IDataItemObserver *> :: iterator citer = clientList.begin (); - // Send data item to all subscribed clients - LOC_LOGD ("LocTech-Label :: SystemStatusOsObserver :: Data Items Out"); - for (; citer != clientList.end (); ++citer) { - do { - list <DataItemId> dataItemIdsSubscribedByThisClient; - list <DataItemId> dataItemIdsToBeSentForThisClient; - this->mParent->mClientIndex->getSubscribedList (*citer, dataItemIdsSubscribedByThisClient); - dataItemIdsSubscribedByThisClient.sort (); - dataItemIdsToBeSent.sort (); - set_intersection (dataItemIdsToBeSent.begin (), - dataItemIdsToBeSent.end (), - dataItemIdsSubscribedByThisClient.begin (), - dataItemIdsSubscribedByThisClient.end (), - inserter (dataItemIdsToBeSentForThisClient, - dataItemIdsToBeSentForThisClient.begin ())); - BREAK_IF_NON_ZERO (4,this->mParent->sendCachedDataItems (dataItemIdsToBeSentForThisClient, *citer)); - dataItemIdsSubscribedByThisClient.clear (); - dataItemIdsToBeSentForThisClient.clear (); - } while (0); - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + list<DataItemId> currentlySubscribedList(0); + mParent->mClientIndex->getSubscribedList(mClient, currentlySubscribedList); -void SystemStatusOsObserver :: HandleTurnOn :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Send action turn on to framework - this->mParent->mContext.mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + list<DataItemId> removeDataItemList(0); + set_difference(currentlySubscribedList.begin(), currentlySubscribedList.end(), + mDataItemList.begin(), mDataItemList.end(), + inserter(removeDataItemList,removeDataItemList.begin())); -void SystemStatusOsObserver :: HandleTurnOff :: proc () const { - int result = 0; - ENTRY_LOG (); - do { - // Send action turn off to framework - this->mParent->mContext.mFrameworkActionReqObj->turnOff(mDataItemId); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); -} + // Handle First Response + list<DataItemId> pendingFirstResponseList(0); + mParent->mClientIndex->add(mClient, mDataItemList, pendingFirstResponseList); -/****************************************************************************** - IDataItemSubscription Overrides -******************************************************************************/ -void SystemStatusOsObserver :: subscribe (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - HandleSubscribeReq * msg = new (nothrow) HandleSubscribeReq (this, l, client); - mContext.mMsgTask->sendMsg (msg); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); -} + // Send First Response + mParent->sendFirstResponse(pendingFirstResponseList, mClient); -void SystemStatusOsObserver :: updateSubscription (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUpdateSubscriptionReq (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mDataItemIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + + // Send subscription list to framework + if (!yetToSubscribeDataItemsList.empty()) { + mParent->mContext.mSubscriptionObj->subscribe( + yetToSubscribeDataItemsList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } + + list<DataItemId> unsubscribeList(0); + list<DataItemId> unused(0); + mParent->mClientIndex->remove(mClient, removeDataItemList, unused); + + if (!mParent->mClientIndex->isSubscribedClient(mClient)) { + mParent->mDataItemIndex->remove( + list<IDataItemObserver*> (1,mClient), unsubscribeList); + } + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following"); + mParent->logMe(unsubscribeList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUpdateSubscriptionReq(this, l, client)); } -void SystemStatusOsObserver :: requestData (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleRequestData (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); +void SystemStatusOsObserver::requestData( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGD("%s]: Subscription object is NULL. Caching requests", __func__); + cacheObserverRequest(mReqDataCache, l, client); + return; + } - EXIT_LOG_WITH_ERROR ("%d",result); -} + struct HandleRequestData : public LocMsg { + HandleRequestData(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleRequestData() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } -void SystemStatusOsObserver :: unsubscribe (const list <DataItemId> & l, IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUnsubscribeReq (this, l, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; + list<DataItemId> yetToSubscribeDataItemsList(0); + mParent->mClientIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + mParent->mDataItemIndex->add( + mClient, mDataItemList, yetToSubscribeDataItemsList); + + // Send subscription list to framework + if (!mDataItemList.empty()) { + mParent->mContext.mSubscriptionObj->requestData(mDataItemList, mParent); + LOC_LOGD("Subscribe Request sent to framework for the following"); + mParent->logMe(yetToSubscribeDataItemsList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleRequestData(this, l, client)); } -void SystemStatusOsObserver :: unsubscribeAll (IDataItemObserver * client) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mSubscriptionObj != NULL) { - mContext.mMsgTask->sendMsg (new (nothrow) HandleUnsubscribeAllReq (this, client)); - } - else { - LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); - result = 1; +void SystemStatusOsObserver::unsubscribe( + const list<DataItemId>& l, IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } + struct HandleUnsubscribeReq : public LocMsg { + HandleUnsubscribeReq(SystemStatusOsObserver* parent, + const list<DataItemId>& l, IDataItemObserver* client) : + mParent(parent), mClient(client), mDataItemList(l) {} + virtual ~HandleUnsubscribeReq() {} + void proc() const { + if (mDataItemList.empty()) { + LOC_LOGV("mDataItemList is empty. Nothing to do. Exiting"); + return; + } + + list<DataItemId> unsubscribeList(0); + list<DataItemId> unused(0); + mParent->mClientIndex->remove(mClient, mDataItemList, unused); + + for (auto each : mDataItemList) { + list<IDataItemObserver*> clientListSubs(0); + list<IDataItemObserver*> clientListOut(0); + mParent->mDataItemIndex->remove( + each, list<IDataItemObserver*> (1,mClient), clientListOut); + // check if there are any other subscribed client for this data item id + mParent->mDataItemIndex->getListOfSubscribedClients(each, clientListSubs); + if (clientListSubs.empty()) + { + LOC_LOGD("Client list subscribed is empty for dataitem - %d", each); + unsubscribeList.push_back(each); + } + } + + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(unsubscribeList); + } } - } while (0); - EXIT_LOG_WITH_ERROR ("%d",result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + const list<DataItemId> mDataItemList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeReq(this, l, client)); } -/****************************************************************************** - IDataItemObserver Overrides -******************************************************************************/ -void SystemStatusOsObserver::getName(string & name) { - name = mAddress; -} +void SystemStatusOsObserver::unsubscribeAll(IDataItemObserver* client) +{ + if (nullptr == mContext.mSubscriptionObj) { + LOC_LOGE("%s:%d]: Subscription object is NULL", __func__, __LINE__); + return; + } + + struct HandleUnsubscribeAllReq : public LocMsg { + HandleUnsubscribeAllReq(SystemStatusOsObserver* parent, + IDataItemObserver* client) : + mParent(parent), mClient(client) {} + virtual ~HandleUnsubscribeAllReq() {} + void proc() const { + list<IDataItemObserver*> clients(1, mClient); + list<DataItemId> unsubscribeList(0); + if(0 == mParent->mClientIndex->remove(mClient)) { + return; + } + mParent->mDataItemIndex->remove(clients, unsubscribeList); -void SystemStatusOsObserver::notify(const std::list <IDataItemCore *> & dlist) { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemCore *> :: const_iterator it = dlist.begin (); - list <IDataItemCore *> dataItemList; - list <DataItemId> ids; - LOC_LOGD("LocTech-Label :: SystemStatusOsObserver :: Data Items In"); - for (; it != dlist.end (); ++it) { - if (*it != NULL) { - string dv; - (*it)->stringify(dv); - LOC_LOGD("LocTech-Value :: Data Item Value: %s", dv.c_str ()); - IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem((*it)->getId()); - BREAK_IF_ZERO (2, dataitem); - // Copy contents into the newly created data item - dataitem->copy(*it); - dataItemList.push_back(dataitem); - ids.push_back((*it)->getId()); + if (!unsubscribeList.empty()) { + // Send unsubscribe to framework + mParent->mContext.mSubscriptionObj->unsubscribe(unsubscribeList, mParent); + LOC_LOGD("Unsubscribe Request sent to framework for the following data items"); + mParent->logMe(unsubscribeList); } } - mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify (this, dataItemList)); - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); + SystemStatusOsObserver* mParent; + IDataItemObserver* mClient; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleUnsubscribeAllReq(this, client)); } /****************************************************************************** - IFrameworkActionReq Overrides + IDataItemObserver Overrides ******************************************************************************/ -void SystemStatusOsObserver :: turnOn (DataItemId dit, int timeOut) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mFrameworkActionReqObj != NULL) { - // Check if data item exists in mActiveRequestCount - map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit); - if (citer == mActiveRequestCount.end ()) { - // Data item not found in map - // Add reference count as 1 and add dataitem to map - pair <DataItemId, int> cpair (dit, 1); - mActiveRequestCount.insert (cpair); - LOC_LOGD("Sending turnOn request"); - // Send action turn on to framework - mContext.mMsgTask->sendMsg (new (nothrow) HandleTurnOn (this, dit, timeOut)); - } else { - // Found in map, update reference count - citer->second++; - LOC_LOGD("HandleTurnOn - Data item:%d Num_refs:%d",dit,citer->second); - } +void SystemStatusOsObserver::notify(const list<IDataItemCore*>& dlist) +{ + list<IDataItemCore*> dataItemList(0); + + for (auto each : dlist) { + string dv; + each->stringify(dv); + LOC_LOGD("notify: DataItem In Value:%s", dv.c_str()); + + IDataItemCore* di = DataItemsFactoryProxy::createNewDataItem(each->getId()); + if (nullptr == di) { + LOC_LOGE("Unable to create dataitem:%d", each->getId()); + return; } - else { - LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); - result = 1; + + // Copy contents into the newly created data item + di->copy(each); + dataItemList.push_back(di); + // Request systemstatus to record this dataitem in its cache + SystemStatus* systemstatus = SystemStatus::getInstance(mContext.mMsgTask); + if(nullptr != systemstatus) { + systemstatus->eventDataItemNotify(di); } - } while (0); + } - EXIT_LOG_WITH_ERROR ("%d", result); -} + struct HandleNotify : public LocMsg { + HandleNotify(SystemStatusOsObserver* parent, const list<IDataItemCore*>& l) : + mParent(parent), mDList(l) {} + virtual ~HandleNotify() { + for (auto each : mDList) { + delete each; + } + } + void proc() const { + // Update Cache with received data items and prepare + // list of data items to be sent. + list<DataItemId> dataItemIdsToBeSent(0); + for (auto item : mDList) { + bool dataItemUpdated = false; + mParent->updateCache(item, dataItemUpdated); + if (dataItemUpdated) { + dataItemIdsToBeSent.push_back(item->getId()); + } + } -void SystemStatusOsObserver :: turnOff (DataItemId dit) { - int result = 0; - ENTRY_LOG (); - do { - if (mContext.mFrameworkActionReqObj != NULL) { - // Check if data item exists in mActiveRequestCount - map <DataItemId, int> :: iterator citer = mActiveRequestCount.find (dit); - if (citer != mActiveRequestCount.end ()) { - citer->second--; - LOC_LOGD("HandleTurnOff - Data item:%d Remaining Num_refs:%d",dit,citer->second); - - if(citer->second == 0) { - LOC_LOGD("Sending turnOff request"); - // if this was last reference, remove item from map and turn off module - mActiveRequestCount.erase(citer); - // Send action turn off to framework - mContext.mMsgTask->sendMsg (new (nothrow) HandleTurnOff (this, dit)); + // Send data item to all subscribed clients + list<IDataItemObserver*> clientList(0); + for (auto each : dataItemIdsToBeSent) { + list<IDataItemObserver*> clients(0); + mParent->mDataItemIndex->getListOfSubscribedClients(each, clients); + for (auto each_cient: clients) { + clientList.push_back(each_cient); } - } else { - // Not found in map - LOC_LOGD ("Data item id %d not found in FrameworkModuleMap",dit); + } + clientList.unique(); + + for (auto client : clientList) { + list<DataItemId> dataItemIdsSubscribedByThisClient(0); + list<DataItemId> dataItemIdsToBeSentForThisClient(0); + mParent->mClientIndex->getSubscribedList( + client, dataItemIdsSubscribedByThisClient); + dataItemIdsSubscribedByThisClient.sort(); + dataItemIdsToBeSent.sort(); + + set_intersection(dataItemIdsToBeSent.begin(), + dataItemIdsToBeSent.end(), + dataItemIdsSubscribedByThisClient.begin(), + dataItemIdsSubscribedByThisClient.end(), + inserter(dataItemIdsToBeSentForThisClient, + dataItemIdsToBeSentForThisClient.begin())); + + mParent->sendCachedDataItems(dataItemIdsToBeSentForThisClient, client); + dataItemIdsSubscribedByThisClient.clear(); + dataItemIdsToBeSentForThisClient.clear(); } } - else { - LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); - result = 1; - } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); + SystemStatusOsObserver* mParent; + const list<IDataItemCore*> mDList; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleNotify(this, dataItemList)); } /****************************************************************************** - Helpers + IFrameworkActionReq Overrides ******************************************************************************/ -void SystemStatusOsObserver :: logMe (const list <DataItemId> & l) { - list <DataItemId> :: const_iterator it = l.begin (); - for (;it != l.end (); ++it) { - LOC_LOGD ("DataItem %d",*it); +void SystemStatusOsObserver::turnOn(DataItemId dit, int timeOut) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; } -} -int SystemStatusOsObserver :: sendFirstResponse (const list <DataItemId> & l, IDataItemObserver * to) { - int result = 0; - ENTRY_LOG (); - do { - if (l.empty ()) { - LOC_LOGV("list is empty. Nothing to do. Exiting"); - result = 0; - break; - } + // Check if data item exists in mActiveRequestCount + map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit); + if (citer == mActiveRequestCount.end()) { + // Data item not found in map + // Add reference count as 1 and add dataitem to map + pair<DataItemId, int> cpair(dit, 1); + mActiveRequestCount.insert(cpair); + LOC_LOGD("Sending turnOn request"); - string clientName; - to->getName (clientName); - LOC_LOGD ("First response sent for the following data items To Client: %s", clientName.c_str()); - - list <IDataItemCore *> dataItems; - list <DataItemId> :: const_iterator diditer = l.begin (); - for (; diditer != l.end (); ++diditer) { - map <DataItemId, IDataItemCore*> :: const_iterator citer = mDataItemCache.find (*diditer); - if (citer != mDataItemCache.end ()) { - string dv; - IDataItemCore * di = citer->second; - di->stringify (dv); - LOC_LOGD ("LocTech-Value :: Data Item: %s", dv.c_str ()); - dataItems.push_back (citer->second); + // Send action turn on to framework + struct HandleTurnOnMsg : public LocMsg { + HandleTurnOnMsg(IFrameworkActionReq* framework, + DataItemId dit, int timeOut) : + mFrameworkActionReqObj(framework), mDataItemId(dit), mTimeOut(timeOut) {} + virtual ~HandleTurnOnMsg() {} + void proc() const { + mFrameworkActionReqObj->turnOn(mDataItemId, mTimeOut); } - } - if (dataItems.empty ()) { - LOC_LOGV("No items to notify. Nothing to do. Exiting"); - result = 0; - break; - } + IFrameworkActionReq* mFrameworkActionReqObj; + DataItemId mDataItemId; + int mTimeOut; + }; + mContext.mMsgTask->sendMsg(new (nothrow) HandleTurnOnMsg(this, dit, timeOut)); + } + else { + // Found in map, update reference count + citer->second++; + LOC_LOGD("turnOn - Data item:%d Num_refs:%d", dit, citer->second); + } +} - // Notify Client - to->notify (dataItems); +void SystemStatusOsObserver::turnOff(DataItemId dit) +{ + if (nullptr == mContext.mFrameworkActionReqObj) { + LOC_LOGE("%s:%d]: Framework action request object is NULL", __func__, __LINE__); + return; + } - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return result; + // Check if data item exists in mActiveRequestCount + map<DataItemId, int>::iterator citer = mActiveRequestCount.find(dit); + if (citer != mActiveRequestCount.end()) { + // found + citer->second--; + LOC_LOGD("turnOff - Data item:%d Remaining:%d", dit, citer->second); + if(citer->second == 0) { + // if this was last reference, remove item from map and turn off module + mActiveRequestCount.erase(citer); + + // Send action turn off to framework + struct HandleTurnOffMsg : public LocMsg { + HandleTurnOffMsg(IFrameworkActionReq* framework, DataItemId dit) : + mFrameworkActionReqObj(framework), mDataItemId(dit) {} + virtual ~HandleTurnOffMsg() {} + void proc() const { + mFrameworkActionReqObj->turnOff(mDataItemId); + } + IFrameworkActionReq* mFrameworkActionReqObj; + DataItemId mDataItemId; + }; + mContext.mMsgTask->sendMsg( + new (nothrow) HandleTurnOffMsg(mContext.mFrameworkActionReqObj, dit)); + } + } } -int SystemStatusOsObserver :: sendCachedDataItems (const list <DataItemId> & l, IDataItemObserver * to) { - int result = 0; - ENTRY_LOG (); - do { - list <IDataItemCore *> dataItems; - list <DataItemId> :: const_iterator it = l.begin (); - string clientName; - to->getName (clientName); - LOC_LOGD ("LocTech-Value :: To Client: %s", clientName.c_str ()); - for (; it != l.end (); ++it) { +/****************************************************************************** + Helpers +******************************************************************************/ +void SystemStatusOsObserver::sendFirstResponse( + const list<DataItemId>& l, IDataItemObserver* to) +{ + if (l.empty()) { + LOC_LOGV("list is empty. Nothing to do. Exiting"); + return; + } + + string clientName; + to->getName(clientName); + list<IDataItemCore*> dataItems(0); + + for (auto each : l) { + map<DataItemId, IDataItemCore*>::const_iterator citer = mDataItemCache.find(each); + if (citer != mDataItemCache.end()) { string dv; - IDataItemCore * di = this->mDataItemCache [ (*it) ]; - di->stringify (dv); - LOC_LOGI("LocTech-Value :: Data Item: %s >> %s", dv.c_str(), clientName.c_str()); - dataItems.push_back (di); + citer->second->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_back(citer->second); } + } + if (dataItems.empty()) { + LOC_LOGV("No items to notify. Nothing to do. Exiting"); + return; + } + to->notify(dataItems); +} - to->notify (dataItems); - - } while (0); - EXIT_LOG_WITH_ERROR ("%d", result); - return result; +void SystemStatusOsObserver::sendCachedDataItems( + const list<DataItemId>& l, IDataItemObserver* to) +{ + string clientName; + to->getName(clientName); + list<IDataItemCore*> dataItems(0); + + for (auto each : l) { + string dv; + IDataItemCore* di = mDataItemCache[each]; + di->stringify(dv); + LOC_LOGI("DataItem: %s >> %s", dv.c_str(), clientName.c_str()); + dataItems.push_back(di); + } + to->notify(dataItems); } -int SystemStatusOsObserver :: updateCache (IDataItemCore * d, bool &dataItemUpdated) { - int result = 0; - ENTRY_LOG (); - do { - BREAK_IF_ZERO (1, d); - // Check if data item exists in cache - map <DataItemId, IDataItemCore*> :: iterator citer = mDataItemCache.find (d->getId ()); - if (citer == mDataItemCache.end ()) { - // New data item; not found in cache - IDataItemCore * dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); - BREAK_IF_ZERO (2, dataitem); - // Copy the contents of the data item - dataitem->copy (d); - pair <DataItemId, IDataItemCore*> cpair (d->getId (), dataitem); - // Insert in mDataItemCache - mDataItemCache.insert (cpair); - dataItemUpdated = true; - } else { - // Found in cache; Update cache if necessary - BREAK_IF_NON_ZERO(3, citer->second->copy (d, &dataItemUpdated)); - } +void SystemStatusOsObserver::updateCache(IDataItemCore* d, bool& dataItemUpdated) +{ + if (nullptr == d) { + return; + } - if (dataItemUpdated) { - LOC_LOGV("DataItem:%d updated:%d", d->getId (), dataItemUpdated); + // Check if data item exists in cache + map<DataItemId, IDataItemCore*>::iterator citer = + mDataItemCache.find(d->getId()); + if (citer == mDataItemCache.end()) { + // New data item; not found in cache + IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem(d->getId()); + if (nullptr == dataitem) { + return; + } + + // Copy the contents of the data item + dataitem->copy(d); + pair<DataItemId, IDataItemCore*> cpair(d->getId(), dataitem); + // Insert in mDataItemCache + mDataItemCache.insert(cpair); + dataItemUpdated = true; + } + else { + // Found in cache; Update cache if necessary + if(0 == citer->second->copy(d, &dataItemUpdated)) { + return; } - } while (0); + } - EXIT_LOG_WITH_ERROR ("%d", result); - return result; + if (dataItemUpdated) { + LOC_LOGV("DataItem:%d updated:%d", d->getId(), dataItemUpdated); + } } } // namespace loc_core diff --git a/gps/core/SystemStatusOsObserver.h b/gps/core/SystemStatusOsObserver.h index 8e42d21..985e5c9 100644 --- a/gps/core/SystemStatusOsObserver.h +++ b/gps/core/SystemStatusOsObserver.h @@ -29,36 +29,34 @@ #ifndef __SYSTEM_STATUS_OSOBSERVER__ #define __SYSTEM_STATUS_OSOBSERVER__ -#include <stdint.h> +#include <cinttypes> #include <string> #include <list> #include <map> #include <new> #include <vector> -#include <platform_lib_log_util.h> -#include <DataItemId.h> + #include <MsgTask.h> +#include <DataItemId.h> #include <IOsObserver.h> +#include <platform_lib_log_util.h> namespace loc_core { - /****************************************************************************** SystemStatusOsObserver ******************************************************************************/ +using namespace std; + // Forward Declarations class IDataItemCore; - -template <typename CT, typename DIT> -class IClientIndex; - -template <typename CT, typename DIT> -class IDataItemIndex; +template<typename CT, typename DIT> class IClientIndex; +template<typename CT, typename DIT> class IDataItemIndex; struct SystemContext { - IDataItemSubscription *mSubscriptionObj; - IFrameworkActionReq *mFrameworkActionReqObj; - const MsgTask *mMsgTask; + IDataItemSubscription* mSubscriptionObj; + IFrameworkActionReq* mFrameworkActionReqObj; + const MsgTask* mMsgTask; inline SystemContext() : mSubscriptionObj(NULL), @@ -66,6 +64,8 @@ struct SystemContext { mMsgTask(NULL) {} }; +typedef map<IDataItemObserver*, list<DataItemId>> ObserverReqCache; + // Clients wanting to get data from OS/Framework would need to // subscribe with OSObserver using IDataItemSubscription interface. // Such clients would need to implement IDataItemObserver interface @@ -80,252 +80,54 @@ public: ~SystemStatusOsObserver(); // To set the subscription object - inline void setSubscriptionObj(IDataItemSubscription *subscriptionObj) { - mContext.mSubscriptionObj = subscriptionObj; - }; + virtual void setSubscriptionObj(IDataItemSubscription* subscriptionObj); // To set the framework action request object - inline void setFrameworkActionReqObj(IFrameworkActionReq *frameworkActionReqObj) { + inline void setFrameworkActionReqObj(IFrameworkActionReq* frameworkActionReqObj) { mContext.mFrameworkActionReqObj = frameworkActionReqObj; } - // IDataItemObserver Overrides - virtual void getName (string & name); - virtual void notify (const std::list <IDataItemCore *> & dlist); - // IDataItemSubscription Overrides - virtual void subscribe (const std :: list <DataItemId> & l, IDataItemObserver * client); - virtual void updateSubscription - ( - const std :: list <DataItemId> & l, - IDataItemObserver * client - ); - virtual void requestData - ( - const std :: list <DataItemId> & l, - IDataItemObserver * client - ); - virtual void unsubscribe (const std :: list <DataItemId> & l, IDataItemObserver * client); - virtual void unsubscribeAll (IDataItemObserver * client); + virtual void subscribe(const list<DataItemId>& l, IDataItemObserver* client); + virtual void updateSubscription(const list<DataItemId>& l, IDataItemObserver* client); + virtual void requestData(const list<DataItemId>& l, IDataItemObserver* client); + virtual void unsubscribe(const list<DataItemId>& l, IDataItemObserver* client); + virtual void unsubscribeAll(IDataItemObserver* client); + + // IDataItemObserver Overrides + virtual void notify(const list<IDataItemCore*>& dlist); + inline virtual void getName(string& name) { + name = mAddress; + } // IFrameworkActionReq Overrides - virtual void turnOn (DataItemId dit, int timeOut = 0); - virtual void turnOff (DataItemId dit); + virtual void turnOn(DataItemId dit, int timeOut = 0); + virtual void turnOff(DataItemId dit); private: - - SystemContext mContext; - const string mAddress; - IClientIndex <IDataItemObserver *, DataItemId> *mClientIndex; - IDataItemIndex <IDataItemObserver *, DataItemId> *mDataItemIndex; - map < DataItemId, IDataItemCore * > mDataItemCache; - map < DataItemId, int > mActiveRequestCount; - - // Nested types - // Messages - struct HandleMsgBase : public LocMsg { - HandleMsgBase (SystemStatusOsObserver * parent); - virtual ~HandleMsgBase (); - // Data members - SystemStatusOsObserver * mParent; - }; + SystemContext mContext; + const string mAddress; + IClientIndex<IDataItemObserver*, DataItemId>* mClientIndex; + IDataItemIndex<IDataItemObserver*, DataItemId>* mDataItemIndex; + map<DataItemId, IDataItemCore*> mDataItemCache; + map<DataItemId, int> mActiveRequestCount; + + // Cache the subscribe and requestData till subscription obj is obtained + ObserverReqCache mSubscribeReqCache; + ObserverReqCache mReqDataCache; + void cacheObserverRequest(ObserverReqCache& reqCache, + const list<DataItemId>& l, IDataItemObserver* client); // Helpers - int sendFirstResponse - ( - const list <DataItemId> & l, - IDataItemObserver * to - ); - - int sendCachedDataItems - ( - const list <DataItemId> & l, - IDataItemObserver * to - ); - - int updateCache (IDataItemCore * d, bool &dataItemUpdated); - void logMe (const list <DataItemId> & l); - - // Messages - struct HandleClientMsg : public LocMsg { - HandleClientMsg (SystemStatusOsObserver * parent, IDataItemObserver * client); - virtual ~HandleClientMsg (); - // Data Members - SystemStatusOsObserver * mParent; - IDataItemObserver * mClient; - }; - - struct HandleSubscribeReq : public HandleClientMsg { - HandleSubscribeReq (SystemStatusOsObserver * parent, - const list <DataItemId> & l, - IDataItemObserver * client); - virtual ~HandleSubscribeReq (); - void proc () const; - // Data members - const list <DataItemId> mDataItemList; - }; - - struct HandleUpdateSubscriptionReq : public HandleClientMsg { - HandleUpdateSubscriptionReq (SystemStatusOsObserver * parent, - const list <DataItemId> & l, - IDataItemObserver * client); - virtual ~HandleUpdateSubscriptionReq (); - void proc () const; - // Data members - const list <DataItemId> mDataItemList; - }; - - struct HandleRequestData : public HandleClientMsg { - HandleRequestData (SystemStatusOsObserver * parent, - const list <DataItemId> & l, - IDataItemObserver * client); - virtual ~HandleRequestData (); - void proc () const; - const list <DataItemId> mDataItemList; - }; - - struct HandleUnsubscribeReq : public HandleClientMsg { - HandleUnsubscribeReq (SystemStatusOsObserver * parent, - const list <DataItemId> & l, - IDataItemObserver * client); - virtual ~HandleUnsubscribeReq (); - void proc () const; - // Data members - const list <DataItemId> mDataItemList; - }; - - struct HandleUnsubscribeAllReq : public HandleClientMsg { - HandleUnsubscribeAllReq - ( - SystemStatusOsObserver * parent, - IDataItemObserver * client - ); - virtual ~HandleUnsubscribeAllReq (); - void proc () const; - }; - - struct HandleNotify : public HandleMsgBase { - HandleNotify (SystemStatusOsObserver * parent, list <IDataItemCore *> dlist); - virtual ~HandleNotify (); - void getListOfClients - ( - const list <DataItemId> & dlist, - list <IDataItemObserver *> & clients - ) const; - void proc () const; - // Data members - list <IDataItemCore *> mDList; - }; - - struct HandleTurnOn : public HandleMsgBase { - HandleTurnOn (SystemStatusOsObserver * parent, - const DataItemId dit, - const int timeOut); - virtual ~HandleTurnOn (); - void proc () const; - // Data members - DataItemId mDataItemId; - int mTimeOut; - }; - - struct HandleTurnOff : public HandleMsgBase { - HandleTurnOff (SystemStatusOsObserver * parent,const DataItemId dit); - virtual ~HandleTurnOff (); - void proc () const; - // Data members - DataItemId mDataItemId; - }; - -}; - - -/****************************************************************************** - Messages -******************************************************************************/ -// Ctors -inline SystemStatusOsObserver :: HandleMsgBase :: HandleMsgBase (SystemStatusOsObserver * parent) -: -mParent (parent) -{} - -inline SystemStatusOsObserver :: HandleClientMsg :: HandleClientMsg -( - SystemStatusOsObserver * parent, - IDataItemObserver * client -) -: -mParent (parent), -mClient (client) -{} - -inline SystemStatusOsObserver :: HandleSubscribeReq :: HandleSubscribeReq - (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client) -: -HandleClientMsg (parent, client), mDataItemList (l) -{} - -inline SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: HandleUpdateSubscriptionReq - (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client) -: -HandleClientMsg (parent, client), mDataItemList (l) -{} - -inline SystemStatusOsObserver :: HandleRequestData :: HandleRequestData - (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client) -: -HandleClientMsg (parent, client), mDataItemList (l) -{} - -inline SystemStatusOsObserver :: HandleUnsubscribeReq :: HandleUnsubscribeReq - (SystemStatusOsObserver * parent, const list <DataItemId> & l, IDataItemObserver * client) -: -HandleClientMsg (parent, client), mDataItemList (l) -{} - -inline SystemStatusOsObserver :: HandleUnsubscribeAllReq :: HandleUnsubscribeAllReq - (SystemStatusOsObserver * parent, IDataItemObserver * client) -: -HandleClientMsg (parent, client) -{} - -inline SystemStatusOsObserver :: HandleNotify :: HandleNotify - (SystemStatusOsObserver * parent, list <IDataItemCore *> dlist) -: -HandleMsgBase (parent), mDList (dlist) -{} - -inline SystemStatusOsObserver :: HandleTurnOn :: HandleTurnOn - (SystemStatusOsObserver * parent, const DataItemId dit,const int timeOut) -: -HandleMsgBase (parent), mDataItemId (dit), mTimeOut (timeOut) -{} - -inline SystemStatusOsObserver :: HandleTurnOff :: HandleTurnOff - (SystemStatusOsObserver * parent, const DataItemId dit) -: -HandleMsgBase (parent), mDataItemId (dit) -{} - -// Dtors -inline SystemStatusOsObserver :: HandleMsgBase :: ~HandleMsgBase () {} -inline SystemStatusOsObserver :: HandleClientMsg :: ~HandleClientMsg () {} -inline SystemStatusOsObserver :: HandleSubscribeReq :: ~HandleSubscribeReq () {} -inline SystemStatusOsObserver :: HandleUpdateSubscriptionReq :: ~HandleUpdateSubscriptionReq() {} -inline SystemStatusOsObserver :: HandleRequestData :: ~HandleRequestData() {} -inline SystemStatusOsObserver :: HandleUnsubscribeReq :: ~HandleUnsubscribeReq () {} -inline SystemStatusOsObserver :: HandleUnsubscribeAllReq :: ~HandleUnsubscribeAllReq () {} - -inline SystemStatusOsObserver :: HandleNotify :: ~HandleNotify () { - list <IDataItemCore *> :: iterator it = mDList.begin (); - for (; it != mDList.end (); ++it) { - delete *it; - *it = NULL; + void sendFirstResponse(const list<DataItemId>& l, IDataItemObserver* to); + void sendCachedDataItems(const list<DataItemId>& l, IDataItemObserver* to); + void updateCache(IDataItemCore* d, bool& dataItemUpdated); + inline void logMe(const list<DataItemId>& l) { + for (auto id : l) { + LOC_LOGD("DataItem %d", id); + } } -} - -inline SystemStatusOsObserver :: HandleTurnOn :: ~HandleTurnOn () {} -inline SystemStatusOsObserver :: HandleTurnOff :: ~HandleTurnOff () {} - +}; } // namespace loc_core diff --git a/gps/etc/Android.mk b/gps/etc/Android.mk deleted file mode 100644 index d9eb0e1..0000000 --- a/gps/etc/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := gps.conf -LOCAL_MODULE_TAGS := optional -LOCAL_MODULE_CLASS := ETC -LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/etc/ -LOCAL_SRC_FILES := gps.conf - -include $(BUILD_PREBUILT) - diff --git a/gps/etc/gps.conf b/gps/etc/gps.conf index 1027d76..e6861d8 100644 --- a/gps/etc/gps.conf +++ b/gps/etc/gps.conf @@ -4,6 +4,19 @@ #XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra2.bin #XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra2.bin +#ifdef VENDOR_EDIT +# zuoyonghua@oneplus.cn add gps xtra server for speed up gps cold start +XTRA_SERVER_1=http://xtrapath1.izatcloud.net/xtra3grc.bin +XTRA_SERVER_2=http://xtrapath2.izatcloud.net/xtra3grc.bin +XTRA_SERVER_3=http://xtrapath3.izatcloud.net/xtra3grc.bin +#endif + +#ifdef VENDOR_EDIT +# songhao@oneplus.cn,XTRA download config for debug +XTRA_TEST_ENABLED = 1 +XTRA_THROTTLE_ENABLED = 0 +#endif + #Version check for XTRA #DISABLE = 0 #AUTO = 1 @@ -38,7 +51,7 @@ INTERMEDIATE_POS=0 #GPS_LOCK = 0 # supl version 1.0 -SUPL_VER=0x10000 +SUPL_VER=0x20000 # Emergency SUPL, 1=enable, 0=disable #SUPL_ES=0 @@ -66,7 +79,7 @@ CAPABILITIES=0x37 # Accuracy threshold for intermediate positions # less accurate positions are ignored, 0 for passing all positions -# ACCURACY_THRES=5000 +ACCURACY_THRES=100 ################################ ##### AGPS server settings ##### @@ -111,7 +124,11 @@ SGLTE_TARGET=0 # 0x1: RRC CPlane # 0x2: RRLP UPlane # 0x4: LLP Uplane -A_GLONASS_POS_PROTOCOL_SELECT = 0 +#ifndef zuoyonghua@oneplus.cn enable all bit mask for GLONASS +#A_GLONASS_POS_PROTOCOL_SELECT = 0 +#else +A_GLONASS_POS_PROTOCOL_SELECT = 15 +#endif ################################################## # Select technology for LPPe Control Plane diff --git a/gps/etc/izat.conf b/gps/etc/izat.conf index d300033..29d9ba4 100644 --- a/gps/etc/izat.conf +++ b/gps/etc/izat.conf @@ -49,7 +49,7 @@ NLP_COMBO_MODE_USES_QNP_WITH_NO_EULA_CONSENT = 1 # NLP PACKAGE AND ACTION SETTINGS ######################################### # OSNLP_PACKAGE/OSNLP_ACTION: name/action of default NLP package -OSNLP_PACKAGE = com.amap.android.ams +OSNLP_PACKAGE = com.google.android.gms OSNLP_ACTION = com.android.location.service.v3.NetworkLocationProvider # REGION_OSNLP_PACKAGE/REGION_OSNLP_ACTION: # These two values will be used as alternative @@ -214,7 +214,7 @@ HARDWARE_TYPE=all PROCESS_NAME=lowi-server PROCESS_ARGUMENT= PROCESS_STATE=ENABLED -PROCESS_GROUPS=gps net_admin wifi inet oem_2901 +PROCESS_GROUPS=gps net_admin wifi inet oem_2950 PREMIUM_FEATURE=0 IZAT_FEATURE_MASK=0xf303 PLATFORMS=all @@ -227,7 +227,7 @@ PROCESS_ARGUMENT= PROCESS_STATE=ENABLED PROCESS_GROUPS=inet gps PREMIUM_FEATURE=1 -IZAT_FEATURE_MASK=0xc0f +IZAT_FEATURE_MASK=0xf0f PLATFORMS=all BASEBAND=all LEAN_TARGETS=DISABLED @@ -236,7 +236,7 @@ HARDWARE_TYPE=all PROCESS_NAME=xtwifi-client PROCESS_ARGUMENT= PROCESS_STATE=ENABLED -PROCESS_GROUPS=wifi inet gps rfs_shared system +PROCESS_GROUPS=wifi inet gps oem_2952 system wakelock PREMIUM_FEATURE=1 IZAT_FEATURE_MASK=0xf0f PLATFORMS=all @@ -247,7 +247,7 @@ HARDWARE_TYPE=all PROCESS_NAME=slim_daemon PROCESS_ARGUMENT= PROCESS_STATE=ENABLED -PROCESS_GROUPS=gps oem_2901 can +PROCESS_GROUPS=gps oem_2950 can PREMIUM_FEATURE=1 IZAT_FEATURE_MASK=0xf0 PLATFORMS=all diff --git a/gps/gnss/Agps.cpp b/gps/gnss/Agps.cpp index 22582d4..72ce293 100644 --- a/gps/gnss/Agps.cpp +++ b/gps/gnss/Agps.cpp @@ -42,7 +42,7 @@ void AgpsStateMachine::processAgpsEvent(AgpsEvent event){ LOC_LOGD("processAgpsEvent(): SM %p, Event %d, State %d", this, event, mState); - switch (event){ + switch (event) { case AGPS_EVENT_SUBSCRIBE: processAgpsEventSubscribe(); @@ -71,7 +71,7 @@ void AgpsStateMachine::processAgpsEvent(AgpsEvent event){ void AgpsStateMachine::processAgpsEventSubscribe(){ - switch (mState){ + switch (mState) { case AGPS_STATE_RELEASED: /* Add subscriber to list @@ -83,7 +83,7 @@ void AgpsStateMachine::processAgpsEventSubscribe(){ * fails for DS State Machine, we want to retry in released state. * for Agps State Machine, sendRsrcRequest() will always return * success. */ - if(requestOrReleaseDataConn(true) == 0){ + if (requestOrReleaseDataConn(true) == 0) { // If data request successful, move to pending state transitionState(AGPS_STATE_PENDING); } @@ -115,7 +115,7 @@ void AgpsStateMachine::processAgpsEventSubscribe(){ void AgpsStateMachine::processAgpsEventUnsubscribe(){ - switch (mState){ + switch (mState) { case AGPS_STATE_RELEASED: notifyEventToSubscriber( @@ -127,12 +127,10 @@ void AgpsStateMachine::processAgpsEventUnsubscribe(){ /* If the subscriber wishes to wait for connection close, * before being removed from list, move to inactive state * and notify */ - if(mCurrentSubscriber->mWaitForCloseComplete){ + if (mCurrentSubscriber->mWaitForCloseComplete) { mCurrentSubscriber->mIsInactive = true; - notifyEventToSubscriber( - AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false); } - else{ + else { /* Notify only current subscriber and then delete it from * subscriberList */ notifyEventToSubscriber( @@ -140,13 +138,13 @@ void AgpsStateMachine::processAgpsEventUnsubscribe(){ } /* If no subscribers in list, release data connection */ - if(mSubscriberList.empty()){ + if (mSubscriberList.empty()) { transitionState(AGPS_STATE_RELEASED); requestOrReleaseDataConn(false); } /* Some subscribers in list, but all inactive; * Release data connection */ - else if(!anyActiveSubscribers()){ + else if(!anyActiveSubscribers()) { transitionState(AGPS_STATE_RELEASING); requestOrReleaseDataConn(false); } @@ -156,12 +154,10 @@ void AgpsStateMachine::processAgpsEventUnsubscribe(){ /* If the subscriber wishes to wait for connection close, * before being removed from list, move to inactive state * and notify */ - if(mCurrentSubscriber->mWaitForCloseComplete){ + if (mCurrentSubscriber->mWaitForCloseComplete) { mCurrentSubscriber->mIsInactive = true; - notifyEventToSubscriber( - AGPS_EVENT_UNSUBSCRIBE, mCurrentSubscriber, false); } - else{ + else { /* Notify only current subscriber and then delete it from * subscriberList */ notifyEventToSubscriber( @@ -171,7 +167,7 @@ void AgpsStateMachine::processAgpsEventUnsubscribe(){ /* If no subscribers in list, just move the state. * Request for releasing data connection should already have been * sent */ - if(mSubscriberList.empty()){ + if (mSubscriberList.empty()) { transitionState(AGPS_STATE_RELEASED); } break; @@ -183,7 +179,7 @@ void AgpsStateMachine::processAgpsEventUnsubscribe(){ void AgpsStateMachine::processAgpsEventGranted(){ - switch (mState){ + switch (mState) { case AGPS_STATE_RELEASED: case AGPS_STATE_ACQUIRED: @@ -206,7 +202,7 @@ void AgpsStateMachine::processAgpsEventGranted(){ void AgpsStateMachine::processAgpsEventReleased(){ - switch (mState){ + switch (mState) { case AGPS_STATE_RELEASED: /* Subscriber list should be empty if we are in released state */ @@ -232,12 +228,12 @@ void AgpsStateMachine::processAgpsEventReleased(){ /* If we have active subscribers now, they must be waiting for * data conn setup */ - if(anyActiveSubscribers()){ + if (anyActiveSubscribers()) { transitionState(AGPS_STATE_PENDING); requestOrReleaseDataConn(true); } /* No active subscribers, move to released state */ - else{ + else { transitionState(AGPS_STATE_RELEASED); } break; @@ -253,7 +249,7 @@ void AgpsStateMachine::processAgpsEventReleased(){ void AgpsStateMachine::processAgpsEventDenied(){ - switch (mState){ + switch (mState) { case AGPS_STATE_RELEASED: LOC_LOGE("Unexpected event DENIED in state %d", mState); @@ -271,12 +267,12 @@ void AgpsStateMachine::processAgpsEventDenied(){ /* If we have active subscribers now, they must be waiting for * data conn setup */ - if(anyActiveSubscribers()){ + if (anyActiveSubscribers()) { transitionState(AGPS_STATE_PENDING); requestOrReleaseDataConn(true); } /* No active subscribers, move to released state */ - else{ + else { transitionState(AGPS_STATE_RELEASED); } break; @@ -299,20 +295,18 @@ void AgpsStateMachine::processAgpsEventDenied(){ * false = Release data connection */ int AgpsStateMachine::requestOrReleaseDataConn(bool request){ - AgpsFrameworkInterface::AGnssStatusIpV4 nifRequest; + AGnssExtStatusIpV4 nifRequest; memset(&nifRequest, 0, sizeof(nifRequest)); - nifRequest.type = (AgpsFrameworkInterface::AGnssType)mAgpsType; + nifRequest.type = mAgpsType; - if(request){ + if (request) { LOC_LOGD("AGPS Data Conn Request"); - nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue) - LOC_GPS_REQUEST_AGPS_DATA_CONN; + nifRequest.status = LOC_GPS_REQUEST_AGPS_DATA_CONN; } else{ LOC_LOGD("AGPS Data Conn Release"); - nifRequest.status = (AgpsFrameworkInterface::AGnssStatusValue) - LOC_GPS_RELEASE_AGPS_DATA_CONN; + nifRequest.status = LOC_GPS_RELEASE_AGPS_DATA_CONN; } mAgpsManager->mFrameworkStatusV4Cb(nifRequest); @@ -328,11 +322,11 @@ void AgpsStateMachine::notifyAllSubscribers( this, event, deleteSubscriberPostNotify, notificationType); std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - while ( it != mSubscriberList.end() ){ + while ( it != mSubscriberList.end() ) { AgpsSubscriber* subscriber = *it; - if(notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS || + if (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ALL_SUBSCRIBERS || (notificationType == AGPS_NOTIFICATION_TYPE_FOR_INACTIVE_SUBSCRIBERS && subscriber->mIsInactive) || (notificationType == AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS && @@ -342,13 +336,13 @@ void AgpsStateMachine::notifyAllSubscribers( * through subscriber list, inefficient; hence pass in false*/ notifyEventToSubscriber(event, subscriber, false); - if(deleteSubscriberPostNotify){ + if (deleteSubscriberPostNotify) { it = mSubscriberList.erase(it); delete subscriber; - } else{ + } else { it++; } - } else{ + } else { it++; } } @@ -362,7 +356,7 @@ void AgpsStateMachine::notifyEventToSubscriber( "SM %p, Event %d Subscriber %p Delete %d", this, event, subscriberToNotify, deleteSubscriberPostNotify); - switch (event){ + switch (event) { case AGPS_EVENT_GRANTED: mAgpsManager->mAtlOpenStatusCb( @@ -409,9 +403,9 @@ void AgpsStateMachine::addSubscriber(AgpsSubscriber* subscriberToAdd){ // Check if subscriber is already present in the current list // If not, then add std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - for(; it != mSubscriberList.end(); it++){ + for (; it != mSubscriberList.end(); it++) { AgpsSubscriber* subscriber = *it; - if(subscriber->equals(subscriberToAdd)){ + if (subscriber->equals(subscriberToAdd)) { LOC_LOGE("Subscriber already in list"); return; } @@ -431,11 +425,11 @@ void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){ while ( it != mSubscriberList.end() ) { AgpsSubscriber* subscriber = *it; - if(subscriber && subscriber->equals(subscriberToDelete)){ + if (subscriber && subscriber->equals(subscriberToDelete)) { it = mSubscriberList.erase(it); delete subscriber; - }else{ + } else { it++; } } @@ -444,9 +438,9 @@ void AgpsStateMachine::deleteSubscriber(AgpsSubscriber* subscriberToDelete){ bool AgpsStateMachine::anyActiveSubscribers(){ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - for(; it != mSubscriberList.end(); it++){ + for (; it != mSubscriberList.end(); it++) { AgpsSubscriber* subscriber = *it; - if(!subscriber->mIsInactive){ + if (!subscriber->mIsInactive) { return true; } } @@ -459,7 +453,7 @@ void AgpsStateMachine::setAPN(char* apn, unsigned int len){ delete mAPN; } - if(apn == NULL || len <= 0){ + if (apn == NULL || len <= 0) { LOC_LOGD("Invalid apn len (%d) or null apn", len); mAPN = NULL; mAPNLen = 0; @@ -467,9 +461,11 @@ void AgpsStateMachine::setAPN(char* apn, unsigned int len){ if (NULL != apn) { mAPN = new char[len+1]; - memcpy(mAPN, apn, len); - mAPN[len] = '\0'; - mAPNLen = len; + if (NULL != mAPN) { + memcpy(mAPN, apn, len); + mAPN[len] = '\0'; + mAPNLen = len; + } } } @@ -477,9 +473,9 @@ AgpsSubscriber* AgpsStateMachine::getSubscriber(int connHandle){ /* Go over the subscriber list */ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - for(; it != mSubscriberList.end(); it++){ + for (; it != mSubscriberList.end(); it++) { AgpsSubscriber* subscriber = *it; - if(subscriber->mConnHandle == connHandle){ + if (subscriber->mConnHandle == connHandle) { return subscriber; } } @@ -492,9 +488,9 @@ AgpsSubscriber* AgpsStateMachine::getFirstSubscriber(bool isInactive){ /* Go over the subscriber list */ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - for(; it != mSubscriberList.end(); it++){ + for (; it != mSubscriberList.end(); it++) { AgpsSubscriber* subscriber = *it; - if(subscriber->mIsInactive == isInactive){ + if(subscriber->mIsInactive == isInactive) { return subscriber; } } @@ -509,7 +505,7 @@ void AgpsStateMachine::dropAllSubscribers(){ /* Go over the subscriber list */ std::list<AgpsSubscriber*>::const_iterator it = mSubscriberList.begin(); - while ( it != mSubscriberList.end() ){ + while ( it != mSubscriberList.end() ) { AgpsSubscriber* subscriber = *it; it = mSubscriberList.erase(it); delete subscriber; @@ -524,14 +520,14 @@ const int DSStateMachine::DATA_CALL_RETRY_DELAY_MSEC = 500; /* Overridden method * DS SM needs to handle one scenario differently */ -void DSStateMachine::processAgpsEvent(AgpsEvent event){ +void DSStateMachine::processAgpsEvent(AgpsEvent event) { LOC_LOGD("DSStateMachine::processAgpsEvent() %d", event); /* DS Client call setup APIs don't return failure/closure separately. * Hence we receive RELEASED event in both cases. * If we are in pending, we should consider RELEASED as DENIED */ - if(event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING){ + if (event == AGPS_EVENT_RELEASED && mState == AGPS_STATE_PENDING) { LOC_LOGD("Translating RELEASED to DENIED event"); event = AGPS_EVENT_DENIED; @@ -549,7 +545,7 @@ void delay_callback(void *callbackData, int result) (void)result; - if(callbackData == NULL) { + if (callbackData == NULL) { LOC_LOGE("delay_callback(): NULL argument received !"); return; } @@ -566,7 +562,7 @@ void DSStateMachine :: retryCallback() /* Request SUPL ES * There must be at least one active subscriber in list */ AgpsSubscriber* subscriber = getFirstSubscriber(false); - if(subscriber == NULL) { + if (subscriber == NULL) { LOC_LOGE("No active subscriber for DS Client call setup"); return; @@ -590,7 +586,7 @@ int DSStateMachine::requestOrReleaseDataConn(bool request){ "request %d", request); /* Release data connection required ? */ - if(!request && mAgpsManager->mDSClientStopDataCallFn){ + if (!request && mAgpsManager->mDSClientStopDataCallFn) { mAgpsManager->mDSClientStopDataCallFn(); LOC_LOGD("DS Client release data call request sent !"); @@ -600,14 +596,14 @@ int DSStateMachine::requestOrReleaseDataConn(bool request){ /* Setup data connection request * There must be at least one active subscriber in list */ AgpsSubscriber* subscriber = getFirstSubscriber(false); - if(subscriber == NULL) { + if (subscriber == NULL) { LOC_LOGE("No active subscriber for DS Client call setup"); return -1; } /* DS Client Fn registered ? */ - if(!mAgpsManager->mDSClientOpenAndStartDataCallFn){ + if (!mAgpsManager->mDSClientOpenAndStartDataCallFn) { LOC_LOGE("DS Client start fn not registered, fallback to SUPL ATL"); notifyEventToSubscriber(AGPS_EVENT_DENIED, subscriber, false); @@ -623,7 +619,7 @@ int DSStateMachine::requestOrReleaseDataConn(bool request){ case LOC_API_ADAPTER_ERR_ENGINE_BUSY: LOC_LOGE("DS Client open call failed, err: %d", ret); mRetries++; - if(mRetries > MAX_START_DATA_CALL_RETRIES) { + if (mRetries > MAX_START_DATA_CALL_RETRIES) { LOC_LOGE("DS Client call retries exhausted, " "falling back to normal SUPL ATL"); @@ -661,7 +657,7 @@ void DSStateMachine::notifyEventToSubscriber( "SM %p, Event %d Subscriber %p Delete %d", this, event, subscriberToNotify, deleteSubscriberPostNotify); - switch (event){ + switch (event) { case AGPS_EVENT_GRANTED: mAgpsManager->mAtlOpenStatusCb( @@ -685,6 +681,7 @@ void DSStateMachine::notifyEventToSubscriber( case AGPS_EVENT_RELEASED: mAgpsManager->mDSClientCloseDataCallFn(); + mAgpsManager->mAtlCloseStatusCb(subscriberToNotify->mConnHandle, 1); break; default: @@ -721,14 +718,14 @@ void AgpsManager::createAgpsStateMachines() { LOC_LOGD("AGNSS NIF: %p", mAgnssNif); } if (NULL == mDsNif && - loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){ + loc_core::ContextBase::mGps_conf.USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) { if(!mDSClientInitFn){ LOC_LOGE("DS Client Init Fn not registered !"); return; } - if(mDSClientInitFn(false) != 0){ + if (mDSClientInitFn(false) != 0) { LOC_LOGE("Failed to init data service client"); return; @@ -747,7 +744,7 @@ AgpsStateMachine* AgpsManager::getAgpsStateMachine(AGpsExtType agpsType) { case LOC_AGPS_TYPE_INVALID: case LOC_AGPS_TYPE_SUPL: - if(mAgnssNif == NULL){ + if (mAgnssNif == NULL) { LOC_LOGE("NULL AGNSS NIF !"); } return mAgnssNif; @@ -777,7 +774,7 @@ void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){ AgpsStateMachine* sm = getAgpsStateMachine(agpsType); - if(sm == NULL){ + if (sm == NULL) { LOC_LOGE("No AGPS State Machine for agpsType: %d", agpsType); mAtlOpenStatusCb( @@ -790,7 +787,7 @@ void AgpsManager::requestATL(int connHandle, AGpsExtType agpsType){ sm->setCurrentSubscriber(&subscriber); /* If DS State Machine, wait for close complete */ - if(agpsType == LOC_AGPS_TYPE_SUPL_ES){ + if (agpsType == LOC_AGPS_TYPE_SUPL_ES) { subscriber.mWaitForCloseComplete = true; } @@ -820,7 +817,7 @@ void AgpsManager::releaseATL(int connHandle){ sm = mDsNif; } - if(sm == NULL){ + if (sm == NULL) { LOC_LOGE("Subscriber with connHandle %d not found in any SM", connHandle); mAtlCloseStatusCb(connHandle, 0); @@ -852,32 +849,15 @@ void AgpsManager::reportDataCallClosed(){ void AgpsManager::reportAtlOpenSuccess( AGpsExtType agpsType, char* apnName, int apnLen, - LocApnIpType ipType){ + AGpsBearerType bearerType){ LOC_LOGD("AgpsManager::reportAtlOpenSuccess(): " - "AgpsType %d, APN [%s], Len %d, IPType %d", - agpsType, apnName, apnLen, ipType); + "AgpsType %d, APN [%s], Len %d, BearerType %d", + agpsType, apnName, apnLen, bearerType); /* Find the state machine instance */ AgpsStateMachine* sm = getAgpsStateMachine(agpsType); - /* Convert LocApnIpType sent by framework to AGpsBearerType */ - AGpsBearerType bearerType; - switch (ipType) { - case LOC_APN_IP_IPV4: - bearerType = AGPS_APN_BEARER_IPV4; - break; - case LOC_APN_IP_IPV6: - bearerType = AGPS_APN_BEARER_IPV6; - break; - case LOC_APN_IP_IPV4V6: - bearerType = AGPS_APN_BEARER_IPV4V6; - break; - default: - bearerType = AGPS_APN_BEARER_IPV4; - break; - } - /* Set bearer and apn info in state machine instance */ sm->setBearer(bearerType); sm->setAPN(apnName, apnLen); @@ -909,19 +889,19 @@ void AgpsManager::handleModemSSR(){ LOC_LOGD("AgpsManager::handleModemSSR"); /* Drop subscribers from all state machines */ - if (mAgnssNif){ + if (mAgnssNif) { mAgnssNif->dropAllSubscribers(); } - if (mInternetNif){ + if (mInternetNif) { mInternetNif->dropAllSubscribers(); } - if(mDsNif){ + if (mDsNif) { mDsNif->dropAllSubscribers(); } // reinitialize DS client in SSR mode - if(loc_core::ContextBase::mGps_conf. - USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL){ + if (loc_core::ContextBase::mGps_conf. + USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL) { mDSClientStopDataCallFn(); mDSClientCloseDataCallFn(); @@ -930,39 +910,3 @@ void AgpsManager::handleModemSSR(){ mDSClientInitFn(true); } } - -AGpsBearerType AgpsUtils::ipTypeToBearerType(LocApnIpType ipType) { - - switch (ipType) { - - case LOC_APN_IP_IPV4: - return AGPS_APN_BEARER_IPV4; - - case LOC_APN_IP_IPV6: - return AGPS_APN_BEARER_IPV6; - - case LOC_APN_IP_IPV4V6: - return AGPS_APN_BEARER_IPV4V6; - - default: - return AGPS_APN_BEARER_IPV4; - } -} - -LocApnIpType AgpsUtils::bearerTypeToIpType(AGpsBearerType bearerType){ - - switch (bearerType) { - - case AGPS_APN_BEARER_IPV4: - return LOC_APN_IP_IPV4; - - case AGPS_APN_BEARER_IPV6: - return LOC_APN_IP_IPV6; - - case AGPS_APN_BEARER_IPV4V6: - return LOC_APN_IP_IPV4V6; - - default: - return LOC_APN_IP_IPV4; - } -} diff --git a/gps/gnss/Agps.h b/gps/gnss/Agps.h index d3fc362..2f89c8c 100644 --- a/gps/gnss/Agps.h +++ b/gps/gnss/Agps.h @@ -87,70 +87,6 @@ typedef enum { AGPS_NOTIFICATION_TYPE_FOR_ACTIVE_SUBSCRIBERS } AgpsNotificationType; -/* Framework AGNSS interface - * This interface is defined in IAGnssCallback provided by - * Android Framework. - * Must be kept in sync with that interface. */ -namespace AgpsFrameworkInterface { - - /** AGNSS type **/ - enum AGnssType : uint8_t { - TYPE_SUPL = 1, - TYPE_C2K = 2 - }; - - enum AGnssStatusValue : uint8_t { - /** GNSS requests data connection for AGNSS. */ - REQUEST_AGNSS_DATA_CONN = 1, - /** GNSS releases the AGNSS data connection. */ - RELEASE_AGNSS_DATA_CONN = 2, - /** AGNSS data connection initiated */ - AGNSS_DATA_CONNECTED = 3, - /** AGNSS data connection completed */ - AGNSS_DATA_CONN_DONE = 4, - /** AGNSS data connection failed */ - AGNSS_DATA_CONN_FAILED = 5 - }; - - /* - * Represents the status of AGNSS augmented to support IPv4. - */ - struct AGnssStatusIpV4 { - AGnssType type; - AGnssStatusValue status; - /* - * 32-bit IPv4 address. - */ - unsigned int ipV4Addr; - }; - - /* - * Represents the status of AGNSS augmented to support IPv6. - */ - struct AGnssStatusIpV6 { - AGnssType type; - AGnssStatusValue status; - /* - * 128-bit IPv6 address. - */ - unsigned char ipV6Addr[16]; - }; - - /* - * Callback with AGNSS(IpV4) status information. - * - * @param status Will be of type AGnssStatusIpV4. - */ - typedef void (*AgnssStatusIpV4Cb)(AGnssStatusIpV4 status); - - /* - * Callback with AGNSS(IpV6) status information. - * - * @param status Will be of type AGnssStatusIpV6. - */ - typedef void (*AgnssStatusIpV6Cb)(AGnssStatusIpV6 status); -} - /* Classes in this header */ class AgpsSubscriber; class AgpsManager; @@ -342,8 +278,7 @@ public: /* Register callbacks */ void registerCallbacks( - AgpsFrameworkInterface::AgnssStatusIpV4Cb - frameworkStatusV4Cb, + AgnssStatusIpV4Cb frameworkStatusV4Cb, AgpsAtlOpenStatusCb atlOpenStatusCb, AgpsAtlCloseStatusCb atlCloseStatusCb, @@ -382,9 +317,8 @@ public: void reportDataCallClosed(); /* Process incoming framework data call events */ - void reportAtlOpenSuccess( - AGpsExtType agpsType, char* apnName, int apnLen, - LocApnIpType ipType); + void reportAtlOpenSuccess(AGpsExtType agpsType, char* apnName, int apnLen, + AGpsBearerType bearerType); void reportAtlOpenFailed(AGpsExtType agpsType); void reportAtlClosed(AGpsExtType agpsType); @@ -392,7 +326,7 @@ public: void handleModemSSR(); protected: - AgpsFrameworkInterface::AgnssStatusIpV4Cb mFrameworkStatusV4Cb; + AgnssStatusIpV4Cb mFrameworkStatusV4Cb; AgpsAtlOpenStatusCb mAtlOpenStatusCb; AgpsAtlCloseStatusCb mAtlCloseStatusCb; diff --git a/gps/gnss/GnssAdapter.cpp b/gps/gnss/GnssAdapter.cpp index 7e638ad..cdda01d 100644 --- a/gps/gnss/GnssAdapter.cpp +++ b/gps/gnss/GnssAdapter.cpp @@ -44,12 +44,20 @@ #include <Agps.h> #include <SystemStatus.h> -#include <loc_nmea.h> #include <vector> -#include <string> + +#define RAD2DEG (180.0 / M_PI) using namespace loc_core; +/* Method to fetch status cb from loc_net_iface library */ +typedef AgpsCbInfo& (*LocAgpsGetAgpsCbInfo)(LocAgpsOpenResultCb openResultCb, + LocAgpsCloseResultCb closeResultCb, void* userDataPtr); + +static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* apn, + AGpsBearerType bearerType, void* userDataPtr); +static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr); + GnssAdapter::GnssAdapter() : LocAdapterBase(0, LocDualContext::getLocFgContext(NULL, @@ -66,12 +74,15 @@ GnssAdapter::GnssAdapter() : mNiData(), mAgpsManager(), mAgpsCbInfo(), - mSystemStatus(SystemStatus::getInstance(mMsgTask)) + mSystemStatus(SystemStatus::getInstance(mMsgTask)), + mServerUrl(""), + mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask) { LOC_LOGD("%s]: Constructor %p", __func__, this); mUlpPositionMode.mode = LOC_POSITION_MODE_INVALID; readConfigCommand(); setConfigCommand(); + initDefaultAgpsCommand(); } void @@ -601,6 +612,10 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) uint32_t* ids = NULL; if (count > 0) { ids = new uint32_t[count]; + if (ids == nullptr) { + LOC_LOGE("%s] new allocation failed, fatal error.", __func__); + return nullptr; + } for (size_t i=0; i < count; ++i) { ids[i] = generateSessionId(); IF_LOC_LOGD { @@ -634,12 +649,15 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) delete[] mIds; } inline virtual void proc() const { - //const size_t MAX_BITS_COUNT = 10; - //LocationError errs[MAX_BITS_COUNT] = {}; LocationError* errs = new LocationError[mCount]; LocationError err = LOCATION_ERROR_SUCCESS; uint32_t index = 0; + if (errs == nullptr) { + LOC_LOGE("%s] new allocation failed, fatal error.", __func__); + return; + } + if (mConfig.flags & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) { uint32_t newGpsLock = mAdapter.convertGpsLock(mConfig.gpsLock); ContextBase::mGps_conf.GPS_LOCK = newGpsLock; @@ -667,30 +685,33 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config) if (GNSS_ASSISTANCE_TYPE_SUPL == mConfig.assistanceServer.type) { if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) { char serverUrl[MAX_URL_LEN] = {}; - uint32_t length = 0; + int32_t length = 0; const char noHost[] = "NONE"; if (NULL == mConfig.assistanceServer.hostName || strncasecmp(noHost, mConfig.assistanceServer.hostName, sizeof(noHost)) == 0) { + err = LOCATION_ERROR_INVALID_PARAMETER; } else { length = snprintf(serverUrl, sizeof(serverUrl), "%s:%u", mConfig.assistanceServer.hostName, mConfig.assistanceServer.port); } - if (sizeof(serverUrl) > length) { + if (length > 0 && strncasecmp(mAdapter.getServerUrl().c_str(), + serverUrl, sizeof(serverUrl)) != 0) { + mAdapter.setServerUrl(serverUrl); err = mApi.setServer(serverUrl, length); - } else { - err = LOCATION_ERROR_INVALID_PARAMETER; } + } else { err = LOCATION_ERROR_SUCCESS; } } else if (GNSS_ASSISTANCE_TYPE_C2K == mConfig.assistanceServer.type) { if (ContextBase::mGps_conf.AGPS_CONFIG_INJECT) { struct in_addr addr; - if (!mAdapter.resolveInAddress(mConfig.assistanceServer.hostName, &addr)) { + if (!mAdapter.resolveInAddress(mConfig.assistanceServer.hostName, + &addr)) { LOC_LOGE("%s]: hostName %s cannot be resolved", __func__, mConfig.assistanceServer.hostName); err = LOCATION_ERROR_INVALID_PARAMETER; @@ -1244,6 +1265,15 @@ GnssAdapter::eraseTrackingSession(LocationAPI* client, uint32_t sessionId) } +bool GnssAdapter::setUlpPositionMode(const LocPosMode& mode) { + if (!mUlpPositionMode.equals(mode)) { + mUlpPositionMode = mode; + return true; + } else { + return false; + } +} + void GnssAdapter::reportResponse(LocationAPI* client, LocationError err, uint32_t sessionId) { @@ -1409,8 +1439,9 @@ GnssAdapter::setPositionModeCommand(LocPosMode& locPosMode) mLocPosMode(locPosMode) {} inline virtual void proc() const { // saves the mode in adapter to be used when startTrackingCommand is called from ULP - mAdapter.setUlpPositionMode(mLocPosMode); - mApi.setPositionMode(mLocPosMode); + if (mAdapter.setUlpPositionMode(mLocPosMode)) { + mApi.setPositionMode(mLocPosMode); + } } }; @@ -1433,8 +1464,10 @@ GnssAdapter::startTrackingCommand() inline virtual void proc() const { // we get this call from ULP, so just call LocApi without multiplexing because // ulp would be doing the multiplexing for us if it is present - LocPosMode& ulpPositionMode = mAdapter.getUlpPositionMode(); - mApi.startFix(ulpPositionMode); + if (!mAdapter.isInSession()) { + LocPosMode& ulpPositionMode = mAdapter.getUlpPositionMode(); + mApi.startFix(ulpPositionMode); + } } }; @@ -2109,6 +2142,10 @@ GnssAdapter::reportNmeaEvent(const char* nmea, size_t length, bool fromUlp) mAdapter(adapter), mNmea(new char[length+1]), mLength(length) { + if (mNmea == nullptr) { + LOC_LOGE("%s] new allocation failed, fatal error.", __func__); + return; + } strlcpy((char*)mNmea, nmea, length+1); } inline virtual ~MsgReportNmea() @@ -2370,6 +2407,57 @@ GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial) mUlpProxy->reportSvPolynomial(svPolynomial); } +void GnssAdapter::initDefaultAgps() { + LOC_LOGD("%s]: ", __func__); + + LocationCapabilitiesMask mask = getCapabilities(); + if (!(mask & LOCATION_CAPABILITIES_GNSS_MSB_BIT) && + !(mask & LOCATION_CAPABILITIES_GNSS_MSA_BIT)) { + LOC_LOGI("%s]: Target does not support MSB and MSA.", __func__); + return; + } + + void *handle = nullptr; + if ((handle = dlopen("libloc_net_iface.so", RTLD_NOW)) == nullptr) { + LOC_LOGE("%s]: libloc_net_iface.so not found !", __func__); + return; + } + + LocAgpsGetAgpsCbInfo getAgpsCbInfo = (LocAgpsGetAgpsCbInfo) + dlsym(handle, "LocNetIfaceAgps_getAgpsCbInfo"); + if (getAgpsCbInfo == nullptr) { + LOC_LOGE("%s]: Failed to get method LocNetIfaceAgps_getStatusCb", __func__); + return; + } + + AgpsCbInfo& cbInfo = getAgpsCbInfo(agpsOpenResultCb, agpsCloseResultCb, this); + + if (cbInfo.statusV4Cb == nullptr) { + LOC_LOGE("%s]: statusV4Cb is nullptr!", __func__); + return; + } + + initAgpsCommand(cbInfo); +} + +void GnssAdapter::initDefaultAgpsCommand() { + LOC_LOGD("%s]: ", __func__); + + struct MsgInitDefaultAgps : public LocMsg { + GnssAdapter& mAdapter; + inline MsgInitDefaultAgps(GnssAdapter& adapter) : + LocMsg(), + mAdapter(adapter) { + LOC_LOGV("MsgInitDefaultAgps"); + } + inline virtual void proc() const { + mAdapter.initDefaultAgps(); + } + }; + + sendMsg(new MsgInitDefaultAgps(*this)); +} + /* INIT LOC AGPS MANAGER */ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ @@ -2432,7 +2520,7 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ AgpsManager* mAgpsManager; - AgpsFrameworkInterface::AgnssStatusIpV4Cb mFrameworkStatusV4Cb; + AgnssStatusIpV4Cb mFrameworkStatusV4Cb; AgpsAtlOpenStatusCb mAtlOpenStatusCb; AgpsAtlCloseStatusCb mAtlCloseStatusCb; @@ -2447,7 +2535,7 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ GnssAdapter& mAdapter; inline AgpsMsgInit(AgpsManager* agpsManager, - AgpsFrameworkInterface::AgnssStatusIpV4Cb frameworkStatusV4Cb, + AgnssStatusIpV4Cb frameworkStatusV4Cb, AgpsAtlOpenStatusCb atlOpenStatusCb, AgpsAtlCloseStatusCb atlCloseStatusCb, AgpsDSClientInitFn dsClientInitFn, @@ -2499,7 +2587,7 @@ void GnssAdapter::initAgpsCommand(const AgpsCbInfo& cbInfo){ /* Send message to initialize AGPS Manager */ sendMsg(new AgpsMsgInit( &mAgpsManager, - (AgpsFrameworkInterface::AgnssStatusIpV4Cb)cbInfo.statusV4Cb, + (AgnssStatusIpV4Cb)cbInfo.statusV4Cb, atlOpenStatusCb, atlCloseStatusCb, dsClientInitFn, dsClientOpenAndStartDataCallFn, dsClientStopDataCallFn, dsClientCloseDataCallFn, @@ -2631,7 +2719,7 @@ bool GnssAdapter::reportDataCallClosed(){ void GnssAdapter::dataConnOpenCommand( AGpsExtType agpsType, - const char* apnName, int apnLen, LocApnIpType ipType){ + const char* apnName, int apnLen, AGpsBearerType bearerType){ LOC_LOGI("GnssAdapter::frameworkDataConnOpen"); @@ -2641,14 +2729,18 @@ void GnssAdapter::dataConnOpenCommand( AGpsExtType mAgpsType; char* mApnName; int mApnLen; - LocApnIpType mIpType; + AGpsBearerType mBearerType; inline AgpsMsgAtlOpenSuccess(AgpsManager* agpsManager, AGpsExtType agpsType, - const char* apnName, int apnLen, LocApnIpType ipType) : + const char* apnName, int apnLen, AGpsBearerType bearerType) : LocMsg(), mAgpsManager(agpsManager), mAgpsType(agpsType), mApnName( - new char[apnLen + 1]), mApnLen(apnLen), mIpType(ipType) { + new char[apnLen + 1]), mApnLen(apnLen), mBearerType(bearerType) { LOC_LOGV("AgpsMsgAtlOpenSuccess"); + if (mApnName == nullptr) { + LOC_LOGE("%s] new allocation failed, fatal error.", __func__); + return; + } memcpy(mApnName, apnName, apnLen); mApnName[apnLen] = 0; } @@ -2660,13 +2752,12 @@ void GnssAdapter::dataConnOpenCommand( inline virtual void proc() const { LOC_LOGV("AgpsMsgAtlOpenSuccess::proc()"); - mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen, - mIpType); + mAgpsManager->reportAtlOpenSuccess(mAgpsType, mApnName, mApnLen, mBearerType); } }; sendMsg( new AgpsMsgAtlOpenSuccess( - &mAgpsManager, (AGpsExtType)agpsType, apnName, apnLen, ipType)); + &mAgpsManager, agpsType, apnName, apnLen, bearerType)); } void GnssAdapter::dataConnClosedCommand(AGpsExtType agpsType){ @@ -2897,16 +2988,12 @@ bool GnssAdapter::getDebugReport(GnssDebugReport& r) } else if(!reports.mBestPosition.empty() && reports.mBestPosition.back().mValid) { r.mLocation.mValid = true; - r.mLocation.mLocation.latitude = - (double)(reports.mBestPosition.back().mBestLat); + r.mLocation.mLocation.latitude = + (double)(reports.mBestPosition.back().mBestLat) * RAD2DEG; r.mLocation.mLocation.longitude = - (double)(reports.mBestPosition.back().mBestLon); - r.mLocation.mLocation.altitude = - reports.mBestPosition.back().mBestAlt; - - r.mLocation.mLocation.timestamp = - reports.mBestPosition.back().mUtcReported.tv_sec * 1000ULL + - reports.mBestPosition.back().mUtcReported.tv_nsec / 1000000ULL; + (double)(reports.mBestPosition.back().mBestLon) * RAD2DEG; + r.mLocation.mLocation.altitude = reports.mBestPosition.back().mBestAlt; + r.mLocation.mUtcReported = reports.mBestPosition.back().mUtcReported; } else { r.mLocation.mValid = false; @@ -3009,3 +3096,36 @@ GnssAdapter::getAgcInformation(GnssMeasurementsNotification& measurements, int m } } +/* Callbacks registered with loc_net_iface library */ +static void agpsOpenResultCb (bool isSuccess, AGpsExtType agpsType, const char* apn, + AGpsBearerType bearerType, void* userDataPtr) { + LOC_LOGD("%s]: ", __func__); + if (userDataPtr == nullptr) { + LOC_LOGE("%s]: userDataPtr is nullptr.", __func__); + return; + } + if (apn == nullptr) { + LOC_LOGE("%s]: apn is nullptr.", __func__); + return; + } + GnssAdapter* adapter = (GnssAdapter*)userDataPtr; + if (isSuccess) { + adapter->dataConnOpenCommand(agpsType, apn, strlen(apn), bearerType); + } else { + adapter->dataConnFailedCommand(agpsType); + } +} + +static void agpsCloseResultCb (bool isSuccess, AGpsExtType agpsType, void* userDataPtr) { + LOC_LOGD("%s]: ", __func__); + if (userDataPtr == nullptr) { + LOC_LOGE("%s]: userDataPtr is nullptr.", __func__); + return; + } + GnssAdapter* adapter = (GnssAdapter*)userDataPtr; + if (isSuccess) { + adapter->dataConnClosedCommand(agpsType); + } else { + adapter->dataConnFailedCommand(agpsType); + } +} diff --git a/gps/gnss/GnssAdapter.h b/gps/gnss/GnssAdapter.h index 46ba34f..e7605f9 100644 --- a/gps/gnss/GnssAdapter.h +++ b/gps/gnss/GnssAdapter.h @@ -106,10 +106,11 @@ class GnssAdapter : public LocAdapterBase { // This must be initialized via initAgps() AgpsManager mAgpsManager; AgpsCbInfo mAgpsCbInfo; - XtraSystemStatusObserver mXtraObserver; /* === SystemStatus ===================================================================== */ SystemStatus* mSystemStatus; + std::string mServerUrl; + XtraSystemStatusObserver mXtraObserver; /*==== CONVERSION ===================================================================*/ static void convertOptions(LocPosMode& out, const LocationOptions& options); @@ -170,7 +171,7 @@ public: void saveTrackingSession(LocationAPI* client, uint32_t sessionId, const LocationOptions& options); void eraseTrackingSession(LocationAPI* client, uint32_t sessionId); - void setUlpPositionMode(const LocPosMode& mode) { mUlpPositionMode = mode; } + bool setUlpPositionMode(const LocPosMode& mode); LocPosMode& getUlpPositionMode() { return mUlpPositionMode; } LocationError startTrackingMultiplex(const LocationOptions& options); LocationError startTracking(const LocationOptions& options); @@ -198,10 +199,10 @@ public: uint32_t* gnssUpdateConfigCommand(GnssConfig config); uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data); + void initDefaultAgpsCommand(); void initAgpsCommand(const AgpsCbInfo& cbInfo); - void dataConnOpenCommand( - AGpsExtType agpsType, - const char* apnName, int apnLen, LocApnIpType ipType); + void dataConnOpenCommand(AGpsExtType agpsType, + const char* apnName, int apnLen, AGpsBearerType bearerType); void dataConnClosedCommand(AGpsExtType agpsType); void dataConnFailedCommand(AGpsExtType agpsType); @@ -215,6 +216,8 @@ public: void setPowerVoteId(uint32_t id) { mPowerVoteId = id; } uint32_t getPowerVoteId() { return mPowerVoteId; } bool resolveInAddress(const char* hostAddress, struct in_addr* inAddress); + virtual bool isInSession() { return !mTrackingSessions.empty(); } + void initDefaultAgps(); /* ==== REPORTS ======================================================================== */ /* ======== EVENTS ====(Called from QMI/ULP Thread)===================================== */ @@ -254,6 +257,8 @@ public: /*==== SYSTEM STATUS ================================================================*/ inline SystemStatus* getSystemStatus(void) { return mSystemStatus; } + std::string& getServerUrl(void) { return mServerUrl; } + void setServerUrl(const char* server) { mServerUrl.assign(server); } /*==== CONVERSION ===================================================================*/ static uint32_t convertGpsLock(const GnssConfigGpsLock gpsLock); @@ -277,10 +282,6 @@ public: void injectLocationCommand(double latitude, double longitude, float accuracy); void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty); - inline void updateConnectionStatusCommand(bool connected, uint8_t type) { - mXtraObserver.updateConnectionStatus(connected, type); - } - }; #endif //GNSS_ADAPTER_H diff --git a/gps/gnss/XtraSystemStatusObserver.cpp b/gps/gnss/XtraSystemStatusObserver.cpp index 58a8522..ce08f64 100644 --- a/gps/gnss/XtraSystemStatusObserver.cpp +++ b/gps/gnss/XtraSystemStatusObserver.cpp @@ -45,40 +45,55 @@ #include <sstream> #include <XtraSystemStatusObserver.h> #include <LocAdapterBase.h> +#include <DataItemId.h> +#include <DataItemsFactoryProxy.h> -using namespace std; using namespace loc_core; #define XTRA_HAL_SOCKET_NAME "/data/vendor/location/xtra/socket_hal_xtra" bool XtraSystemStatusObserver::updateLockStatus(uint32_t lock) { - std::stringstream ss; + stringstream ss; ss << "gpslock"; ss << " " << lock; ss << "\n"; // append seperator return ( sendEvent(ss) ); } -bool XtraSystemStatusObserver::updateConnectionStatus(bool connected, uint8_t type) { - std::stringstream ss; +bool XtraSystemStatusObserver::updateConnectionStatus(bool connected, uint32_t type) { + stringstream ss; ss << "connection"; ss << " " << (connected ? "1" : "0"); ss << " " << (int)type; ss << "\n"; // append seperator return ( sendEvent(ss) ); } +bool XtraSystemStatusObserver::updateTac(const string& tac) { + stringstream ss; + ss << "tac"; + ss << " " << tac.c_str(); + ss << "\n"; // append seperator + return ( sendEvent(ss) ); +} + +bool XtraSystemStatusObserver::updateMccMnc(const string& mccmnc) { + stringstream ss; + ss << "mncmcc"; + ss << " " << mccmnc.c_str(); + ss << "\n"; // append seperator + return ( sendEvent(ss) ); +} -bool XtraSystemStatusObserver::sendEvent(std::stringstream& event) { +bool XtraSystemStatusObserver::sendEvent(const stringstream& event) { int socketFd = createSocket(); if (socketFd < 0) { LOC_LOGe("XTRA unreachable. sending failed."); return false; } - const std::string& data = event.str(); + const string& data = event.str(); int remain = data.length(); ssize_t sent = 0; - while (remain > 0 && (sent = ::send(socketFd, data.c_str() + (data.length() - remain), remain, MSG_NOSIGNAL)) > 0) { @@ -125,3 +140,95 @@ void XtraSystemStatusObserver::closeSocket(const int socketFd) { } } } + +void XtraSystemStatusObserver::subscribe(bool yes) +{ + // Subscription data list + list<DataItemId> subItemIdList; + subItemIdList.push_back(NETWORKINFO_DATA_ITEM_ID); + subItemIdList.push_back(MCCMNC_DATA_ITEM_ID); + + if (yes) { + mSystemStatusObsrvr->subscribe(subItemIdList, this); + + list<DataItemId> reqItemIdList; + reqItemIdList.push_back(TAC_DATA_ITEM_ID); + + mSystemStatusObsrvr->requestData(reqItemIdList, this); + + } else { + mSystemStatusObsrvr->unsubscribe(subItemIdList, this); + } +} + +// IDataItemObserver overrides +void XtraSystemStatusObserver::getName(string& name) +{ + name = "XtraSystemStatusObserver"; +} + +void XtraSystemStatusObserver::notify(const list<IDataItemCore*>& dlist) +{ + struct handleOsObserverUpdateMsg : public LocMsg { + XtraSystemStatusObserver* mXtraSysStatObj; + list <IDataItemCore*> mDataItemList; + + inline handleOsObserverUpdateMsg(XtraSystemStatusObserver* xtraSysStatObs, + const list<IDataItemCore*>& dataItemList) : + mXtraSysStatObj(xtraSysStatObs) { + for (auto eachItem : dataItemList) { + IDataItemCore* dataitem = DataItemsFactoryProxy::createNewDataItem( + eachItem->getId()); + if (NULL == dataitem) { + break; + } + // Copy the contents of the data item + dataitem->copy(eachItem); + + mDataItemList.push_back(dataitem); + } + } + + inline ~handleOsObserverUpdateMsg() { + for (auto each : mDataItemList) { + delete each; + } + } + + inline void proc() const { + for (auto each : mDataItemList) { + switch (each->getId()) + { + case NETWORKINFO_DATA_ITEM_ID: + { + SystemStatusNetworkInfo* networkInfo = + reinterpret_cast<SystemStatusNetworkInfo*>(each); + mXtraSysStatObj->updateConnectionStatus(networkInfo->mConnected, + networkInfo->mType); + } + break; + + case TAC_DATA_ITEM_ID: + { + SystemStatusTac* tac = reinterpret_cast<SystemStatusTac*>(each); + mXtraSysStatObj->updateTac(tac->mValue); + } + break; + + case MCCMNC_DATA_ITEM_ID: + { + SystemStatusMccMnc* mccmnc = reinterpret_cast<SystemStatusMccMnc*>(each); + mXtraSysStatObj->updateMccMnc(mccmnc->mValue); + } + break; + + default: + break; + } + } + } + }; + mMsgTask->sendMsg(new (nothrow) handleOsObserverUpdateMsg(this, dlist)); +} + + diff --git a/gps/gnss/XtraSystemStatusObserver.h b/gps/gnss/XtraSystemStatusObserver.h index e49f17b..42f49b5 100644 --- a/gps/gnss/XtraSystemStatusObserver.h +++ b/gps/gnss/XtraSystemStatusObserver.h @@ -29,25 +29,42 @@ #ifndef XTRA_SYSTEM_STATUS_OBS_H #define XTRA_SYSTEM_STATUS_OBS_H -#include <stdint.h> +#include <cinttypes> +#include <MsgTask.h> +using namespace std; +using loc_core::IOsObserver; +using loc_core::IDataItemObserver; +using loc_core::IDataItemCore; -class XtraSystemStatusObserver { + +class XtraSystemStatusObserver : public IDataItemObserver { public : // constructor & destructor - XtraSystemStatusObserver() { + inline XtraSystemStatusObserver(IOsObserver* sysStatObs, const MsgTask* msgTask): + mSystemStatusObsrvr(sysStatObs), mMsgTask(msgTask) { + subscribe(true); } + inline XtraSystemStatusObserver() {}; + inline virtual ~XtraSystemStatusObserver() { subscribe(false); } - virtual ~XtraSystemStatusObserver() { - } + // IDataItemObserver overrides + inline virtual void getName(string& name); + virtual void notify(const list<IDataItemCore*>& dlist); bool updateLockStatus(uint32_t lock); - bool updateConnectionStatus(bool connected, uint8_t type); + bool updateConnectionStatus(bool connected, uint32_t type); + bool updateTac(const string& tac); + bool updateMccMnc(const string& mccmnc); + inline const MsgTask* getMsgTask() { return mMsgTask; } + void subscribe(bool yes); private: int createSocket(); void closeSocket(const int32_t socketFd); - bool sendEvent(std::stringstream& event); + bool sendEvent(const stringstream& event); + IOsObserver* mSystemStatusObsrvr; + const MsgTask* mMsgTask; }; diff --git a/gps/gnss/location_gnss.cpp b/gps/gnss/location_gnss.cpp index a99d8ef..b5623e1 100644 --- a/gps/gnss/location_gnss.cpp +++ b/gps/gnss/location_gnss.cpp @@ -228,7 +228,7 @@ static void agpsDataConnOpen( if (NULL != gGnssAdapter) { gGnssAdapter->dataConnOpenCommand( - agpsType, apnName, apnLen, ipType); + agpsType, apnName, apnLen, (AGpsBearerType)ipType); } } static void agpsDataConnClosed(AGpsExtType agpsType) { @@ -253,6 +253,6 @@ static void getDebugReport(GnssDebugReport& report) { static void updateConnectionStatus(bool connected, uint8_t type) { if (NULL != gGnssAdapter) { - gGnssAdapter->updateConnectionStatusCommand(connected, type); + gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type); } -}
\ No newline at end of file +} diff --git a/gps/gnsspps/Android.mk b/gps/gnsspps/Android.mk new file mode 100644 index 0000000..f87b674 --- /dev/null +++ b/gps/gnsspps/Android.mk @@ -0,0 +1,36 @@ +ifneq ($(BOARD_VENDOR_QCOM_GPS_LOC_API_HARDWARE),) +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := libgnsspps +LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib +LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64 +LOCAL_MODULE_TAGS := optional + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libcutils \ + libgps.utils \ + liblog + +LOCAL_SRC_FILES += \ + gnsspps.c + +LOCAL_CFLAGS += \ + -fno-short-enums \ + -D_ANDROID_ + +## Includes +LOCAL_HEADER_LIBRARIES := \ + libgps.utils_headers \ + libloc_pla_headers +LOCAL_CFLAGS += $(GNSS_CFLAGS) +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_MODULE := libgnsspps_headers +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) +include $(BUILD_HEADER_LIBRARY) + +endif diff --git a/gps/gnsspps/Makefile.am b/gps/gnsspps/Makefile.am new file mode 100644 index 0000000..390c1cc --- /dev/null +++ b/gps/gnsspps/Makefile.am @@ -0,0 +1,36 @@ +AM_CFLAGS = \ + $(LOCPLA_CFLAGS) \ + $(GPSUTILS_CFLAGS) \ + -I./ + +ACLOCAL_AMFLAGS = -I m4 + +libgnsspps_la_SOURCES = \ + gnsspps.c + +if USE_GLIB +libgnsspps_la_CFLAGS = -DUSE_GLIB $(AM_CFLAGS) @GLIB_CFLAGS@ +libgnsspps_la_LDFLAGS = -lstdc++ -Wl,-z,defs -lpthread @GLIB_LIBS@ -shared -version-info 1:0:0 +libgnsspps_la_CPPFLAGS = -DUSE_GLIB $(AM_CFLAGS) $(AM_CPPFLAGS) @GLIB_CFLAGS@ +else +libgnsspps_la_CFLAGS = $(AM_CFLAGS) +libgnsspps_la_LDFLAGS = -Wl,-z,defs -lpthread -shared -version-info 1:0:0 +libgnsspps_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) +endif + +libgnsspps_la_LIBADD = -lstdc++ $(GPSUTILS_LIBS) + +library_include_HEADERS = \ + gnsspps.h + +#Create and Install libraries +lib_LTLIBRARIES = libgnsspps.la + +library_includedir = $(pkgincludedir) +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = gnsspps.pc +EXTRA_DIST = $(pkgconfig_DATA) + + + + diff --git a/gps/gnsspps/configure.ac b/gps/gnsspps/configure.ac new file mode 100644 index 0000000..b0ffa77 --- /dev/null +++ b/gps/gnsspps/configure.ac @@ -0,0 +1,64 @@ +# configure.ac -- Autoconf script for gps lbs-core +# +# Process this file with autoconf to produce a configure script + +# Requires autoconf tool later than 2.61 +AC_PREREQ(2.61) +# Initialize the gps lbs-core package version 1.0.0 +AC_INIT([gnsspps],1.0.0) +# Does not strictly follow GNU Coding standards +AM_INIT_AUTOMAKE([foreign]) +# Disables auto rebuilding of configure, Makefile.ins +AM_MAINTAINER_MODE +# Verifies the --srcdir is correct by checking for the path +AC_CONFIG_SRCDIR([Makefile.am]) +# defines some macros variable to be included by source +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# Checks for programs. +AC_PROG_LIBTOOL +AC_PROG_CXX +AC_PROG_CC +AM_PROG_CC_C_O +AC_PROG_AWK +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +PKG_PROG_PKG_CONFIG + +# Checks for libraries. +PKG_CHECK_MODULES([LOCPLA], [loc-pla]) +AC_SUBST([LOCPLA_CFLAGS]) +AC_SUBST([LOCPLA_LIBS]) + +PKG_CHECK_MODULES([GPSUTILS], [gps-utils]) +AC_SUBST([GPSUTILS_CFLAGS]) +AC_SUBST([GPSUTILS_LIBS]) + +AC_ARG_WITH([glib], + AC_HELP_STRING([--with-glib], + [enable glib, building HLOS systems which use glib])) + +if (test "x${with_glib}" = "xyes"); then + AC_DEFINE(ENABLE_USEGLIB, 1, [Define if HLOS systems uses glib]) + PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GThread >= 2.16 is required)) + PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes, + AC_MSG_ERROR(GLib >= 2.16 is required)) + GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS" + GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS" + + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) +fi + +AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes") + +AC_CONFIG_FILES([ \ + Makefile \ + gnsspps.pc + ]) + +AC_OUTPUT diff --git a/gps/gnsspps/gnsspps.c b/gps/gnsspps/gnsspps.c new file mode 100644 index 0000000..f92a862 --- /dev/null +++ b/gps/gnsspps/gnsspps.c @@ -0,0 +1,194 @@ +/* Copyright (c) 2011-2015, 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 Foundatoin, 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. + */ +#include <platform_lib_log_util.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <pthread.h> +#include <timepps.h> +#include <linux/types.h> + +//DRsync kernel timestamp +static struct timespec drsyncKernelTs = {0,0}; +//DRsync userspace timestamp +static struct timespec drsyncUserTs = {0,0}; +//flag to stop fetching timestamp +static int isActive = 0; +static pps_handle handle; + +static pthread_mutex_t ts_lock; + + /* checks the PPS source and opens it */ +int check_device(char *path, pps_handle *handle) +{ + int ret; + + /* Try to find the source by using the supplied "path" name */ + ret = open(path, O_RDWR); + if (ret < 0) + { + LOC_LOGV("%s:%d unable to open device %s", __func__, __LINE__, path); + return ret; + } + + /* Open the PPS source */ + ret = pps_create(ret, handle); + if (ret < 0) + { + LOC_LOGV( "%s:%d cannot create a PPS source from device %s", __func__, __LINE__, path); + return -1; + } + return 0; +} + +/* fetches the timestamp from the PPS source */ +int read_pps(pps_handle *handle) +{ + struct timespec timeout; + pps_info infobuf; + int ret; + // 3sec timeout + timeout.tv_sec = 3; + timeout.tv_nsec = 0; + + ret = pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,&timeout); + + if (ret < 0 && ret !=-EINTR) + { + LOC_LOGV("%s:%d pps_fetch() error %d", __func__, __LINE__, ret); + return -1; + } + + pthread_mutex_lock(&ts_lock); + drsyncKernelTs.tv_sec = infobuf.tv_sec; + drsyncKernelTs.tv_nsec = infobuf.tv_nsec; + ret = clock_gettime(CLOCK_BOOTTIME,&drsyncUserTs); + pthread_mutex_unlock(&ts_lock); + + if(ret != 0) + { + LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__); + } + return 0; +} + +#ifdef __cplusplus +extern "C" { +#endif +/* infinitely calls read_pps() */ +void *thread_handle(void *input) +{ + int ret; + if(input != NULL) + { + LOC_LOGV("%s:%d Thread Input is present", __func__, __LINE__); + } + while(isActive) + { + ret = read_pps(&handle); + + if (ret == -1 && errno != ETIMEDOUT ) + { + LOC_LOGV("%s:%d Could not fetch PPS source", __func__, __LINE__); + } + } + return NULL; +} + +/* opens the device and fetches from PPS source */ +int initPPS(char *devname) +{ + int ret,pid; + pthread_t thread; + isActive = 1; + + ret = check_device(devname, &handle); + if (ret < 0) + { + LOC_LOGV("%s:%d Could not find PPS source", __func__, __LINE__); + return 0; + } + + pthread_mutex_init(&ts_lock,NULL); + + pid = pthread_create(&thread,NULL,&thread_handle,NULL); + if(pid != 0) + { + LOC_LOGV("%s:%d Could not create thread in InitPPS", __func__, __LINE__); + return 0; + } + return 1; +} + +/* stops fetching and closes the device */ +void deInitPPS() +{ + pthread_mutex_lock(&ts_lock); + isActive = 0; + pthread_mutex_unlock(&ts_lock); + + pthread_mutex_destroy(&ts_lock); + pps_destroy(handle); +} + +/* retrieves DRsync kernel timestamp,DRsync userspace timestamp + and updates current timestamp */ +/* Returns: + * 1. @Param out DRsync kernel timestamp + * 2. @Param out DRsync userspace timestamp + * 3. @Param out current timestamp + */ +int getPPS(struct timespec *fineKernelTs ,struct timespec *currentTs, + struct timespec *fineUserTs) +{ + int ret; + + pthread_mutex_lock(&ts_lock); + fineKernelTs->tv_sec = drsyncKernelTs.tv_sec; + fineKernelTs->tv_nsec = drsyncKernelTs.tv_nsec; + + fineUserTs->tv_sec = drsyncUserTs.tv_sec; + fineUserTs->tv_nsec = drsyncUserTs.tv_nsec; + + ret = clock_gettime(CLOCK_BOOTTIME,currentTs); + pthread_mutex_unlock(&ts_lock); + if(ret != 0) + { + LOC_LOGV("%s:%d clock_gettime() error",__func__,__LINE__); + return 0; + } + return 1; +} + +#ifdef __cplusplus +} +#endif + diff --git a/gps/gnsspps/gnsspps.h b/gps/gnsspps/gnsspps.h new file mode 100644 index 0000000..3642f3b --- /dev/null +++ b/gps/gnsspps/gnsspps.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2011-2015, 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 Foundatoin, 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. + */ +#ifndef _GNSSPPS_H +#define _GNSSPPS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* opens the device and fetches from PPS source */ +int initPPS(char *devname); +/* updates the fine time stamp */ +int getPPS(struct timespec *current_ts, struct timespec *current_boottime, struct timespec *last_boottime); +/* stops fetching and closes the device */ +void deInitPPS(); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/gps/gnsspps/gnsspps.pc.in b/gps/gnsspps/gnsspps.pc.in new file mode 100644 index 0000000..604eedd --- /dev/null +++ b/gps/gnsspps/gnsspps.pc.in @@ -0,0 +1,10 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: gnsspps +Description: QTI GPS drplugin-client +Version: @VERSION +Libs: -L${libdir} -lgnsspps +Cflags: -I${includedir}/gnsspps diff --git a/gps/gnsspps/timepps.h b/gps/gnsspps/timepps.h new file mode 100644 index 0000000..fe0d8f0 --- /dev/null +++ b/gps/gnsspps/timepps.h @@ -0,0 +1,106 @@ +/* Copyright (c) 2011-2015, 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 Foundatoin, 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. + */ +#include <errno.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <linux/types.h> +#include <linux/pps.h> + +#ifndef _TIMEPPS_H +#define _TIMEPPS_H + +#ifdef __cplusplus +extern "C" { +#endif +/* time of assert event */ +typedef struct timespec pps_info; +/* represents pps source */ +typedef int pps_handle; + + /* Open the PPS source */ +static __inline int pps_create(int source, pps_handle *handle) +{ + int ret; + struct pps_kparams dummy; + + if (!handle) + { + errno = EINVAL; + return -1; + } + /* check if current device is valid pps */ + ret = ioctl(source, PPS_GETPARAMS, &dummy); + if (ret) + { + errno = EOPNOTSUPP; + return -1; + } + *handle = source; + + return 0; +} +/* close the pps source */ +static __inline int pps_destroy(pps_handle handle) +{ + return close(handle); +} +/*reads timestamp from pps device*/ +static __inline int pps_fetch(pps_handle handle, const int tsformat, + pps_info *ppsinfobuf, + const struct timespec *timeout) +{ + struct pps_fdata fdata; + int ret; + + if (tsformat != PPS_TSFMT_TSPEC) + { + errno = EINVAL; + return -1; + } + if (timeout) + { + fdata.timeout.sec = timeout->tv_sec; + fdata.timeout.nsec = timeout->tv_nsec; + fdata.timeout.flags = ~PPS_TIME_INVALID; + } + else + { + fdata.timeout.flags = PPS_TIME_INVALID; + } + ret = ioctl(handle, PPS_FETCH, &fdata); + + ppsinfobuf->tv_sec = fdata.info.assert_tu.sec; + ppsinfobuf->tv_nsec = fdata.info.assert_tu.nsec; + + return ret; +} + +#ifdef __cplusplus +} +#endif +#endif diff --git a/gps/location/location_interface.h b/gps/location/location_interface.h index 9a71fff..33ec29e 100644 --- a/gps/location/location_interface.h +++ b/gps/location/location_interface.h @@ -51,9 +51,9 @@ struct GnssInterface { void (*injectLocation)(double latitude, double longitude, float accuracy); void (*injectTime)(int64_t time, int64_t timeReference, int32_t uncertainty); void (*agpsInit)(const AgpsCbInfo& cbInfo); - void (*agpsDataConnOpen)(short agpsType, const char* apnName, int apnLen, int ipType); - void (*agpsDataConnClosed)(short agpsType); - void (*agpsDataConnFailed)(short agpsType); + void (*agpsDataConnOpen)(AGpsExtType agpsType, const char* apnName, int apnLen, int ipType); + void (*agpsDataConnClosed)(AGpsExtType agpsType); + void (*agpsDataConnFailed)(AGpsExtType agpsType); void (*getDebugReport)(GnssDebugReport& report); void (*updateConnectionStatus)(bool connected, uint8_t type); }; diff --git a/gps/utils/gps_extended_c.h b/gps/utils/gps_extended_c.h index a6a8d5d..f87a942 100644 --- a/gps/utils/gps_extended_c.h +++ b/gps/utils/gps_extended_c.h @@ -143,7 +143,7 @@ typedef struct { /** AGPS type */ -typedef int16_t AGpsExtType; +typedef int8_t AGpsExtType; #define LOC_AGPS_TYPE_INVALID -1 #define LOC_AGPS_TYPE_ANY 0 #define LOC_AGPS_TYPE_SUPL 1 @@ -156,10 +156,10 @@ typedef int16_t AGpsExtType; #define SSID_BUF_SIZE (32+1) typedef int16_t AGpsBearerType; -#define AGPS_APN_BEARER_INVALID -1 -#define AGPS_APN_BEARER_IPV4 0 -#define AGPS_APN_BEARER_IPV6 1 -#define AGPS_APN_BEARER_IPV4V6 2 +#define AGPS_APN_BEARER_INVALID 0 +#define AGPS_APN_BEARER_IPV4 1 +#define AGPS_APN_BEARER_IPV6 2 +#define AGPS_APN_BEARER_IPV4V6 3 typedef enum { AGPS_CB_PRIORITY_LOW = 1, @@ -1238,6 +1238,50 @@ typedef struct Gnss_Srn_MacAddr_Type macAddrType; /* SRN AP MAC Address type */ } GnssSrnDataReq; +/* + * Represents the status of AGNSS augmented to support IPv4. + */ +struct AGnssExtStatusIpV4 { + AGpsExtType type; + LocAGpsStatusValue status; + /* + * 32-bit IPv4 address. + */ + uint32_t ipV4Addr; +}; + +/* + * Represents the status of AGNSS augmented to support IPv6. + */ +struct AGnssExtStatusIpV6 { + AGpsExtType type; + LocAGpsStatusValue status; + /* + * 128-bit IPv6 address. + */ + uint8_t ipV6Addr[16]; +}; + +/* + * Callback with AGNSS(IpV4) status information. + * + * @param status Will be of type AGnssExtStatusIpV4. + */ +typedef void (*AgnssStatusIpV4Cb)(AGnssExtStatusIpV4 status); + +/* + * Callback with AGNSS(IpV6) status information. + * + * @param status Will be of type AGnssExtStatusIpV6. + */ +typedef void (*AgnssStatusIpV6Cb)(AGnssExtStatusIpV6 status); + +/* Constructs for interaction with loc_net_iface library */ +typedef void (*LocAgpsOpenResultCb)(bool isSuccess, AGpsExtType agpsType, const char* apn, + AGpsBearerType bearerType, void* userDataPtr); + +typedef void (*LocAgpsCloseResultCb)(bool isSuccess, AGpsExtType agpsType, void* userDataPtr); + #ifdef __cplusplus } diff --git a/gps/utils/loc_gps.h b/gps/utils/loc_gps.h index 77ebe54..5e915a3 100644 --- a/gps/utils/loc_gps.h +++ b/gps/utils/loc_gps.h @@ -208,7 +208,7 @@ typedef int LocGpsNiEncodingType; #define LOC_GPS_ENC_UNKNOWN -1 /** AGPS status event values. */ -typedef uint16_t LocAGpsStatusValue; +typedef uint8_t LocAGpsStatusValue; /** GPS requests data connection for AGPS. */ #define LOC_GPS_REQUEST_AGPS_DATA_CONN 1 /** GPS releases the AGPS data connection. */ |