platform_hardware_interfaces/wifi/aidl/default/wifi_feature_flags.cpp
Gabriel Biren f3262f970d Add AIDL implementation for the vendor HAL service.
Bug: 205044134
Test: Pass AIDL VTS tests and regression tests.
Change-Id: Iad04ce01f71fc220443e05a4be05d7d5545227e8
2022-12-02 14:01:50 -08:00

228 lines
9.5 KiB
C++

/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <android-base/logging.h>
#include <cutils/properties.h>
#include "wifi_feature_flags.h"
namespace aidl {
namespace android {
namespace hardware {
namespace wifi {
namespace feature_flags {
/* The chip may either have a single mode supporting any number of combinations,
* or a fixed dual-mode (so it involves firmware loading to switch between
* modes) setting. If there is a need to support more modes, it needs to be
* implemented manually in WiFi HAL (see changeFirmwareMode in
* WifiChip::handleChipConfiguration).
*
* Supported combinations are defined in device's makefile, for example:
* WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
* WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
* What this means:
* Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
* operations.
* Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
*
* For backward compatibility, the following makefile flags can be used to
* generate combinations list:
* - WIFI_HIDL_FEATURE_DUAL_INTERFACE
* - WIFI_HIDL_FEATURE_DISABLE_AP
* - WIFI_HIDL_FEATURE_AWARE
* However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
* With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
* two concurrency combinations:
* Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
* concurrent iface operations.
* Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
* iface operations.
*
* The only dual-mode configuration supported is for alternating STA and AP
* mode, that may involve firmware reloading. In such case, there are 2 separate
* modes of operation with 1 concurrency combination each:
* Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
* concurrent iface operations.
* Mode 2 (AP mode): Will support 1 AP iface operation.
*
* If Aware is enabled, the concurrency combination will be modified to support either
* P2P or NAN in place of just P2P.
*/
// clang-format off
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS
constexpr int kMainModeId = chip_mode_ids::kV3;
#elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
// former V2 (fixed dual interface) setup expressed as V3
constexpr int kMainModeId = chip_mode_ids::kV3;
# ifdef WIFI_HIDL_FEATURE_DISABLE_AP
# ifdef WIFI_HIDL_FEATURE_AWARE
// 1 STA + 1 of (P2P or NAN)
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
# else
// 1 STA + 1 P2P
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
# endif
# else
# ifdef WIFI_HIDL_FEATURE_AWARE
// (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
{{{STA}, 1}, {{P2P, NAN}, 1}}
# else
// (1 STA + 1 AP) or (1 STA + 1 P2P)
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
{{{STA}, 1}, {{P2P}, 1}}
# endif
# endif
#else
// V1 (fixed single interface, dual-mode chip)
constexpr int kMainModeId = chip_mode_ids::kV1Sta;
# ifdef WIFI_HIDL_FEATURE_AWARE
// 1 STA + 1 of (P2P or NAN)
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
# else
// 1 STA + 1 P2P
# define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
# endif
# ifndef WIFI_HIDL_FEATURE_DISABLE_AP
# define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
# endif
#endif
// clang-format on
// Convert from the legacy format (used by the WIFI_HAL_INTERFACE_COMBINATIONS
// config variable) to a list of ChipConcurrencyCombination objects.
std::vector<IWifiChip::ChipConcurrencyCombination> legacyToChipConcurrencyComboList(
std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits) {
std::vector<IWifiChip::ChipConcurrencyCombination> combos;
for (auto& legacyLimit : legacyLimits) {
IWifiChip::ChipConcurrencyCombination combo = {legacyLimit};
combos.push_back(combo);
}
return combos;
}
#define STA IfaceConcurrencyType::STA
#define AP IfaceConcurrencyType::AP
#define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
#define P2P IfaceConcurrencyType::P2P
#define NAN IfaceConcurrencyType::NAN_IFACE
static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
{kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
{chip_mode_ids::kV1Ap,
legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
#endif
};
static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
#ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
{chip_mode_ids::kV3,
legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
#endif
};
constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
"persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
// List of pre-defined concurrency combinations that can be enabled at runtime via
// setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
// corresponding index value.
static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
// Legacy combination - No STA/AP concurrencies.
// 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
{"No STA/AP Concurrency",
{{kMainModeId,
legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
// STA + AP concurrency
// 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
{"STA + AP Concurrency",
{{kMainModeId, legacyToChipConcurrencyComboList(
{{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
// STA + STA concurrency
// 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
{"Dual STA Concurrency",
{{kMainModeId, legacyToChipConcurrencyComboList(
{{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
// AP + AP + STA concurrency
// 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
{"Dual AP Concurrency",
{{kMainModeId, legacyToChipConcurrencyComboList(
{{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
// STA + STA concurrency and AP + AP + STA concurrency
// 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
{"Dual STA & Dual AP Concurrency",
{{kMainModeId, legacyToChipConcurrencyComboList(
{{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
// STA + STA concurrency
// 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
{"Dual STA or STA plus single other interface",
{{kMainModeId, legacyToChipConcurrencyComboList(
{{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
#undef STA
#undef AP
#undef AP_BRIDGED
#undef P2P
#undef NAN
#ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
#pragma message \
"WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
"'config_wifi_ap_randomization_supported' in " \
"frameworks/base/core/res/res/values/config.xml in the device overlay " \
"instead"
#endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
WifiFeatureFlags::WifiFeatureFlags() {}
std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
// Debug property not set, use the device preset concurrency combination.
if (res <= 0) return kChipModesPrimary;
// Debug property set, use one of the debug preset concurrency combination.
unsigned long idx = std::stoul(buffer.data());
if (idx >= kDebugChipModes.size()) {
LOG(ERROR) << "Invalid index set in property: "
<< kDebugPresetInterfaceCombinationIdxProperty;
return kChipModesPrimary;
}
std::string name;
std::vector<IWifiChip::ChipMode> chip_modes;
std::tie(name, chip_modes) = kDebugChipModes[idx];
LOG(INFO) << "Using debug chip mode: <" << name
<< "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
return chip_modes;
}
std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
}
} // namespace feature_flags
} // namespace wifi
} // namespace hardware
} // namespace android
} // namespace aidl