• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <aidl/android/hardware/wifi/BnWifiStaIfaceEventCallback.h>
25 #include <android/binder_manager.h>
26 #include <android/binder_status.h>
27 #include <binder/IServiceManager.h>
28 #include <binder/ProcessState.h>
29 #include <cutils/properties.h>
30 
31 #include "wifi_aidl_test_utils.h"
32 
33 using aidl::android::hardware::wifi::BnWifiStaIfaceEventCallback;
34 using aidl::android::hardware::wifi::CachedScanData;
35 using aidl::android::hardware::wifi::IWifi;
36 using aidl::android::hardware::wifi::IWifiStaIface;
37 using aidl::android::hardware::wifi::MacAddress;
38 using aidl::android::hardware::wifi::Ssid;
39 using aidl::android::hardware::wifi::StaApfPacketFilterCapabilities;
40 using aidl::android::hardware::wifi::StaBackgroundScanCapabilities;
41 using aidl::android::hardware::wifi::StaBackgroundScanParameters;
42 using aidl::android::hardware::wifi::StaLinkLayerStats;
43 using aidl::android::hardware::wifi::StaRoamingCapabilities;
44 using aidl::android::hardware::wifi::StaRoamingConfig;
45 using aidl::android::hardware::wifi::StaRoamingState;
46 using aidl::android::hardware::wifi::TwtCapabilities;
47 using aidl::android::hardware::wifi::TwtRequest;
48 using aidl::android::hardware::wifi::WifiBand;
49 using aidl::android::hardware::wifi::WifiDebugRxPacketFateReport;
50 using aidl::android::hardware::wifi::WifiDebugTxPacketFateReport;
51 using aidl::android::hardware::wifi::WifiStatusCode;
52 
53 namespace {
54 const int kTestCmdId = 123;
55 const std::array<uint8_t, 6> kTestMacAddr1 = {0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f};
56 const std::array<uint8_t, 6> kTestMacAddr2 = {0x4a, 0x5b, 0x6c, 0x7d, 0x8e, 0x9f};
57 }  // namespace
58 
59 class WifiStaIfaceAidlTest : public testing::TestWithParam<std::string> {
60   public:
SetUp()61     void SetUp() override {
62         stopWifiService(getInstanceName());
63         wifi_sta_iface_ = getWifiStaIface(getInstanceName());
64         ASSERT_NE(nullptr, wifi_sta_iface_.get());
65         ASSERT_TRUE(wifi_sta_iface_->getInterfaceVersion(&interface_version_).isOk());
66     }
67 
TearDown()68     void TearDown() override { stopWifiService(getInstanceName()); }
69 
70   protected:
isFeatureSupported(IWifiStaIface::FeatureSetMask expected)71     bool isFeatureSupported(IWifiStaIface::FeatureSetMask expected) {
72         int32_t features = 0;
73         EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
74         return features & static_cast<int32_t>(expected);
75     }
76 
isTwtSupported()77     bool isTwtSupported() {
78         TwtCapabilities twt_capabilities = {};
79         auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
80         return status.isOk() && twt_capabilities.isTwtRequesterSupported;
81     }
82 
createStaIface(std::shared_ptr<IWifiStaIface> * sta_iface)83     ndk::ScopedAStatus createStaIface(std::shared_ptr<IWifiStaIface>* sta_iface) {
84         std::shared_ptr<IWifiChip> wifi_chip = getWifiChip(getInstanceName());
85         EXPECT_NE(nullptr, wifi_chip.get());
86         return wifi_chip->createStaIface(sta_iface);
87     }
88 
89     std::shared_ptr<IWifiStaIface> wifi_sta_iface_;
90     int interface_version_;
91 
92     // Checks if the mDNS Offload is supported by any NIC.
isMdnsOffloadPresentInNIC()93     bool isMdnsOffloadPresentInNIC() {
94         return testing::deviceSupportsFeature("com.google.android.tv.mdns_offload");
95     }
96 
doesDeviceSupportFullNetworkingUnder2w()97     bool doesDeviceSupportFullNetworkingUnder2w() {
98         return testing::deviceSupportsFeature("com.google.android.tv.full_networking_under_2w");
99     }
100 
101     // Detect TV devices.
isTvDevice()102     bool isTvDevice() {
103         return testing::deviceSupportsFeature("android.software.leanback") ||
104                testing::deviceSupportsFeature("android.hardware.type.television");
105     }
106 
107     // Detect Panel TV devices by using ro.oem.key1 property.
108     // https://docs.partner.android.com/tv/build/platform/props-vars/ro-oem-key1
isPanelTvDevice()109     bool isPanelTvDevice() {
110         const std::string oem_key1 = getPropertyString("ro.oem.key1");
111         if (oem_key1.size() < 9) {
112             return false;
113         }
114         if (oem_key1.substr(0, 3) != "ATV") {
115             return false;
116         }
117         const std::string psz_string = oem_key1.substr(6, 3);
118         // If PSZ string contains non digit, then it is not a panel TV device.
119         for (char ch : psz_string) {
120             if (!isdigit(ch)) {
121                 return false;
122             }
123         }
124         // If PSZ is "000", then it is not a panel TV device.
125         if (psz_string == "000") {
126             return false;
127         }
128         return true;
129     }
130 
getPropertyString(const char * property_name)131     std::string getPropertyString(const char* property_name) {
132         char property_string_raw_bytes[PROPERTY_VALUE_MAX] = {};
133         int len = property_get(property_name, property_string_raw_bytes, "");
134         return std::string(property_string_raw_bytes, len);
135     }
136 
137   private:
getInstanceName()138     const char* getInstanceName() { return GetParam().c_str(); }
139 };
140 
141 /*
142  * GetFactoryMacAddress
143  * Ensures that calls to getFactoryMacAddress will retrieve a non-zero MAC.
144  */
TEST_P(WifiStaIfaceAidlTest,GetFactoryMacAddress)145 TEST_P(WifiStaIfaceAidlTest, GetFactoryMacAddress) {
146     std::array<uint8_t, 6> mac;
147     EXPECT_TRUE(wifi_sta_iface_->getFactoryMacAddress(&mac).isOk());
148     std::array<uint8_t, 6> all_zero_mac = {0, 0, 0, 0, 0, 0};
149     EXPECT_NE(mac, all_zero_mac);
150 }
151 
152 /*
153  * GetFeatureSet
154  */
TEST_P(WifiStaIfaceAidlTest,GetFeatureSet)155 TEST_P(WifiStaIfaceAidlTest, GetFeatureSet) {
156     int32_t features = 0;
157     EXPECT_TRUE(wifi_sta_iface_->getFeatureSet(&features).isOk());
158     EXPECT_NE(features, 0);
159 }
160 
161 /*
162  * CheckApfIsSupported:
163  * Ensures the APF packet filter is fully supported as required in VSR 14:
164  * https://docs.partner.android.com/gms/policies/vsr/vsr-14
165  */
166 // @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)167 TEST_P(WifiStaIfaceAidlTest, CheckApfIsSupported) {
168     const std::string oem_key1 = getPropertyString("ro.oem.key1");
169     if (isTvDevice()) {
170         // Flat panel TV devices that support MDNS offload do not have to implement APF if the WiFi
171         // chipset does not have sufficient RAM to do so.
172         if (isPanelTvDevice() && isMdnsOffloadPresentInNIC()) {
173             GTEST_SKIP() << "Panel TV supports mDNS offload. It is not required to support APF";
174         }
175         // For TV devices declaring the
176         // com.google.android.tv.full_networking_under_2w feature, this indicates
177         // the device can meet the <= 2W standby power requirement while
178         // continuously processing network packets on the CPU, even in standby mode.
179         // In these cases, APF support is strongly recommended rather than being
180         // mandatory.
181         if (doesDeviceSupportFullNetworkingUnder2w()) {
182             GTEST_SKIP() << "TV Device meets the <= 2W standby power demand requirement. It is not "
183                             "required to support APF.";
184         }
185     }
186     int vendor_api_level = property_get_int32("ro.vendor.api_level", 0);
187     // Before VSR 14, APF support is optional.
188     if (vendor_api_level < __ANDROID_API_U__) {
189         if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::APF)) {
190             GTEST_SKIP() << "APF packet filter capabilities are not supported.";
191         }
192         StaApfPacketFilterCapabilities apf_caps = {};
193         EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
194         return;
195     }
196 
197     EXPECT_TRUE(isFeatureSupported(IWifiStaIface::FeatureSetMask::APF));
198     StaApfPacketFilterCapabilities apf_caps = {};
199     EXPECT_TRUE(wifi_sta_iface_->getApfPacketFilterCapabilities(&apf_caps).isOk());
200     EXPECT_GE(apf_caps.version, 4);
201     // Based on VSR-14 the usable memory must be at least 1024 bytes.
202     EXPECT_GE(apf_caps.maxLength, 1024);
203     if (vendor_api_level >= __ANDROID_API_V__) {
204         // Based on VSR-15 the usable memory must be at least 2000 bytes.
205         EXPECT_GE(apf_caps.maxLength, 2000);
206     }
207 }
208 
209 /*
210  * GetBackgroundScanCapabilities
211  */
TEST_P(WifiStaIfaceAidlTest,GetBackgroundScanCapabilities)212 TEST_P(WifiStaIfaceAidlTest, GetBackgroundScanCapabilities) {
213     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN)) {
214         GTEST_SKIP() << "Background scan capabilities are not supported.";
215     }
216     StaBackgroundScanCapabilities caps = {};
217     EXPECT_TRUE(wifi_sta_iface_->getBackgroundScanCapabilities(&caps).isOk());
218 }
219 
220 /*
221  * GetLinkLayerStats
222  * Ensures that calls to getLinkLayerStats will retrieve a non-empty
223  * StaLinkLayerStats after link layer stats collection is enabled.
224  */
TEST_P(WifiStaIfaceAidlTest,GetLinkLayerStats)225 TEST_P(WifiStaIfaceAidlTest, GetLinkLayerStats) {
226     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
227         GTEST_SKIP() << "Skipping this test since link layer stats are not supported.";
228     }
229 
230     // Enable link layer stats collection.
231     EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
232 
233     // Retrieve link layer stats.
234     StaLinkLayerStats link_layer_stats = {};
235     EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
236     EXPECT_GT(link_layer_stats.timeStampInMs, 0);
237 
238     // Try to create a 2nd iface. If successful, it should fill the duty cycle field.
239     std::shared_ptr<IWifiStaIface> iface;
240     auto status = createStaIface(&iface);
241     if (status.isOk()) {
242         EXPECT_GT(link_layer_stats.iface.links[0].timeSliceDutyCycleInPercent, 0);
243     }
244 
245     // Disable link layer stats collection.
246     EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
247 }
248 
249 /*
250  * SetMacAddress
251  * Ensures that calls to setMacAddress will return successfully.
252  */
TEST_P(WifiStaIfaceAidlTest,SetMacAddress)253 TEST_P(WifiStaIfaceAidlTest, SetMacAddress) {
254     std::array<uint8_t, 6> mac = {0x12, 0x22, 0x33, 0x52, 0x10, 0x41};
255     EXPECT_TRUE(wifi_sta_iface_->setMacAddress(mac).isOk());
256 }
257 
258 /*
259  * SetScanMode
260  */
TEST_P(WifiStaIfaceAidlTest,SetScanMode)261 TEST_P(WifiStaIfaceAidlTest, SetScanMode) {
262     auto status = wifi_sta_iface_->setScanMode(true);
263     EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
264 
265     status = wifi_sta_iface_->setScanMode(false);
266     EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
267 }
268 
269 /*
270  * LinkLayerStatsCollection
271  */
TEST_P(WifiStaIfaceAidlTest,LinkLayerStatsCollection)272 TEST_P(WifiStaIfaceAidlTest, LinkLayerStatsCollection) {
273     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::LINK_LAYER_STATS)) {
274         GTEST_SKIP() << "Link layer stats collection is not supported.";
275     }
276 
277     // Enable link layer stats collection.
278     EXPECT_TRUE(wifi_sta_iface_->enableLinkLayerStatsCollection(true).isOk());
279 
280     // Retrieve link layer stats.
281     StaLinkLayerStats link_layer_stats = {};
282     EXPECT_TRUE(wifi_sta_iface_->getLinkLayerStats(&link_layer_stats).isOk());
283 
284     // Disable link layer stats collection.
285     EXPECT_TRUE(wifi_sta_iface_->disableLinkLayerStatsCollection().isOk());
286 }
287 
288 /*
289  * RSSIMonitoring
290  * Ensures that calls to startRssiMonitoring and stopRssiMonitoring will fail
291  * if the device is not connected to an AP.
292  */
TEST_P(WifiStaIfaceAidlTest,RSSIMonitoring)293 TEST_P(WifiStaIfaceAidlTest, RSSIMonitoring) {
294     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::RSSI_MONITOR)) {
295         GTEST_SKIP() << "RSSI monitoring is not supported.";
296     }
297 
298     const int cmd = 1;
299     const int maxRssi = -50;
300     const int minRssi = -90;
301     // Expected to fail because device is not connected to an AP.
302     EXPECT_FALSE(wifi_sta_iface_->startRssiMonitoring(cmd, maxRssi, minRssi).isOk());
303     EXPECT_FALSE(wifi_sta_iface_->stopRssiMonitoring(cmd).isOk());
304 }
305 
306 /*
307  * RoamingControl
308  */
TEST_P(WifiStaIfaceAidlTest,RoamingControl)309 TEST_P(WifiStaIfaceAidlTest, RoamingControl) {
310     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CONTROL_ROAMING)) {
311         GTEST_SKIP() << "Roaming control is not supported.";
312     }
313 
314     // Retrieve roaming capabilities.
315     StaRoamingCapabilities caps = {};
316     EXPECT_TRUE(wifi_sta_iface_->getRoamingCapabilities(&caps).isOk());
317 
318     // Set up roaming configuration based on roaming capabilities.
319     StaRoamingConfig roaming_config = {};
320     if (caps.maxBlocklistSize > 0) {
321         MacAddress block_list_entry;
322         block_list_entry.data = std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}};
323         roaming_config.bssidBlocklist = {block_list_entry};
324     }
325     if (caps.maxAllowlistSize > 0) {
326         Ssid allow_list_entry = {};
327         allow_list_entry.data = std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}};
328         roaming_config.ssidAllowlist = {allow_list_entry};
329     }
330 
331     // Configure roaming.
332     EXPECT_TRUE(wifi_sta_iface_->configureRoaming(roaming_config).isOk());
333 
334     // Enable roaming.
335     EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::ENABLED).isOk());
336 }
337 
338 /*
339  * RoamingModeControl
340  */
TEST_P(WifiStaIfaceAidlTest,RoamingModeControl)341 TEST_P(WifiStaIfaceAidlTest, RoamingModeControl) {
342     if (interface_version_ < 2) {
343         GTEST_SKIP() << "Roaming mode control is available as of sta_iface V2";
344     }
345     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ROAMING_MODE_CONTROL)) {
346         GTEST_SKIP() << "Roaming mode control is not supported.";
347     }
348 
349     // Enable aggressive roaming.
350     EXPECT_TRUE(wifi_sta_iface_->setRoamingState(StaRoamingState::AGGRESSIVE).isOk());
351 }
352 
353 /*
354  * EnableNDOffload
355  */
TEST_P(WifiStaIfaceAidlTest,EnableNDOffload)356 TEST_P(WifiStaIfaceAidlTest, EnableNDOffload) {
357     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::ND_OFFLOAD)) {
358         GTEST_SKIP() << "ND offload is not supported.";
359     }
360     EXPECT_TRUE(wifi_sta_iface_->enableNdOffload(true).isOk());
361 }
362 
363 /*
364  * PacketFateMonitoring
365  */
TEST_P(WifiStaIfaceAidlTest,PacketFateMonitoring)366 TEST_P(WifiStaIfaceAidlTest, PacketFateMonitoring) {
367     // Start packet fate monitoring.
368     auto status = wifi_sta_iface_->startDebugPacketFateMonitoring();
369     EXPECT_TRUE(status.isOk() || checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED));
370 
371     // Retrieve packets.
372     if (status.isOk()) {
373         std::vector<WifiDebugRxPacketFateReport> rx_reports;
374         std::vector<WifiDebugTxPacketFateReport> tx_reports;
375         EXPECT_TRUE(wifi_sta_iface_->getDebugRxPacketFates(&rx_reports).isOk());
376         EXPECT_TRUE(wifi_sta_iface_->getDebugTxPacketFates(&tx_reports).isOk());
377     }
378 }
379 
380 /*
381  * CachedScanData
382  */
TEST_P(WifiStaIfaceAidlTest,CachedScanData)383 TEST_P(WifiStaIfaceAidlTest, CachedScanData) {
384     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::CACHED_SCAN_DATA)) {
385         GTEST_SKIP() << "Cached scan data is not supported.";
386     }
387 
388     // Retrieve cached scan data.
389     CachedScanData cached_scan_data = {};
390     EXPECT_TRUE(wifi_sta_iface_->getCachedScanData(&cached_scan_data).isOk());
391 
392     if (cached_scan_data.cachedScanResults.size() > 0) {
393         EXPECT_GT(cached_scan_data.cachedScanResults[0].frequencyMhz, 0);
394     }
395 }
396 
397 class WifiStaIfaceEventCallback : public BnWifiStaIfaceEventCallback {
398   public:
399     WifiStaIfaceEventCallback() = default;
400 
onBackgroundFullScanResult(int32_t,int32_t,const::aidl::android::hardware::wifi::StaScanResult &)401     ::ndk::ScopedAStatus onBackgroundFullScanResult(
402             int32_t /* in_cmdId */, int32_t /* in_bucketsScanned */,
403             const ::aidl::android::hardware::wifi::StaScanResult& /* in_result */) override {
404         return ndk::ScopedAStatus::ok();
405     }
onBackgroundScanFailure(int32_t)406     ::ndk::ScopedAStatus onBackgroundScanFailure(int32_t /* in_cmdId */) override {
407         return ndk::ScopedAStatus::ok();
408     }
onBackgroundScanResults(int32_t,const std::vector<::aidl::android::hardware::wifi::StaScanData> &)409     ::ndk::ScopedAStatus onBackgroundScanResults(
410             int32_t /* in_cmdId */,
411             const std::vector<::aidl::android::hardware::wifi::StaScanData>& /* in_scanDatas */)
412             override {
413         return ndk::ScopedAStatus::ok();
414     }
onRssiThresholdBreached(int32_t,const std::array<uint8_t,6> &,int32_t)415     ::ndk::ScopedAStatus onRssiThresholdBreached(int32_t /* in_cmdId */,
416                                                  const std::array<uint8_t, 6>& /* in_currBssid */,
417                                                  int32_t /* in_currRssi */) override {
418         return ndk::ScopedAStatus::ok();
419     }
onTwtFailure(int32_t,::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::TwtErrorCode)420     ::ndk::ScopedAStatus onTwtFailure(int32_t /*in_cmdId*/,
421                                       ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
422                                               TwtErrorCode /* in_error */) override {
423         return ndk::ScopedAStatus::ok();
424     }
onTwtSessionCreate(int32_t,const::aidl::android::hardware::wifi::TwtSession &)425     ::ndk::ScopedAStatus onTwtSessionCreate(
426             int32_t /* in_cmdId */,
427             const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
428         return ndk::ScopedAStatus::ok();
429     }
onTwtSessionUpdate(int32_t,const::aidl::android::hardware::wifi::TwtSession &)430     ::ndk::ScopedAStatus onTwtSessionUpdate(
431             int32_t /* in_cmdId */,
432             const ::aidl::android::hardware::wifi::TwtSession& /* in_twtSession */) override {
433         return ndk::ScopedAStatus::ok();
434     }
onTwtSessionTeardown(int32_t,int32_t,::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::TwtTeardownReasonCode)435     ::ndk::ScopedAStatus onTwtSessionTeardown(
436             int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
437             ::aidl::android::hardware::wifi::IWifiStaIfaceEventCallback::
438                     TwtTeardownReasonCode /* in_reasonCode */) override {
439         return ndk::ScopedAStatus::ok();
440     }
onTwtSessionStats(int32_t,int32_t,const::aidl::android::hardware::wifi::TwtSessionStats &)441     ::ndk::ScopedAStatus onTwtSessionStats(
442             int32_t /* in_cmdId */, int32_t /* in_twtSessionId */,
443             const ::aidl::android::hardware::wifi::TwtSessionStats& /* in_twtSessionStats */)
444             override {
445         return ndk::ScopedAStatus::ok();
446     }
onTwtSessionSuspend(int32_t,int32_t)447     ::ndk::ScopedAStatus onTwtSessionSuspend(int32_t /* in_cmdId */,
448                                              int32_t /* in_twtSessionId */) override {
449         return ndk::ScopedAStatus::ok();
450     }
onTwtSessionResume(int32_t,int32_t)451     ::ndk::ScopedAStatus onTwtSessionResume(int32_t /* in_cmdId */,
452                                             int32_t /* in_twtSessionId */) override {
453         return ndk::ScopedAStatus::ok();
454     }
455 };
456 
457 /**
458  * TwtGetCapabilities
459  */
TEST_P(WifiStaIfaceAidlTest,TwtGetCapabilities)460 TEST_P(WifiStaIfaceAidlTest, TwtGetCapabilities) {
461     if (interface_version_ < 2) {
462         GTEST_SKIP() << "TwtGetCapabilities is available as of sta_iface V2";
463     }
464 
465     TwtCapabilities twt_capabilities = {};
466     auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
467     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
468         GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
469     }
470     EXPECT_TRUE(status.isOk());
471     if (!twt_capabilities.isTwtRequesterSupported) {
472         GTEST_SKIP() << "TWT is not supported";
473     }
474 
475     EXPECT_GT(twt_capabilities.minWakeDurationUs, 0);
476     EXPECT_GT(twt_capabilities.maxWakeDurationUs, 0);
477     EXPECT_GT(twt_capabilities.minWakeIntervalUs, 0);
478     EXPECT_GT(twt_capabilities.maxWakeIntervalUs, 0);
479 }
480 
481 /**
482  * TwtSessionSetup
483  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionSetup)484 TEST_P(WifiStaIfaceAidlTest, TwtSessionSetup) {
485     if (interface_version_ < 2) {
486         GTEST_SKIP() << "TwtSessionSetup is available as of sta_iface V2";
487     }
488 
489     TwtCapabilities twt_capabilities = {};
490     auto status = wifi_sta_iface_->twtGetCapabilities(&twt_capabilities);
491     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
492         GTEST_SKIP() << "twtGetCapabilities() is not supported by the vendor";
493     }
494     EXPECT_TRUE(status.isOk());
495     if (!twt_capabilities.isTwtRequesterSupported) {
496         GTEST_SKIP() << "TWT is not supported";
497     }
498     const std::shared_ptr<WifiStaIfaceEventCallback> callback =
499             ndk::SharedRefBase::make<WifiStaIfaceEventCallback>();
500     ASSERT_NE(callback, nullptr);
501     EXPECT_TRUE(wifi_sta_iface_->registerEventCallback(callback).isOk());
502 
503     TwtRequest twtRequest;
504     twtRequest.mloLinkId = 0;
505     twtRequest.minWakeDurationUs = twt_capabilities.minWakeDurationUs;
506     twtRequest.maxWakeDurationUs = twt_capabilities.maxWakeDurationUs;
507     twtRequest.minWakeIntervalUs = twt_capabilities.minWakeIntervalUs;
508     twtRequest.maxWakeIntervalUs = twt_capabilities.maxWakeIntervalUs;
509     EXPECT_TRUE(wifi_sta_iface_->twtSessionSetup(1, twtRequest).isOk());
510 }
511 
512 /**
513  * TwtSessionGetStats
514  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionGetStats)515 TEST_P(WifiStaIfaceAidlTest, TwtSessionGetStats) {
516     if (interface_version_ < 2) {
517         GTEST_SKIP() << "TwtSessionGetStats is available as of sta_iface V2";
518     }
519     if (!isTwtSupported()) {
520         GTEST_SKIP() << "TWT is not supported";
521     }
522 
523     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
524     // as the error code.
525     EXPECT_TRUE(wifi_sta_iface_->twtSessionGetStats(1, 10).isOk());
526 }
527 
528 /**
529  * TwtSessionTeardown
530  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionTeardown)531 TEST_P(WifiStaIfaceAidlTest, TwtSessionTeardown) {
532     if (interface_version_ < 2) {
533         GTEST_SKIP() << "TwtSessionTeardown is available as of sta_iface V2";
534     }
535     if (!isTwtSupported()) {
536         GTEST_SKIP() << "TWT is not supported";
537     }
538 
539     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
540     // as the error code.
541     EXPECT_TRUE(wifi_sta_iface_->twtSessionTeardown(1, 10).isOk());
542 }
543 
544 /**
545  * TwtSessionUpdate
546  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionUpdate)547 TEST_P(WifiStaIfaceAidlTest, TwtSessionUpdate) {
548     if (interface_version_ < 2) {
549         GTEST_SKIP() << "TwtSessionUpdate is available as of sta_iface V2";
550     }
551     if (!isTwtSupported()) {
552         GTEST_SKIP() << "TWT is not supported";
553     }
554 
555     TwtRequest twtRequest;
556     twtRequest.mloLinkId = 0;
557     twtRequest.minWakeDurationUs = 1000;
558     twtRequest.maxWakeDurationUs = 10000;
559     twtRequest.minWakeIntervalUs = 10000;
560     twtRequest.maxWakeIntervalUs = 100000;
561 
562     auto status = wifi_sta_iface_->twtSessionUpdate(1, 10, twtRequest);
563     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
564         GTEST_SKIP() << "TwtSessionUpdate is not supported";
565     }
566     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
567     // as the error code.
568     EXPECT_TRUE(status.isOk());
569 }
570 
571 /**
572  * TwtSessionSuspend
573  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionSuspend)574 TEST_P(WifiStaIfaceAidlTest, TwtSessionSuspend) {
575     if (interface_version_ < 2) {
576         GTEST_SKIP() << "TwtSessionSuspend is available as of sta_iface V2";
577     }
578     if (!isTwtSupported()) {
579         GTEST_SKIP() << "TWT is not supported";
580     }
581 
582     auto status = wifi_sta_iface_->twtSessionSuspend(1, 10);
583     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
584         GTEST_SKIP() << "TwtSessionSuspend is not supported";
585     }
586     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
587     // as the error code.
588     EXPECT_TRUE(status.isOk());
589 }
590 
591 /**
592  * TwtSessionResume
593  */
TEST_P(WifiStaIfaceAidlTest,TwtSessionResume)594 TEST_P(WifiStaIfaceAidlTest, TwtSessionResume) {
595     if (interface_version_ < 2) {
596         GTEST_SKIP() << "TwtSessionResume is available as of sta_iface V2";
597     }
598     if (!isTwtSupported()) {
599         GTEST_SKIP() << "TWT is not supported";
600     }
601 
602     auto status = wifi_sta_iface_->twtSessionResume(1, 10);
603     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
604         GTEST_SKIP() << "TwtSessionResume is not supported";
605     }
606     // Expecting a IWifiStaIfaceEventCallback.onTwtFailure() with INVALID_PARAMS
607     // as the error code.
608     EXPECT_TRUE(status.isOk());
609 }
610 
611 /*
612  * SetDtimMultiplier
613  */
TEST_P(WifiStaIfaceAidlTest,SetDtimMultiplier)614 TEST_P(WifiStaIfaceAidlTest, SetDtimMultiplier) {
615     // Multiplied value
616     auto status = wifi_sta_iface_->setDtimMultiplier(2);
617     if (checkStatusCode(&status, WifiStatusCode::ERROR_NOT_SUPPORTED)) {
618         GTEST_SKIP() << "SetDtimMultiplier is not supported";
619     }
620     EXPECT_TRUE(status.isOk());
621 
622     // Driver default value
623     EXPECT_TRUE(wifi_sta_iface_->setDtimMultiplier(0).isOk());
624 }
625 
626 /*
627  * Start/Stop Background Scan
628  */
TEST_P(WifiStaIfaceAidlTest,StartAndStopBackgroundScan)629 TEST_P(WifiStaIfaceAidlTest, StartAndStopBackgroundScan) {
630     if (!isFeatureSupported(IWifiStaIface::FeatureSetMask::BACKGROUND_SCAN)) {
631         GTEST_SKIP() << "Background scan is not supported";
632     }
633     StaBackgroundScanParameters scanParams;
634     EXPECT_TRUE(wifi_sta_iface_->startBackgroundScan(kTestCmdId, scanParams).isOk());
635     EXPECT_TRUE(wifi_sta_iface_->stopBackgroundScan(kTestCmdId).isOk());
636 }
637 
638 /*
639  * Start/Stop Sending Keep-Alive Packets
640  */
TEST_P(WifiStaIfaceAidlTest,StartAndStopSendingKeepAlivePackets)641 TEST_P(WifiStaIfaceAidlTest, StartAndStopSendingKeepAlivePackets) {
642     std::vector<uint8_t> ipPacketData(20);
643     uint16_t etherType = 0x0800;  // IPv4
644     uint32_t periodInMs = 1000;   // 1 sec
645 
646     auto status = wifi_sta_iface_->startSendingKeepAlivePackets(
647             kTestCmdId, ipPacketData, etherType, kTestMacAddr1, kTestMacAddr2, periodInMs);
648     if (!status.isOk()) {
649         // The device may not support this operation or the specific test values
650         GTEST_SKIP() << "StartAndStopSendingKeepAlivePackets is not supported"
651                      << ", status=" << status.getServiceSpecificError();
652     }
653     EXPECT_TRUE(status.isOk());
654 
655     // If start was successful, then stop should also work
656     EXPECT_TRUE(wifi_sta_iface_->stopSendingKeepAlivePackets(kTestCmdId).isOk());
657 }
658 
659 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceAidlTest);
660 INSTANTIATE_TEST_SUITE_P(WifiTest, WifiStaIfaceAidlTest,
661                          testing::ValuesIn(android::getAidlHalInstanceNames(IWifi::descriptor)),
662                          android::PrintInstanceNameToString);
663 
main(int argc,char ** argv)664 int main(int argc, char** argv) {
665     ::testing::InitGoogleTest(&argc, argv);
666     android::ProcessState::self()->setThreadPoolMaxThreadCount(1);
667     android::ProcessState::self()->startThreadPool();
668     return RUN_ALL_TESTS();
669 }
670