FR 45651 - GNSS SV/Constellation Control
Adding support for configuring GNSS SVs
and constellations to be used.
Change-Id: I47d5cd9d08ac9aaf633be2fe3b1bd152a2f4293b
CRs-Fixed: 2184871
diff --git a/sdm845/android/Gnss.cpp b/sdm845/android/Gnss.cpp
index 878cd20..d31a18b 100644
--- a/sdm845/android/Gnss.cpp
+++ b/sdm845/android/Gnss.cpp
@@ -234,6 +234,10 @@
mPendingConfig.flags |= GNSS_CONFIG_FLAGS_SUPL_MODE_BIT;
mPendingConfig.suplModeMask = gnssConfig.suplModeMask;
}
+ if (gnssConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ mPendingConfig.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ mPendingConfig.blacklistedSvIds = gnssConfig.blacklistedSvIds;
+ }
}
return true;
}
diff --git a/sdm845/android/GnssConfiguration.cpp b/sdm845/android/GnssConfiguration.cpp
index 9eeceac..cee928a 100644
--- a/sdm845/android/GnssConfiguration.cpp
+++ b/sdm845/android/GnssConfiguration.cpp
@@ -23,6 +23,7 @@
#include <log_util.h>
#include "Gnss.h"
#include "GnssConfiguration.h"
+#include <android/hardware/gnss/1.0/types.h>
namespace android {
namespace hardware {
@@ -30,6 +31,8 @@
namespace V1_1 {
namespace implementation {
+using ::android::hardware::gnss::V1_0::GnssConstellationType;
+
GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
}
@@ -222,10 +225,60 @@
// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow.
Return<bool> GnssConfiguration::setBlacklist(
- const hidl_vec<GnssConfiguration::BlacklistedSource>& /*blacklist*/) {
+ const hidl_vec<GnssConfiguration::BlacklistedSource>& blacklist) {
ENTRY_LOG_CALLFLOW();
- return true;
+ if (nullptr == mGnss) {
+ LOC_LOGe("mGnss is null");
+ return false;
+ }
+
+ GnssConfig config;
+ memset(&config, 0, sizeof(GnssConfig));
+ config.size = sizeof(GnssConfig);
+ config.flags = GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ config.blacklistedSvIds.clear();
+
+ GnssSvIdSource source = {};
+ for (int idx = 0; idx < (int)blacklist.size(); idx++) {
+ setBlacklistedSource(source, blacklist[idx]);
+ config.blacklistedSvIds.push_back(source);
+ }
+
+ return mGnss->updateConfiguration(config);
+}
+
+void GnssConfiguration::setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource) {
+
+ copyToSource.size = sizeof(GnssSvIdSource);
+
+ switch(copyFromSource.constellation) {
+ case GnssConstellationType::GPS:
+ copyToSource.constellation = GNSS_SV_TYPE_GPS;
+ break;
+ case GnssConstellationType::SBAS:
+ copyToSource.constellation = GNSS_SV_TYPE_SBAS;
+ break;
+ case GnssConstellationType::GLONASS:
+ copyToSource.constellation = GNSS_SV_TYPE_GLONASS;
+ break;
+ case GnssConstellationType::QZSS:
+ copyToSource.constellation = GNSS_SV_TYPE_QZSS;
+ break;
+ case GnssConstellationType::BEIDOU:
+ copyToSource.constellation = GNSS_SV_TYPE_BEIDOU;
+ break;
+ case GnssConstellationType::GALILEO:
+ copyToSource.constellation = GNSS_SV_TYPE_GALILEO;
+ break;
+ default:
+ copyToSource.constellation = GNSS_SV_TYPE_UNKNOWN;
+ break;
+ }
+
+ copyToSource.svId = copyFromSource.svid;
}
} // namespace implementation
diff --git a/sdm845/android/GnssConfiguration.h b/sdm845/android/GnssConfiguration.h
index f46f607..15ee290 100644
--- a/sdm845/android/GnssConfiguration.h
+++ b/sdm845/android/GnssConfiguration.h
@@ -64,6 +64,9 @@
private:
Gnss* mGnss = nullptr;
+ void setBlacklistedSource(
+ GnssSvIdSource& copyToSource,
+ const GnssConfiguration::BlacklistedSource& copyFromSource);
};
} // namespace implementation
diff --git a/sdm845/core/LocAdapterBase.cpp b/sdm845/core/LocAdapterBase.cpp
index 6b5f75a..162b14b 100644
--- a/sdm845/core/LocAdapterBase.cpp
+++ b/sdm845/core/LocAdapterBase.cpp
@@ -161,4 +161,10 @@
reportWwanZppFix(LocGpsLocation &/*zppLoc*/)
DEFAULT_IMPL(false)
+void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/)
+DEFAULT_IMPL()
+
+void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/)
+DEFAULT_IMPL()
+
} // namespace loc_core
diff --git a/sdm845/core/LocAdapterBase.h b/sdm845/core/LocAdapterBase.h
index 8e854f4..d08864d 100644
--- a/sdm845/core/LocAdapterBase.h
+++ b/sdm845/core/LocAdapterBase.h
@@ -153,6 +153,8 @@
virtual void reportGnssMeasurementDataEvent(const GnssMeasurementsNotification& measurements,
int msInWeek);
virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
+ virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
+ virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
};
} // namespace loc_core
diff --git a/sdm845/core/LocApiBase.cpp b/sdm845/core/LocApiBase.cpp
index f0af91f..01e8565 100644
--- a/sdm845/core/LocApiBase.cpp
+++ b/sdm845/core/LocApiBase.cpp
@@ -408,6 +408,28 @@
TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssMeasurementDataEvent(measurements, msInWeek));
}
+void LocApiBase::reportGnssSvIdConfig(const GnssSvIdConfig& config)
+{
+ // Print the config
+ LOC_LOGv("gloBlacklistSvMask: %" PRIu64 ", bdsBlacklistSvMask: %" PRIu64 ",\n"
+ "qzssBlacklistSvMask: %" PRIu64 ", galBlacklistSvMask: %" PRIu64,
+ config.gloBlacklistSvMask, config.bdsBlacklistSvMask,
+ config.qzssBlacklistSvMask, config.galBlacklistSvMask);
+
+ // Loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvIdConfigEvent(config));
+}
+
+void LocApiBase::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
+{
+ // Print the config
+ LOC_LOGv("blacklistedMask: %" PRIu64 ", enabledMask: %" PRIu64,
+ config.blacklistedSvTypesMask, config.enabledSvTypesMask);
+
+ // Loop through adapters, and deliver to all adapters.
+ TO_ALL_LOCADAPTERS(mLocAdapters[i]->reportGnssSvTypeConfigEvent(config));
+}
+
enum loc_api_adapter_err LocApiBase::
open(LOC_API_ADAPTER_EVENT_MASK_T /*mask*/)
DEFAULT_IMPL(LOC_API_ADAPTER_ERR_SUCCESS)
@@ -606,4 +628,24 @@
return ((mFeaturesSupported[arrayIndex] >> bitPos ) & 0x1);
}
+LocationError LocApiBase::
+ setBlacklistSv(const GnssSvIdConfig& /*config*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+LocationError LocApiBase::
+ getBlacklistSv()
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+LocationError LocApiBase::
+ setConstellationControl(const GnssSvTypeConfig& /*config*/)
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+LocationError LocApiBase::
+ getConstellationControl()
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
+LocationError LocApiBase::
+ resetConstellationControl()
+DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
+
} // namespace loc_core
diff --git a/sdm845/core/LocApiBase.h b/sdm845/core/LocApiBase.h
index d6b213b..042ef2c 100644
--- a/sdm845/core/LocApiBase.h
+++ b/sdm845/core/LocApiBase.h
@@ -134,6 +134,8 @@
void reportGnssMeasurementData(GnssMeasurementsNotification& measurements, int msInWeek);
void saveSupportedFeatureList(uint8_t *featureList);
void reportWwanZppFix(LocGpsLocation &zppLoc);
+ void reportGnssSvIdConfig(const GnssSvIdConfig& config);
+ void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
// downward calls
// All below functions are to be defined by adapter specific modules:
@@ -256,6 +258,13 @@
Check if a feature is supported
*/
bool isFeatureSupported(uint8_t featureVal);
+
+ /* Requests for SV/Constellation Control */
+ virtual LocationError setBlacklistSv(const GnssSvIdConfig& config);
+ virtual LocationError getBlacklistSv();
+ virtual LocationError setConstellationControl(const GnssSvTypeConfig& config);
+ virtual LocationError getConstellationControl();
+ virtual LocationError resetConstellationControl();
};
typedef LocApiBase* (getLocApi_t)(const MsgTask* msgTask,
diff --git a/sdm845/gnss/GnssAdapter.cpp b/sdm845/gnss/GnssAdapter.cpp
index 2761543..bc1e111 100644
--- a/sdm845/gnss/GnssAdapter.cpp
+++ b/sdm845/gnss/GnssAdapter.cpp
@@ -72,6 +72,9 @@
mControlCallbacks(),
mPowerVoteId(0),
mNmeaMask(0),
+ mGnssSvIdConfig(),
+ mGnssSvTypeConfig(),
+ mGnssSvTypeConfigCb(nullptr),
mNiData(),
mAgpsManager(),
mAgpsCbInfo(),
@@ -894,6 +897,23 @@
errs[index++] = err;
}
}
+ if (mConfig.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ // Check if feature is supported
+ if (!mApi.isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature constellation enablement not supported.");
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ } else {
+ // Send the SV ID Config to Modem
+ err = mAdapter.gnssSvIdConfigUpdate(mConfig.blacklistedSvIds);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGe("Failed to send config to modem, err %d", err);
+ }
+ }
+ if (index < mCount) {
+ errs[index++] = err;
+ }
+ }
mAdapter.reportResponse(index, errs, mIds);
delete[] errs;
@@ -909,6 +929,516 @@
return ids;
}
+LocationError
+GnssAdapter::gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds)
+{
+ // Clear the existing config
+ memset(&mGnssSvIdConfig, 0, sizeof(GnssSvIdConfig));
+
+ // Convert the sv id lists to masks
+ convertToGnssSvIdConfig(blacklistedSvIds, mGnssSvIdConfig);
+
+ // Now send to Modem
+ return gnssSvIdConfigUpdate();
+}
+
+LocationError
+GnssAdapter::gnssSvIdConfigUpdate()
+{
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ mGnssSvIdConfig.bdsBlacklistSvMask, mGnssSvIdConfig.gloBlacklistSvMask,
+ mGnssSvIdConfig.qzssBlacklistSvMask, mGnssSvIdConfig.galBlacklistSvMask);
+
+ // Now set required blacklisted SVs
+ return mLocApi->setBlacklistSv(mGnssSvIdConfig);
+}
+
+uint32_t*
+GnssAdapter::gnssGetConfigCommand(GnssConfigFlagsMask configMask) {
+
+ // count the number of bits set
+ GnssConfigFlagsMask flagsCopy = configMask;
+ size_t count = 0;
+ while (flagsCopy > 0) {
+ if (flagsCopy & 1) {
+ count++;
+ }
+ flagsCopy >>= 1;
+ }
+ std::string idsString = "[";
+ uint32_t* ids = NULL;
+ if (count > 0) {
+ ids = new uint32_t[count];
+ if (nullptr == ids) {
+ LOC_LOGe("new allocation failed, fatal error.");
+ return nullptr;
+ }
+ for (size_t i=0; i < count; ++i) {
+ ids[i] = generateSessionId();
+ IF_LOC_LOGD {
+ idsString += std::to_string(ids[i]) + " ";
+ }
+ }
+ }
+ idsString += "]";
+
+ LOC_LOGd("ids %s flags 0x%X", idsString.c_str(), configMask);
+
+ struct MsgGnssGetConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ LocApiBase& mApi;
+ GnssConfigFlagsMask mConfigMask;
+ uint32_t* mIds;
+ size_t mCount;
+ inline MsgGnssGetConfig(GnssAdapter& adapter,
+ LocApiBase& api,
+ GnssConfigFlagsMask configMask,
+ uint32_t* ids,
+ size_t count) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mConfigMask(configMask),
+ mIds(ids),
+ mCount(count) {}
+ inline virtual ~MsgGnssGetConfig()
+ {
+ delete[] mIds;
+ }
+ inline virtual void proc() const {
+
+ LocationError* errs = new LocationError[mCount];
+ LocationError err = LOCATION_ERROR_SUCCESS;
+ uint32_t index = 0;
+
+ if (nullptr == errs) {
+ LOC_LOGE("%s] new allocation failed, fatal error.", __func__);
+ return;
+ }
+
+ if (mConfigMask & GNSS_CONFIG_FLAGS_GPS_LOCK_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_VERSION_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SET_ASSISTANCE_DATA_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPP_PROFILE_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_CONTROL_PLANE_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_LPPE_USER_PLANE_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_AGLONASS_POSITION_PROTOCOL_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT) {
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_SUPL_MODE_BIT) {
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ if (index < mCount) {
+ errs[index++] = LOCATION_ERROR_NOT_SUPPORTED;
+ }
+ }
+ if (mConfigMask & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
+ // Check if feature is supported
+ if (!mApi.isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ err = LOCATION_ERROR_NOT_SUPPORTED;
+ } else {
+ // Send request to Modem to fetch the config
+ err = mApi.getBlacklistSv();
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGe("getConfig request to modem failed, err %d", err);
+ }
+ }
+ if (index < mCount) {
+ errs[index++] = err;
+ }
+ }
+
+ mAdapter.reportResponse(index, errs, mIds);
+ delete[] errs;
+ }
+ };
+
+ if (NULL != ids) {
+ sendMsg(new MsgGnssGetConfig(*this, *mLocApi, configMask, ids, count));
+ } else {
+ LOC_LOGe("No GNSS config items to Get");
+ }
+
+ return ids;
+}
+
+void
+GnssAdapter::convertToGnssSvIdConfig(
+ const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config)
+{
+ config.size = sizeof(GnssSvIdConfig);
+
+ // Empty vector => Clear any previous blacklisted SVs
+ if (0 == blacklistedSvIds.size()) {
+ config.gloBlacklistSvMask = 0;
+ config.bdsBlacklistSvMask = 0;
+ config.qzssBlacklistSvMask = 0;
+ config.galBlacklistSvMask = 0;
+ } else {
+ // Parse the vector and convert SV IDs to mask values
+ for (GnssSvIdSource source : blacklistedSvIds) {
+ uint64_t* svMaskPtr = NULL;
+ GnssSvId initialSvId = 0;
+ switch(source.constellation) {
+ case GNSS_SV_TYPE_GLONASS:
+ svMaskPtr = &config.gloBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_GLO_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_BEIDOU:
+ svMaskPtr = &config.bdsBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_BDS_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_QZSS:
+ svMaskPtr = &config.qzssBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID;
+ break;
+ case GNSS_SV_TYPE_GALILEO:
+ svMaskPtr = &config.galBlacklistSvMask;
+ initialSvId = GNSS_SV_CONFIG_GAL_INITIAL_SV_ID;
+ break;
+ default:
+ break;
+ }
+
+ if (NULL == svMaskPtr) {
+ LOC_LOGe("Invalid constellation %d", source.constellation);
+ } else {
+ // SV ID 0 = All SV IDs
+ if (0 == source.svId) {
+ *svMaskPtr = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ } else if (source.svId < initialSvId || source.svId >= initialSvId + 64) {
+ LOC_LOGe("Invalid sv id %d for sv type %d",
+ source.svId, source.constellation);
+ } else {
+ *svMaskPtr |= (1 << (source.svId - initialSvId));
+ }
+ }
+ }
+ }
+}
+
+void GnssAdapter::convertFromGnssSvIdConfig(
+ const GnssSvIdConfig& svConfig, GnssConfig& config)
+{
+ // Convert blacklisted SV mask values to vectors
+ if (svConfig.bdsBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.bdsBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_BDS_INITIAL_SV_ID, GNSS_SV_TYPE_BEIDOU);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.galBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.galBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_GAL_INITIAL_SV_ID, GNSS_SV_TYPE_GALILEO);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.gloBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.gloBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_GLO_INITIAL_SV_ID, GNSS_SV_TYPE_GLONASS);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+ if (svConfig.qzssBlacklistSvMask) {
+ convertGnssSvIdMaskToList(
+ svConfig.qzssBlacklistSvMask, config.blacklistedSvIds,
+ GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID, GNSS_SV_TYPE_QZSS);
+ config.flags |= GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT;
+ }
+}
+
+void GnssAdapter::convertGnssSvIdMaskToList(
+ uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
+ GnssSvId initialSvId, GnssSvType svType)
+{
+ GnssSvIdSource source = {};
+ source.size = sizeof(GnssSvIdSource);
+ source.constellation = svType;
+
+ // SV ID 0 => All SV IDs in mask
+ if (GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK == svIdMask) {
+ source.svId = 0;
+ svIds.push_back(source);
+ return;
+ }
+
+ // Convert each bit in svIdMask to vector entry
+ uint32_t bitNumber = 0;
+ while (svIdMask > 0) {
+ if (svIdMask & 0x1) {
+ source.svId = bitNumber + initialSvId;
+ svIds.push_back(source);
+ }
+ bitNumber++;
+ svIdMask >>= 1;
+ }
+}
+
+void GnssAdapter::reportGnssSvIdConfigEvent(const GnssSvIdConfig& config)
+{
+ struct MsgReportGnssSvIdConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ const GnssSvIdConfig mConfig;
+ inline MsgReportGnssSvIdConfig(GnssAdapter& adapter,
+ const GnssSvIdConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ mAdapter.reportGnssSvIdConfig(mConfig);
+ }
+ };
+
+ sendMsg(new MsgReportGnssSvIdConfig(*this, config));
+}
+
+void GnssAdapter::reportGnssSvIdConfig(const GnssSvIdConfig& svIdConfig)
+{
+ GnssConfig config = {};
+ config.size = sizeof(GnssConfig);
+
+ // Invoke control clients config callback
+ if (nullptr != mControlCallbacks.gnssConfigCb &&
+ svIdConfig.size == sizeof(GnssSvIdConfig)) {
+ convertFromGnssSvIdConfig(svIdConfig, config);
+ LOC_LOGd("blacklist bds 0x%" PRIx64 ", glo 0x%" PRIx64
+ ", qzss 0x%" PRIx64 ", gal 0x%" PRIx64,
+ svIdConfig.bdsBlacklistSvMask, svIdConfig.gloBlacklistSvMask,
+ svIdConfig.qzssBlacklistSvMask, svIdConfig.galBlacklistSvMask);
+ mControlCallbacks.gnssConfigCb(config);
+ } else {
+ LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
+ }
+}
+
+void
+GnssAdapter::gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config)
+{
+ struct MsgGnssUpdateSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ GnssSvTypeConfig mConfig;
+ inline MsgGnssUpdateSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api,
+ GnssSvTypeConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ // Check if feature is supported
+ if (!mApi->isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Send update request to modem
+ LocationError err = mAdapter->gnssSvTypeConfigUpdate(mConfig);
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("Set constellation request failed, err %d", err);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssUpdateSvTypeConfig(this, mLocApi, config));
+}
+
+LocationError
+GnssAdapter::gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config)
+{
+ gnssSetSvTypeConfig(config);
+ return gnssSvTypeConfigUpdate();
+}
+
+LocationError
+GnssAdapter::gnssSvTypeConfigUpdate()
+{
+ LocationError err = LOCATION_ERROR_GENERAL_FAILURE;
+ LOC_LOGd("constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64,
+ mGnssSvTypeConfig.blacklistedSvTypesMask, mGnssSvTypeConfig.enabledSvTypesMask);
+
+ if (mGnssSvTypeConfig.size == sizeof(mGnssSvTypeConfig)) {
+ GnssSvIdConfig blacklistConfig = {};
+ // Revert to previously blacklisted SVs for each enabled constellation
+ blacklistConfig = mGnssSvIdConfig;
+ // Blacklist all SVs for each disabled constellation
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask) {
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GLO_BIT) {
+ blacklistConfig.gloBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_BDS_BIT) {
+ blacklistConfig.bdsBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_QZSS_BIT) {
+ blacklistConfig.qzssBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ if (mGnssSvTypeConfig.blacklistedSvTypesMask & GNSS_SV_TYPES_MASK_GAL_BIT) {
+ blacklistConfig.galBlacklistSvMask = GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK;
+ }
+ }
+
+ // Send blacklist info
+ err = mLocApi->setBlacklistSv(blacklistConfig);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGE("Failed to send Set Blacklist");
+ }
+ // Send only enabled constellation config
+ if (mGnssSvTypeConfig.enabledSvTypesMask) {
+ GnssSvTypeConfig svTypeConfig = {sizeof(GnssSvTypeConfig), 0, 0};
+ svTypeConfig.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
+ err = mLocApi->setConstellationControl(svTypeConfig);
+ if (LOCATION_ERROR_SUCCESS != err) {
+ LOC_LOGE("Failed to send Set Constellation");
+ }
+ }
+ } else {
+ LOC_LOGE("Invalid GnssSvTypeConfig size");
+ err = LOCATION_ERROR_SUCCESS;
+ }
+
+ return err;
+}
+
+void
+GnssAdapter::gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback)
+{
+ struct MsgGnssGetSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ GnssSvTypeConfigCallback mCallback;
+ inline MsgGnssGetSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api,
+ GnssSvTypeConfigCallback callback) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api),
+ mCallback(callback) {}
+ inline virtual void proc() const {
+ if (!mApi->isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Save the callback
+ mAdapter->gnssSetSvTypeConfigCallback(mCallback);
+ // Send GET request to modem
+ LocationError err = mApi->getConstellationControl();
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("Get constellation request failed, err %d", err);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssGetSvTypeConfig(this, mLocApi, callback));
+}
+
+void
+GnssAdapter::gnssResetSvTypeConfigCommand()
+{
+ struct MsgGnssResetSvTypeConfig : public LocMsg {
+ GnssAdapter* mAdapter;
+ LocApiBase* mApi;
+ inline MsgGnssResetSvTypeConfig(
+ GnssAdapter* adapter,
+ LocApiBase* api) :
+ LocMsg(),
+ mAdapter(adapter),
+ mApi(api) {}
+ inline virtual void proc() const {
+ if (!mApi->isFeatureSupported(
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
+ LOC_LOGe("Feature not supported.");
+ } else {
+ // Reset constellation config
+ mAdapter->gnssSetSvTypeConfig({sizeof(GnssSvTypeConfig), 0, 0});
+ // Re-enforce SV blacklist config
+ LocationError err = mAdapter->gnssSvIdConfigUpdate();
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("SV Config request failed, err %d", err);
+ }
+ // Send reset request to modem
+ err = mApi->resetConstellationControl();
+ if (err != LOCATION_ERROR_SUCCESS) {
+ LOC_LOGe("Reset constellation request failed, err %d", err);
+ }
+ }
+ }
+ };
+
+ sendMsg(new MsgGnssResetSvTypeConfig(this, mLocApi));
+}
+
+void GnssAdapter::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config)
+{
+ struct MsgReportGnssSvTypeConfig : public LocMsg {
+ GnssAdapter& mAdapter;
+ const GnssSvTypeConfig mConfig;
+ inline MsgReportGnssSvTypeConfig(GnssAdapter& adapter,
+ const GnssSvTypeConfig& config) :
+ LocMsg(),
+ mAdapter(adapter),
+ mConfig(config) {}
+ inline virtual void proc() const {
+ mAdapter.reportGnssSvTypeConfig(mConfig);
+ }
+ };
+
+ sendMsg(new MsgReportGnssSvTypeConfig(*this, config));
+}
+
+void GnssAdapter::reportGnssSvTypeConfig(const GnssSvTypeConfig& config)
+{
+ // Invoke Get SV Type Callback
+ if (NULL != mGnssSvTypeConfigCb &&
+ config.size == sizeof(GnssSvTypeConfig)) {
+ LOC_LOGd("constellations blacklisted 0x%" PRIx64 ", enabled 0x%" PRIx64,
+ config.blacklistedSvTypesMask, config.enabledSvTypesMask);
+ mGnssSvTypeConfigCb(config);
+ } else {
+ LOC_LOGe("Failed to report, size %d", (uint32_t)config.size);
+ }
+}
+
uint32_t
GnssAdapter::gnssDeleteAidingDataCommand(GnssAidingData& data)
{
@@ -1140,7 +1670,6 @@
}
++it; // increment only when not erasing an iterator
}
-
}
void
@@ -1193,6 +1722,8 @@
mAdapter(adapter) {}
virtual void proc() const {
mAdapter.restartSessions();
+ mAdapter.gnssSvIdConfigUpdate();
+ mAdapter.gnssSvTypeConfigUpdate();
}
};
diff --git a/sdm845/gnss/GnssAdapter.h b/sdm845/gnss/GnssAdapter.h
index 7f4986f..580c7cd 100644
--- a/sdm845/gnss/GnssAdapter.h
+++ b/sdm845/gnss/GnssAdapter.h
@@ -94,10 +94,13 @@
GnssSvUsedInPosition mGnssSvIdUsedInPosition;
bool mGnssSvIdUsedInPosAvail;
- /* ==== CONTROL ======================================================================== */
+ /* ==== CONTROL ================================================================= */
LocationControlCallbacks mControlCallbacks;
uint32_t mPowerVoteId;
uint32_t mNmeaMask;
+ GnssSvIdConfig mGnssSvIdConfig;
+ GnssSvTypeConfig mGnssSvTypeConfig;
+ GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
/* ==== NI ============================================================================= */
NiData mNiData;
@@ -191,7 +194,7 @@
bool hasNiNotifyCallback(LocationAPI* client);
NiData& getNiData() { return mNiData; }
- /* ==== CONTROL ======================================================================== */
+ /* ==== CONTROL CLIENT ================================================================= */
/* ======== COMMANDS ====(Called from Client Thread)==================================== */
uint32_t enableCommand(LocationTechnologyType techType);
void disableCommand(uint32_t id);
@@ -199,9 +202,31 @@
void readConfigCommand();
void setConfigCommand();
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
+ uint32_t* gnssGetConfigCommand(GnssConfigFlagsMask mask);
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
void gnssUpdateXtraThrottleCommand(const bool enabled);
+ /* ==== GNSS SV TYPE CONFIG ============================================================ */
+ /* ==== COMMANDS ====(Called from Client Thread)======================================== */
+ /* ==== These commands are received directly from client bypassing Location API ======== */
+ void gnssUpdateSvTypeConfigCommand(GnssSvTypeConfig config);
+ void gnssGetSvTypeConfigCommand(GnssSvTypeConfigCallback callback);
+ void gnssResetSvTypeConfigCommand();
+
+ /* ==== UTILITIES ====================================================================== */
+ LocationError gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds);
+ LocationError gnssSvIdConfigUpdate();
+ LocationError gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config);
+ LocationError gnssSvTypeConfigUpdate();
+ inline void gnssSetSvTypeConfig(const GnssSvTypeConfig& config)
+ { mGnssSvTypeConfig = config; }
+ inline void gnssSetSvTypeConfigCallback(GnssSvTypeConfigCallback callback)
+ { mGnssSvTypeConfigCb = callback; }
+ inline GnssSvTypeConfigCallback gnssGetSvTypeConfigCallback()
+ { return mGnssSvTypeConfigCb; }
+
+ /* ==== AGPS =========================================================================== */
+ /* ======== COMMANDS ====(Called from Client Thread)==================================== */
void initDefaultAgpsCommand();
void initAgpsCommand(const AgpsCbInfo& cbInfo);
void dataConnOpenCommand(AGpsExtType agpsType,
@@ -236,6 +261,8 @@
int msInWeek);
virtual void reportSvMeasurementEvent(GnssSvMeasurementSet &svMeasurementSet);
virtual void reportSvPolynomialEvent(GnssSvPolynomial &svPolynomial);
+ virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
+ virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
virtual bool requestATL(int connHandle, LocAGpsType agps_type, LocApnTypeMask mask);
virtual bool releaseATL(int connHandle);
@@ -254,6 +281,8 @@
void reportNmea(const char* nmea, size_t length);
bool requestNiNotify(const GnssNiNotification& notify, const void* data);
void reportGnssMeasurementData(const GnssMeasurementsNotification& measurements);
+ void reportGnssSvIdConfig(const GnssSvIdConfig& config);
+ void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
/*======== GNSSDEBUG ================================================================*/
bool getDebugReport(GnssDebugReport& report);
@@ -283,6 +312,13 @@
static void convertSatelliteInfo(std::vector<GnssDebugSatelliteInfo>& out,
const GnssSvType& in_constellation,
const SystemStatusReports& in);
+ static void convertToGnssSvIdConfig(
+ const std::vector<GnssSvIdSource>& blacklistedSvIds, GnssSvIdConfig& config);
+ static void convertFromGnssSvIdConfig(
+ const GnssSvIdConfig& svConfig, GnssConfig& config);
+ static void convertGnssSvIdMaskToList(
+ uint64_t svIdMask, std::vector<GnssSvIdSource>& svIds,
+ GnssSvId initialSvId, GnssSvType svType);
void injectLocationCommand(double latitude, double longitude, float accuracy);
void injectTimeCommand(int64_t time, int64_t timeReference, int32_t uncertainty);
diff --git a/sdm845/gnss/location_gnss.cpp b/sdm845/gnss/location_gnss.cpp
index 3e989c9..0dac13d 100644
--- a/sdm845/gnss/location_gnss.cpp
+++ b/sdm845/gnss/location_gnss.cpp
@@ -51,6 +51,11 @@
static uint32_t enable(LocationTechnologyType techType);
static void disable(uint32_t id);
static uint32_t* gnssUpdateConfig(GnssConfig config);
+static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
+
+static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config);
+static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback);
+static void gnssResetSvTypeConfig();
static void injectLocation(double latitude, double longitude, float accuracy);
static void injectTime(int64_t time, int64_t timeReference, int32_t uncertainty);
@@ -77,6 +82,10 @@
enable,
disable,
gnssUpdateConfig,
+ gnssGetConfig,
+ gnssUpdateSvTypeConfig,
+ gnssGetSvTypeConfig,
+ gnssResetSvTypeConfig,
gnssDeleteAidingData,
gnssUpdateXtraThrottle,
injectLocation,
@@ -167,7 +176,7 @@
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
{
if (NULL != gGnssAdapter) {
- return gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
+ gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
}
}
@@ -183,7 +192,7 @@
static void disable(uint32_t id)
{
if (NULL != gGnssAdapter) {
- return gGnssAdapter->disableCommand(id);
+ gGnssAdapter->disableCommand(id);
}
}
@@ -196,6 +205,36 @@
}
}
+static uint32_t* gnssGetConfig(GnssConfigFlagsMask mask)
+{
+ if (NULL != gGnssAdapter) {
+ return gGnssAdapter->gnssGetConfigCommand(mask);
+ } else {
+ return NULL;
+ }
+}
+
+static void gnssUpdateSvTypeConfig(GnssSvTypeConfig& config)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssUpdateSvTypeConfigCommand(config);
+ }
+}
+
+static void gnssGetSvTypeConfig(GnssSvTypeConfigCallback& callback)
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssGetSvTypeConfigCommand(callback);
+ }
+}
+
+static void gnssResetSvTypeConfig()
+{
+ if (NULL != gGnssAdapter) {
+ gGnssAdapter->gnssResetSvTypeConfigCommand();
+ }
+}
+
static uint32_t gnssDeleteAidingData(GnssAidingData& data)
{
if (NULL != gGnssAdapter) {
diff --git a/sdm845/location/LocationAPI.cpp b/sdm845/location/LocationAPI.cpp
index 0111a9c..6bd5b15 100644
--- a/sdm845/location/LocationAPI.cpp
+++ b/sdm845/location/LocationAPI.cpp
@@ -627,6 +627,21 @@
return ids;
}
+uint32_t* LocationControlAPI::gnssGetConfig(GnssConfigFlagsMask mask) {
+
+ uint32_t* ids = NULL;
+ pthread_mutex_lock(&gDataMutex);
+
+ if (NULL != gData.gnssInterface) {
+ ids = gData.gnssInterface->gnssGetConfig(mask);
+ } else {
+ LOC_LOGe("No gnss interface available for Control API client %p", this);
+ }
+
+ pthread_mutex_unlock(&gDataMutex);
+ return ids;
+}
+
uint32_t
LocationControlAPI::gnssDeleteAidingData(GnssAidingData& data)
{
diff --git a/sdm845/location/LocationAPI.h b/sdm845/location/LocationAPI.h
index 530b1b0..de18031 100644
--- a/sdm845/location/LocationAPI.h
+++ b/sdm845/location/LocationAPI.h
@@ -229,6 +229,7 @@
GNSS_CONFIG_FLAGS_EM_PDN_FOR_EM_SUPL_VALID_BIT = (1<<7),
GNSS_CONFIG_FLAGS_SUPL_EM_SERVICES_BIT = (1<<8),
GNSS_CONFIG_FLAGS_SUPL_MODE_BIT = (1<<9),
+ GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT = (1<<10)
} GnssConfigFlagsBits;
typedef enum {
@@ -537,12 +538,22 @@
GnssSvOptionsMask gnssSvOptionsMask; // Bitwise OR of GnssSvOptionsBits
} GnssSv;
-typedef struct {
+struct GnssConfigSetAssistanceServer {
size_t size; // set to sizeof(GnssConfigSetAssistanceServer)
GnssAssistanceType type; // SUPL or C2K
const char* hostName; // null terminated string
uint32_t port; // port of server
-} GnssConfigSetAssistanceServer;
+
+ inline bool equals(const GnssConfigSetAssistanceServer& config) {
+ if (config.type == type && config.port == port &&
+ ((NULL == config.hostName && NULL == hostName) ||
+ (NULL != config.hostName && NULL != hostName &&
+ 0 == strcmp(config.hostName, hostName)))) {
+ return true;
+ }
+ return false;
+ }
+};
typedef struct {
size_t size; // set to sizeof(GnssMeasurementsData)
@@ -602,7 +613,40 @@
GnssMeasurementsClock clock; // clock
} GnssMeasurementsNotification;
+typedef uint32_t GnssSvId;
+
+struct GnssSvIdSource{
+ size_t size; // set to sizeof(GnssSvIdSource)
+ GnssSvType constellation; // constellation for the sv to blacklist
+ GnssSvId svId; // sv id to blacklist
+};
+inline bool operator ==(GnssSvIdSource const& left, GnssSvIdSource const& right) {
+ return left.size == right.size &&
+ left.constellation == right.constellation && left.svId == right.svId;
+}
+
+#define GNSS_SV_CONFIG_ALL_BITS_ENABLED_MASK ((uint64_t)0xFFFFFFFFFFFFFFFF)
typedef struct {
+ size_t size; // set to sizeof(GnssSvIdConfig)
+
+ // GLONASS - SV 65 maps to bit 0
+#define GNSS_SV_CONFIG_GLO_INITIAL_SV_ID 65
+ uint64_t gloBlacklistSvMask;
+
+ // BEIDOU - SV 201 maps to bit 0
+#define GNSS_SV_CONFIG_BDS_INITIAL_SV_ID 201
+ uint64_t bdsBlacklistSvMask;
+
+ // QZSS - SV 193 maps to bit 0
+#define GNSS_SV_CONFIG_QZSS_INITIAL_SV_ID 193
+ uint64_t qzssBlacklistSvMask;
+
+ // GAL - SV 301 maps to bit 0
+#define GNSS_SV_CONFIG_GAL_INITIAL_SV_ID 301
+ uint64_t galBlacklistSvMask;
+} GnssSvIdConfig;
+
+struct GnssConfig{
size_t size; // set to sizeof(GnssConfig)
GnssConfigFlagsMask flags; // bitwise OR of GnssConfigFlagsBits to mark which params are valid
GnssConfigGpsLock gpsLock;
@@ -615,7 +659,26 @@
GnssConfigEmergencyPdnForEmergencySupl emergencyPdnForEmergencySupl;
GnssConfigSuplEmergencyServices suplEmergencyServices;
GnssConfigSuplModeMask suplModeMask; //bitwise OR of GnssConfigSuplModeBits
-} GnssConfig;
+ std::vector<GnssSvIdSource> blacklistedSvIds;
+
+ inline bool equals(const GnssConfig& config) {
+ if (flags == config.flags &&
+ gpsLock == config.gpsLock &&
+ suplVersion == config.suplVersion &&
+ assistanceServer.equals(config.assistanceServer) &&
+ lppProfile == config.lppProfile &&
+ lppeControlPlaneMask == config.lppeControlPlaneMask &&
+ lppeUserPlaneMask == config.lppeUserPlaneMask &&
+ aGlonassPositionProtocolMask == config.aGlonassPositionProtocolMask &&
+ emergencyPdnForEmergencySupl == config.emergencyPdnForEmergencySupl &&
+ suplEmergencyServices == config.suplEmergencyServices &&
+ suplModeMask == config.suplModeMask &&
+ blacklistedSvIds == config.blacklistedSvIds) {
+ return true;
+ }
+ return false;
+ }
+};
typedef struct {
size_t size; // set to sizeof
@@ -744,6 +807,11 @@
GnssMeasurementsNotification gnssMeasurementsNotification
)> gnssMeasurementsCallback;
+/* Provides the current GNSS configuration to the client */
+typedef std::function<void(
+ GnssConfig& config
+)> gnssConfigCallback;
+
typedef struct {
size_t size; // set to sizeof(LocationCallbacks)
capabilitiesCallback capabilitiesCb; // mandatory
@@ -908,6 +976,7 @@
size_t size; // set to sizeof(LocationControlCallbacks)
responseCallback responseCb; // mandatory
collectiveResponseCallback collectiveResponseCb; // mandatory
+ gnssConfigCallback gnssConfigCb; // optional
} LocationControlCallbacks;
class LocationControlAPI
@@ -961,6 +1030,21 @@
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
uint32_t* gnssUpdateConfig(GnssConfig config);
+ /* gnssGetConfig fetches the current constellation and SV configuration
+ on the GNSS engine.
+ Returns a session id array with an id for each of the bits set in
+ the mask parameter, order from low bits to high bits.
+ Response is sent via the registered gnssConfigCallback.
+ This effect is global for all clients of LocationAPI
+ collectiveResponseCallback returns:
+ LOCATION_ERROR_SUCCESS if session was successful
+ LOCATION_ERROR_INVALID_PARAMETER if any parameter is invalid
+ LOCATION_ERROR_CALLBACK_MISSING If no gnssConfigCallback
+ was passed in createInstance
+ LOCATION_ERROR_NOT_SUPPORTED If read of requested configuration
+ is not supported */
+ uint32_t* gnssGetConfig(GnssConfigFlagsMask mask);
+
/* delete specific gnss aiding data for testing, which returns a session id
that will be returned in responseCallback to match command with response.
Only allowed in userdebug builds. This effect is global for all clients of LocationAPI
diff --git a/sdm845/location/LocationAPIClientBase.cpp b/sdm845/location/LocationAPIClientBase.cpp
index 626968c..65a0984 100644
--- a/sdm845/location/LocationAPIClientBase.cpp
+++ b/sdm845/location/LocationAPIClientBase.cpp
@@ -26,7 +26,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#define LOG_NDDEBUG 0
+#define LOG_NDEBUG 0
#define LOG_TAG "LocSvc_APIClientBase"
#include <loc_pla.h>
@@ -45,7 +45,7 @@
pthread_mutex_init(&mMutex, nullptr);
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
memset(&mConfig, 0, sizeof(GnssConfig));
@@ -75,7 +75,7 @@
}
for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
pthread_mutex_unlock(&mMutex);
@@ -142,24 +142,43 @@
uint32_t LocationAPIControlClient::locAPIGnssUpdateConfig(GnssConfig config)
{
uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
- if (memcmp(&mConfig, &config, sizeof(GnssConfig)) == 0) {
- LOC_LOGV("%s:%d] GnssConfig is identical to previous call", __FUNCTION__, __LINE__);
- retVal = LOCATION_ERROR_SUCCESS;
- return retVal;
+
+ pthread_mutex_lock(&mMutex);
+ if (mLocationControlAPI) {
+ if (mConfig.equals(config)) {
+ LOC_LOGv("GnssConfig is identical to previous call");
+ retVal = LOCATION_ERROR_SUCCESS;
+ } else {
+ mConfig = config;
+ uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
+ LOC_LOGv("gnssUpdateConfig return array: %p", idArray);
+ if (nullptr != idArray) {
+ if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr()) {
+ mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].reset(idArray);
+ }
+ mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].push(new GnssUpdateConfigRequest(*this));
+ retVal = LOCATION_ERROR_SUCCESS;
+ }
+ }
}
+ pthread_mutex_unlock(&mMutex);
+ return retVal;
+}
+
+uint32_t LocationAPIControlClient::locAPIGnssGetConfig(GnssConfigFlagsMask mask)
+{
+ uint32_t retVal = LOCATION_ERROR_GENERAL_FAILURE;
pthread_mutex_lock(&mMutex);
if (mLocationControlAPI) {
- memcpy(&mConfig, &config, sizeof(GnssConfig));
-
- uint32_t* idArray = mLocationControlAPI->gnssUpdateConfig(config);
- LOC_LOGV("%s:%d] gnssUpdateConfig return array: %p", __FUNCTION__, __LINE__, idArray);
- if (idArray != nullptr) {
- if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() != CONFIG_SESSION_ID) {
- mRequestQueues[CTRL_REQUEST_CONFIG].reset(CONFIG_SESSION_ID);
+ uint32_t* idArray = mLocationControlAPI->gnssGetConfig(mask);
+ LOC_LOGv("gnssGetConfig return array: %p", idArray);
+ if (nullptr != idArray) {
+ if (nullptr != mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr()) {
+ mRequestQueues[CTRL_REQUEST_CONFIG_GET].reset(idArray);
}
- mRequestQueues[CTRL_REQUEST_CONFIG].push(new GnssUpdateConfigRequest(*this));
+ mRequestQueues[CTRL_REQUEST_CONFIG_GET].push(new GnssGetConfigRequest(*this));
retVal = LOCATION_ERROR_SUCCESS;
}
}
@@ -191,12 +210,7 @@
LOC_LOGV("%s:%d] SUCCESS: %d id: %d", __FUNCTION__, __LINE__, errors[i], ids[i]);
}
}
- LocationAPIRequest* request = nullptr;
- pthread_mutex_lock(&mMutex);
- if (mRequestQueues[CTRL_REQUEST_CONFIG].getSession() == CONFIG_SESSION_ID) {
- request = mRequestQueues[CTRL_REQUEST_CONFIG].pop();
- }
- pthread_mutex_unlock(&mMutex);
+ LocationAPIRequest* request = getRequestBySessionArrayPtr(ids);
if (request) {
request->onCollectiveResponse(count, errors, ids);
delete request;
@@ -207,13 +221,30 @@
{
pthread_mutex_lock(&mMutex);
LocationAPIRequest* request = nullptr;
- for (int i = 0; i < CTRL_REQUEST_MAX; i++) {
- if (i != CTRL_REQUEST_CONFIG &&
- mRequestQueues[i].getSession() == session) {
- request = mRequestQueues[i].pop();
- break;
- }
+
+ if (mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].getSession() == session) {
+ request = mRequestQueues[CTRL_REQUEST_DELETEAIDINGDATA].pop();
+ } else if (mRequestQueues[CTRL_REQUEST_CONTROL].getSession() == session) {
+ request = mRequestQueues[CTRL_REQUEST_CONTROL].pop();
}
+
+ pthread_mutex_unlock(&mMutex);
+ return request;
+}
+
+LocationAPIRequest*
+LocationAPIControlClient::getRequestBySessionArrayPtr(
+ uint32_t* sessionArrayPtr)
+{
+ pthread_mutex_lock(&mMutex);
+ LocationAPIRequest* request = nullptr;
+
+ if (mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].getSessionArrayPtr() == sessionArrayPtr) {
+ request = mRequestQueues[CTRL_REQUEST_CONFIG_UPDATE].pop();
+ } else if (mRequestQueues[CTRL_REQUEST_CONFIG_GET].getSessionArrayPtr() == sessionArrayPtr) {
+ request = mRequestQueues[CTRL_REQUEST_CONFIG_GET].pop();
+ }
+
pthread_mutex_unlock(&mMutex);
return request;
}
@@ -234,7 +265,7 @@
pthread_mutex_init(&mMutex, &attr);
for (int i = 0; i < REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
}
@@ -291,7 +322,7 @@
}
for (int i = 0; i < REQUEST_MAX; i++) {
- mRequestQueues[i].reset(0);
+ mRequestQueues[i].reset((uint32_t)0);
}
pthread_mutex_unlock(&mMutex);
diff --git a/sdm845/location/LocationAPIClientBase.h b/sdm845/location/LocationAPIClientBase.h
index 4bd1466..4d48932 100644
--- a/sdm845/location/LocationAPIClientBase.h
+++ b/sdm845/location/LocationAPIClientBase.h
@@ -57,7 +57,8 @@
enum CTRL_REQUEST_TYPE {
CTRL_REQUEST_DELETEAIDINGDATA = 0,
CTRL_REQUEST_CONTROL,
- CTRL_REQUEST_CONFIG,
+ CTRL_REQUEST_CONFIG_UPDATE,
+ CTRL_REQUEST_CONFIG_GET,
CTRL_REQUEST_MAX,
};
@@ -74,12 +75,13 @@
class RequestQueue {
public:
- RequestQueue(): mSession(0) {
+ RequestQueue(): mSession(0), mSessionArrayPtr(nullptr) {
}
virtual ~RequestQueue() {
- reset(0);
+ reset((uint32_t)0);
}
void inline setSession(uint32_t session) { mSession = session; }
+ void inline setSessionArrayPtr(uint32_t* ptr) { mSessionArrayPtr = ptr; }
void reset(uint32_t session) {
LocationAPIRequest* request = nullptr;
while (!mQueue.empty()) {
@@ -89,6 +91,10 @@
}
mSession = session;
}
+ void reset(uint32_t* sessionArrayPtr) {
+ reset((uint32_t)0);
+ mSessionArrayPtr = sessionArrayPtr;
+ }
void push(LocationAPIRequest* request) {
mQueue.push(request);
}
@@ -101,8 +107,10 @@
return request;
}
uint32_t getSession() { return mSession; }
+ uint32_t* getSessionArrayPtr() { return mSessionArrayPtr; }
private:
uint32_t mSession;
+ uint32_t* mSessionArrayPtr;
std::queue<LocationAPIRequest*> mQueue;
};
@@ -114,12 +122,15 @@
LocationAPIControlClient& operator=(const LocationAPIControlClient&) = delete;
LocationAPIRequest* getRequestBySession(uint32_t session);
+ LocationAPIRequest* getRequestBySessionArrayPtr(uint32_t* sessionArrayPtr);
// LocationControlAPI
uint32_t locAPIGnssDeleteAidingData(GnssAidingData& data);
uint32_t locAPIEnable(LocationTechnologyType techType);
void locAPIDisable();
uint32_t locAPIGnssUpdateConfig(GnssConfig config);
+ uint32_t locAPIGnssGetConfig(GnssConfigFlagsMask config);
+ inline LocationControlAPI* getControlAPI() { return mLocationControlAPI; }
// callbacks
void onCtrlResponseCb(LocationError error, uint32_t id);
@@ -130,6 +141,8 @@
inline virtual void onDisableCb(LocationError /*error*/) {}
inline virtual void onGnssUpdateConfigCb(
size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
+ inline virtual void onGnssGetConfigCb(
+ size_t /*count*/, LocationError* /*errors*/, uint32_t* /*ids*/) {}
class GnssDeleteAidingDataRequest : public LocationAPIRequest {
public:
@@ -167,6 +180,15 @@
LocationAPIControlClient& mAPI;
};
+ class GnssGetConfigRequest : public LocationAPIRequest {
+ public:
+ GnssGetConfigRequest(LocationAPIControlClient& API) : mAPI(API) {}
+ inline void onCollectiveResponse(size_t count, LocationError* errors, uint32_t* ids) {
+ mAPI.onGnssGetConfigCb(count, errors, ids);
+ }
+ LocationAPIControlClient& mAPI;
+ };
+
private:
pthread_mutex_t mMutex;
LocationControlAPI* mLocationControlAPI;
diff --git a/sdm845/location/location_interface.h b/sdm845/location/location_interface.h
index 27589f7..f4f904d 100644
--- a/sdm845/location/location_interface.h
+++ b/sdm845/location/location_interface.h
@@ -47,6 +47,10 @@
uint32_t (*enable)(LocationTechnologyType techType);
void (*disable)(uint32_t id);
uint32_t* (*gnssUpdateConfig)(GnssConfig config);
+ uint32_t* (*gnssGetConfig)(GnssConfigFlagsMask config);
+ void (*gnssUpdateSvTypeConfig)(GnssSvTypeConfig& config);
+ void (*gnssGetSvTypeConfig)(GnssSvTypeConfigCallback& callback);
+ void (*gnssResetSvTypeConfig)();
uint32_t (*gnssDeleteAidingData)(GnssAidingData& data);
void (*gnssUpdateXtraThrottle)(const bool enabled);
void (*injectLocation)(double latitude, double longitude, float accuracy);
diff --git a/sdm845/utils/gps_extended_c.h b/sdm845/utils/gps_extended_c.h
index f6b49bf..892bb09 100644
--- a/sdm845/utils/gps_extended_c.h
+++ b/sdm845/utils/gps_extended_c.h
@@ -116,8 +116,9 @@
LOC_SUPPORTED_FEATURE_ODCPI_2_V02 = 0, /**< Support ODCPI version 2 feature */
LOC_SUPPORTED_FEATURE_WIFI_AP_DATA_INJECT_2_V02, /**< Support Wifi AP data inject version 2 feature */
LOC_SUPPORTED_FEATURE_DEBUG_NMEA_V02, /**< Support debug NMEA feature */
- LOC_SUPPORTED_FEATURE_GNSS_ONLY_POSITION_REPORT, /**< Support GNSS Only position reports */
- LOC_SUPPORTED_FEATURE_FDCL /**< Support FDCL */
+ LOC_SUPPORTED_FEATURE_GNSS_ONLY_POSITION_REPORT_V02, /**< Support the GNSS only position report feature */
+ LOC_SUPPORTED_FEATURE_FDCL_V02, /**< Support the FDCL feature */
+ LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02, /**< Support the GNSS constellation enablement feature */
} loc_supported_feature_enum;
typedef struct {
@@ -1281,6 +1282,32 @@
Gnss_Srn_MacAddr_Type macAddrType; /* SRN AP MAC Address type */
} GnssSrnDataReq;
+/* Mask indicating enabled or disabled constellations */
+typedef uint64_t GnssSvTypesMask;
+typedef enum {
+ GNSS_SV_TYPES_MASK_GLO_BIT = (1<<0),
+ GNSS_SV_TYPES_MASK_BDS_BIT = (1<<1),
+ GNSS_SV_TYPES_MASK_QZSS_BIT = (1<<2),
+ GNSS_SV_TYPES_MASK_GAL_BIT = (1<<3),
+} GnssSvTypesMaskBits;
+
+/* This SV Type config is injected directly to GNSS Adapter
+ * bypassing Location API */
+typedef struct {
+ size_t size; // set to sizeof(GnssSvTypeConfig)
+ // Enabled Constellations
+ GnssSvTypesMask enabledSvTypesMask;
+ // Disabled Constellations
+ GnssSvTypesMask blacklistedSvTypesMask;
+} GnssSvTypeConfig;
+
+/* Provides the current GNSS SV Type configuration to the client.
+ * This is fetched via direct call to GNSS Adapter bypassing
+ * Location API */
+typedef std::function<void(
+ const GnssSvTypeConfig& config
+)> GnssSvTypeConfigCallback;
+
/*
* Represents the status of AGNSS augmented to support IPv4.
*/