1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <string>
18
19 #include <android-base/logging.h>
20 #include <cutils/properties.h>
21
22 #include "wifi_feature_flags.h"
23
24 namespace aidl {
25 namespace android {
26 namespace hardware {
27 namespace wifi {
28 namespace feature_flags {
29
30 /* The chip may either have a single mode supporting any number of combinations,
31 * or a fixed dual-mode (so it involves firmware loading to switch between
32 * modes) setting. If there is a need to support more modes, it needs to be
33 * implemented manually in WiFi HAL (see changeFirmwareMode in
34 * WifiChip::handleChipConfiguration).
35 *
36 * Supported combinations are defined in device's makefile, for example:
37 * WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
38 * WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
39 * What this means:
40 * Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
41 * operations.
42 * Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
43 *
44 * For backward compatibility, the following makefile flags can be used to
45 * generate combinations list:
46 * - WIFI_HIDL_FEATURE_DUAL_INTERFACE
47 * - WIFI_HIDL_FEATURE_DISABLE_AP
48 * - WIFI_HIDL_FEATURE_AWARE
49 * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
50 * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
51 * two concurrency combinations:
52 * Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
53 * concurrent iface operations.
54 * Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
55 * iface operations.
56 *
57 * The only dual-mode configuration supported is for alternating STA and AP
58 * mode, that may involve firmware reloading. In such case, there are 2 separate
59 * modes of operation with 1 concurrency combination each:
60 * Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
61 * concurrent iface operations.
62 * Mode 2 (AP mode): Will support 1 AP iface operation.
63 *
64 * If Aware is enabled, the concurrency combination will be modified to support either
65 * P2P or NAN in place of just P2P.
66 */
67 // clang-format off
68 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS
69 constexpr int kMainModeId = chip_mode_ids::kV3;
70 #elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
71 // former V2 (fixed dual interface) setup expressed as V3
72 constexpr int kMainModeId = chip_mode_ids::kV3;
73 # ifdef WIFI_HIDL_FEATURE_DISABLE_AP
74 # ifdef WIFI_HIDL_FEATURE_AWARE
75 // 1 STA + 1 of (P2P or NAN)
76 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
77 # else
78 // 1 STA + 1 P2P
79 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
80 # endif
81 # else
82 # ifdef WIFI_HIDL_FEATURE_AWARE
83 // (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
84 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
85 {{{STA}, 1}, {{P2P, NAN}, 1}}
86 # else
87 // (1 STA + 1 AP) or (1 STA + 1 P2P)
88 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
89 {{{STA}, 1}, {{P2P}, 1}}
90 # endif
91 # endif
92 #else
93 // V1 (fixed single interface, dual-mode chip)
94 constexpr int kMainModeId = chip_mode_ids::kV1Sta;
95 # ifdef WIFI_HIDL_FEATURE_AWARE
96 // 1 STA + 1 of (P2P or NAN)
97 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
98 # else
99 // 1 STA + 1 P2P
100 # define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
101 # endif
102
103 # ifndef WIFI_HIDL_FEATURE_DISABLE_AP
104 # define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
105 # endif
106 #endif
107 // clang-format on
108
109 // Convert from the legacy format (used by the WIFI_HAL_INTERFACE_COMBINATIONS
110 // config variable) to a list of ChipConcurrencyCombination objects.
legacyToChipConcurrencyComboList(std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits)111 std::vector<IWifiChip::ChipConcurrencyCombination> legacyToChipConcurrencyComboList(
112 std::vector<std::vector<IWifiChip::ChipConcurrencyCombinationLimit>> legacyLimits) {
113 std::vector<IWifiChip::ChipConcurrencyCombination> combos;
114 for (auto& legacyLimit : legacyLimits) {
115 IWifiChip::ChipConcurrencyCombination combo = {legacyLimit};
116 combos.push_back(combo);
117 }
118 return combos;
119 }
120
121 #define STA IfaceConcurrencyType::STA
122 #define AP IfaceConcurrencyType::AP
123 #define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
124 #define P2P IfaceConcurrencyType::P2P
125 #define NAN IfaceConcurrencyType::NAN_IFACE
126 static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
127 {kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
128 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
129 {chip_mode_ids::kV1Ap,
130 legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
131 #endif
132 };
133
134 static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
135 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
136 {chip_mode_ids::kV3,
137 legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
138 #endif
139 };
140
141 constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
142 "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
143 // List of pre-defined concurrency combinations that can be enabled at runtime via
144 // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
145 // corresponding index value.
146 static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
147 // Legacy combination - No STA/AP concurrencies.
148 // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
149 {"No STA/AP Concurrency",
150 {{kMainModeId,
151 legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
152
153 // STA + AP concurrency
154 // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
155 {"STA + AP Concurrency",
156 {{kMainModeId, legacyToChipConcurrencyComboList(
157 {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
158
159 // STA + STA concurrency
160 // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
161 {"Dual STA Concurrency",
162 {{kMainModeId, legacyToChipConcurrencyComboList(
163 {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
164
165 // AP + AP + STA concurrency
166 // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
167 {"Dual AP Concurrency",
168 {{kMainModeId, legacyToChipConcurrencyComboList(
169 {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
170
171 // STA + STA concurrency and AP + AP + STA concurrency
172 // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
173 {"Dual STA & Dual AP Concurrency",
174 {{kMainModeId, legacyToChipConcurrencyComboList(
175 {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
176
177 // STA + STA concurrency
178 // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
179 {"Dual STA or STA plus single other interface",
180 {{kMainModeId, legacyToChipConcurrencyComboList(
181 {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
182
183 #undef STA
184 #undef AP
185 #undef AP_BRIDGED
186 #undef P2P
187 #undef NAN
188
189 #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
190 #pragma message \
191 "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
192 "'config_wifi_ap_randomization_supported' in " \
193 "frameworks/base/core/res/res/values/config.xml in the device overlay " \
194 "instead"
195 #endif // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
196
WifiFeatureFlags()197 WifiFeatureFlags::WifiFeatureFlags() {}
198
getChipModesForPrimary()199 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
200 std::array<char, PROPERTY_VALUE_MAX> buffer;
201 auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
202 // Debug property not set, use the device preset concurrency combination.
203 if (res <= 0) return kChipModesPrimary;
204
205 // Debug property set, use one of the debug preset concurrency combination.
206 unsigned long idx = std::stoul(buffer.data());
207 if (idx >= kDebugChipModes.size()) {
208 LOG(ERROR) << "Invalid index set in property: "
209 << kDebugPresetInterfaceCombinationIdxProperty;
210 return kChipModesPrimary;
211 }
212 std::string name;
213 std::vector<IWifiChip::ChipMode> chip_modes;
214 std::tie(name, chip_modes) = kDebugChipModes[idx];
215 LOG(INFO) << "Using debug chip mode: <" << name
216 << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
217 return chip_modes;
218 }
219
getChipModes(bool is_primary)220 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
221 return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
222 }
223
224 } // namespace feature_flags
225 } // namespace wifi
226 } // namespace hardware
227 } // namespace android
228 } // namespace aidl
229