Wifi: Filter usable channels by Coex, Concurrency
Add ability to filter usable channel due to coex &
concurrency limitations. List of usable channels could
be limited due to coex restrictions and also due to
concurrency limitations & connection state.
Bug: 160212907
Test: VTS - VtsHalWifiV1_5TargetTest
Change-Id: Ic36b792b93fc4a6e328b9bc606a5286b8c1fd690
diff --git a/wifi/1.5/IWifiChip.hal b/wifi/1.5/IWifiChip.hal
index 209190a..5a3e288 100644
--- a/wifi/1.5/IWifiChip.hal
+++ b/wifi/1.5/IWifiChip.hal
@@ -236,19 +236,54 @@
setCountryCode(int8_t[2] code) generates (WifiStatus status);
/**
+ * Usable Wifi channels filter masks.
+ */
+ enum UsableChannelFilter : uint32_t {
+ /**
+ * Filter Wifi channels that should be avoided due to extreme
+ * cellular coexistence restrictions. Some Wifi channels can have
+ * extreme interference from/to cellular due to short frequency
+ * seperation with neighboring cellular channels or when there
+ * is harmonic and intermodulation interference. Channels which
+ * only have some performance degradation (e.g. power back off is
+ * sufficient to deal with coexistence issue) can be included and
+ * should not be filtered out.
+ */
+ CELLULAR_COEXISTENCE = 1 << 0,
+ /**
+ * Filter based on concurrency state.
+ * Examples:
+ * - 5GHz SAP operation may be supported in standalone mode, but if
+ * there is STA connection on 5GHz DFS channel, none of the 5GHz
+ * channels are usable for SAP if device does not support DFS SAP mode.
+ * - P2P GO may not be supported on indoor channels in EU during
+ * standalone mode but if there is a STA connection on indoor channel,
+ * P2P GO may be supported by some vendors on the same STA channel.
+ */
+ CONCURRENCY = 1 << 1,
+ };
+
+ /**
* Retrieve list of usable Wifi channels for the specified band &
* operational modes.
*
* The list of usable Wifi channels in a given band depends on factors
- * like current country code, operational mode (e.g. STA, SAP, CLI, GO,
- * TDLS, NAN) and any hard restrictons due to DFS, LTE Coex and
- * MCC(multi channel-concurrency).
+ * like current country code, operational mode (e.g. STA, SAP, WFD-CLI,
+ * WFD-GO, TDLS, NAN) and other restrictons due to DFS, cellular coexistence
+ * and conncurency state of the device.
*
* @param band |WifiBand| for which list of usable channels is requested.
* @param ifaceModeMask Bitmask of the modes represented by |WifiIfaceMode|
* Bitmask respresents all the modes that the caller is interested
- * in (e.g. STA, SAP, CLI, GO, TDLS, NAN).
- * Note: Bitmask does not represent concurrency matrix.
+ * in (e.g. STA, SAP, CLI, GO, TDLS, NAN). E.g. If the caller is
+ * interested in knowing usable channels for P2P CLI, P2P GO & NAN,
+ * ifaceModeMask would be set to
+ * IFACE_MODE_P2P_CLIENT|IFACE_MODE_P2P_GO|IFACE_MODE_NAN.
+ * @param filterMask Bitmask of filters represented by
+ * |UsableChannelFilter|. Specifies whether driver should filter
+ * channels based on additional criteria. If no filter is specified
+ * driver should return usable channels purely based on regulatory
+ * constraints.
* @return status WifiStatus of the operation.
* Possible status codes:
* |WifiStatusCode.SUCCESS|,
@@ -257,10 +292,15 @@
* |WifiStatusCode.FAILURE_UNKNOWN|
* @return channels List of channels represented by |WifiUsableChannel|
* Each entry represents a channel frequency, bandwidth and
- * bitmask of operational modes (e.g. STA, SAP, CLI, GO, TDLS, NAN)
- * allowed on that channel.
- * Note: Bitmask does not represent concurrency matrix.
+ * bitmask of modes (e.g. STA, SAP, CLI, GO, TDLS, NAN) that are
+ * allowed on that channel. E.g. If only STA mode can be supported
+ * on an indoor channel, only the IFACE_MODE_STA bit would be set
+ * for that channel. If 5GHz SAP cannot be supported, then none of
+ * the 5GHz channels will have IFACE_MODE_SOFTAP bit set.
+ * Note: Bits do not represent concurrency state. Each bit only
+ * represents whether particular mode is allowed on that channel.
*/
- getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask)
+ getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask,
+ bitfield<UsableChannelFilter> filterMask)
generates (WifiStatus status, vec<WifiUsableChannel> channels);
};
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index 7cee4cd..3c69da5 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -445,6 +445,20 @@
return hidl_iface_mask;
}
+uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask) {
+ uint32_t legacy_filter_mask = 0;
+ if (hidl_filter_mask &
+ IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE) {
+ legacy_filter_mask |=
+ legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+ }
+ if (hidl_filter_mask & IWifiChip::UsableChannelFilter::CONCURRENCY) {
+ legacy_filter_mask |=
+ legacy_hal::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
+ }
+ return legacy_filter_mask;
+}
+
bool convertLegacyWifiUsableChannelToHidl(
const legacy_hal::wifi_usable_channel& legacy_usable_channel,
V1_5::WifiUsableChannel* hidl_usable_channel) {
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index c0d7bf8..8b81033 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -208,6 +208,7 @@
std::vector<V1_4::RttResult>* hidl_results);
uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
+uint32_t convertHidlUsableChannelFilterToLegacy(uint32_t hidl_filter_mask);
bool convertLegacyWifiUsableChannelsToHidl(
const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 2dc7314..0450a7b 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -740,10 +740,11 @@
Return<void> WifiChip::getUsableChannels(
WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<UsableChannelFilter> filterMask,
getUsableChannels_cb _hidl_cb) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
&WifiChip::getUsableChannelsInternal, _hidl_cb, band,
- ifaceModeMask);
+ ifaceModeMask, filterMask);
}
void WifiChip::invalidateAndRemoveAllIfaces() {
@@ -1500,13 +1501,17 @@
}
std::pair<WifiStatus, std::vector<WifiUsableChannel>>
-WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) {
+WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
+ uint32_t filterMask) {
legacy_hal::wifi_error legacy_status;
std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
std::tie(legacy_status, legacy_usable_channels) =
legacy_hal_.lock()->getUsableChannels(
hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
- hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask));
+ hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
+ hidl_struct_util::convertHidlUsableChannelFilterToLegacy(
+ filterMask));
+
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index d542792..b4ed30e 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -180,9 +180,10 @@
setCoexUnsafeChannels_cb hidl_status_cb) override;
Return<void> setCountryCode(const hidl_array<int8_t, 2>& code,
setCountryCode_cb _hidl_cb) override;
- Return<void> getUsableChannels(WifiBand band,
- hidl_bitfield<WifiIfaceMode> ifaceModeMask,
- getUsableChannels_cb _hidl_cb) override;
+ Return<void> getUsableChannels(
+ WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
+ hidl_bitfield<UsableChannelFilter> filterMask,
+ getUsableChannels_cb _hidl_cb) override;
private:
void invalidateAndRemoveAllIfaces();
@@ -265,7 +266,8 @@
std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions);
WifiStatus setCountryCodeInternal(const std::array<int8_t, 2>& code);
std::pair<WifiStatus, std::vector<WifiUsableChannel>>
- getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask);
+ getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
+ uint32_t filterMask);
WifiStatus handleChipConfiguration(
std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
WifiStatus registerDebugRingBufferCallback();
diff --git a/wifi/1.5/default/wifi_legacy_hal.cpp b/wifi/1.5/default/wifi_legacy_hal.cpp
index 94603b3..f5ca753 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -1638,12 +1638,14 @@
}
std::pair<wifi_error, std::vector<wifi_usable_channel>>
-WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask) {
+WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_mask,
+ uint32_t filter_mask) {
std::vector<wifi_usable_channel> channels;
channels.resize(kMaxWifiUsableChannels);
uint32_t size = 0;
wifi_error status = global_func_table_.wifi_get_usable_channels(
- global_handle_, band_mask, iface_mode_mask, channels.size(), &size,
+ global_handle_, band_mask, iface_mode_mask, filter_mask,
+ channels.size(), &size,
reinterpret_cast<wifi_usable_channel*>(channels.data()));
CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
channels.resize(size);
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index dc641ae..03ca841 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -313,6 +313,8 @@
using ::wifi_tx_packet_fate;
using ::wifi_tx_report;
using ::wifi_usable_channel;
+using ::WIFI_USABLE_CHANNEL_FILTER_CELLULAR_COEXISTENCE;
+using ::WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY;
using ::WLAN_MAC_2_4_BAND;
using ::WLAN_MAC_5_0_BAND;
using ::WLAN_MAC_60_0_BAND;
@@ -705,7 +707,7 @@
// Retrieve the list of usable channels in the requested bands
// for the requested modes
std::pair<wifi_error, std::vector<wifi_usable_channel>> getUsableChannels(
- uint32_t band_mask, uint32_t iface_mode_mask);
+ uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask);
private:
// Retrieve interface handles for all the available interfaces.
diff --git a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
index 509f1bd..5ac747d 100644
--- a/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
+++ b/wifi/1.5/vts/functional/wifi_chip_hidl_test.cpp
@@ -195,10 +195,12 @@
TEST_P(WifiChipHidlTest, getUsableChannels) {
uint32_t ifaceModeMask =
WifiIfaceMode::IFACE_MODE_P2P_CLIENT | WifiIfaceMode::IFACE_MODE_P2P_GO;
+ uint32_t filterMask = IWifiChip::UsableChannelFilter::CELLULAR_COEXISTENCE |
+ IWifiChip::UsableChannelFilter::CONCURRENCY;
configureChipForIfaceType(IfaceType::STA, true);
WifiBand band = WifiBand::BAND_24GHZ_5GHZ_6GHZ;
- const auto& statusNonEmpty =
- HIDL_INVOKE(wifi_chip_, getUsableChannels, band, ifaceModeMask);
+ const auto& statusNonEmpty = HIDL_INVOKE(wifi_chip_, getUsableChannels,
+ band, ifaceModeMask, filterMask);
if (statusNonEmpty.first.code != WifiStatusCode::SUCCESS) {
EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
statusNonEmpty.first.code);