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