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

Commit 94bcce5e authored by Quang Luong's avatar Quang Luong
Browse files

[WifiCoex] Add WifiChip HIDL APIs for coex

Add HIDL APIs to convey a list of unsafe Wifi channels to the driver for
coex channel avoidance.

Bug: 153651001
Test: build
Change-Id: I8b14f0e2d8855c1f1e363d612617256d8e928f30
parent cb3498d9
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.hardware.wifi@1.5;

import @1.0::WifiStatus;
import @1.0::IfaceType;
import @1.5::IWifiApIface;
import @1.0::IWifiIface;
import @1.3::IWifiChip;
@@ -129,7 +130,6 @@ interface IWifiChip extends @1.4::IWifiChip {
     */
    setMultiStaUseCase(MultiStaUseCase useCase) generates (WifiStatus status);


    /**
     * Create bridged IWifiApIface.
     *
@@ -167,4 +167,47 @@ interface IWifiChip extends @1.4::IWifiChip {
     */
    removeIfaceInstanceFromBridgedApIface(string brIfaceName, string ifaceInstanceName)
        generates (WifiStatus status);

    /**
     * Representation of a Wi-Fi channel for Wi-Fi coex channel avoidance.
     */
    struct CoexUnsafeChannel {
        /* The band of the channel */
        WifiBand band;
        /* The channel number */
        uint32_t channel;
        /** The power cap will be a maximum power value in dbm that is allowed to be transmitted by
            the chip on this channel. A value of PowerCapConstant.NO_POWER_CAP means no limitation
            on transmitted power is needed by the chip for this channel.
        */
        int32_t powerCapDbm;
    };

    enum PowerCapConstant : int32_t {
        NO_POWER_CAP = 0x7FFFFFFF,
    };

    /**
     * Invoked to indicate that the provided |CoexUnsafeChannels| should be avoided with the
     * specified restrictions.
     *
     * Channel avoidance is a suggestion and should be done on a best-effort approach. If a provided
     * channel is used, then the specified power cap should be applied.
     *
     * In addition, hard restrictions on the Wifi modes may be indicated by |IfaceType| bits
     * (STA, AP, P2P, NAN, etc) in the |restrictions| bitfield. If a hard restriction is provided,
     * then the channels should be completely avoided for the provided Wifi modes instead of by
     * best-effort.
     *
     * @param unsafeChannels List of |CoexUnsafeChannels| to avoid.
     * @param restrictions Bitset of |IfaceType| values indicating Wifi modes to completely avoid.
     * @return status WifiStatus of the operation.
     *         Possible status codes:
     *         |WifiStatusCode.SUCCESS|,
     *         |WifiStatusCode.ERROR_WIFI_CHIP_INVALID|,
     *         |WifiStatusCode.ERROR_INVALID_ARGS|,
     */
    setCoexUnsafeChannels(
        vec<CoexUnsafeChannel> unsafeChannels, bitfield<IfaceType> restrictions)
            generates (WifiStatus status);
};
+41 −0
Original line number Diff line number Diff line
@@ -2800,6 +2800,47 @@ legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
    }
    CHECK(false);
}

bool convertHidlCoexUnsafeChannelToLegacy(
    const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
    legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel) {
    if (!legacy_unsafe_channel) {
        return false;
    }
    *legacy_unsafe_channel = {};
    switch (hidl_unsafe_channel.band) {
        case WifiBand::BAND_24GHZ:
            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_2_4_BAND;
            break;
        case WifiBand::BAND_5GHZ:
            legacy_unsafe_channel->band = legacy_hal::WLAN_MAC_5_0_BAND;
            break;
        default:
            return false;
    };
    legacy_unsafe_channel->channel = hidl_unsafe_channel.channel;
    legacy_unsafe_channel->power_cap_dbm = hidl_unsafe_channel.powerCapDbm;
    return true;
}

bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
    const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
    std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels) {
    if (!legacy_unsafe_channels) {
        return false;
    }
    *legacy_unsafe_channels = {};
    for (const auto& hidl_unsafe_channel : hidl_unsafe_channels) {
        legacy_hal::wifi_coex_unsafe_channel legacy_unsafe_channel;
        if (!hidl_struct_util::convertHidlCoexUnsafeChannelToLegacy(
                hidl_unsafe_channel, &legacy_unsafe_channel)) {
            return false;
        }
        legacy_unsafe_channels->push_back(legacy_unsafe_channel);
    }
    return true;
}

}  // namespace hidl_struct_util
}  // namespace implementation
}  // namespace V1_5
+6 −0
Original line number Diff line number Diff line
@@ -71,6 +71,12 @@ legacy_hal::wifi_interface_type convertHidlIfaceTypeToLegacy(
    IfaceType hidl_interface_type);
legacy_hal::wifi_multi_sta_use_case convertHidlMultiStaUseCaseToLegacy(
    IWifiChip::MultiStaUseCase use_case);
bool convertHidlCoexUnsafeChannelToLegacy(
    const IWifiChip::CoexUnsafeChannel& hidl_unsafe_channel,
    legacy_hal::wifi_coex_unsafe_channel* legacy_unsafe_channel);
bool convertHidlVectorOfCoexUnsafeChannelToLegacy(
    const std::vector<IWifiChip::CoexUnsafeChannel>& hidl_unsafe_channels,
    std::vector<legacy_hal::wifi_coex_unsafe_channel>* legacy_unsafe_channels);

// STA iface conversion methods.
bool convertLegacyFeaturesToHidlStaCapabilities(
+21 −0
Original line number Diff line number Diff line
@@ -722,6 +722,15 @@ Return<void> WifiChip::setMultiStaUseCase(
                           hidl_status_cb, use_case);
}

Return<void> WifiChip::setCoexUnsafeChannels(
    const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
    hidl_bitfield<IfaceType> restrictions,
    setCoexUnsafeChannels_cb hidl_status_cb) {
    return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
                           &WifiChip::setCoexUnsafeChannelsInternal,
                           hidl_status_cb, unsafeChannels, restrictions);
}

void WifiChip::invalidateAndRemoveAllIfaces() {
    invalidateAndClearBridgedApAll();
    invalidateAndClearAll(ap_ifaces_);
@@ -1447,6 +1456,18 @@ WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
    return createWifiStatusFromLegacyError(legacy_status);
}

WifiStatus WifiChip::setCoexUnsafeChannelsInternal(
    std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) {
    std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
    if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(
            unsafe_channels, &legacy_unsafe_channels)) {
        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
    }
    auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels(
        legacy_unsafe_channels, restrictions);
    return createWifiStatusFromLegacyError(legacy_status);
}

WifiStatus WifiChip::handleChipConfiguration(
    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
    ChipModeId mode_id) {
+6 −0
Original line number Diff line number Diff line
@@ -174,6 +174,10 @@ class WifiChip : public V1_5::IWifiChip {
    Return<void> setMultiStaUseCase(
        MultiStaUseCase use_case,
        setMultiStaUseCase_cb hidl_status_cb) override;
    Return<void> setCoexUnsafeChannels(
        const hidl_vec<CoexUnsafeChannel>& unsafe_channels,
        hidl_bitfield<IfaceType> restrictions,
        setCoexUnsafeChannels_cb hidl_status_cb) override;

   private:
    void invalidateAndRemoveAllIfaces();
@@ -252,6 +256,8 @@ class WifiChip : public V1_5::IWifiChip {
        const sp<V1_4::IWifiChipEventCallback>& event_callback);
    WifiStatus setMultiStaPrimaryConnectionInternal(const std::string& ifname);
    WifiStatus setMultiStaUseCaseInternal(MultiStaUseCase use_case);
    WifiStatus setCoexUnsafeChannelsInternal(
        std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions);

    WifiStatus handleChipConfiguration(
        std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
Loading