Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a630a38 authored by Kumar Anand's avatar Kumar Anand
Browse files

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
parent 24a732cd
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -234,4 +234,33 @@ interface IWifiChip extends @1.4::IWifiChip {
     *         |WifiStatusCode.FAILURE_IFACE_INVALID|
     */
    setCountryCode(int8_t[2] code) generates (WifiStatus status);

    /**
     * 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).
     *
     * @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.
     * @return status WifiStatus of the operation.
     *         Possible status codes:
     *         |WifiStatusCode.SUCCESS|,
     *         |WifiStatusCode.ERROR_NOT_SUPPORTED|,
     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
     *         |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.
     */
    getUsableChannels(WifiBand band, bitfield<WifiIfaceMode> ifaceModeMask)
        generates (WifiStatus status, vec<WifiUsableChannel> channels);
};
+123 −0
Original line number Diff line number Diff line
@@ -356,6 +356,129 @@ bool convertLegacyWifiMacInfoToHidl(
    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>*
+5 −0
Original line number Diff line number Diff line
@@ -206,6 +206,11 @@ bool convertLegacyRttCapabilitiesToHidl(
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
+27 −0
Original line number Diff line number Diff line
@@ -738,6 +738,14 @@ Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
                           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 @@ WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
    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) {
+5 −0
Original line number Diff line number Diff line
@@ -180,6 +180,9 @@ class WifiChip : public V1_5::IWifiChip {
        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 @@ class WifiChip : public V1_5::IWifiChip {
    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();
Loading