From 98edc19bea3cf5787e5af903c8408dede420be58 Mon Sep 17 00:00:00 2001 From: Saurabh Srivastava Date: Sun, 8 Apr 2018 23:35:14 +0530 Subject: [PATCH] FR 48850 - Device based hybrid ODCPI Adding support for sending ODCPI request to framework via IGnss interface. Change-Id: I97ab4f00505705fedc266998602499fd344baf31 CRs-Fixed: 2217664 --- android/Gnss.cpp | 37 +++++++++- android/Gnss.h | 4 + android/location_api/LocationUtil.cpp | 83 ++++++++++++++++----- android/location_api/LocationUtil.h | 1 + core/LocAdapterBase.cpp | 4 + core/LocAdapterBase.h | 1 + core/LocApiBase.cpp | 9 +++ core/LocApiBase.h | 3 + gnss/GnssAdapter.cpp | 102 ++++++++++++++++++++++++++ gnss/GnssAdapter.h | 19 ++++- gnss/location_gnss.cpp | 20 +++++ location/location_interface.h | 2 + utils/gps_extended_c.h | 14 ++++ 13 files changed, 280 insertions(+), 19 deletions(-) diff --git a/android/Gnss.cpp b/android/Gnss.cpp index 36598236..5cec786a 100644 --- a/android/Gnss.cpp +++ b/android/Gnss.cpp @@ -25,6 +25,8 @@ #include #include #include "Gnss.h" +#include + typedef void* (getLocationInterface)(); #define IMAGES_INFO_FILE "/sys/devices/soc0/images" @@ -372,6 +374,14 @@ Return> Gnss::getExtensionAGnssRil() { Return Gnss::setCallback_1_1(const sp& callback) { ENTRY_LOG_CALLFLOW(); callback->gnssNameCb(getVersionString()); + mGnssCbIface_1_1 = callback; + GnssInterface* gnssInterface = getGnssInterface(); + if (nullptr != gnssInterface) { + OdcpiRequestCallback cb = [this](const OdcpiRequestInfo& odcpiRequest) { + odcpiRequestCb(odcpiRequest); + }; + gnssInterface->odcpiInit(cb); + } return setCallback(callback); } @@ -407,11 +417,36 @@ Return> Gnss::getExtensionGnssConfiguration_1_1() { return mGnssConfig; } -Return Gnss::injectBestLocation(const GnssLocation&) { +Return Gnss::injectBestLocation(const GnssLocation& gnssLocation) { ENTRY_LOG_CALLFLOW(); + GnssInterface* gnssInterface = getGnssInterface(); + if (nullptr != gnssInterface) { + Location location = {}; + convertGnssLocation(gnssLocation, location); + gnssInterface->odcpiInject(location); + } return true; } +void Gnss::odcpiRequestCb(const OdcpiRequestInfo& request) { + ENTRY_LOG_CALLFLOW(); + if (mGnssCbIface_1_1 != nullptr) { + // For emergency mode, request DBH (Device based hybrid) location + // Mark Independent from GNSS flag to false. + if (ODCPI_REQUEST_TYPE_START == request.type) { + if (request.isEmergencyMode) { + mGnssCbIface_1_1->gnssRequestLocationCb(false); + } else { + mGnssCbIface_1_1->gnssRequestLocationCb(true); + } + } else { + LOC_LOGv("Unsupported ODCPI request type: %d", request.type); + } + } else { + LOC_LOGe("ODCPI request not supported."); + } +} + IGnss* HIDL_FETCH_IGnss(const char* hal) { ENTRY_LOG_CALLFLOW(); IGnss* iface = nullptr; diff --git a/android/Gnss.h b/android/Gnss.h index c562b1fb..4c0c8b05 100644 --- a/android/Gnss.h +++ b/android/Gnss.h @@ -111,6 +111,9 @@ struct Gnss : public IGnss { Return updateConfiguration(GnssConfig& gnssConfig); GnssInterface* getGnssInterface(); + // Callback for ODCPI request + void odcpiRequestCb(const OdcpiRequestInfo& request); + private: struct GnssDeathRecipient : hidl_death_recipient { GnssDeathRecipient(sp gnss) : mGnss(gnss) { @@ -134,6 +137,7 @@ struct Gnss : public IGnss { GnssAPIClient* mApi = nullptr; sp mGnssCbIface = nullptr; + sp mGnssCbIface_1_1 = nullptr; sp mGnssNiCbIface = nullptr; GnssConfig mPendingConfig; GnssInterface* mGnssInterface = nullptr; diff --git a/android/location_api/LocationUtil.cpp b/android/location_api/LocationUtil.cpp index 7f3a74bc..f1d051c1 100644 --- a/android/location_api/LocationUtil.cpp +++ b/android/location_api/LocationUtil.cpp @@ -42,34 +42,83 @@ using ::android::hardware::gnss::V1_0::GnssLocationFlags; void convertGnssLocation(Location& in, GnssLocation& out) { memset(&out, 0, sizeof(GnssLocation)); - if (in.flags & LOCATION_HAS_LAT_LONG_BIT) + if (in.flags & LOCATION_HAS_LAT_LONG_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_LAT_LONG; - if (in.flags & LOCATION_HAS_ALTITUDE_BIT) + out.latitudeDegrees = in.latitude; + out.longitudeDegrees = in.longitude; + } + if (in.flags & LOCATION_HAS_ALTITUDE_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_ALTITUDE; - if (in.flags & LOCATION_HAS_SPEED_BIT) + out.altitudeMeters = in.altitude; + } + if (in.flags & LOCATION_HAS_SPEED_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED; - if (in.flags & LOCATION_HAS_BEARING_BIT) + out.speedMetersPerSec = in.speed; + } + if (in.flags & LOCATION_HAS_BEARING_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING; - if (in.flags & LOCATION_HAS_ACCURACY_BIT) + out.bearingDegrees = in.bearing; + } + if (in.flags & LOCATION_HAS_ACCURACY_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_HORIZONTAL_ACCURACY; - if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) + out.horizontalAccuracyMeters = in.accuracy; + } + if (in.flags & LOCATION_HAS_VERTICAL_ACCURACY_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_VERTICAL_ACCURACY; - if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) + out.verticalAccuracyMeters = in.verticalAccuracy; + } + if (in.flags & LOCATION_HAS_SPEED_ACCURACY_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_SPEED_ACCURACY; - if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) + out.speedAccuracyMetersPerSecond = in.speedAccuracy; + } + if (in.flags & LOCATION_HAS_BEARING_ACCURACY_BIT) { out.gnssLocationFlags |= GnssLocationFlags::HAS_BEARING_ACCURACY; - out.latitudeDegrees = in.latitude; - out.longitudeDegrees = in.longitude; - out.altitudeMeters = in.altitude; - out.speedMetersPerSec = in.speed; - out.bearingDegrees = in.bearing; - out.horizontalAccuracyMeters = in.accuracy; - out.verticalAccuracyMeters = in.verticalAccuracy; - out.speedAccuracyMetersPerSecond = in.speedAccuracy; - out.bearingAccuracyDegrees = in.bearingAccuracy; + out.bearingAccuracyDegrees = in.bearingAccuracy; + } + out.timestamp = static_cast(in.timestamp); } +void convertGnssLocation(const GnssLocation& in, Location& out) +{ + memset(&out, 0, sizeof(out)); + if (in.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG) { + out.flags |= LOCATION_HAS_LAT_LONG_BIT; + out.latitude = in.latitudeDegrees; + out.longitude = in.longitudeDegrees; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE) { + out.flags |= LOCATION_HAS_ALTITUDE_BIT; + out.altitude = in.altitudeMeters; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED) { + out.flags |= LOCATION_HAS_SPEED_BIT; + out.speed = in.speedMetersPerSec; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) { + out.flags |= LOCATION_HAS_BEARING_BIT; + out.bearing = in.bearingDegrees; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_HORIZONTAL_ACCURACY) { + out.flags |= LOCATION_HAS_ACCURACY_BIT; + out.accuracy = in.horizontalAccuracyMeters; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_VERTICAL_ACCURACY) { + out.flags |= LOCATION_HAS_VERTICAL_ACCURACY_BIT; + out.verticalAccuracy = in.verticalAccuracyMeters; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_SPEED_ACCURACY) { + out.flags |= LOCATION_HAS_SPEED_ACCURACY_BIT; + out.speedAccuracy = in.speedAccuracyMetersPerSecond; + } + if (in.gnssLocationFlags & GnssLocationFlags::HAS_BEARING_ACCURACY) { + out.flags |= LOCATION_HAS_BEARING_ACCURACY_BIT; + out.bearingAccuracy = in.bearingAccuracyDegrees; + } + + out.timestamp = static_cast(in.timestamp); +} + void convertGnssConstellationType(GnssSvType& in, GnssConstellationType& out) { switch(in) { diff --git a/android/location_api/LocationUtil.h b/android/location_api/LocationUtil.h index acc0eabc..63f4f6f0 100644 --- a/android/location_api/LocationUtil.h +++ b/android/location_api/LocationUtil.h @@ -41,6 +41,7 @@ namespace V1_1 { namespace implementation { void convertGnssLocation(Location& in, V1_0::GnssLocation& out); +void convertGnssLocation(const V1_0::GnssLocation& in, Location& out); void convertGnssConstellationType(GnssSvType& in, V1_0::GnssConstellationType& out); void convertGnssEphemerisType(GnssEphemerisType& in, GnssDebug::SatelliteEphemerisType& out); void convertGnssEphemerisSource(GnssEphemerisSource& in, GnssDebug::SatelliteEphemerisSource& out); diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index 5f98456c..267d539f 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -173,4 +173,8 @@ DEFAULT_IMPL() void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/) DEFAULT_IMPL() +bool LocAdapterBase:: + requestOdcpiEvent(OdcpiRequestInfo& /*request*/) +DEFAULT_IMPL(false) + } // namespace loc_core diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 9fcee128..2083ac41 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -160,6 +160,7 @@ public: GpsLocationExtended &location_extended, LocPosTechMask tech_mask); virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config); virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config); + virtual bool requestOdcpiEvent(OdcpiRequestInfo& request); }; } // namespace loc_core diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 9c547261..3eec209b 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -288,6 +288,11 @@ void LocApiBase::reportZppBestAvailableFix(LocGpsLocation &zppLoc, location_extended, tech_mask)); } +void LocApiBase::requestOdcpi(OdcpiRequestInfo& request) +{ + // loop through adapters, and deliver to the first handling adapter. + TO_1ST_HANDLING_LOCADAPTERS(mLocAdapters[i]->requestOdcpiEvent(request)); +} void LocApiBase::reportSv(GnssSvNotification& svNotify) { @@ -467,6 +472,10 @@ void LocApiBase:: injectPosition(double /*latitude*/, double /*longitude*/, float /*accuracy*/) DEFAULT_IMPL() +void LocApiBase:: + injectPosition(const Location& /*location*/, bool /*onDemandCpi*/) +DEFAULT_IMPL() + void LocApiBase:: setTime(LocGpsUtcTime /*time*/, int64_t /*timeReference*/, int /*uncertainty*/) DEFAULT_IMPL() diff --git a/core/LocApiBase.h b/core/LocApiBase.h index 17ccc4ef..7b3aee32 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -159,6 +159,7 @@ public: LocPosTechMask tech_mask); void reportGnssSvIdConfig(const GnssSvIdConfig& config); void reportGnssSvTypeConfig(const GnssSvTypeConfig& config); + void requestOdcpi(OdcpiRequestInfo& request); // downward calls // All below functions are to be defined by adapter specific modules: @@ -174,6 +175,8 @@ public: virtual void injectPosition(double latitude, double longitude, float accuracy); + virtual void + injectPosition(const Location& location, bool onDemandCpi); virtual void setTime(LocGpsUtcTime time, int64_t timeReference, int uncertainty); diff --git a/gnss/GnssAdapter.cpp b/gnss/GnssAdapter.cpp index 0bbc3f5c..703eec8e 100644 --- a/gnss/GnssAdapter.cpp +++ b/gnss/GnssAdapter.cpp @@ -80,6 +80,9 @@ GnssAdapter::GnssAdapter() : mNiData(), mAgpsManager(), mAgpsCbInfo(), + mOdcpiRequestCb(nullptr), + mOdcpiRequestActive(false), + mOdcpiInjectedPositionCount(0), mSystemStatus(SystemStatus::getInstance(mMsgTask)), mServerUrl(":"), mXtraObserver(mSystemStatus->getOsObserver(), mMsgTask) @@ -1865,6 +1868,11 @@ GnssAdapter::updateClientsEventMask() mask |= LOC_API_ADAPTER_BIT_LOCATION_SERVER_REQUEST; } + // Add ODCPI handling + if (nullptr != mOdcpiRequestCb) { + mask |= LOC_API_ADAPTER_BIT_REQUEST_WIFI; + } + updateEvtMask(mask, LOC_REGISTRATION_MASK_SET); } @@ -3389,6 +3397,100 @@ GnssAdapter::reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial) mEngHubProxy->gnssReportSvPolynomial(svPolynomial); } +bool +GnssAdapter::requestOdcpiEvent(OdcpiRequestInfo& request) +{ + LOC_LOGd("ODCPI request: type %d, tbf %d, isEmergency %d", request.type, + request.tbfMillis, request.isEmergencyMode); + + struct MsgRequestOdcpi : public LocMsg { + GnssAdapter& mAdapter; + OdcpiRequestInfo mOdcpiRequest; + inline MsgRequestOdcpi(GnssAdapter& adapter, OdcpiRequestInfo& request) : + LocMsg(), + mAdapter(adapter), + mOdcpiRequest(request) {} + inline virtual void proc() const { + mAdapter.requestOdcpi(mOdcpiRequest); + } + }; + + sendMsg(new MsgRequestOdcpi(*this, request)); + return true; +} + +void GnssAdapter::requestOdcpi(const OdcpiRequestInfo& request) +{ + if (nullptr != mOdcpiRequestCb) { + mOdcpiInjectedPositionCount = 0; + if (ODCPI_REQUEST_TYPE_START == request.type) { + mOdcpiRequestCb(request); + mOdcpiRequestActive = true; + } else { + mOdcpiRequestActive = false; + } + } else { + LOC_LOGe("ODCPI request not supported"); + } +} + +void GnssAdapter::initOdcpiCommand(const OdcpiRequestCallback& callback) +{ + struct MsgInitOdcpi : public LocMsg { + GnssAdapter& mAdapter; + OdcpiRequestCallback mOdcpiCb; + inline MsgInitOdcpi(GnssAdapter& adapter, + const OdcpiRequestCallback& callback) : + LocMsg(), + mAdapter(adapter), + mOdcpiCb(callback) {} + inline virtual void proc() const { + mAdapter.initOdcpi(mOdcpiCb); + } + }; + + sendMsg(new MsgInitOdcpi(*this, callback)); +} + +void GnssAdapter::initOdcpi(const OdcpiRequestCallback& callback) +{ + mOdcpiRequestCb = callback; + + /* Register for WIFI request */ + updateEvtMask(LOC_API_ADAPTER_BIT_REQUEST_WIFI, + LOC_REGISTRATION_MASK_ENABLED); +} + +void GnssAdapter::injectOdcpiCommand(const Location& location) +{ + struct MsgInjectOdcpi : public LocMsg { + GnssAdapter& mAdapter; + Location mLocation; + inline MsgInjectOdcpi(GnssAdapter& adapter, const Location& location) : + LocMsg(), + mAdapter(adapter), + mLocation(location) {} + inline virtual void proc() const { + mAdapter.injectOdcpi(mLocation); + } + }; + + sendMsg(new MsgInjectOdcpi(*this, location)); +} + +void GnssAdapter::injectOdcpi(const Location& location) +{ + mLocApi->injectPosition(location, true); + if (mOdcpiRequestActive) { + mOdcpiInjectedPositionCount++; + if (mOdcpiInjectedPositionCount >= + ODCPI_INJECTED_POSITION_COUNT_PER_REQUEST) { + mOdcpiRequestActive = false; + mOdcpiInjectedPositionCount = 0; + } + } +} + void GnssAdapter::initDefaultAgps() { LOC_LOGD("%s]: ", __func__); diff --git a/gnss/GnssAdapter.h b/gnss/GnssAdapter.h index ff66de43..277cc2a8 100644 --- a/gnss/GnssAdapter.h +++ b/gnss/GnssAdapter.h @@ -45,6 +45,7 @@ #define MAX_SATELLITES_IN_USE 12 #define LOC_NI_NO_RESPONSE_TIME 20 #define LOC_GPS_NI_RESPONSE_IGNORE 4 +#define ODCPI_INJECTED_POSITION_COUNT_PER_REQUEST 30 class GnssAdapter; @@ -110,12 +111,17 @@ class GnssAdapter : public LocAdapterBase { /* ==== NI ============================================================================= */ NiData mNiData; - /* ==== AGPS ========================================================*/ + /* ==== AGPS =========================================================================== */ // This must be initialized via initAgps() AgpsManager mAgpsManager; AgpsCbInfo mAgpsCbInfo; void initAgps(const AgpsCbInfo& cbInfo); + /* ==== ODCPI ========================================================================== */ + OdcpiRequestCallback mOdcpiRequestCb; + bool mOdcpiRequestActive; + uint32_t mOdcpiInjectedPositionCount; + /* === SystemStatus ===================================================================== */ SystemStatus* mSystemStatus; std::string mServerUrl; @@ -129,6 +135,10 @@ class GnssAdapter : public LocAdapterBase { static void convertLocationInfo(GnssLocationInfoNotification& out, const GpsLocationExtended& locationExtended); + /* ======== UTILITIES ================================================================== */ + inline void initOdcpi(const OdcpiRequestCallback& callback); + inline void injectOdcpi(const Location& location); + public: GnssAdapter(); @@ -250,6 +260,11 @@ public: void dataConnClosedCommand(AGpsExtType agpsType); void dataConnFailedCommand(AGpsExtType agpsType); + /* ========= ODCPI ===================================================================== */ + /* ======== COMMANDS ====(Called from Client Thread)==================================== */ + void initOdcpiCommand(const OdcpiRequestCallback& callback); + void injectOdcpiCommand(const Location& location); + /* ======== RESPONSES ================================================================== */ void reportResponse(LocationError err, uint32_t sessionId); void reportResponse(size_t count, LocationError* errs, uint32_t* ids); @@ -290,6 +305,7 @@ public: virtual bool reportDataCallClosed(); virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc, GpsLocationExtended &location_extended, LocPosTechMask tech_mask); + virtual bool requestOdcpiEvent(OdcpiRequestInfo& request); /* ======== UTILITIES ================================================================= */ bool needReport(const UlpLocation& ulpLocation, @@ -304,6 +320,7 @@ public: void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements); void reportGnssSvIdConfig(const GnssSvIdConfig& config); void reportGnssSvTypeConfig(const GnssSvTypeConfig& config); + void requestOdcpi(const OdcpiRequestInfo& request); /*======== GNSSDEBUG ================================================================*/ bool getDebugReport(GnssDebugReport& report); diff --git a/gnss/location_gnss.cpp b/gnss/location_gnss.cpp index 34903950..105145a4 100644 --- a/gnss/location_gnss.cpp +++ b/gnss/location_gnss.cpp @@ -67,6 +67,9 @@ static void agpsDataConnFailed(AGpsExtType agpsType); static void getDebugReport(GnssDebugReport& report); static void updateConnectionStatus(bool connected, int8_t type); +static void odcpiInit(const OdcpiRequestCallback& callback); +static void odcpiInject(const Location& location); + static const GnssInterface gGnssInterface = { sizeof(GnssInterface), initialize, @@ -96,6 +99,8 @@ static const GnssInterface gGnssInterface = { agpsDataConnFailed, getDebugReport, updateConnectionStatus, + odcpiInit, + odcpiInject, }; #ifndef DEBUG_X86 @@ -307,3 +312,18 @@ static void updateConnectionStatus(bool connected, int8_t type) { gGnssAdapter->getSystemStatus()->eventConnectionStatus(connected, type); } } + +static void odcpiInit(const OdcpiRequestCallback& callback) +{ + if (NULL != gGnssAdapter) { + gGnssAdapter->initOdcpiCommand(callback); + } +} + +static void odcpiInject(const Location& location) +{ + if (NULL != gGnssAdapter) { + gGnssAdapter->injectOdcpiCommand(location); + } +} + diff --git a/location/location_interface.h b/location/location_interface.h index a460bb62..3c1558e9 100644 --- a/location/location_interface.h +++ b/location/location_interface.h @@ -61,6 +61,8 @@ struct GnssInterface { void (*agpsDataConnFailed)(AGpsExtType agpsType); void (*getDebugReport)(GnssDebugReport& report); void (*updateConnectionStatus)(bool connected, int8_t type); + void (*odcpiInit)(const OdcpiRequestCallback& callback); + void (*odcpiInject)(const Location& location); }; struct FlpInterface { diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h index 5db1b130..c0b97af2 100644 --- a/utils/gps_extended_c.h +++ b/utils/gps_extended_c.h @@ -1514,6 +1514,20 @@ struct AGnssExtStatusIpV6 { uint8_t ipV6Addr[16]; }; +/* ODCPI Request Info */ +enum OdcpiRequestType { + ODCPI_REQUEST_TYPE_START, + ODCPI_REQUEST_TYPE_STOP +}; +struct OdcpiRequestInfo { + size_t size; + OdcpiRequestType type; + uint32_t tbfMillis; + bool isEmergencyMode; +}; +/* Callback to send ODCPI request to framework */ +typedef std::function OdcpiRequestCallback; + /* * Callback with AGNSS(IpV4) status information. *