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(const char * instance_name)180 std::shared_ptr<IWifiApIface> getWifiApIface(const char* instance_name) {
181     std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
182     if (!wifi_chip.get()) {
183         return nullptr;
184     }
185     if (!configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP)) {
186         return nullptr;
187     }
188     std::shared_ptr<IWifiApIface> iface;
189     auto status = wifi_chip->createApIface(&iface);
190     if (!status.isOk()) {
191         return nullptr;
192     }
193     return iface;
194 }
195 
getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip)196 std::shared_ptr<IWifiApIface> getBridgedWifiApIface(std::shared_ptr<IWifiChip> wifi_chip) {
197     if (!wifi_chip.get()) {
198         return nullptr;
199     }
200     int mode_id;
201     std::shared_ptr<IWifiApIface> iface;
202     configureChipToSupportConcurrencyTypeInternal(wifi_chip, IfaceConcurrencyType::AP, &mode_id);
203     auto status = wifi_chip->createBridgedApIface(&iface);
204     if (!status.isOk()) {
205         return nullptr;
206     }
207     return iface;
208 }
209 
getBridgedWifiApIface(const char * instance_name)210 std::shared_ptr<IWifiApIface> getBridgedWifiApIface(const char* instance_name) {
211     std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(instance_name);
212     return getBridgedWifiApIface(wifi_chip);
213 }
214 
configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type,int * configured_mode_id)215 bool configureChipToSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
216                                            IfaceConcurrencyType type, int* configured_mode_id) {
217     if (!wifi_chip.get()) {
218         return false;
219     }
220     return configureChipToSupportConcurrencyTypeInternal(wifi_chip, type, configured_mode_id);
221 }
222 
doesChipSupportConcurrencyType(const std::shared_ptr<IWifiChip> & wifi_chip,IfaceConcurrencyType type)223 bool doesChipSupportConcurrencyType(const std::shared_ptr<IWifiChip>& wifi_chip,
224                                     IfaceConcurrencyType type) {
225     if (!wifi_chip.get()) {
226         return false;
227     }
228     std::vector<IWifiChip::ChipMode> chip_modes;
229     auto status = wifi_chip->getAvailableModes(&chip_modes);
230     if (!status.isOk()) {
231         return false;
232     }
233     int mode_id;
234     return findAnyModeSupportingConcurrencyType(type, chip_modes, &mode_id);
235 }
236 
stopWifiService(const char * instance_name)237 void stopWifiService(const char* instance_name) {
238     std::shared_ptr<IWifi> wifi = getWifi(instance_name);
239     if (wifi != nullptr) {
240         wifi->stop();
241     }
242 }
243 
getChipFeatureSet(const std::shared_ptr<IWifiChip> & wifi_chip)244 int32_t getChipFeatureSet(const std::shared_ptr<IWifiChip>& wifi_chip) {
245     if (!wifi_chip.get()) {
246         return 0;
247     }
248     int32_t features = 0;
249     if (wifi_chip->getFeatureSet(&features).isOk()) {
250         return features;
251     }
252     return 0;
253 }
254 
isAidlServiceAvailable(const char * instance_name)255 bool isAidlServiceAvailable(const char* instance_name) {
256     return AServiceManager_isDeclared(instance_name);
257 }
258 
generateOuiKeyedDataList(int size)259 std::vector<OuiKeyedData> generateOuiKeyedDataList(int size) {
260     std::vector<OuiKeyedData> dataList;
261     for (int i = 0; i < size; i++) {
262         dataList.push_back(generateOuiKeyedData(i + 1));
263     }
264     return dataList;
265 }
266 
267 // Generate OuiKeyedData list fully wrapped in std::optional
generateOuiKeyedDataListOptional(int size)268 std::optional<std::vector<std::optional<OuiKeyedData>>> generateOuiKeyedDataListOptional(int size) {
269     std::vector<std::optional<OuiKeyedData>> dataList;
270     for (int i = 0; i < size; i++) {
271         dataList.push_back(generateOuiKeyedDataOptional(i + 1));
272     }
273     return std::optional<std::vector<std::optional<OuiKeyedData>>>{dataList};
274 }
275