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