Wifi: HAL API to query the list of usable channels

API can be used to query what modes (SAP, STA,
WFD Client, WFD Group Owner, TDLS, NAN) can be
supported on each channel for specified band.
Needs support from Wifi chip vendors.

Bug: 160212907
Test: VTS - VtsHalWifiV1_5TargetTest
Change-Id: Icf270b8c2ee14c794778421c9d988712c5c38380
diff --git a/wifi/1.5/default/hidl_struct_util.cpp b/wifi/1.5/default/hidl_struct_util.cpp
index 8e2e647..7cee4cd 100644
--- a/wifi/1.5/default/hidl_struct_util.cpp
+++ b/wifi/1.5/default/hidl_struct_util.cpp
@@ -356,6 +356,129 @@
     return true;
 }
 
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand hidl_band) {
+    switch (hidl_band) {
+        case V1_5::WifiBand::BAND_24GHZ:
+            return legacy_hal::WLAN_MAC_2_4_BAND;
+        case V1_5::WifiBand::BAND_5GHZ:
+        case V1_5::WifiBand::BAND_5GHZ_DFS:
+        case V1_5::WifiBand::BAND_5GHZ_WITH_DFS:
+            return legacy_hal::WLAN_MAC_5_0_BAND;
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ:
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS:
+            return (legacy_hal::WLAN_MAC_2_4_BAND |
+                    legacy_hal::WLAN_MAC_5_0_BAND);
+        case V1_5::WifiBand::BAND_6GHZ:
+            return legacy_hal::WLAN_MAC_6_0_BAND;
+        case V1_5::WifiBand::BAND_5GHZ_6GHZ:
+            return (legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND);
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_6GHZ:
+        case V1_5::WifiBand::BAND_24GHZ_5GHZ_WITH_DFS_6GHZ:
+            return (legacy_hal::WLAN_MAC_2_4_BAND |
+                    legacy_hal::WLAN_MAC_5_0_BAND |
+                    legacy_hal::WLAN_MAC_6_0_BAND);
+        case V1_5::WifiBand::BAND_60GHZ:
+            return legacy_hal::WLAN_MAC_60_0_BAND;
+        default:
+            return (
+                legacy_hal::WLAN_MAC_2_4_BAND | legacy_hal::WLAN_MAC_5_0_BAND |
+                legacy_hal::WLAN_MAC_6_0_BAND | legacy_hal::WLAN_MAC_60_0_BAND);
+    }
+}
+
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask) {
+    uint32_t legacy_iface_mask = 0;
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_STA) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_STA);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_SOFTAP);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_P2P_GO);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_NAN) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_NAN);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_TDLS) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_TDLS);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_MESH) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_MESH);
+    }
+    if (hidl_iface_mask & V1_5::WifiIfaceMode::IFACE_MODE_IBSS) {
+        legacy_iface_mask |= (1 << legacy_hal::WIFI_INTERFACE_IBSS);
+    }
+    return legacy_iface_mask;
+}
+
+uint32_t convertLegacyWifiInterfaceModeToHidl(uint32_t legacy_iface_mask) {
+    uint32_t hidl_iface_mask = 0;
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_STA)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_STA;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_SOFTAP)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_SOFTAP;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_CLIENT)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_CLIENT;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_P2P_GO)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_P2P_GO;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_NAN)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_NAN;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_TDLS)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_TDLS;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_MESH)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_MESH;
+    }
+    if (legacy_iface_mask & (1 << legacy_hal::WIFI_INTERFACE_IBSS)) {
+        hidl_iface_mask |= V1_5::WifiIfaceMode::IFACE_MODE_IBSS;
+    }
+    return hidl_iface_mask;
+}
+
+bool convertLegacyWifiUsableChannelToHidl(
+    const legacy_hal::wifi_usable_channel& legacy_usable_channel,
+    V1_5::WifiUsableChannel* hidl_usable_channel) {
+    if (!hidl_usable_channel) {
+        return false;
+    }
+    *hidl_usable_channel = {};
+    hidl_usable_channel->channel = legacy_usable_channel.freq;
+    hidl_usable_channel->channelBandwidth =
+        convertLegacyWifiChannelWidthToHidl(legacy_usable_channel.width);
+    hidl_usable_channel->ifaceModeMask = convertLegacyWifiInterfaceModeToHidl(
+        legacy_usable_channel.iface_mode_mask);
+
+    return true;
+}
+
+bool convertLegacyWifiUsableChannelsToHidl(
+    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels) {
+    if (!hidl_usable_channels) {
+        return false;
+    }
+    *hidl_usable_channels = {};
+    for (const auto& legacy_usable_channel : legacy_usable_channels) {
+        V1_5::WifiUsableChannel hidl_usable_channel;
+        if (!convertLegacyWifiUsableChannelToHidl(legacy_usable_channel,
+                                                  &hidl_usable_channel)) {
+            return false;
+        }
+        hidl_usable_channels->push_back(hidl_usable_channel);
+    }
+    return true;
+}
+
 bool convertLegacyWifiMacInfosToHidl(
     const std::vector<legacy_hal::WifiMacInfo>& legacy_mac_infos,
     std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>*
diff --git a/wifi/1.5/default/hidl_struct_util.h b/wifi/1.5/default/hidl_struct_util.h
index feb47ef..c0d7bf8 100644
--- a/wifi/1.5/default/hidl_struct_util.h
+++ b/wifi/1.5/default/hidl_struct_util.h
@@ -206,6 +206,11 @@
 bool convertLegacyVectorOfRttResultToHidl(
     const std::vector<const legacy_hal::wifi_rtt_result*>& legacy_results,
     std::vector<V1_4::RttResult>* hidl_results);
+uint32_t convertHidlWifiBandToLegacyMacBand(V1_5::WifiBand band);
+uint32_t convertHidlWifiIfaceModeToLegacy(uint32_t hidl_iface_mask);
+bool convertLegacyWifiUsableChannelsToHidl(
+    const std::vector<legacy_hal::wifi_usable_channel>& legacy_usable_channels,
+    std::vector<V1_5::WifiUsableChannel>* hidl_usable_channels);
 }  // namespace hidl_struct_util
 }  // namespace implementation
 }  // namespace V1_5
diff --git a/wifi/1.5/default/wifi_chip.cpp b/wifi/1.5/default/wifi_chip.cpp
index 414d74c..92acfd2 100644
--- a/wifi/1.5/default/wifi_chip.cpp
+++ b/wifi/1.5/default/wifi_chip.cpp
@@ -738,6 +738,14 @@
                            code);
 }
 
+Return<void> WifiChip::getUsableChannels(
+    WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
+    getUsableChannels_cb _hidl_cb) {
+    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
+                           &WifiChip::getUsableChannelsInternal, _hidl_cb, band,
+                           ifaceModeMask);
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearBridgedApAll();
     invalidateAndClearAll(ap_ifaces_);
@@ -1490,6 +1498,25 @@
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
+std::pair<WifiStatus, std::vector<WifiUsableChannel>>
+WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask) {
+    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));
+    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
+        return {createWifiStatusFromLegacyError(legacy_status), {}};
+    }
+    std::vector<WifiUsableChannel> hidl_usable_channels;
+    if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(
+            legacy_usable_channels, &hidl_usable_channels)) {
+        return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
+    }
+    return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
+}
+
 WifiStatus WifiChip::handleChipConfiguration(
     /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
     ChipModeId mode_id) {
diff --git a/wifi/1.5/default/wifi_chip.h b/wifi/1.5/default/wifi_chip.h
index 7d7a9b5..d542792 100644
--- a/wifi/1.5/default/wifi_chip.h
+++ b/wifi/1.5/default/wifi_chip.h
@@ -180,6 +180,9 @@
         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;
 
    private:
     void invalidateAndRemoveAllIfaces();
@@ -261,6 +264,8 @@
     WifiStatus setCoexUnsafeChannelsInternal(
         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);
     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 3e65ee0..94603b3 100644
--- a/wifi/1.5/default/wifi_legacy_hal.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal.cpp
@@ -36,6 +36,7 @@
 static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
 static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
 static constexpr uint32_t kMaxRingBuffers = 10;
+static constexpr uint32_t kMaxWifiUsableChannels = 256;
 // need a long timeout (1000ms) for chips that unload their driver.
 static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
 static constexpr char kDriverPropName[] = "wlan.driver.status";
@@ -1636,6 +1637,19 @@
                                                    multiplier);
 }
 
+std::pair<wifi_error, std::vector<wifi_usable_channel>>
+WifiLegacyHal::getUsableChannels(uint32_t band_mask, uint32_t iface_mode_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,
+        reinterpret_cast<wifi_usable_channel*>(channels.data()));
+    CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
+    channels.resize(size);
+    return {status, std::move(channels)};
+}
+
 void WifiLegacyHal::invalidate() {
     global_handle_ = nullptr;
     iface_name_to_handle_.clear();
diff --git a/wifi/1.5/default/wifi_legacy_hal.h b/wifi/1.5/default/wifi_legacy_hal.h
index 0cc1cff..dc641ae 100644
--- a/wifi/1.5/default/wifi_legacy_hal.h
+++ b/wifi/1.5/default/wifi_legacy_hal.h
@@ -36,9 +36,13 @@
 namespace legacy_hal {
 // Import all the types defined inside the legacy HAL header files into this
 // namespace.
+using ::frame_info;
+using ::frame_type;
 using ::FRAME_TYPE_80211_MGMT;
 using ::FRAME_TYPE_ETHERNET_II;
 using ::FRAME_TYPE_UNKNOWN;
+using ::fw_roaming_state_t;
+using ::mac_addr;
 using ::NAN_CHANNEL_24G_BAND;
 using ::NAN_CHANNEL_5G_BAND_HIGH;
 using ::NAN_CHANNEL_5G_BAND_LOW;
@@ -80,8 +84,6 @@
 using ::NAN_RESPONSE_TCA;
 using ::NAN_RESPONSE_TRANSMIT_FOLLOWUP;
 using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-using ::NAN_SECURITY_KEY_INPUT_PASSPHRASE;
-using ::NAN_SECURITY_KEY_INPUT_PMK;
 using ::NAN_SECURITY_KEY_INPUT_PMK;
 using ::NAN_SERVICE_ACCEPT_POLICY_ALL;
 using ::NAN_SERVICE_ACCEPT_POLICY_NONE;
@@ -154,19 +156,20 @@
 using ::RTT_PEER_P2P_CLIENT;
 using ::RTT_PEER_P2P_GO;
 using ::RTT_PEER_STA;
+using ::rtt_peer_type;
 using ::RTT_STATUS_ABORTED;
-using ::RTT_STATUS_FAILURE;
 using ::RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL;
 using ::RTT_STATUS_FAIL_BUSY_TRY_LATER;
 using ::RTT_STATUS_FAIL_FTM_PARAM_OVERRIDE;
 using ::RTT_STATUS_FAIL_INVALID_TS;
-using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
 using ::RTT_STATUS_FAIL_NO_CAPABILITY;
 using ::RTT_STATUS_FAIL_NO_RSP;
+using ::RTT_STATUS_FAIL_NOT_SCHEDULED_YET;
 using ::RTT_STATUS_FAIL_PROTOCOL;
 using ::RTT_STATUS_FAIL_REJECTED;
 using ::RTT_STATUS_FAIL_SCHEDULE;
 using ::RTT_STATUS_FAIL_TM_TIMEOUT;
+using ::RTT_STATUS_FAILURE;
 using ::RTT_STATUS_INVALID_REQ;
 using ::RTT_STATUS_NAN_RANGING_CONCURRENCY_NOT_SUPPORTED;
 using ::RTT_STATUS_NAN_RANGING_PROTOCOL_FAILURE;
@@ -185,6 +188,8 @@
 using ::RX_PKT_FATE_FW_DROP_OTHER;
 using ::RX_PKT_FATE_FW_QUEUED;
 using ::RX_PKT_FATE_SUCCESS;
+using ::ssid_t;
+using ::transaction_id;
 using ::TX_PKT_FATE_ACKED;
 using ::TX_PKT_FATE_DRV_DROP_INVALID;
 using ::TX_PKT_FATE_DRV_DROP_NOBUFS;
@@ -199,24 +204,31 @@
 using ::WIFI_AC_BK;
 using ::WIFI_AC_VI;
 using ::WIFI_AC_VO;
+using ::wifi_band;
 using ::WIFI_BAND_A;
-using ::WIFI_BAND_ABG;
-using ::WIFI_BAND_ABG_WITH_DFS;
 using ::WIFI_BAND_A_DFS;
 using ::WIFI_BAND_A_WITH_DFS;
+using ::WIFI_BAND_ABG;
+using ::WIFI_BAND_ABG_WITH_DFS;
 using ::WIFI_BAND_BG;
 using ::WIFI_BAND_UNSPECIFIED;
+using ::wifi_cached_scan_results;
 using ::WIFI_CHAN_WIDTH_10;
 using ::WIFI_CHAN_WIDTH_160;
 using ::WIFI_CHAN_WIDTH_20;
 using ::WIFI_CHAN_WIDTH_40;
 using ::WIFI_CHAN_WIDTH_5;
-using ::WIFI_CHAN_WIDTH_5;
 using ::WIFI_CHAN_WIDTH_80;
 using ::WIFI_CHAN_WIDTH_80P80;
 using ::WIFI_CHAN_WIDTH_INVALID;
+using ::wifi_channel_info;
+using ::wifi_channel_stat;
+using ::wifi_channel_width;
+using ::wifi_coex_restriction;
+using ::wifi_coex_unsafe_channel;
 using ::WIFI_DUAL_STA_NON_TRANSIENT_UNBIASED;
 using ::WIFI_DUAL_STA_TRANSIENT_PREFER_PRIMARY;
+using ::wifi_error;
 using ::WIFI_ERROR_BUSY;
 using ::WIFI_ERROR_INVALID_ARGS;
 using ::WIFI_ERROR_INVALID_REQUEST_ID;
@@ -228,12 +240,29 @@
 using ::WIFI_ERROR_TOO_MANY_REQUESTS;
 using ::WIFI_ERROR_UNINITIALIZED;
 using ::WIFI_ERROR_UNKNOWN;
+using ::wifi_gscan_capabilities;
+using ::wifi_hal_fn;
+using ::wifi_information_element;
+using ::WIFI_INTERFACE_IBSS;
+using ::WIFI_INTERFACE_MESH;
+using ::wifi_interface_mode;
+using ::WIFI_INTERFACE_NAN;
+using ::WIFI_INTERFACE_P2P_CLIENT;
+using ::WIFI_INTERFACE_P2P_GO;
+using ::WIFI_INTERFACE_SOFTAP;
+using ::WIFI_INTERFACE_STA;
+using ::WIFI_INTERFACE_TDLS;
+using ::wifi_interface_type;
 using ::WIFI_INTERFACE_TYPE_AP;
 using ::WIFI_INTERFACE_TYPE_NAN;
 using ::WIFI_INTERFACE_TYPE_P2P;
 using ::WIFI_INTERFACE_TYPE_STA;
+using ::WIFI_INTERFACE_UNKNOWN;
+using ::wifi_latency_mode;
 using ::WIFI_LATENCY_MODE_LOW;
 using ::WIFI_LATENCY_MODE_NORMAL;
+using ::wifi_lci_information;
+using ::wifi_lcr_information;
 using ::WIFI_LOGGER_CONNECT_EVENT_SUPPORTED;
 using ::WIFI_LOGGER_DRIVER_DUMP_SUPPORTED;
 using ::WIFI_LOGGER_MEMORY_DUMP_SUPPORTED;
@@ -242,61 +271,34 @@
 using ::WIFI_LOGGER_WAKE_LOCK_SUPPORTED;
 using ::WIFI_MOTION_EXPECTED;
 using ::WIFI_MOTION_NOT_EXPECTED;
+using ::wifi_motion_pattern;
 using ::WIFI_MOTION_UNKNOWN;
+using ::wifi_multi_sta_use_case;
+using ::wifi_power_scenario;
 using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_OFF;
 using ::WIFI_POWER_SCENARIO_ON_BODY_CELL_ON;
 using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_OFF;
 using ::WIFI_POWER_SCENARIO_ON_HEAD_CELL_ON;
 using ::WIFI_POWER_SCENARIO_VOICE_CALL;
-using ::WIFI_RTT_BW_10;
-using ::WIFI_RTT_BW_160;
-using ::WIFI_RTT_BW_20;
-using ::WIFI_RTT_BW_40;
-using ::WIFI_RTT_BW_5;
-using ::WIFI_RTT_BW_80;
-using ::WIFI_RTT_PREAMBLE_HE;
-using ::WIFI_RTT_PREAMBLE_HT;
-using ::WIFI_RTT_PREAMBLE_LEGACY;
-using ::WIFI_RTT_PREAMBLE_VHT;
-using ::WIFI_SCAN_FLAG_INTERRUPTED;
-using ::WIFI_SUCCESS;
-using ::WLAN_MAC_2_4_BAND;
-using ::WLAN_MAC_5_0_BAND;
-using ::WLAN_MAC_6_0_BAND;
-using ::frame_info;
-using ::frame_type;
-using ::fw_roaming_state_t;
-using ::mac_addr;
-using ::rtt_peer_type;
-using ::ssid_t;
-using ::transaction_id;
-using ::wifi_band;
-using ::wifi_cached_scan_results;
-using ::wifi_channel_info;
-using ::wifi_channel_stat;
-using ::wifi_channel_width;
-using ::wifi_coex_restriction;
-using ::wifi_coex_unsafe_channel;
-using ::wifi_error;
-using ::wifi_gscan_capabilities;
-using ::wifi_hal_fn;
-using ::wifi_information_element;
-using ::wifi_interface_type;
-using ::wifi_latency_mode;
-using ::wifi_lci_information;
-using ::wifi_lcr_information;
-using ::wifi_motion_pattern;
-using ::wifi_multi_sta_use_case;
-using ::wifi_power_scenario;
 using ::wifi_rate;
 using ::wifi_request_id;
 using ::wifi_ring_buffer_status;
 using ::wifi_roaming_capabilities;
 using ::wifi_roaming_config;
 using ::wifi_rtt_bw;
+using ::WIFI_RTT_BW_10;
+using ::WIFI_RTT_BW_160;
+using ::WIFI_RTT_BW_20;
+using ::WIFI_RTT_BW_40;
+using ::WIFI_RTT_BW_5;
+using ::WIFI_RTT_BW_80;
 using ::wifi_rtt_capabilities;
 using ::wifi_rtt_config;
 using ::wifi_rtt_preamble;
+using ::WIFI_RTT_PREAMBLE_HE;
+using ::WIFI_RTT_PREAMBLE_HT;
+using ::WIFI_RTT_PREAMBLE_LEGACY;
+using ::WIFI_RTT_PREAMBLE_VHT;
 using ::wifi_rtt_responder;
 using ::wifi_rtt_result;
 using ::wifi_rtt_status;
@@ -305,9 +307,16 @@
 using ::wifi_rx_report;
 using ::wifi_scan_bucket_spec;
 using ::wifi_scan_cmd_params;
+using ::WIFI_SCAN_FLAG_INTERRUPTED;
 using ::wifi_scan_result;
+using ::WIFI_SUCCESS;
 using ::wifi_tx_packet_fate;
 using ::wifi_tx_report;
+using ::wifi_usable_channel;
+using ::WLAN_MAC_2_4_BAND;
+using ::WLAN_MAC_5_0_BAND;
+using ::WLAN_MAC_60_0_BAND;
+using ::WLAN_MAC_6_0_BAND;
 
 // APF capabilities supported by the iface.
 struct PacketFilterCapabilities {
@@ -693,6 +702,11 @@
     wifi_error setDtimConfig(const std::string& iface_name,
                              uint32_t multiplier);
 
+    // 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);
+
    private:
     // Retrieve interface handles for all the available interfaces.
     wifi_error retrieveIfaceHandles();
diff --git a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
index 7ba5d9b..6212960 100644
--- a/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
+++ b/wifi/1.5/default/wifi_legacy_hal_stubs.cpp
@@ -159,6 +159,7 @@
     populateStubFor(&hal_fn->wifi_twt_get_stats);
     populateStubFor(&hal_fn->wifi_twt_clear_stats);
     populateStubFor(&hal_fn->wifi_set_dtim_config);
+    populateStubFor(&hal_fn->wifi_get_usable_channels);
     return true;
 }
 }  // namespace legacy_hal