• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 android {
25 namespace hardware {
26 namespace wifi {
27 namespace V1_6 {
28 namespace implementation {
29 namespace feature_flags {
30 
31 using V1_0::ChipModeId;
32 using V1_0::IWifiChip;
33 using V1_6::IfaceConcurrencyType;
34 
35 /* The chip may either have a single mode supporting any number of combinations,
36  * or a fixed dual-mode (so it involves firmware loading to switch between
37  * modes) setting. If there is a need to support more modes, it needs to be
38  * implemented manually in WiFi HAL (see changeFirmwareMode in
39  * WifiChip::handleChipConfiguration).
40  *
41  * Supported combinations are defined in device's makefile, for example:
42  *    WIFI_HAL_INTERFACE_COMBINATIONS := {{{STA, AP}, 1}, {{P2P, NAN}, 1}},
43  *    WIFI_HAL_INTERFACE_COMBINATIONS += {{{STA}, 1}, {{AP}, 2}}
44  * What means:
45  *    Interface concurrency combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
46  *                             operations.
47  *    Interface concurrency combination 2: 1 STA and 2 AP concurrent iface operations.
48  *
49  * For backward compatibility, the following makefile flags can be used to
50  * generate combinations list:
51  *  - WIFI_HIDL_FEATURE_DUAL_INTERFACE
52  *  - WIFI_HIDL_FEATURE_DISABLE_AP
53  *  - WIFI_HIDL_FEATURE_AWARE
54  * However, they are ignored if WIFI_HAL_INTERFACE_COMBINATIONS was provided.
55  * With WIFI_HIDL_FEATURE_DUAL_INTERFACE flag set, there is a single mode with
56  * two concurrency combinations:
57  *    Interface Concurrency Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
58  *                             concurrent iface operations.
59  *    Interface Concurrency Combination 2: Will support 1 STA and 1 AP concurrent
60  *                             iface operations.
61  *
62  * The only dual-mode configuration supported is for alternating STA and AP
63  * mode, that may involve firmware reloading. In such case, there are 2 separate
64  * modes of operation with 1 concurrency combination each:
65  *    Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN (optional)
66  *                       concurrent iface operations.
67  *    Mode 2 (AP mode): Will support 1 AP iface operation.
68  *
69  * If Aware is enabled, the concurrency combination will be modified to support either
70  * P2P or NAN in place of just P2P.
71  */
72 // clang-format off
73 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS
74 constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
75 #elif defined(WIFI_HIDL_FEATURE_DUAL_INTERFACE)
76 // former V2 (fixed dual interface) setup expressed as V3
77 constexpr ChipModeId kMainModeId = chip_mode_ids::kV3;
78 #  ifdef WIFI_HIDL_FEATURE_DISABLE_AP
79 #    ifdef WIFI_HIDL_FEATURE_AWARE
80 //     1 STA + 1 of (P2P or NAN)
81 #      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
82 #    else
83 //     1 STA + 1 P2P
84 #      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
85 #    endif
86 #  else
87 #    ifdef WIFI_HIDL_FEATURE_AWARE
88 //     (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
89 #      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
90                                               {{{STA}, 1}, {{P2P, NAN}, 1}}
91 #    else
92 //     (1 STA + 1 AP) or (1 STA + 1 P2P)
93 #      define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{AP}, 1}},\
94                                               {{{STA}, 1}, {{P2P}, 1}}
95 #    endif
96 #  endif
97 #else
98 // V1 (fixed single interface, dual-mode chip)
99 constexpr ChipModeId kMainModeId = chip_mode_ids::kV1Sta;
100 #  ifdef WIFI_HIDL_FEATURE_AWARE
101 //   1 STA + 1 of (P2P or NAN)
102 #    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P, NAN}, 1}}
103 #  else
104 //   1 STA + 1 P2P
105 #    define WIFI_HAL_INTERFACE_COMBINATIONS {{{STA}, 1}, {{P2P}, 1}}
106 #  endif
107 
108 #  ifndef WIFI_HIDL_FEATURE_DISABLE_AP
109 #    define WIFI_HAL_INTERFACE_COMBINATIONS_AP {{{AP}, 1}}
110 #  endif
111 #endif
112 // clang-format on
113 
114 /**
115  * Helper class to convert a collection of combination limits to a combination.
116  *
117  * The main point here is to simplify the syntax required by
118  * WIFI_HAL_INTERFACE_COMBINATIONS.
119  */
120 struct ChipConcurrencyCombination
121     : public hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> {
ChipConcurrencyCombinationandroid::hardware::wifi::V1_6::implementation::feature_flags::ChipConcurrencyCombination122     ChipConcurrencyCombination(
123             const std::initializer_list<V1_6::IWifiChip::ChipConcurrencyCombinationLimit> list)
124         : hidl_vec(list) {}
125 
operator V1_6::IWifiChip::ChipConcurrencyCombinationandroid::hardware::wifi::V1_6::implementation::feature_flags::ChipConcurrencyCombination126     operator V1_6::IWifiChip::ChipConcurrencyCombination() const { return {*this}; }
127 
make_vecandroid::hardware::wifi::V1_6::implementation::feature_flags::ChipConcurrencyCombination128     static hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination> make_vec(
129             const std::initializer_list<ChipConcurrencyCombination> list) {
130         return hidl_vec<V1_6::IWifiChip::ChipConcurrencyCombination>(  //
131                 std::begin(list), std::end(list));
132     }
133 };
134 
135 #define STA IfaceConcurrencyType::STA
136 #define AP IfaceConcurrencyType::AP
137 #define AP_BRIDGED IfaceConcurrencyType::AP_BRIDGED
138 #define P2P IfaceConcurrencyType::P2P
139 #define NAN IfaceConcurrencyType::NAN
140 static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesPrimary{
141         {kMainModeId, ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
142 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
143         {chip_mode_ids::kV1Ap,
144          ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
145 #endif
146 };
147 
148 static const std::vector<V1_6::IWifiChip::ChipMode> kChipModesSecondary{
149 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP
150         {chip_mode_ids::kV3,
151          ChipConcurrencyCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_SECONDARY_CHIP})},
152 #endif
153 };
154 
155 constexpr char kDebugPresetInterfaceCombinationIdxProperty[] =
156         "persist.vendor.debug.wifi.hal.preset_interface_combination_idx";
157 // List of pre-defined concurrency combinations that can be enabled at runtime via
158 // setting the property: "kDebugPresetInterfaceCombinationIdxProperty" to the
159 // corresponding index value.
160 static const std::vector<std::pair<std::string, std::vector<V1_6::IWifiChip::ChipMode>>>
161         kDebugChipModes{// Legacy combination - No STA/AP concurrencies.
162                         // 0 - (1 AP) or (1 STA + 1 of (P2P or NAN))
163                         {"No STA/AP Concurrency",
164                          {{kMainModeId, ChipConcurrencyCombination::make_vec(
165                                                 {{{{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
166 
167                         // STA + AP concurrency
168                         // 1 - (1 STA + 1 AP) or (1 STA + 1 of (P2P or NAN))
169                         {"STA + AP Concurrency",
170                          {{kMainModeId,
171                            ChipConcurrencyCombination::make_vec(
172                                    {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
173 
174                         // STA + STA concurrency
175                         // 2 - (1 STA + 1 AP) or (2 STA + 1 of (P2P or NAN))
176                         {"Dual STA Concurrency",
177                          {{kMainModeId,
178                            ChipConcurrencyCombination::make_vec(
179                                    {{{{STA}, 1}, {{AP}, 1}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
180 
181                         // AP + AP + STA concurrency
182                         // 3 - (1 STA + 2 AP) or (1 STA + 1 of (P2P or NAN))
183                         {"Dual AP Concurrency",
184                          {{kMainModeId,
185                            ChipConcurrencyCombination::make_vec(
186                                    {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 1}, {{P2P, NAN}, 1}}})}}},
187 
188                         // STA + STA concurrency and AP + AP + STA concurrency
189                         // 4 - (1 STA + 2 AP) or (2 STA + 1 of (P2P or NAN))
190                         {"Dual STA & Dual AP Concurrency",
191                          {{kMainModeId,
192                            ChipConcurrencyCombination::make_vec(
193                                    {{{{STA}, 1}, {{AP}, 2}}, {{{STA}, 2}, {{P2P, NAN}, 1}}})}}},
194 
195                         // STA + STA concurrency
196                         // 5 - (1 STA + 1 AP (bridged or single) | P2P | NAN), or (2 STA))
197                         {"Dual STA or STA plus single other interface",
198                          {{kMainModeId, ChipConcurrencyCombination::make_vec(
199                                                 {{{{STA}, 1}, {{P2P, NAN, AP, AP_BRIDGED}, 1}},
200                                                  {{{STA}, 2}}})}}}};
201 
202 #undef STA
203 #undef AP
204 #undef P2P
205 #undef NAN
206 
207 #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
208 #pragma message                                                                   \
209         "WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION is deprecated; override " \
210         "'config_wifi_ap_randomization_supported' in "                            \
211         "frameworks/base/core/res/res/values/config.xml in the device overlay "   \
212         "instead"
213 #endif  // WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
214 
WifiFeatureFlags()215 WifiFeatureFlags::WifiFeatureFlags() {}
216 
getChipModesForPrimary()217 std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModesForPrimary() {
218     std::array<char, PROPERTY_VALUE_MAX> buffer;
219     auto res = property_get(kDebugPresetInterfaceCombinationIdxProperty, buffer.data(), nullptr);
220     // Debug property not set, use the device preset concurrency combination.
221     if (res <= 0) return kChipModesPrimary;
222 
223     // Debug property set, use one of the debug preset concurrency combination.
224     unsigned long idx = std::stoul(buffer.data());
225     if (idx >= kDebugChipModes.size()) {
226         LOG(ERROR) << "Invalid index set in property: "
227                    << kDebugPresetInterfaceCombinationIdxProperty;
228         return kChipModesPrimary;
229     }
230     std::string name;
231     std::vector<V1_6::IWifiChip::ChipMode> chip_modes;
232     std::tie(name, chip_modes) = kDebugChipModes[idx];
233     LOG(INFO) << "Using debug chip mode: <" << name
234               << "> set via property: " << kDebugPresetInterfaceCombinationIdxProperty;
235     return chip_modes;
236 }
237 
getChipModes(bool is_primary)238 std::vector<V1_6::IWifiChip::ChipMode> WifiFeatureFlags::getChipModes(bool is_primary) {
239     return (is_primary) ? getChipModesForPrimary() : kChipModesSecondary;
240 }
241 
242 }  // namespace feature_flags
243 }  // namespace implementation
244 }  // namespace V1_6
245 }  // namespace wifi
246 }  // namespace hardware
247 }  // namespace android
248