• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #undef NAN  // undefine NAN from math.h
126 #define NAN IfaceConcurrencyType::NAN_IFACE
127 static const std::vector<IWifiChip::ChipMode> kChipModesPrimary{
128         {kMainModeId, legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS})},
129 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
130         {chip_mode_ids::kV1Ap,
131          legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
132 #endif
133 };
134 
135 static const std::vector<IWifiChip::ChipMode> kChipModesSecondary{
136 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
137         {chip_mode_ids::kV3,
138          legacyToChipConcurrencyComboList({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
139 #endif
140 };
141 
142 constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
143         "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
144 // List of pre-defined concurrency combinations that can be enabled at runtime via
145 // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
146 // corresponding index value.
147 static const std::vector<std::pair<std::string, std::vector<IWifiChip::ChipMode>>> kDebugChipModes{
148         // Legacy combination - No STA/AP concurrencies.
149         // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
150         {"No STA/AP Concurrency",
151          {{kMainModeId,
152            legacyToChipConcurrencyComboList({{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
153 
154         // STA + AP concurrency
155         // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
156         {"STA + AP Concurrency",
157          {{kMainModeId, legacyToChipConcurrencyComboList(
158                                 {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
159 
160         // STA + STA concurrency
161         // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
162         {"Dual STA Concurrency",
163          {{kMainModeId, legacyToChipConcurrencyComboList(
164                                 {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
165 
166         // AP + AP + STA concurrency
167         // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
168         {"Dual AP Concurrency",
169          {{kMainModeId, legacyToChipConcurrencyComboList(
170                                 {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
171 
172         // STA + STA concurrency and AP + AP + STA concurrency
173         // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
174         {"Dual STA & Dual AP Concurrency",
175          {{kMainModeId, legacyToChipConcurrencyComboList(
176                                 {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
177 
178         // STA + STA concurrency
179         // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
180         {"Dual STA or STA plus single other interface",
181          {{kMainModeId, legacyToChipConcurrencyComboList(
182                                 {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}}, {{{STA}, 2}}})}}}};
183 
184 #undef STA
185 #undef AP
186 #undef AP_BRIDGED
187 #undef P2P
188 #undef NAN
189 
190 #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
191 #pragma message                                                                   \
192         "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
193         "'config_wifi_ap_randomization_supported' in "                            \
194         "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
195         "instead"
196 #endif  // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
197 
WifiFeatureFlags()198 WifiFeatureFlags::WifiFeatureFlags() {}
199 
getChipModesForPrimary()200 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
201     std::array<char, PROPERTY_VALUE_MAX> buffer;
202     auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
203     // Debug property not set, use the device preset concurrency combination.
204     if (res <= 0) return kChipModesPrimary;
205 
206     // Debug property set, use one of the debug preset concurrency combination.
207     unsigned long idx = std::stoul(buffer.data());
208     if (idx >= kDebugChipModes.size()) {
209         LOG(ERROR) << "Invalid index set in property: "
210                    << kDebugPresetInterfaceCombinationIdxProperty;
211         return kChipModesPrimary;
212     }
213     std::string name;
214     std::vector<IWifiChip::ChipMode> chip_modes;
215     std::tie(name, chip_modes) = kDebugChipModes[idx];
216     LOG(INFO) << "Using debug chip mode: <" << name
217               << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
218     return chip_modes;
219 }
220 
getChipModes(bool is_primary)221 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
222     return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
223 }
224 
225 }  // namespace feature_flags
226 }  // namespace wifi
227 }  // namespace hardware
228 }  // namespace android
229 }  // namespace aidl
230