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 "wifi_feature_flags.h"
18 
19 namespace android {
20 namespace hardware {
21 namespace wifi {
22 namespace V1_3 {
23 namespace implementation {
24 namespace feature_flags {
25 
26 using V1_0::ChipModeId;
27 using V1_0::IfaceType;
28 using V1_0::IWifiChip;
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 means:
40  *    Interface combination 1: 1 STA or AP and 1 P2P or NAN concurrent iface
41  *                             operations.
42  *    Interface 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 interface combinations:
52  *    Interface Combination 1: Will support 1 STA and 1 P2P or NAN (optional)
53  *                             concurrent iface operations.
54  *    Interface 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 interface 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 iface 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 ChipModeId 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 ChipModeId 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 ChipModeId 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 /**
110  * Helper class to convert a collection of combination limits to a combination.
111  *
112  * The main point here is to simplify the syntax required by
113  * WIFI_HAL_INTERFACE_COMBINATIONS.
114  */
115 struct ChipIfaceCombination
116     : public hidl_vec<IWifiChip::ChipIfaceCombinationLimit> {
ChipIfaceCombinationandroid::hardware::wifi::V1_3::implementation::feature_flags::ChipIfaceCombination117     ChipIfaceCombination(
118         const std::initializer_list<IWifiChip::ChipIfaceCombinationLimit> list)
119         : hidl_vec(list) {}
120 
operator IWifiChip::ChipIfaceCombinationandroid::hardware::wifi::V1_3::implementation::feature_flags::ChipIfaceCombination121     operator IWifiChip::ChipIfaceCombination() const { return {*this}; }
122 
make_vecandroid::hardware::wifi::V1_3::implementation::feature_flags::ChipIfaceCombination123     static hidl_vec<IWifiChip::ChipIfaceCombination> make_vec(
124         const std::initializer_list<ChipIfaceCombination> list) {
125         return hidl_vec<IWifiChip::ChipIfaceCombination>(  //
126             std::begin(list), std::end(list));
127     }
128 };
129 
130 #define STA IfaceType::STA
131 #define AP IfaceType::AP
132 #define P2P IfaceType::P2P
133 #define NAN IfaceType::NAN
134 static const std::vector<IWifiChip::ChipMode> kChipModes{
135     {kMainModeId,
136      ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS})},
137 #ifdef WIFI_HAL_INTERFACE_COMBINATIONS_AP
138     {chip_mode_ids::kV1Ap,
139      ChipIfaceCombination::make_vec({WIFI_HAL_INTERFACE_COMBINATIONS_AP})},
140 #endif
141 };
142 #undef STA
143 #undef AP
144 #undef P2P
145 #undef NAN
146 
147 #ifdef WIFI_HIDL_FEATURE_DISABLE_AP_MAC_RANDOMIZATION
148 static const bool wifiHidlFeatureDisableApMacRandomization = true;
149 #else
150 static const bool wifiHidlFeatureDisableApMacRandomization = false;
151 #endif  // WIFI_HIDL_FEATURE_DISABLE_AP
152 
WifiFeatureFlags()153 WifiFeatureFlags::WifiFeatureFlags() {}
154 
getChipModes()155 std::vector<IWifiChip::ChipMode> WifiFeatureFlags::getChipModes() {
156     return kChipModes;
157 }
158 
isApMacRandomizationDisabled()159 bool WifiFeatureFlags::isApMacRandomizationDisabled() {
160     return wifiHidlFeatureDisableApMacRandomization;
161 }
162 
163 }  // namespace feature_flags
164 }  // namespace implementation
165 }  // namespace V1_3
166 }  // namespace wifi
167 }  // namespace hardware
168 }  // namespace android
169