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