wifi: Add support for RSSI monitoring

Bug: 31991459
Test: Compiles
Change-Id: I8794cea12a0d1c727bd0e37123152c8da11eeabf
This commit is contained in:
Roshan Pius
2016-12-06 10:04:05 -08:00
parent e3f72ff344
commit d476754bc0
7 changed files with 193 additions and 10 deletions

View File

@@ -44,10 +44,14 @@ interface IWifiStaIface extends IWifiIface {
* If set indicates that the link layer stats APIs are supported.
*/
LINK_LAYER_STATS = 1 << 2,
/**
* If set indicates that the RSSI monitor APIs are supported.
*/
RSSI_MONITOR = 1 << 3,
/**
* Tracks connection packets' fate.
*/
DEBUG_PACKET_FATE_SUPPORTED = 1 << 3
DEBUG_PACKET_FATE_SUPPORTED = 1 << 4
};
/**
@@ -258,6 +262,44 @@ interface IWifiStaIface extends IWifiIface {
*/
getLinkLayerStats() generates (WifiStatus status, StaLinkLayerStats stats);
/**
* Start RSSI monitoring on the currently connected access point.
* Once the monitoring is enabled,
* |IWifiStaIfaceEventCallback.onRssiThresholdBreached| callback must be
* invoked to indicate if the RSSI goes above |maxRssi| or below |minRssi|.
* Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
*
* @param cmdId command Id to use for this invocation.
* @param maxRssi Maximum RSSI threshold.
* @param minRssi Minimum RSSI threshold.
* @return status WifiStatus of the operation.
* Possible status codes:
* |WifiStatusCode.SUCCESS|,
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_ARGS_INVALID|,
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
* |WifiStatusCode.ERROR_UNKNOWN|
*/
startRssiMonitoring(CommandId cmdId, Rssi maxRssi, Rssi minRssi)
generates (WifiStatus status);
/**
* Stop RSSI monitoring.
* Must fail if |StaIfaceCapabilityMask.RSSI_MONITOR| is not set.
*
* @param cmdId command Id corresponding to the request.
* @return status WifiStatus of the operation.
* Possible status codes:
* |WifiStatusCode.SUCCESS|,
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
* |WifiStatusCode.ERROR_NOT_STARTED|,
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
* |WifiStatusCode.ERROR_UNKNOWN|
*/
stopRssiMonitoring(CommandId cmdId) generates (WifiStatus status);
/**
* API to start packet fate monitoring.
* - Once stared, monitoring must remain active until HAL is unloaded.

View File

@@ -20,6 +20,8 @@ interface IWifiStaIfaceEventCallback {
/**
* Callback indicating that an ongoing background scan request has failed.
* The background scan needs to be restarted to continue scanning.
*
* @param cmdId command ID corresponding to the request.
*/
oneway onBackgroundScanFailure(CommandId cmdId);
@@ -28,7 +30,7 @@ interface IWifiStaIfaceEventCallback {
* |REPORT_EVENTS_FULL_RESULTS| flag set in
* |StaBackgroundScanBucketParameters.eventReportScheme|.
*
* @param cmdId command Id corresponding to the request.
* @param cmdId command ID corresponding to the request.
* @parm result Full scan result for an AP.
*/
oneway onBackgroundFullScanResult(CommandId cmdId, StaScanResult result);
@@ -39,8 +41,18 @@ interface IWifiStaIfaceEventCallback {
* |REPORT_EVENTS_EACH_SCAN| or one of the configured thresholds was
* breached.
*
* @param cmdId command Id corresponding to the request.
* @param cmdId command ID corresponding to the request.
* @parm scanDatas List of scan result for all AP's seen since last callback.
*/
oneway onBackgroundScanResults(CommandId cmdId, vec<StaScanData> scanDatas);
/**
* Called when the RSSI of the currently connected access point goes beyond the
* thresholds set via |IWifiStaIface.startRssiMonitoring|.
*
* @param cmdId command ID corresponding to the request.
* @param currBssid BSSID of the currently connected access point.
* @param currRssi RSSI of the currently connected access point.
*/
oneway onRssiThresholdBreached(CommandId cmdId, Bssid currBssid, Rssi currRssi);
};

View File

@@ -64,6 +64,8 @@ convertLegacyFeatureToHidlStaIfaceCapability(uint32_t feature) {
return HidlStaIfaceCaps::BACKGROUND_SCAN;
case WIFI_FEATURE_LINK_LAYER_STATS:
return HidlStaIfaceCaps::LINK_LAYER_STATS;
case WIFI_FEATURE_RSSI_MONITOR:
return HidlStaIfaceCaps::RSSI_MONITOR;
};
CHECK(false) << "Unknown legacy feature: " << feature;
return {};
@@ -210,8 +212,9 @@ bool convertLegacyFeaturesToHidlStaCapabilities(
*hidl_caps |= convertLegacyLoggerFeatureToHidlStaIfaceCapability(feature);
}
}
for (const auto feature :
{WIFI_FEATURE_GSCAN, WIFI_FEATURE_LINK_LAYER_STATS}) {
for (const auto feature : {WIFI_FEATURE_GSCAN,
WIFI_FEATURE_LINK_LAYER_STATS,
WIFI_FEATURE_RSSI_MONITOR}) {
if (feature & legacy_feature_set) {
*hidl_caps |= convertLegacyFeatureToHidlStaIfaceCapability(feature);
}

View File

@@ -90,16 +90,25 @@ void onGscanFullResult(wifi_request_id id,
// Callback to be invoked for link layer stats results.
std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
on_link_layer_stats_result_internal_callback;
void onLinkLayerStatsDataResult(wifi_request_id id,
wifi_iface_stat* iface_stat,
int num_radios,
wifi_radio_stat* radio_stat) {
void onLinkLayerStatsResult(wifi_request_id id,
wifi_iface_stat* iface_stat,
int num_radios,
wifi_radio_stat* radio_stat) {
if (on_link_layer_stats_result_internal_callback) {
on_link_layer_stats_result_internal_callback(
id, iface_stat, num_radios, radio_stat);
}
}
// Callback to be invoked for rssi threshold breach.
std::function<void((wifi_request_id, uint8_t*, int8_t))>
on_rssi_threshold_breached_internal_callback;
void onRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
if (on_rssi_threshold_breached_internal_callback) {
on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
}
}
// Callback to be invoked for ring buffer data indication.
std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
on_ring_buffer_data_internal_callback;
@@ -537,11 +546,53 @@ std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats() {
};
wifi_error status = global_func_table_.wifi_get_link_stats(
0, wlan_interface_handle_, {onLinkLayerStatsDataResult});
0, wlan_interface_handle_, {onLinkLayerStatsResult});
on_link_layer_stats_result_internal_callback = nullptr;
return {status, link_stats};
}
wifi_error WifiLegacyHal::startRssiMonitoring(
wifi_request_id id,
int8_t max_rssi,
int8_t min_rssi,
const on_rssi_threshold_breached_callback&
on_threshold_breached_user_callback) {
if (on_rssi_threshold_breached_internal_callback) {
return WIFI_ERROR_NOT_AVAILABLE;
}
on_rssi_threshold_breached_internal_callback =
[on_threshold_breached_user_callback](
wifi_request_id id, uint8_t* bssid_ptr, int8_t rssi) {
if (!bssid_ptr) {
return;
}
std::array<uint8_t, 6> bssid_arr;
// |bssid_ptr| pointer is assumed to have 6 bytes for the mac address.
std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
on_threshold_breached_user_callback(id, bssid_arr, rssi);
};
return global_func_table_.wifi_start_rssi_monitoring(
id,
wlan_interface_handle_,
max_rssi,
min_rssi,
{onRssiThresholdBreached});
}
wifi_error WifiLegacyHal::stopRssiMonitoring(wifi_request_id id) {
if (!on_rssi_threshold_breached_internal_callback) {
return WIFI_ERROR_NOT_AVAILABLE;
}
wifi_error status =
global_func_table_.wifi_stop_rssi_monitoring(id, wlan_interface_handle_);
// If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
// other error should be treated as the end of background scan.
if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
on_rssi_threshold_breached_internal_callback = nullptr;
}
return status;
}
std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
uint32_t supported_features;
wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
@@ -1017,6 +1068,7 @@ void WifiLegacyHal::invalidate() {
on_gscan_event_internal_callback = nullptr;
on_gscan_full_result_internal_callback = nullptr;
on_link_layer_stats_result_internal_callback = nullptr;
on_rssi_threshold_breached_internal_callback = nullptr;
on_ring_buffer_data_internal_callback = nullptr;
on_rtt_results_internal_callback = nullptr;
on_nan_notify_response_user_callback = nullptr;

View File

@@ -101,6 +101,10 @@ using on_gscan_full_result_callback =
using on_gscan_results_callback = std::function<void(
wifi_request_id, const std::vector<wifi_cached_scan_results>&)>;
// Invoked when the rssi value breaches the thresholds set.
using on_rssi_threshold_breached_callback =
std::function<void(wifi_request_id, std::array<uint8_t, 6>, int8_t)>;
// Callback for RTT range request results.
// Rtt results contain IE info and are hence passed by reference, to
// preserve the |LCI| and |LCR| pointers. Callee must not retain
@@ -167,6 +171,13 @@ class WifiLegacyHal {
wifi_error enableLinkLayerStats(bool debug);
wifi_error disableLinkLayerStats();
std::pair<wifi_error, LinkLayerStats> getLinkLayerStats();
// RSSI monitor functions.
wifi_error startRssiMonitoring(wifi_request_id id,
int8_t max_rssi,
int8_t min_rssi,
const on_rssi_threshold_breached_callback&
on_threshold_breached_callback);
wifi_error stopRssiMonitoring(wifi_request_id id);
// Logger/debug functions.
std::pair<wifi_error, uint32_t> getLoggerSupportedFeatureSet();
wifi_error startPktFateMonitoring();

View File

@@ -163,6 +163,29 @@ Return<void> WifiStaIface::getLinkLayerStats(
hidl_status_cb);
}
Return<void> WifiStaIface::startRssiMonitoring(
uint32_t cmd_id,
int32_t max_rssi,
int32_t min_rssi,
startRssiMonitoring_cb hidl_status_cb) {
return validateAndCall(this,
WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiStaIface::startRssiMonitoringInternal,
hidl_status_cb,
cmd_id,
max_rssi,
min_rssi);
}
Return<void> WifiStaIface::stopRssiMonitoring(
uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) {
return validateAndCall(this,
WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiStaIface::stopRssiMonitoringInternal,
hidl_status_cb,
cmd_id);
}
Return<void> WifiStaIface::startDebugPacketFateMonitoring(
startDebugPacketFateMonitoring_cb hidl_status_cb) {
return validateAndCall(this,
@@ -384,6 +407,35 @@ WifiStaIface::getLinkLayerStatsInternal() {
return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
}
WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id,
int32_t max_rssi,
int32_t min_rssi) {
android::wp<WifiStaIface> weak_ptr_this(this);
const auto& on_threshold_breached_callback = [weak_ptr_this](
legacy_hal::wifi_request_id id,
std::array<uint8_t, 6> bssid,
int8_t rssi) {
const auto shared_ptr_this = weak_ptr_this.promote();
if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
LOG(ERROR) << "Callback invoked on an invalid object";
return;
}
for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
callback->onRssiThresholdBreached(id, bssid, rssi);
}
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startRssiMonitoring(
cmd_id, max_rssi, min_rssi, on_threshold_breached_callback);
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->stopRssiMonitoring(cmd_id);
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startPktFateMonitoring();

View File

@@ -70,6 +70,13 @@ class WifiStaIface : public IWifiStaIface {
Return<void> disableLinkLayerStatsCollection(
disableLinkLayerStatsCollection_cb hidl_status_cb) override;
Return<void> getLinkLayerStats(getLinkLayerStats_cb hidl_status_cb) override;
Return<void> startRssiMonitoring(
uint32_t cmd_id,
int32_t max_rssi,
int32_t min_rssi,
startRssiMonitoring_cb hidl_status_cb) override;
Return<void> stopRssiMonitoring(
uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) override;
Return<void> startDebugPacketFateMonitoring(
startDebugPacketFateMonitoring_cb hidl_status_cb) override;
Return<void> stopDebugPacketFateMonitoring(
@@ -100,6 +107,10 @@ class WifiStaIface : public IWifiStaIface {
WifiStatus enableLinkLayerStatsCollectionInternal(bool debug);
WifiStatus disableLinkLayerStatsCollectionInternal();
std::pair<WifiStatus, StaLinkLayerStats> getLinkLayerStatsInternal();
WifiStatus startRssiMonitoringInternal(uint32_t cmd_id,
int32_t max_rssi,
int32_t min_rssi);
WifiStatus stopRssiMonitoringInternal(uint32_t cmd_id);
WifiStatus startDebugPacketFateMonitoringInternal();
WifiStatus stopDebugPacketFateMonitoringInternal();
std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>