FR 45651 - GNSS SV/Constellation Control

Adding support for configuring GNSS SVs
and constellations to be used.

Change-Id: I47d5cd9d08ac9aaf633be2fe3b1bd152a2f4293b
CRs-Fixed: 2184871
This commit is contained in:
Saurabh Srivastava 2018-05-20 19:29:46 +05:30
parent a93b10c677
commit eaf7e54b54
17 changed files with 956 additions and 43 deletions

View file

@ -234,6 +234,10 @@ Return<bool> Gnss::updateConfiguration(GnssConfig& gnssConfig) {
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;
}

View file

@ -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 gnss {
namespace V1_1 {
namespace implementation {
using ::android::hardware::gnss::V1_0::GnssConstellationType;
GnssConfiguration::GnssConfiguration(Gnss* gnss) : mGnss(gnss) {
}
@ -222,10 +225,60 @@ Return<bool> GnssConfiguration::setEmergencySuplPdn(bool enabled) {
// 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

View file

@ -64,6 +64,9 @@ struct GnssConfiguration : public IGnssConfiguration {
private:
Gnss* mGnss = nullptr;
void setBlacklistedSource(
GnssSvIdSource& copyToSource,
const GnssConfiguration::BlacklistedSource& copyFromSource);
};
} // namespace implementation

View file

@ -167,5 +167,10 @@ bool LocAdapterBase::
GpsLocationExtended& /*location_extended*/, LocPosTechMask /*tech_mask*/)
DEFAULT_IMPL(false)
void LocAdapterBase::reportGnssSvIdConfigEvent(const GnssSvIdConfig& /*config*/)
DEFAULT_IMPL()
void LocAdapterBase::reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& /*config*/)
DEFAULT_IMPL()
} // namespace loc_core

View file

@ -157,6 +157,8 @@ public:
virtual bool reportWwanZppFix(LocGpsLocation &zppLoc);
virtual bool reportZppBestAvailableFix(LocGpsLocation &zppLoc,
GpsLocationExtended &location_extended, LocPosTechMask tech_mask);
virtual void reportGnssSvIdConfigEvent(const GnssSvIdConfig& config);
virtual void reportGnssSvTypeConfigEvent(const GnssSvTypeConfig& config);
};
} // namespace loc_core

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2014, 2016-2017 The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2014, 2016-2018 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
@ -423,6 +423,28 @@ void LocApiBase::reportGnssMeasurementData(GnssMeasurementsNotification& measure
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)
@ -591,4 +613,22 @@ LocationError LocApiBase::
setXtraVersionCheckSync(uint32_t /*check*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
LocationError LocApiBase::setBlacklistSvSync(const GnssSvIdConfig& /*config*/)
DEFAULT_IMPL(LOCATION_ERROR_SUCCESS)
void LocApiBase::setBlacklistSv(const GnssSvIdConfig& /*config*/)
DEFAULT_IMPL()
void LocApiBase::getBlacklistSv()
DEFAULT_IMPL()
void LocApiBase::setConstellationControl(const GnssSvTypeConfig& /*config*/)
DEFAULT_IMPL()
void LocApiBase::getConstellationControl()
DEFAULT_IMPL()
void LocApiBase::resetConstellationControl()
DEFAULT_IMPL()
} // namespace loc_core

View file

@ -157,6 +157,8 @@ public:
void reportWwanZppFix(LocGpsLocation &zppLoc);
void reportZppBestAvailableFix(LocGpsLocation &zppLoc, GpsLocationExtended &location_extended,
LocPosTechMask tech_mask);
void reportGnssSvIdConfig(const GnssSvIdConfig& config);
void reportGnssSvTypeConfig(const GnssSvTypeConfig& config);
// downward calls
// All below functions are to be defined by adapter specific modules:
@ -260,6 +262,13 @@ public:
virtual LocationError setXtraVersionCheckSync(uint32_t check);
/* Requests for SV/Constellation Control */
virtual LocationError setBlacklistSvSync(const GnssSvIdConfig& config);
virtual void setBlacklistSv(const GnssSvIdConfig& config);
virtual void getBlacklistSv();
virtual void setConstellationControl(const GnssSvTypeConfig& config);
virtual void getConstellationControl();
virtual void resetConstellationControl();
};
typedef LocApiBase* (getLocApi_t)(LOC_API_ADAPTER_EVENT_MASK_T exMask,

View file

@ -74,6 +74,9 @@ GnssAdapter::GnssAdapter() :
mControlCallbacks(),
mPowerVoteId(0),
mNmeaMask(0),
mGnssSvIdConfig(),
mGnssSvTypeConfig(),
mGnssSvTypeConfigCb(nullptr),
mNiData(),
mAgpsManager(),
mAgpsCbInfo(),
@ -1037,6 +1040,24 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
}
}
}
if (gnssConfigRequested.flags & GNSS_CONFIG_FLAGS_BLACKLISTED_SV_IDS_BIT) {
index++;
// Check if feature is supported
if (!ContextBase::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 = adapter.gnssSvIdConfigUpdateSync(gnssConfigRequested.blacklistedSvIds);
if (LOCATION_ERROR_SUCCESS != err) {
LOC_LOGe("Failed to send config to modem, err %d", err);
}
}
if (index < countOfConfigs) {
errsList[index] = err;
}
}
configCollectiveResponse->returnToSender(errsList);
}));
}
@ -1051,6 +1072,521 @@ GnssAdapter::gnssUpdateConfigCommand(GnssConfig config)
return ids;
}
void
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
gnssSvIdConfigUpdate();
}
void
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
mLocApi->setBlacklistSv(mGnssSvIdConfig);
}
LocationError
GnssAdapter::gnssSvIdConfigUpdateSync(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 gnssSvIdConfigUpdateSync();
}
LocationError
GnssAdapter::gnssSvIdConfigUpdateSync()
{
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->setBlacklistSvSync(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 (!ContextBase::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
mApi.getBlacklistSv();
err = LOCATION_ERROR_SUCCESS;
}
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 (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
} else {
// Send update request to modem
mAdapter->gnssSvTypeConfigUpdate(mConfig);
}
}
};
sendMsg(new MsgGnssUpdateSvTypeConfig(this, mLocApi, config));
}
void
GnssAdapter::gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config)
{
gnssSetSvTypeConfig(config);
gnssSvTypeConfigUpdate();
}
void
GnssAdapter::gnssSvTypeConfigUpdate()
{
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
mLocApi->setBlacklistSv(blacklistConfig);
// Send only enabled constellation config
if (mGnssSvTypeConfig.enabledSvTypesMask) {
GnssSvTypeConfig svTypeConfig = {sizeof(GnssSvTypeConfig), 0, 0};
svTypeConfig.enabledSvTypesMask = mGnssSvTypeConfig.enabledSvTypesMask;
mLocApi->setConstellationControl(svTypeConfig);
}
} else {
LOC_LOGE("Invalid GnssSvTypeConfig size");
}
}
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 (!ContextBase::isFeatureSupported(
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02)) {
LOC_LOGe("Feature not supported.");
} else {
// Save the callback
mAdapter->gnssSetSvTypeConfigCallback(mCallback);
// Send GET request to modem
mApi->getConstellationControl();
}
}
};
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 (!ContextBase::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
mAdapter->gnssSvIdConfigUpdate();
// Send reset request to modem
mApi->resetConstellationControl();
}
}
};
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);
}
}
void GnssAdapter::deleteAidingData(const GnssAidingData &data, uint32_t sessionId) {
mLocApi->deleteAidingData(data, new LocApiResponse(*getContext(),
[this, sessionId] (LocationError err) {
@ -1345,6 +1881,8 @@ GnssAdapter::handleEngineUpEvent()
mAdapter.broadcastCapabilities(mAdapter.getCapabilities());
// restart sessions
mAdapter.restartSessions();
mAdapter.gnssSvIdConfigUpdate();
mAdapter.gnssSvTypeConfigUpdate();
}
};

View file

@ -103,6 +103,9 @@ class GnssAdapter : public LocAdapterBase {
LocationControlCallbacks mControlCallbacks;
uint32_t mPowerVoteId;
uint32_t mNmeaMask;
GnssSvIdConfig mGnssSvIdConfig;
GnssSvTypeConfig mGnssSvTypeConfig;
GnssSvTypeConfigCallback mGnssSvTypeConfigCb;
/* ==== NI ============================================================================= */
NiData mNiData;
@ -200,7 +203,7 @@ public:
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);
@ -210,10 +213,34 @@ public:
void requestUlpCommand();
void initEngHubProxyCommand();
uint32_t* gnssUpdateConfigCommand(GnssConfig config);
uint32_t* gnssGetConfigCommand(GnssConfigFlagsMask mask);
uint32_t gnssDeleteAidingDataCommand(GnssAidingData& data);
void deleteAidingData(const GnssAidingData &data, uint32_t sessionId);
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 gnssSvIdConfigUpdateSync(const std::vector<GnssSvIdSource>& blacklistedSvIds);
LocationError gnssSvIdConfigUpdateSync();
void gnssSvIdConfigUpdate(const std::vector<GnssSvIdSource>& blacklistedSvIds);
void gnssSvIdConfigUpdate();
void gnssSvTypeConfigUpdate(const GnssSvTypeConfig& config);
void 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,
@ -251,6 +278,8 @@ public:
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);
@ -271,6 +300,8 @@ public:
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);
@ -296,6 +327,13 @@ public:
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);

View file

@ -51,6 +51,11 @@ static void setControlCallbacks(LocationControlCallbacks& controlCallbacks);
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 @@ static const GnssInterface gGnssInterface = {
enable,
disable,
gnssUpdateConfig,
gnssGetConfig,
gnssUpdateSvTypeConfig,
gnssGetSvTypeConfig,
gnssResetSvTypeConfig,
gnssDeleteAidingData,
gnssUpdateXtraThrottle,
injectLocation,
@ -167,7 +176,7 @@ static void gnssNiResponse(LocationAPI* client, uint32_t id, GnssNiResponse resp
static void setControlCallbacks(LocationControlCallbacks& controlCallbacks)
{
if (NULL != gGnssAdapter) {
return gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
gGnssAdapter->setControlCallbacksCommand(controlCallbacks);
}
}
@ -183,7 +192,7 @@ static uint32_t enable(LocationTechnologyType techType)
static void disable(uint32_t id)
{
if (NULL != gGnssAdapter) {
return gGnssAdapter->disableCommand(id);
gGnssAdapter->disableCommand(id);
}
}
@ -196,6 +205,36 @@ static uint32_t* gnssUpdateConfig(GnssConfig config)
}
}
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) {

View file

@ -628,6 +628,21 @@ LocationControlAPI::gnssUpdateConfig(GnssConfig config)
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)
{

View file

@ -178,6 +178,7 @@ typedef struct {
size_t size; // set to sizeof(LocationControlCallbacks)
responseCallback responseCb; // mandatory
collectiveResponseCallback collectiveResponseCb; // mandatory
gnssConfigCallback gnssConfigCb; // optional
} LocationControlCallbacks;
class LocationControlAPI : public ILocationControlAPI
@ -231,6 +232,21 @@ public:
LOCATION_ERROR_GENERAL_FAILURE if failure for any other reason */
virtual uint32_t* gnssUpdateConfig(GnssConfig config) override;
/* 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

View file

@ -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 @@ LocationAPIControlClient::LocationAPIControlClient() :
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 @@ LocationAPIControlClient::~LocationAPIControlClient()
}
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 @@ void LocationAPIControlClient::locAPIDisable()
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__);
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 @@ void LocationAPIControlClient::onCtrlCollectiveResponseCb(
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 @@ LocationAPIRequest* LocationAPIControlClient::getRequestBySession(uint32_t sessi
{
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 @@ LocationAPIClientBase::LocationAPIClientBase() :
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 @@ LocationAPIClientBase::~LocationAPIClientBase()
}
for (int i = 0; i < REQUEST_MAX; i++) {
mRequestQueues[i].reset(0);
mRequestQueues[i].reset((uint32_t)0);
}
pthread_mutex_unlock(&mMutex);

View file

@ -57,7 +57,8 @@ enum REQUEST_TYPE {
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 @@ public:
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 @@ public:
}
mSession = session;
}
void reset(uint32_t* sessionArrayPtr) {
reset((uint32_t)0);
mSessionArrayPtr = sessionArrayPtr;
}
void push(LocationAPIRequest* request) {
mQueue.push(request);
}
@ -101,8 +107,10 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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;

View file

@ -270,6 +270,7 @@ typedef enum {
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 {
@ -740,12 +741,22 @@ typedef struct {
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)
@ -805,7 +816,40 @@ typedef struct {
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;
@ -818,7 +862,26 @@ typedef struct {
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
@ -947,6 +1010,11 @@ typedef std::function<void(
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

View file

@ -47,6 +47,10 @@ struct GnssInterface {
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);

View file

@ -119,8 +119,8 @@ typedef enum {
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_CONSTELLATION_ENABLEMENT, /**< Support constellation enablement */
LOC_SUPPORTED_FEATURE_AGPM, /**< Support AGPM feature */
LOC_SUPPORTED_FEATURE_CONSTELLATION_ENABLEMENT_V02, /**< Support constellation enablement */
LOC_SUPPORTED_FEATURE_AGPM_V02, /**< Support AGPM feature */
LOC_SUPPORTED_FEATURE_XTRA_INTEGRITY /**< Support XTRA integrity */
} loc_supported_feature_enum;
@ -1461,6 +1461,32 @@ typedef struct
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.
*/