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 <android/log.h>
18
19 #include <VtsHalHidlTargetTestBase.h>
20
21 #include <wifi_system/interface_tool.h>
22
23 #include "wifi_hidl_call_util.h"
24 #include "wifi_hidl_test_utils.h"
25
26 using ::android::hardware::wifi::V1_0::IWifi;
27 using ::android::hardware::wifi::V1_0::IWifiApIface;
28 using ::android::hardware::wifi::V1_0::IWifiChip;
29 using ::android::hardware::wifi::V1_0::IWifiIface;
30 using ::android::hardware::wifi::V1_0::IWifiNanIface;
31 using ::android::hardware::wifi::V1_0::IWifiP2pIface;
32 using ::android::hardware::wifi::V1_0::IWifiRttController;
33 using ::android::hardware::wifi::V1_0::IWifiStaIface;
34 using ::android::hardware::wifi::V1_0::ChipModeId;
35 using ::android::hardware::wifi::V1_0::ChipId;
36 using ::android::hardware::wifi::V1_0::IfaceType;
37 using ::android::hardware::wifi::V1_0::WifiStatus;
38 using ::android::hardware::wifi::V1_0::WifiStatusCode;
39 using ::android::sp;
40 using ::android::hardware::hidl_string;
41 using ::android::hardware::hidl_vec;
42 using ::android::wifi_system::InterfaceTool;
43
44 extern WifiHidlEnvironment* gEnv;
45
46 namespace {
47 constexpr uint32_t kHalStartRetryMaxCount = 5;
48 constexpr uint32_t kHalStartRetryIntervalInMs = 2;
49
findAnyModeSupportingIfaceType(IfaceType desired_type,const std::vector<IWifiChip::ChipMode> & modes,ChipModeId * mode_id)50 bool findAnyModeSupportingIfaceType(
51 IfaceType desired_type, const std::vector<IWifiChip::ChipMode>& modes,
52 ChipModeId* mode_id) {
53 for (const auto& mode : modes) {
54 for (const auto& combination : mode.availableCombinations) {
55 for (const auto& iface_limit : combination.limits) {
56 const auto& iface_types = iface_limit.types;
57 if (std::find(iface_types.begin(), iface_types.end(),
58 desired_type) != iface_types.end()) {
59 *mode_id = mode.id;
60 return true;
61 }
62 }
63 }
64 }
65 return false;
66 }
67
configureChipToSupportIfaceTypeInternal(const sp<IWifiChip> & wifi_chip,IfaceType type,ChipModeId * configured_mode_id)68 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip,
69 IfaceType type,
70 ChipModeId* configured_mode_id) {
71 if (!configured_mode_id) {
72 return false;
73 }
74 const auto& status_and_modes = HIDL_INVOKE(wifi_chip, getAvailableModes);
75 if (status_and_modes.first.code != WifiStatusCode::SUCCESS) {
76 return false;
77 }
78 if (!findAnyModeSupportingIfaceType(type, status_and_modes.second,
79 configured_mode_id)) {
80 return false;
81 }
82 if (HIDL_INVOKE(wifi_chip, configureChip, *configured_mode_id).code !=
83 WifiStatusCode::SUCCESS) {
84 return false;
85 }
86 return true;
87 }
88
configureChipToSupportIfaceTypeInternal(const sp<IWifiChip> & wifi_chip,IfaceType type)89 bool configureChipToSupportIfaceTypeInternal(const sp<IWifiChip>& wifi_chip,
90 IfaceType type) {
91 ChipModeId mode_id;
92 return configureChipToSupportIfaceTypeInternal(wifi_chip, type, &mode_id);
93 }
94 } // namespace
95
getWifi(const std::string & instance_name)96 sp<IWifi> getWifi(const std::string& instance_name) {
97 if ((!gEnv && instance_name.empty()) || (gEnv && !instance_name.empty())) {
98 ALOGE("instance_name and gEnv must have one and only one set.");
99 return nullptr;
100 }
101 if (gEnv) {
102 return ::testing::VtsHalHidlTargetTestBase::getService<IWifi>(
103 gEnv->getServiceName<IWifi>());
104 } else {
105 return IWifi::getService(instance_name);
106 }
107 }
108
getWifiChip(const std::string & instance_name)109 sp<IWifiChip> getWifiChip(const std::string& instance_name) {
110 sp<IWifi> wifi = getWifi(instance_name);
111 if (!wifi.get()) {
112 return nullptr;
113 }
114 uint32_t retry_count = 0;
115 auto status = HIDL_INVOKE(wifi, start);
116 while (retry_count < kHalStartRetryMaxCount &&
117 status.code == WifiStatusCode::ERROR_NOT_AVAILABLE) {
118 retry_count++;
119 usleep(kHalStartRetryIntervalInMs * 1000);
120 status = HIDL_INVOKE(wifi, start);
121 }
122 if (status.code != WifiStatusCode::SUCCESS) {
123 return nullptr;
124 }
125 const auto& status_and_chip_ids = HIDL_INVOKE(wifi, getChipIds);
126 const auto& chip_ids = status_and_chip_ids.second;
127 if (status_and_chip_ids.first.code != WifiStatusCode::SUCCESS ||
128 chip_ids.size() != 1) {
129 return nullptr;
130 }
131 const auto& status_and_chip = HIDL_INVOKE(wifi, getChip, chip_ids[0]);
132 if (status_and_chip.first.code != WifiStatusCode::SUCCESS) {
133 return nullptr;
134 }
135 return status_and_chip.second;
136 }
137
setIfaceUp(const sp<IWifiIface> & iface)138 void setIfaceUp(const sp<IWifiIface>& iface) {
139 // Set the iface up before retrurning the object.
140 const auto& status_and_name = HIDL_INVOKE(iface, getName);
141 if (status_and_name.first.code == WifiStatusCode::SUCCESS) {
142 const auto& iface_name = status_and_name.second;
143 InterfaceTool iface_tool;
144 iface_tool.SetUpState(iface_name.c_str(), true);
145 }
146 }
147
getWifiApIface(const std::string & instance_name)148 sp<IWifiApIface> getWifiApIface(const std::string& instance_name) {
149 sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
150 if (!wifi_chip.get()) {
151 return nullptr;
152 }
153 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::AP)) {
154 return nullptr;
155 }
156 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createApIface);
157 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) {
158 return nullptr;
159 }
160 setIfaceUp(status_and_iface.second);
161 return status_and_iface.second;
162 }
163
getWifiNanIface(const std::string & instance_name)164 sp<IWifiNanIface> getWifiNanIface(const std::string& instance_name) {
165 sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
166 if (!wifi_chip.get()) {
167 return nullptr;
168 }
169 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::NAN)) {
170 return nullptr;
171 }
172 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createNanIface);
173 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) {
174 return nullptr;
175 }
176 setIfaceUp(status_and_iface.second);
177 return status_and_iface.second;
178 }
179
getWifiP2pIface(const std::string & instance_name)180 sp<IWifiP2pIface> getWifiP2pIface(const std::string& instance_name) {
181 sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
182 if (!wifi_chip.get()) {
183 return nullptr;
184 }
185 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::P2P)) {
186 return nullptr;
187 }
188 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createP2pIface);
189 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) {
190 return nullptr;
191 }
192 setIfaceUp(status_and_iface.second);
193 return status_and_iface.second;
194 }
195
getWifiStaIface(const std::string & instance_name)196 sp<IWifiStaIface> getWifiStaIface(const std::string& instance_name) {
197 sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
198 if (!wifi_chip.get()) {
199 return nullptr;
200 }
201 if (!configureChipToSupportIfaceTypeInternal(wifi_chip, IfaceType::STA)) {
202 return nullptr;
203 }
204 const auto& status_and_iface = HIDL_INVOKE(wifi_chip, createStaIface);
205 if (status_and_iface.first.code != WifiStatusCode::SUCCESS) {
206 return nullptr;
207 }
208 setIfaceUp(status_and_iface.second);
209 return status_and_iface.second;
210 }
211
getWifiRttController(const std::string & instance_name)212 sp<IWifiRttController> getWifiRttController(const std::string& instance_name) {
213 sp<IWifiChip> wifi_chip = getWifiChip(instance_name);
214 if (!wifi_chip.get()) {
215 return nullptr;
216 }
217 sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface(instance_name);
218 if (!wifi_sta_iface.get()) {
219 return nullptr;
220 }
221 const auto& status_and_controller =
222 HIDL_INVOKE(wifi_chip, createRttController, wifi_sta_iface);
223 if (status_and_controller.first.code != WifiStatusCode::SUCCESS) {
224 return nullptr;
225 }
226 return status_and_controller.second;
227 }
228
configureChipToSupportIfaceType(const sp<IWifiChip> & wifi_chip,IfaceType type,ChipModeId * configured_mode_id)229 bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip,
230 IfaceType type,
231 ChipModeId* configured_mode_id) {
232 return configureChipToSupportIfaceTypeInternal(wifi_chip, type,
233 configured_mode_id);
234 }
235
stopWifi(const std::string & instance_name)236 void stopWifi(const std::string& instance_name) {
237 sp<IWifi> wifi = getWifi(instance_name);
238 ASSERT_NE(wifi, nullptr);
239 HIDL_INVOKE(wifi, stop);
240 }
241