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 "wifi_aidl_test_utils.h"
18
19 using ::android::wifi_system::InterfaceTool;
20
21 namespace {
findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,const std::vector<IWifiChip::ChipMode> & modes,int * mode_id)22 bool findAnyModeSupportingConcurrencyType(IfaceConcurrencyType desired_type,
23 const std::vector<IWifiChip::ChipMode>& modes,
24 int* mode_id) {
25 for (const auto& mode : modes) {
26 for (const auto& combination : mode.availableCombinations) {
27 for (const auto& iface_limit : combination.limits) {
28 const auto& iface_types = iface_limit.types;
29 if (std::find(iface_types.begin(), iface_types.end(), desired_type) !=
30 iface_types.end()) {
31 *mode_id = mode.id;
32 return true;
33 }
34 }
35 }
36 }
37 return false;
38 }
39
configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type,int * configured_mode_id)40 bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
41 IfaceConcurrencyType type,
42 int* configured_mode_id) {
43 if (!configured_mode_id) {
44 return false;
45 }
46 std::vector<IWifiChip::ChipMode> chip_modes;
47 auto status = wifi_chip->getAvailableModes(&chip_modes);
48 if (!status.isOk()) {
49 return false;
50 }
51 if (!findAnyModeSupportingConcurrencyType(type, chip_modes, configured_mode_id)) {
52 return false;
53 }
54 if (!wifi_chip->configureChip(*configured_mode_id).isOk()) {
55 return false;
56 }
57 return true;
58 }
59
configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type)60 bool configureChipToSupportConcurrencyTypeInternal(const std::shared_ptr<IWifiChip>& wifi_chip,
61 IfaceConcurrencyType type) {
62 int mode_id;
63 return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, &mode_id);
64 }
65
generateOuiKeyedData(int oui)66 OuiKeyedData generateOuiKeyedData(int oui) {
67 PersistableBundle bundle;
68 bundle.putString("stringKey", "stringValue");
69 bundle.putInt("intKey", 12345);
70
71 OuiKeyedData data;
72 data.oui = oui;
73 data.vendorData = bundle;
74 return data;
75 }
76
77 // Wraps generateOuiKeyedData result in std::optional
generateOuiKeyedDataOptional(int oui)78 std::optional<OuiKeyedData> generateOuiKeyedDataOptional(int oui) {
79 return std::optional<OuiKeyedData>{generateOuiKeyedData(oui)};
80 }
81
82 } // namespace
83
checkStatusCode(ndk::ScopedAStatus * status,WifiStatusCode expected_code)84 bool checkStatusCode(ndk::ScopedAStatus* status, WifiStatusCode expected_code) {
85 if (status == nullptr) {
86 return false;
87 }
88 return status->getServiceSpecificError() == static_cast<int32_t>(expected_code);
89 }
90
getWifi(const char * instance_name)91 std::shared_ptr<IWifi> getWifi(const char* instance_name) {
92 return IWifi::fromBinder(ndk::SpAIBinder(AServiceManager_waitForService(instance_name)));
93 }
94
getWifiChip(const char * instance_name)95 std::shared_ptr<IWifiChip> getWifiChip(const char* instance_name) {
96 std::shared_ptr<IWifi> wifi = getWifi(instance_name);
97 if (!wifi.get()) {
98 return nullptr;
99 }
100
101 const int retry_interval_ms = 2;
102 const int max_retries = 5;
103 int retry_count = 0;
104 auto status = wifi->start();
105 while (retry_count < max_retries && !status.isOk()) {
106 retry_count++;
107 usleep(retry_interval_ms * 1000);
108 status = wifi->start();
109 }
110 if (!status.isOk()) {
111 return nullptr;
112 }
113
114 std::vector<int> chip_ids = {};
115 status = wifi->getChipIds(&chip_ids);
116 if (!status.isOk() || chip_ids.size() == 0) {
117 return nullptr;
118 }
119 std::shared_ptr<IWifiChip> chip;
120 status = wifi->getChip(chip_ids[0], &chip);
121 if (!status.isOk()) {
122 return nullptr;
123 }
124 return chip;
125 }
126
setupStaIface(const std::shared_ptr<IWifiStaIface> & iface)127 void setupStaIface(const std::shared_ptr<IWifiStaIface>& iface) {
128 std::string iface_name;
129 auto status = iface->getName(&iface_name);
130 if (status.isOk()) {
131 InterfaceTool iface_tool;
132 iface_tool.SetUpState(iface_name.c_str(), true);
133 }
134 }
135
setupNanIface(const std::shared_ptr<IWifiNanIface> & iface)136 void setupNanIface(const std::shared_ptr<IWifiNanIface>& iface) {
137 std::string iface_name;
138 auto status = iface->getName(&iface_name);
139 if (status.isOk()) {
140 InterfaceTool iface_tool;
141 iface_tool.SetUpState(iface_name.c_str(), true);
142 }
143 }
144
getWifiStaIface(const char * instance_name)145 std::shared_ptr<IWifiStaIface> getWifiStaIface(const char* instance_name) {
146 std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
147 if (!wifi_chip.get()) {
148 return nullptr;
149 }
150 if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::STA)) {
151 return nullptr;
152 }
153 std::shared_ptr<IWifiStaIface> iface;
154 auto status = wifi_chip->createStaIface(&iface);
155 if (!status.isOk()) {
156 return nullptr;
157 }
158 setupStaIface(iface);
159 return iface;
160 }
161
getWifiNanIface(const char * instance_name)162 std::shared_ptr<IWifiNanIface> getWifiNanIface(const char* instance_name) {
163 std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
164 if (!wifi_chip.get()) {
165 return nullptr;
166 }
167 if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip,
168 IfaceConcurrencyType::NAN_IFACE)) {
169 return nullptr;
170 }
171 std::shared_ptr<IWifiNanIface> iface;
172 auto status = wifi_chip->createNanIface(&iface);
173 if (!status.isOk()) {
174 return nullptr;
175 }
176 setupNanIface(iface);
177 return iface;
178 }
179
getWifiApIface(std::shared_ptr<IWifiChip> wifi_chip)180 std::shared_ptr<IWifiApIface> getWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
181 if (!wifi_chip.get()) {
182 return nullptr;
183 }
184 if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
185 return nullptr;
186 }
187 std::shared_ptr<IWifiApIface> iface;
188 auto status = wifi_chip->createApIface(&iface);
189 if (!status.isOk()) {
190 return nullptr;
191 }
192 return iface;
193 }
194
getWifiApIface(const char * instance_name)195 std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
196 std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
197 return getWifiApIface(wifi_chip);
198 }
199
getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip)200 std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
201 if (!wifi_chip.get()) {
202 return nullptr;
203 }
204 int mode_id;
205 std::shared_ptr<IWifiApIface> iface;
206 configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP, &mode_id);
207 auto status = wifi_chip->createBridgedApIface(&iface);
208 if (!status.isOk()) {
209 return nullptr;
210 }
211 return iface;
212 }
213
getBridgedWifiApIface(const char * instance_name)214 std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name) {
215 std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
216 return getBridgedWifiApIface(wifi_chip);
217 }
218
configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type,int * configured_mode_id)219 bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
220 IfaceConcurrencyType type, int* configured_mode_id) {
221 if (!wifi_chip.get()) {
222 return false;
223 }
224 return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
225 }
226
doesChipSupportConcurrencyType(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type)227 bool doesChipSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
228 IfaceConcurrencyType type) {
229 if (!wifi_chip.get()) {
230 return false;
231 }
232 std::vector<IWifiChip::ChipMode> chip_modes;
233 auto status = wifi_chip->getAvailableModes(&chip_modes);
234 if (!status.isOk()) {
235 return false;
236 }
237 int mode_id;
238 return findAnyModeSupportingConcurrencyType(type, chip_modes, &mode_id);
239 }
240
stopWifiService(const char * instance_name)241 void stopWifiService(const char* instance_name) {
242 std::shared_ptr<IWifi> wifi = getWifi(instance_name);
243 if (wifi != nullptr) {
244 wifi->stop();
245 }
246 }
247
getChipFeatureSet(const std::shared_ptr<IWifiChip> & wifi_chip)248 int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip) {
249 if (!wifi_chip.get()) {
250 return 0;
251 }
252 int32_t features = 0;
253 if (wifi_chip->getFeatureSet(&features).isOk()) {
254 return features;
255 }
256 return 0;
257 }
258
isAidlServiceAvailable(const char * instance_name)259 bool isAidlServiceAvailable(const char* instance_name) {
260 return AServiceManager_isDeclared(instance_name);
261 }
262
generateOuiKeyedDataList(int size)263 std::vector<OuiKeyedData> generateOuiKeyedDataList(int size) {
264 std::vector<OuiKeyedData> dataList;
265 for (int i = 0; i < size; i++) {
266 dataList.push_back(generateOuiKeyedData(i + 1));
267 }
268 return dataList;
269 }
270
271 // Generate OuiKeyedData list fully wrapped in std::optional
generateOuiKeyedDataListOptional(int size)272 std::optional<std::vector<std::optional<OuiKeyedData>>> generateOuiKeyedDataListOptional(int size) {
273 std::vector<std::optional<OuiKeyedData>> dataList;
274 for (int i = 0; i < size; i++) {
275 dataList.push_back(generateOuiKeyedDataOptional(i + 1));
276 }
277 return std::optional<std::vector<std::optional<OuiKeyedData>>>{dataList};
278 }
279