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