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