diff --git a/core/LocAdapterBase.cpp b/core/LocAdapterBase.cpp index eea8eddf..23184dff 100644 --- a/core/LocAdapterBase.cpp +++ b/core/LocAdapterBase.cpp @@ -132,4 +132,8 @@ DEFAULT_IMPL(false) void LocAdapterBase:: shutdown() DEFAULT_IMPL() + +void LocAdapterBase:: + reportGpsMeasurementData(GpsData &gpsMeasurementData) +DEFAULT_IMPL() } // namespace loc_core diff --git a/core/LocAdapterBase.h b/core/LocAdapterBase.h index 2fec3128..9d5f6a81 100644 --- a/core/LocAdapterBase.h +++ b/core/LocAdapterBase.h @@ -112,6 +112,7 @@ public: inline virtual bool isInSession() { return false; } virtual void shutdown(); ContextBase* getContext() const { return mContext; } + virtual void reportGpsMeasurementData(GpsData &gpsMeasurementData); }; } // namespace loc_core diff --git a/core/LocApiBase.cpp b/core/LocApiBase.cpp index 82bfe21e..f56694e7 100644 --- a/core/LocApiBase.cpp +++ b/core/LocApiBase.cpp @@ -363,6 +363,12 @@ void* LocApiBase :: getSibling() LocApiProxyBase* LocApiBase :: getLocApiProxy() DEFAULT_IMPL(NULL) +void LocApiBase::reportGpsMeasurementData(GpsData &gpsMeasurementData) +{ + // loop through adapters, and deliver to all adapters. + TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGpsMeasurementData(gpsMeasurementData)); +} + enum loc_api_adapter_err LocApiBase:: open(LOC_API_ADAPTER_EVENT_MASK_T mask) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) @@ -526,4 +532,14 @@ DEFAULT_IMPL(-1) enum loc_api_adapter_err LocApiBase:: setXtraVersionCheck(enum xtra_version_check check) DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS) + +int LocApiBase:: + updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, + loc_registration_mask_status isEnabled) +DEFAULT_IMPL(-1) + +bool LocApiBase:: + gnssConstellationConfig() +DEFAULT_IMPL(false) + } // namespace loc_core diff --git a/core/LocApiBase.h b/core/LocApiBase.h index f68cf739..414769b5 100644 --- a/core/LocApiBase.h +++ b/core/LocApiBase.h @@ -130,6 +130,7 @@ public: void reportDataCallClosed(); void requestNiNotify(GpsNiNotification ¬ify, const void* data); void saveSupportedMsgList(uint64_t supportedMsgList); + void reportGpsMeasurementData(GpsData &gpsMeasurementData); // downward calls // All below functions are to be defined by adapter specific modules: @@ -237,7 +238,18 @@ public: -1 on failure */ virtual int getGpsLock(void); + virtual enum loc_api_adapter_err setXtraVersionCheck(enum xtra_version_check check); + + /* + Update gps reporting events + */ + virtual int updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, + loc_registration_mask_status isEnabled); + /* + Check if the modem support the service + */ + virtual bool gnssConstellationConfig(); }; typedef LocApiBase* (getLocApi_t)(const MsgTask* msgTask, diff --git a/core/LocDualContext.cpp b/core/LocDualContext.cpp index ab151109..41ad4f0a 100644 --- a/core/LocDualContext.cpp +++ b/core/LocDualContext.cpp @@ -50,7 +50,8 @@ LocDualContext::mBgExclMask = LOC_API_ADAPTER_BIT_NMEA_POSITION_REPORT | LOC_API_ADAPTER_BIT_IOCTL_REPORT | LOC_API_ADAPTER_BIT_STATUS_REPORT | - LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT); + LOC_API_ADAPTER_BIT_GEOFENCE_GEN_ALERT | + LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT); const MsgTask* LocDualContext::mMsgTask = NULL; ContextBase* LocDualContext::mFgContext = NULL; diff --git a/core/gps_extended_c.h b/core/gps_extended_c.h index acf92b36..8a4e340f 100644 --- a/core/gps_extended_c.h +++ b/core/gps_extended_c.h @@ -347,6 +347,7 @@ enum loc_api_adapter_event_index { LOC_API_ADAPTER_BATCHED_GENFENCE_BREACH_REPORT, // LOC_API_ADAPTER_GDT_UPLOAD_BEGIN_REQ, // GDT upload start request LOC_API_ADAPTER_GDT_UPLOAD_END_REQ, // GDT upload end request + LOC_API_ADAPTER_GNSS_MEASUREMENT, // GNSS Measurement report LOC_API_ADAPTER_EVENT_MAX }; @@ -375,6 +376,7 @@ enum loc_api_adapter_event_index { #define LOC_API_ADAPTER_BIT_BATCHED_POSITION_REPORT (1<updateRegistrationMask(event, isEnabled); + if (result == LOC_API_ADAPTER_ERR_SUCCESS) { + LOC_LOGD("%s] update registration mask succeed.", __func__); + } else { + LOC_LOGE("%s] update registration mask failed.", __func__); + } +} + +/* + Set Gnss Constellation Config + */ +bool LocEngAdapter::gnssConstellationConfig() +{ + LOC_LOGD("entering %s", __func__); + bool result = false; + result = mLocApi->gnssConstellationConfig(); + return result; +} diff --git a/loc_api/libloc_api_50001/LocEngAdapter.h b/loc_api/libloc_api_50001/LocEngAdapter.h index b857d198..e5d10184 100644 --- a/loc_api/libloc_api_50001/LocEngAdapter.h +++ b/loc_api/libloc_api_50001/LocEngAdapter.h @@ -284,6 +284,7 @@ public: virtual bool requestSuplES(int connHandle); virtual bool reportDataCallOpened(); virtual bool reportDataCallClosed(); + virtual void reportGpsMeasurementData(GpsData &gpsMeasurementData); inline const LocPosMode& getPositionMode() const {return mFixCriteria;} @@ -334,6 +335,16 @@ public: return mLocApi->getGpsLock(); } + /* + Update Registration Mask + */ + void updateRegistrationMask(LOC_API_ADAPTER_EVENT_MASK_T event, + loc_registration_mask_status isEnabled); + + /* + Set Gnss Constellation Config + */ + bool gnssConstellationConfig(); }; #endif //LOC_API_ENG_ADAPTER_H diff --git a/loc_api/libloc_api_50001/loc.cpp b/loc_api/libloc_api_50001/loc.cpp index 158176f5..4cf4ba95 100644 --- a/loc_api/libloc_api_50001/loc.cpp +++ b/loc_api/libloc_api_50001/loc.cpp @@ -150,6 +150,17 @@ typedef struct { static s_loc_mdm_info loc_mdm_info; static void loc_pm_event_notifier(void *client_data, enum pm_event event); #endif /*MODEM_POWER_VOTE*/ +// For shutting down MDM in fusion devices +static int mdm_fd = -1; +static int loc_gps_measurement_init(GpsMeasurementCallbacks* callbacks); +static void loc_gps_measurement_close(); + +static const GpsMeasurementInterface sLocEngGpsMeasurementInterface = +{ + sizeof(GpsMeasurementInterface), + loc_gps_measurement_init, + loc_gps_measurement_close +}; static void loc_agps_ril_init( AGpsRilCallbacks* callbacks ); static void loc_agps_ril_set_ref_location(const AGpsRefLocation *agps_reflocation, size_t sz_struct); @@ -776,6 +787,10 @@ const void* loc_get_extension(const char* name) { ret_val = &sLocEngConfigInterface; } + else if (strcmp(name, GPS_MEASUREMENT_INTERFACE) == 0) + { + ret_val = &sLocEngGpsMeasurementInterface; + } else { LOC_LOGE ("get_extension: Invalid interface passed in\n"); @@ -983,6 +998,56 @@ static int loc_xtra_inject_data(char* data, int length) return ret_val; } +/*=========================================================================== +FUNCTION loc_gps_measurement_init + +DESCRIPTION + This function initializes the gps measurement interface + +DEPENDENCIES + NONE + +RETURN VALUE + None + +SIDE EFFECTS + N/A + +===========================================================================*/ +static int loc_gps_measurement_init(GpsMeasurementCallbacks* callbacks) +{ + ENTRY_LOG(); + int ret_val = loc_eng_gps_measurement_init(loc_afw_data, + callbacks); + + EXIT_LOG(%d, ret_val); + return ret_val; +} + +/*=========================================================================== +FUNCTION loc_gps_measurement_close + +DESCRIPTION + This function closes the gps measurement interface + +DEPENDENCIES + NONE + +RETURN VALUE + None + +SIDE EFFECTS + N/A + +===========================================================================*/ +static void loc_gps_measurement_close() +{ + ENTRY_LOG(); + loc_eng_gps_measurement_close(loc_afw_data); + + EXIT_LOG(%s, VOID_RET); +} + /*=========================================================================== FUNCTION loc_ni_init diff --git a/loc_api/libloc_api_50001/loc_eng.cpp b/loc_api/libloc_api_50001/loc_eng.cpp index 18ffc5ef..448cc793 100644 --- a/loc_api/libloc_api_50001/loc_eng.cpp +++ b/loc_api/libloc_api_50001/loc_eng.cpp @@ -1372,6 +1372,33 @@ struct LocEngEnableData : public LocMsg { // case LOC_ENG_MSG_INJECT_XTRA_DATA: // loc_eng_xtra.cpp +// case LOC_ENG_MSG_SET_CAPABILITIES: +struct LocEngSetCapabilities : public LocMsg { + loc_eng_data_s_type* mLocEng; + inline LocEngSetCapabilities(loc_eng_data_s_type* locEng) : + LocMsg(), mLocEng(locEng) + { + locallog(); + } + inline virtual void proc() const { + if (NULL != mLocEng->set_capabilities_cb) { + LOC_LOGV("calling set_capabilities_cb 0x%x", + gps_conf.CAPABILITIES); + mLocEng->set_capabilities_cb(gps_conf.CAPABILITIES); + } else { + LOC_LOGV("set_capabilities_cb is NULL.\n"); + } + } + inline void locallog() const + { + LOC_LOGV("LocEngSetCapabilities"); + } + inline virtual void log() const + { + locallog(); + } +}; + // case LOC_ENG_MSG_LOC_INIT: struct LocEngInit : public LocMsg { loc_eng_data_s_type* mLocEng; @@ -1382,6 +1409,8 @@ struct LocEngInit : public LocMsg { } inline virtual void proc() const { loc_eng_reinit(*mLocEng); + // set the capabilities + mLocEng->adapter->sendMsg(new LocEngSetCapabilities(mLocEng)); } inline void locallog() const { @@ -1571,6 +1600,99 @@ struct LocEngInstallAGpsCert : public LocMsg { } }; +struct LocEngUpdateRegistrationMask : public LocMsg { + loc_eng_data_s_type* mLocEng; + LOC_API_ADAPTER_EVENT_MASK_T mMask; + loc_registration_mask_status mIsEnabled; + inline LocEngUpdateRegistrationMask(loc_eng_data_s_type* locEng, + LOC_API_ADAPTER_EVENT_MASK_T mask, + loc_registration_mask_status isEnabled) : + LocMsg(), mLocEng(locEng), mMask(mask), mIsEnabled(isEnabled) { + locallog(); + } + inline virtual void proc() const { + loc_eng_data_s_type *locEng = (loc_eng_data_s_type *)mLocEng; + locEng->adapter->updateRegistrationMask(mMask, + mIsEnabled); + } + void locallog() const { + LOC_LOGV("LocEngUpdateRegistrationMask\n"); + } + virtual void log() const { + locallog(); + } +}; + +struct LocEngGnssConstellationConfig : public LocMsg { + LocEngAdapter* mAdapter; + inline LocEngGnssConstellationConfig(LocEngAdapter* adapter) : + LocMsg(), mAdapter(adapter) { + locallog(); + } + inline virtual void proc() const { + if (mAdapter->gnssConstellationConfig()) { + LOC_LOGV("Modem supports GNSS measurements\n"); + gps_conf.CAPABILITIES |= GPS_CAPABILITY_MEASUREMENTS; + } else { + LOC_LOGV("Modem does not support GNSS measurements\n"); + } + } + void locallog() const { + LOC_LOGV("LocEngGnssConstellationConfig\n"); + } + virtual void log() const { + locallog(); + } +}; + +// case LOC_ENG_MSG_REPORT_GNSS_MEASUREMENT: +LocEngReportGpsMeasurement::LocEngReportGpsMeasurement(void* locEng, + GpsData &gpsData) : + LocMsg(), mLocEng(locEng), mGpsData(gpsData) +{ + locallog(); +} +void LocEngReportGpsMeasurement::proc() const { + loc_eng_data_s_type* locEng = (loc_eng_data_s_type*) mLocEng; + if (locEng->mute_session_state != LOC_MUTE_SESS_IN_SESSION) + { + if (locEng->gps_measurement_cb != NULL) { + locEng->gps_measurement_cb((GpsData*)&(mGpsData)); + } + } +} +void LocEngReportGpsMeasurement::locallog() const { + IF_LOC_LOGV { + LOC_LOGV("%s:%d]: Received in GPS HAL." + "GNSS Measurements count: %d \n", + __func__, __LINE__, mGpsData.measurement_count); + for (int i =0; i< mGpsData.measurement_count && i < GPS_MAX_SVS; i++) { + LOC_LOGV(" GNSS measurement data in GPS HAL: \n" + " GPS_HAL => Measurement ID | prn | time_offset_ns | state |" + " received_gps_tow_ns| c_n0_dbhz | pseudorange_rate_mps |" + " pseudorange_rate_uncertainty_mps |" + " accumulated_delta_range_state | flags \n" + " GPS_HAL => %d | %d | %f | %d | %lld | %f | %f | %f | %d | %d \n", + i, + mGpsData.measurements[i].prn, + mGpsData.measurements[i].time_offset_ns, + mGpsData.measurements[i].state, + mGpsData.measurements[i].received_gps_tow_ns, + mGpsData.measurements[i].c_n0_dbhz, + mGpsData.measurements[i].pseudorange_rate_mps, + mGpsData.measurements[i].pseudorange_rate_uncertainty_mps, + mGpsData.measurements[i].accumulated_delta_range_state, + mGpsData.measurements[i].flags); + } + LOC_LOGV(" GPS_HAL => Clocks Info: type | time_ns \n" + " GPS_HAL => Clocks Info: %d | %lld", mGpsData.clock.type, + mGpsData.clock.time_ns); + } +} +inline void LocEngReportGpsMeasurement::log() const { + locallog(); +} + /********************************************************************* * Initialization checking macros *********************************************************************/ @@ -1638,10 +1760,6 @@ int loc_eng_init(loc_eng_data_s_type &loc_eng_data, LocCallbacks* callbacks, memset(&loc_eng_data, 0, sizeof (loc_eng_data)); - if (NULL != callbacks->set_capabilities_cb) { - callbacks->set_capabilities_cb(gps_conf.CAPABILITIES); - } - // Save callbacks loc_eng_data.location_cb = callbacks->location_cb; loc_eng_data.sv_status_cb = callbacks->sv_status_cb; @@ -1690,6 +1808,7 @@ static int loc_eng_reinit(loc_eng_data_s_type &loc_eng_data) int ret_val = LOC_API_ADAPTER_ERR_SUCCESS; LocEngAdapter* adapter = loc_eng_data.adapter; + adapter->sendMsg(new LocEngGnssConstellationConfig(adapter)); adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER)); adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE)); adapter->sendMsg(new LocEngSensorControlConfig(adapter, sap_conf.SENSOR_USAGE, @@ -2626,33 +2745,32 @@ void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data, ENTRY_LOG_CALLFLOW(); if (config_data && length > 0) { - loc_gps_cfg_s_type gps_conf_old = gps_conf; + loc_gps_cfg_s_type gps_conf_tmp = gps_conf; UTIL_UPDATE_CONF(config_data, length, gps_conf_table); LocEngAdapter* adapter = loc_eng_data.adapter; // it is possible that HAL is not init'ed at this time if (adapter) { - if (gps_conf_old.SUPL_VER != gps_conf.SUPL_VER) { + if (gps_conf_tmp.SUPL_VER != gps_conf.SUPL_VER) { adapter->sendMsg(new LocEngSuplVer(adapter, gps_conf.SUPL_VER)); } - if (gps_conf_old.LPP_PROFILE != gps_conf.LPP_PROFILE) { + if (gps_conf_tmp.LPP_PROFILE != gps_conf.LPP_PROFILE) { adapter->sendMsg(new LocEngLppConfig(adapter, gps_conf.LPP_PROFILE)); } - if (gps_conf_old.A_GLONASS_POS_PROTOCOL_SELECT != gps_conf.A_GLONASS_POS_PROTOCOL_SELECT) { + if (gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT != gps_conf.A_GLONASS_POS_PROTOCOL_SELECT) { adapter->sendMsg(new LocEngAGlonassProtocol(adapter, gps_conf.A_GLONASS_POS_PROTOCOL_SELECT)); } - if (gps_conf_old.SUPL_MODE != gps_conf.SUPL_MODE) { + if (gps_conf_tmp.SUPL_MODE != gps_conf.SUPL_MODE) { adapter->sendMsg(new LocEngSuplMode(adapter->getUlpProxy())); } } - gps_conf_old.SUPL_VER = gps_conf.SUPL_VER; - gps_conf_old.LPP_PROFILE = gps_conf.LPP_PROFILE; - gps_conf_old.A_GLONASS_POS_PROTOCOL_SELECT = gps_conf.A_GLONASS_POS_PROTOCOL_SELECT; - gps_conf_old.SUPL_MODE = gps_conf.SUPL_MODE; - gps_conf = gps_conf_old; - + gps_conf_tmp.SUPL_VER = gps_conf.SUPL_VER; + gps_conf_tmp.LPP_PROFILE = gps_conf.LPP_PROFILE; + gps_conf_tmp.A_GLONASS_POS_PROTOCOL_SELECT = gps_conf.A_GLONASS_POS_PROTOCOL_SELECT; + gps_conf_tmp.GPS_LOCK = gps_conf.GPS_LOCK; + gps_conf = gps_conf_tmp; } EXIT_LOG(%s, VOID_RET); @@ -2862,3 +2980,80 @@ void loc_eng_handle_shutdown(loc_eng_data_s_type &locEng) locEng.shutdown_cb(); EXIT_LOG(%d, 0); } + +/*=========================================================================== +FUNCTION loc_eng_gps_measurement_init + +DESCRIPTION + Initialize gps measurement module. + +DEPENDENCIES + N/A + +RETURN VALUE + 0: success + +SIDE EFFECTS + N/A + +===========================================================================*/ +int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data, + GpsMeasurementCallbacks* callbacks) +{ + ENTRY_LOG_CALLFLOW(); + + STATE_CHECK((NULL == loc_eng_data.gps_measurement_cb), + "gps measurement already initialized", + return GPS_MEASUREMENT_ERROR_ALREADY_INIT); + STATE_CHECK((callbacks != NULL), + "callbacks can not be NULL", + return GPS_MEASUREMENT_ERROR_GENERIC); + STATE_CHECK(loc_eng_data.adapter, + "GpsInterface must be initialized first", + return GPS_MEASUREMENT_ERROR_GENERIC); + + // updated the mask + LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; + loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask( + &loc_eng_data, + event, + LOC_REGISTRATION_MASK_ENABLED)); + // set up the callback + loc_eng_data.gps_measurement_cb = callbacks->measurement_callback; + LOC_LOGD ("%s, event masks updated successfully", __func__); + + return GPS_MEASUREMENT_OPERATION_SUCCESS; +} + +/*=========================================================================== +FUNCTION loc_eng_gps_measurement_close + +DESCRIPTION + Close gps measurement module. + +DEPENDENCIES + N/A + +RETURN VALUE + N/A + +SIDE EFFECTS + N/A + +===========================================================================*/ +void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data) +{ + ENTRY_LOG_CALLFLOW(); + + INIT_CHECK(loc_eng_data.adapter, return); + + // updated the mask + LOC_API_ADAPTER_EVENT_MASK_T event = LOC_API_ADAPTER_BIT_GNSS_MEASUREMENT; + loc_eng_data.adapter->sendMsg(new LocEngUpdateRegistrationMask( + &loc_eng_data, + event, + LOC_REGISTRATION_MASK_DISABLED)); + // set up the callback + loc_eng_data.gps_measurement_cb = NULL; + EXIT_LOG(%d, 0); +} diff --git a/loc_api/libloc_api_50001/loc_eng.h b/loc_api/libloc_api_50001/loc_eng.h index d049afae..813da482 100644 --- a/loc_api/libloc_api_50001/loc_eng.h +++ b/loc_api/libloc_api_50001/loc_eng.h @@ -94,6 +94,7 @@ typedef struct loc_eng_data_s gps_acquire_wakelock acquire_wakelock_cb; gps_release_wakelock release_wakelock_cb; gps_request_utc_time request_utc_time_cb; + gps_measurement_callback gps_measurement_cb; boolean intermediateFix; AGpsStatusValue agps_status; loc_eng_xtra_data_s_type xtra_module_data; @@ -259,6 +260,9 @@ extern void loc_eng_ni_reset_on_engine_restart(loc_eng_data_s_type &loc_eng_data void loc_eng_configuration_update (loc_eng_data_s_type &loc_eng_data, const char* config_data, int32_t length); +int loc_eng_gps_measurement_init(loc_eng_data_s_type &loc_eng_data, + GpsMeasurementCallbacks* callbacks); +void loc_eng_gps_measurement_close(loc_eng_data_s_type &loc_eng_data); #ifdef __cplusplus } diff --git a/loc_api/libloc_api_50001/loc_eng_msg.h b/loc_api/libloc_api_50001/loc_eng_msg.h index b767dc5f..e3c48fb4 100644 --- a/loc_api/libloc_api_50001/loc_eng_msg.h +++ b/loc_api/libloc_api_50001/loc_eng_msg.h @@ -289,6 +289,16 @@ struct LocEngGetZpp : public LocMsg { void send() const; }; +struct LocEngReportGpsMeasurement : public LocMsg { + void* mLocEng; + const GpsData mGpsData; + LocEngReportGpsMeasurement(void* locEng, + GpsData &gpsData); + virtual void proc() const; + void locallog() const; + virtual void log() const; +}; + struct LocEngShutdown : public LocMsg { LocEngAdapter* mAdapter; LocEngShutdown(LocEngAdapter* adapter);