1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Staache 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 <cctype>
18 #include <vector>
19
20 #include <VtsCoreUtil.h>
21 #include <aidl/Gtest.h>
22 #include <aidl/Vintf.h>
23 #include <aidl/android/hardware/wifi/BnWifi.h>
24 #include <android/binder_manager.h>
25 #include <android/binder_status.h>
26 #include <binder/IServiceManager.h>
27 #include <binder/ProcessState.h>
28 #include <cutils/properties.h>
29
30 #include "wifi_aidl_test_utils.h"
31
32 using aidl::android::hardware::wifi::CachedScanData;
33 using aidl::android::hardware::wifi::IWifi;
34 using aidl::android::hardware::wifi::IWifiStaIface;
35 using aidl::android::hardware::wifi::MacAddress;
36 using aidl::android::hardware::wifi::Ssid;
37 using aidl::android::hardware::wifi::StaApfPacketFilterCapabilities;
38 using aidl::android::hardware::wifi::StaBackgroundScanCapabilities;
39 using aidl::android::hardware::wifi::StaLinkLayerStats;
40 using aidl::android::hardware::wifi::StaRoamingCapabilities;
41 using aidl::android::hardware::wifi::StaRoamingConfig;
42 using aidl::android::hardware::wifi::StaRoamingState;
43 using aidl::android::hardware::wifi::TwtCapabilities;
44 using aidl::android::hardware::wifi::TwtRequest;
45 using aidl::android::hardware::wifi::WifiBand;
46 using aidl::android::hardware::wifi::WifiDebugRxPacketFateReport;
47 using aidl::android::hardware::wifi::WifiDebugTxPacketFateReport;
48 using aidl::android::hardware::wifi::WifiStatusCode;
49
50 class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
51 public:
SetUp()52 void SetUp() override {
53 stopWifiService(getInstanceName());
54 wifi_sta_iface_ = getWifiStaIface(getInstanceName());
55 ASSERT_NE(nullptr, wifi_sta_iface_.get());
56 ASSERT_TRUE(wifi_sta_iface_->getInterfaceVersion(&interface_version_).isOk());
57 }
58
TearDown()59 void TearDown() override { stopWifiService(getInstanceName()); }
60
61 protected:
isFeatureSupported(IWifiStaIface::FeatureSetMask expected)62 bool isFeatureSupported(IWifiStaIface::FeatureSetMask expected) {
63 int32_t features = 0;
64 EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
65 return features & static_cast<int32_t>(expected);
66 }
67
createStaIface(std::shared_ptr<IWifiStaIface> * sta_iface)68 ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* sta_iface) {
69 std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
70 EXPECT_NE(nullptr, wifi_chip.get());
71 return wifi_chip->createStaIface(sta_iface);
72 }
73
74 std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
75 int interface_version_;
76
77 // Checks if the mDNS Offload is supported by any NIC.
isMdnsOffloadPresentInNIC()78 bool isMdnsOffloadPresentInNIC() {
79 return testing::deviceSupportsFeature("com.google.android.tv.mdns_offload");
80 }
81
doesDeviceSupportFullNetworkingUnder2w()82 bool doesDeviceSupportFullNetworkingUnder2w() {
83 return testing::deviceSupportsFeature("com.google.android.tv.full_networking_under_2w");
84 }
85
86 // Detect TV devices.
isTvDevice()87 bool isTvDevice() {
88 return testing::deviceSupportsFeature("android.software.leanback") ||
89 testing::deviceSupportsFeature("android.hardware.type.television");
90 }
91
92 // Detect Panel TV devices by using ro.oem.key1 property.
93 // https://docs.partner.android.com/tv/build/platform/props-vars/ro-oem-key1
isPanelTvDevice()94 bool isPanelTvDevice() {
95 const std::string oem_key1 = getPropertyString("ro.oem.key1");
96 if (oem_key1.size() < 9) {
97 return false;
98 }
99 if (oem_key1.substr(0, 3) != "ATV") {
100 return false;
101 }
102 const std::string psz_string = oem_key1.substr(6, 3);
103 // If PSZ string contains non digit, then it is not a panel TV device.
104 for (char ch : psz_string) {
105 if (!isdigit(ch)) {
106 return false;
107 }
108 }
109 // If PSZ is "000", then it is not a panel TV device.
110 if (psz_string == "000") {
111 return false;
112 }
113 return true;
114 }
115
getPropertyString(const char * property_name)116 std::string getPropertyString(const char* property_name) {
117 char property_string_raw_bytes[PROPERTY_VALUE_MAX] = {};
118 int len = property_get(property_name, property_string_raw_bytes, "");
119 return std::string(property_string_raw_bytes, len);
120 }
121
122 private:
getInstanceName()123 const char* getInstanceName() { return GetParam().c_str(); }
124 };
125
126 /*
127 * GetFactoryMacAddress
128 * Ensures that calls to getFactoryMacAddress will retrieve a non-zero MAC.
129 */
TEST_P(WifiStaIfaceAidlTest,GetFactoryMacAddress)130 TEST_P(WifiStaIfaceAidlTest, GetFactoryMacAddress) {
131 std::array<uint8_t, 6> mac;
132 EXPECT_TRUE(wifi_sta_iface_->getFactoryMacAddress(&mac).isOk());
133 std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
134 EXPECT_NE(mac, all_zero_mac);
135 }
136
137 /*
138 * GetFeatureSet
139 */
TEST_P(WifiStaIfaceAidlTest,GetFeatureSet)140 TEST_P(WifiStaIfaceAidlTest, GetFeatureSet) {
141 int32_t features = 0;
142 EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
143 EXPECT_NE(features, 0);
144 }
145
146 /*
147 * CheckApfIsSupported:
148 * Ensures the APF packet filter is fully supported as required in VSR 14:
149 * https://docs.partner.android.com/gms/policies/vsr/vsr-14
150 */
151 // @VsrTest = VSR-5.3.12-001|VSR-5.3.12-003|VSR-5.3.12-004|VSR-5.3.12-009
TEST_P(WifiStaIfaceAidlTest,CheckApfIsSupported)152 TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
153 const std::string oem_key1 = getPropertyString("ro.oem.key1");
154 if (isTvDevice()) {
155 // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
156 // chipset does not have sufficient RAM to do so.
157 if (isPanelTvDevice() && isMdnsOffloadPresentInNIC()) {
158 GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
159 }
160 // For TV devices declaring the
161 // com.google.android.tv.full_networking_under_2w feature, this indicates
162 // the device can meet the <= 2W standby power requirement while
163 // continuously processing network packets on the CPU, even in standby mode.
164 // In these cases, APF support is strongly recommended rather than being
165 // mandatory.
166 if (doesDeviceSupportFullNetworkingUnder2w()) {
167 GTEST_SKIP() << "TV Device meets the <= 2W standby power demand requirement. It is not "
168 "required to support APF.";
169 }
170 }
171 int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
172 // Before VSR 14, APF support is optional.
173 if (vendor_api_level < __ANDROID_API_U__) {
174 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::APF)) {
175 GTEST_SKIP() << "APF packet filter capabilities are not supported.";
176 }
177 StaApfPacketFilterCapabilities apf_caps = {};
178 EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
179 return;
180 }
181
182 EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
183 StaApfPacketFilterCapabilities apf_caps = {};
184 EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
185 EXPECT_GE(apf_caps.version, 4);
186 // Based on VSR-14 the usable memory must be at least 1024 bytes.
187 EXPECT_GE(apf_caps.maxLength, 1024);
188 if (vendor_api_level >= __ANDROID_API_V__) {
189 // Based on VSR-15 the usable memory must be at least 2000 bytes.
190 EXPECT_GE(apf_caps.maxLength, 2000);
191 }
192 }
193
194 /*
195 * GetBackgroundScanCapabilities
196 */
TEST_P(WifiStaIfaceAidlTest,GetBackgroundScanCapabilities)197 TEST_P(WifiStaIfaceAidlTest, GetBackgroundScanCapabilities) {
198 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN)) {
199 GTEST_SKIP() << "Background scan capabilities are not supported.";
200 }
201 StaBackgroundScanCapabilities caps = {};
202 EXPECT_TRUE(wifi_sta_iface_->getBackgroundScanCapabilities(&caps).isOk());
203 }
204
205 /*
206 * GetLinkLayerStats
207 * Ensures that calls to getLinkLayerStats will retrieve a non-empty
208 * StaLinkLayerStats after link layer stats collection is enabled.
209 */
TEST_P(WifiStaIfaceAidlTest,GetLinkLayerStats)210 TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
211 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
212 GTEST_SKIP() << "Skipping this test since link layer stats are not supported.";
213 }
214
215 // Enable link layer stats collection.
216 EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
217
218 // Retrieve link layer stats.
219 StaLinkLayerStats link_layer_stats = {};
220 EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
221 EXPECT_GT(link_layer_stats.timeStampInMs, 0);
222
223 // Try to create a 2nd iface. If successful, it should fill the duty cycle field.
224 std::shared_ptr<IWifiStaIface> iface;
225 auto status = createStaIface(&iface);
226 if (status.isOk()) {
227 EXPECT_GT(link_layer_stats.iface.links[0].timeSliceDutyCycleInPercent, 0);
228 }
229
230 // Disable link layer stats collection.
231 EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
232 }
233
234 /*
235 * SetMacAddress
236 * Ensures that calls to setMacAddress will return successfully.
237 */
TEST_P(WifiStaIfaceAidlTest,SetMacAddress)238 TEST_P(WifiStaIfaceAidlTest, SetMacAddress) {
239 std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x41};
240 EXPECT_TRUE(wifi_sta_iface_->setMacAddress(mac).isOk());
241 }
242
243 /*
244 * SetScanMode
245 */
TEST_P(WifiStaIfaceAidlTest,SetScanMode)246 TEST_P(WifiStaIfaceAidlTest, SetScanMode) {
247 auto status = wifi_sta_iface_->setScanMode(true);
248 EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
249
250 status = wifi_sta_iface_->setScanMode(false);
251 EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
252 }
253
254 /*
255 * LinkLayerStatsCollection
256 */
TEST_P(WifiStaIfaceAidlTest,LinkLayerStatsCollection)257 TEST_P(WifiStaIfaceAidlTest, LinkLayerStatsCollection) {
258 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
259 GTEST_SKIP() << "Link layer stats collection is not supported.";
260 }
261
262 // Enable link layer stats collection.
263 EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
264
265 // Retrieve link layer stats.
266 StaLinkLayerStats link_layer_stats = {};
267 EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
268
269 // Disable link layer stats collection.
270 EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
271 }
272
273 /*
274 * RSSIMonitoring
275 * Ensures that calls to startRssiMonitoring and stopRssiMonitoring will fail
276 * if the device is not connected to an AP.
277 */
TEST_P(WifiStaIfaceAidlTest,RSSIMonitoring)278 TEST_P(WifiStaIfaceAidlTest, RSSIMonitoring) {
279 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::RSSI_MONITOR)) {
280 GTEST_SKIP() << "RSSI monitoring is not supported.";
281 }
282
283 const int cmd = 1;
284 const int maxRssi = -50;
285 const int minRssi = -90;
286 // Expected to fail because device is not connected to an AP.
287 EXPECT_FALSE(wifi_sta_iface_->startRssiMonitoring(cmd, maxRssi, minRssi).isOk());
288 EXPECT_FALSE(wifi_sta_iface_->stopRssiMonitoring(cmd).isOk());
289 }
290
291 /*
292 * RoamingControl
293 */
TEST_P(WifiStaIfaceAidlTest,RoamingControl)294 TEST_P(WifiStaIfaceAidlTest, RoamingControl) {
295 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CONTROL_ROAMING)) {
296 GTEST_SKIP() << "Roaming control is not supported.";
297 }
298
299 // Retrieve roaming capabilities.
300 StaRoamingCapabilities caps = {};
301 EXPECT_TRUE(wifi_sta_iface_->getRoamingCapabilities(&caps).isOk());
302
303 // Set up roaming configuration based on roaming capabilities.
304 StaRoamingConfig roaming_config = {};
305 if (caps.maxBlocklistSize > 0) {
306 MacAddress block_list_entry;
307 block_list_entry.data = std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
308 roaming_config.bssidBlocklist = {block_list_entry};
309 }
310 if (caps.maxAllowlistSize > 0) {
311 Ssid allow_list_entry = {};
312 allow_list_entry.data = std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}};
313 roaming_config.ssidAllowlist = {allow_list_entry};
314 }
315
316 // Configure roaming.
317 EXPECT_TRUE(wifi_sta_iface_->configureRoaming(roaming_config).isOk());
318
319 // Enable roaming.
320 EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::ENABLED).isOk());
321 }
322
323 /*
324 * RoamingModeControl
325 */
TEST_P(WifiStaIfaceAidlTest,RoamingModeControl)326 TEST_P(WifiStaIfaceAidlTest, RoamingModeControl) {
327 if (interface_version_ < 2) {
328 GTEST_SKIP() << "Roaming mode control is available as of sta_iface V2";
329 }
330 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ROAMING_MODE_CONTROL)) {
331 GTEST_SKIP() << "Roaming mode control is not supported.";
332 }
333
334 // Enable aggressive roaming.
335 EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::AGGRESSIVE).isOk());
336 }
337
338 /*
339 * EnableNDOffload
340 */
TEST_P(WifiStaIfaceAidlTest,EnableNDOffload)341 TEST_P(WifiStaIfaceAidlTest, EnableNDOffload) {
342 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ND_OFFLOAD)) {
343 GTEST_SKIP() << "ND offload is not supported.";
344 }
345 EXPECT_TRUE(wifi_sta_iface_->enableNdOffload(true).isOk());
346 }
347
348 /*
349 * PacketFateMonitoring
350 */
TEST_P(WifiStaIfaceAidlTest,PacketFateMonitoring)351 TEST_P(WifiStaIfaceAidlTest, PacketFateMonitoring) {
352 // Start packet fate monitoring.
353 auto status = wifi_sta_iface_->startDebugPacketFateMonitoring();
354 EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
355
356 // Retrieve packets.
357 if (status.isOk()) {
358 std::vector<WifiDebugRxPacketFateReport> rx_reports;
359 std::vector<WifiDebugTxPacketFateReport> tx_reports;
360 EXPECT_TRUE(wifi_sta_iface_->getDebugRxPacketFates(&rx_reports).isOk());
361 EXPECT_TRUE(wifi_sta_iface_->getDebugTxPacketFates(&tx_reports).isOk());
362 }
363 }
364
365 /*
366 * CachedScanData
367 */
TEST_P(WifiStaIfaceAidlTest,CachedScanData)368 TEST_P(WifiStaIfaceAidlTest, CachedScanData) {
369 if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CACHED_SCAN_DATA)) {
370 GTEST_SKIP() << "Cached scan data is not supported.";
371 }
372
373 // Retrieve cached scan data.
374 CachedScanData cached_scan_data = {};
375 EXPECT_TRUE(wifi_sta_iface_->getCachedScanData(&cached_scan_data).isOk());
376
377 if (cached_scan_data.cachedScanResults.size() > 0) {
378 EXPECT_GT(cached_scan_data.cachedScanResults[0].frequencyMhz, 0);
379 }
380 }
381
TEST_P(WifiStaIfaceAidlTest,TwtGetCapabilities)382 TEST_P(WifiStaIfaceAidlTest, TwtGetCapabilities) {
383 if (interface_version_ < 2) {
384 GTEST_SKIP() << "TwtGetCapabilities is available as of sta_iface V2";
385 }
386
387 TwtCapabilities twt_capabilities = {};
388 auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
389 if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
390 GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
391 }
392 EXPECT_TRUE(status.isOk());
393 if (!twt_capabilities.isTwtRequesterSupported) {
394 GTEST_SKIP() << "TWT is not supported";
395 }
396
397 EXPECT_GT(twt_capabilities.minWakeDurationUs, 0);
398 EXPECT_GT(twt_capabilities.maxWakeDurationUs, 0);
399 EXPECT_GT(twt_capabilities.minWakeIntervalUs, 0);
400 EXPECT_GT(twt_capabilities.maxWakeIntervalUs, 0);
401 }
402
TEST_P(WifiStaIfaceAidlTest,TwtSessionSetup)403 TEST_P(WifiStaIfaceAidlTest, TwtSessionSetup) {
404 if (interface_version_ < 2) {
405 GTEST_SKIP() << "TwtSessionSetup is available as of sta_iface V2";
406 }
407
408 TwtCapabilities twt_capabilities = {};
409 auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
410 if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
411 GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
412 }
413 EXPECT_TRUE(status.isOk());
414 if (!twt_capabilities.isTwtRequesterSupported) {
415 GTEST_SKIP() << "TWT is not supported";
416 }
417
418 TwtRequest twtRequest;
419 twtRequest.mloLinkId = 0;
420 twtRequest.minWakeDurationUs = twt_capabilities.minWakeDurationUs;
421 twtRequest.maxWakeDurationUs = twt_capabilities.maxWakeDurationUs;
422 twtRequest.minWakeIntervalUs = twt_capabilities.minWakeIntervalUs;
423 twtRequest.maxWakeIntervalUs = twt_capabilities.maxWakeIntervalUs;
424 EXPECT_TRUE(wifi_sta_iface_->twtSessionSetup(1, twtRequest).isOk());
425 }
426
TEST_P(WifiStaIfaceAidlTest,TwtSessionGetStats)427 TEST_P(WifiStaIfaceAidlTest, TwtSessionGetStats) {
428 if (interface_version_ < 2) {
429 GTEST_SKIP() << "TwtSessionGetStats is available as of sta_iface V2";
430 }
431
432 TwtCapabilities twt_capabilities = {};
433 auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
434 if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
435 GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
436 }
437 EXPECT_TRUE(status.isOk());
438 if (!twt_capabilities.isTwtRequesterSupported) {
439 GTEST_SKIP() << "TWT is not supported";
440 }
441
442 // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
443 // as the error code.
444 EXPECT_TRUE(wifi_sta_iface_->twtSessionGetStats(1, 10).isOk());
445 }
446
TEST_P(WifiStaIfaceAidlTest,TwtSessionTeardown)447 TEST_P(WifiStaIfaceAidlTest, TwtSessionTeardown) {
448 if (interface_version_ < 2) {
449 GTEST_SKIP() << "TwtSessionTeardown is available as of sta_iface V3";
450 }
451
452 TwtCapabilities twt_capabilities = {};
453 auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
454 if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
455 GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
456 }
457 EXPECT_TRUE(status.isOk());
458 if (!twt_capabilities.isTwtRequesterSupported) {
459 GTEST_SKIP() << "TWT is not supported";
460 }
461
462 // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
463 // as the error code.
464 EXPECT_TRUE(wifi_sta_iface_->twtSessionTeardown(1, 10).isOk());
465 }
466
467 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceAidlTest);
468 INSTANTIATE_TEST_SUITE_P(WifiTest, WifiStaIfaceAidlTest,
469 testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
470 android::PrintInstanceNameToString);
471
main(int argc,char ** argv)472 int main(int argc, char** argv) {
473 ::testing::InitGoogleTest(&argc, argv);
474 android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
475 android::ProcessState::self()->startThreadPool();
476 return RUN_ALL_TESTS();
477 }
478