1 /*
2  * Copyright (C) 2016 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 <android-base/logging.h>
18 
19 #include <android/hardware/wifi/1.0/IWifi.h>
20 #include <android/hardware/wifi/1.0/IWifiStaIface.h>
21 #include <android/hardware/wifi/1.3/IWifiStaIface.h>
22 #include <gtest/gtest.h>
23 #include <hidl/GtestPrinter.h>
24 #include <hidl/ServiceManagement.h>
25 
26 #include "wifi_hidl_call_util.h"
27 #include "wifi_hidl_test_utils.h"
28 
29 using ::android::sp;
30 using ::android::hardware::wifi::V1_0::Bssid;
31 using ::android::hardware::wifi::V1_0::CommandId;
32 using ::android::hardware::wifi::V1_0::IfaceType;
33 using ::android::hardware::wifi::V1_0::IWifi;
34 using ::android::hardware::wifi::V1_0::IWifiStaIface;
35 using ::android::hardware::wifi::V1_0::Rssi;
36 using ::android::hardware::wifi::V1_0::Ssid;
37 using ::android::hardware::wifi::V1_0::StaApfPacketFilterCapabilities;
38 using ::android::hardware::wifi::V1_0::StaRoamingConfig;
39 using ::android::hardware::wifi::V1_0::StaRoamingState;
40 using ::android::hardware::wifi::V1_0::WifiBand;
41 using ::android::hardware::wifi::V1_0::WifiStatus;
42 using ::android::hardware::wifi::V1_0::WifiStatusCode;
43 
44 /**
45  * Fixture to use for all STA Iface HIDL interface tests.
46  */
47 class WifiStaIfaceHidlTest : public ::testing::TestWithParam<std::string> {
48    public:
SetUp()49     virtual void SetUp() override {
50         // Make sure test starts with a clean state
51         stopWifi(GetInstanceName());
52 
53         wifi_sta_iface_ = getWifiStaIface(GetInstanceName());
54         ASSERT_NE(nullptr, wifi_sta_iface_.get());
55     }
56 
TearDown()57     virtual void TearDown() override { stopWifi(GetInstanceName()); }
58 
59    protected:
isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask)60     bool isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask cap_mask) {
61         const auto& status_and_caps =
62             HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
63         EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
64         return (status_and_caps.second & cap_mask) != 0;
65     }
66 
67     sp<IWifiStaIface> wifi_sta_iface_;
GetInstanceName()68     std::string GetInstanceName() { return GetParam(); }
69 };
70 
71 /*
72  * Create:
73  * Ensures that an instance of the IWifiStaIface proxy object is
74  * successfully created.
75  */
TEST_P(WifiStaIfaceHidlTest,Create)76 TEST_P(WifiStaIfaceHidlTest, Create) {
77     // The creation of a proxy object is tested as part of SetUp method.
78 }
79 
80 /*
81  * GetCapabilities:
82  */
TEST_P(WifiStaIfaceHidlTest,GetCapabilities)83 TEST_P(WifiStaIfaceHidlTest, GetCapabilities) {
84     const auto& status_and_caps = HIDL_INVOKE(wifi_sta_iface_, getCapabilities);
85     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
86     EXPECT_GT(status_and_caps.second, 0u);
87 }
88 
89 /*
90  * GetType:
91  * Ensures that the correct interface type is returned for station interface.
92  */
TEST_P(WifiStaIfaceHidlTest,GetType)93 TEST_P(WifiStaIfaceHidlTest, GetType) {
94     const auto& status_and_type = HIDL_INVOKE(wifi_sta_iface_, getType);
95     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_type.first.code);
96     EXPECT_EQ(IfaceType::STA, status_and_type.second);
97 }
98 
99 /*
100  * GetApfPacketFilterCapabilities:
101  * Ensures that we can retrieve APF packet filter capabilites.
102  */
TEST_P(WifiStaIfaceHidlTest,GetApfPacketFilterCapabilities)103 TEST_P(WifiStaIfaceHidlTest, GetApfPacketFilterCapabilities) {
104     if (!isCapabilitySupported(IWifiStaIface::StaIfaceCapabilityMask::APF)) {
105         // No-op if APF packet filer is not supported.
106         return;
107     }
108 
109     const auto& status_and_caps =
110         HIDL_INVOKE(wifi_sta_iface_, getApfPacketFilterCapabilities);
111     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
112 }
113 
114 /*
115  * GetBackgroundScanCapabilities:
116  * Ensures that we can retrieve background scan capabilities.
117  */
TEST_P(WifiStaIfaceHidlTest,GetBackgroundScanCapabilities)118 TEST_P(WifiStaIfaceHidlTest, GetBackgroundScanCapabilities) {
119     if (!isCapabilitySupported(
120             IWifiStaIface::StaIfaceCapabilityMask::BACKGROUND_SCAN)) {
121         // No-op if background scan is not supported.
122         return;
123     }
124 
125     const auto& status_and_caps =
126         HIDL_INVOKE(wifi_sta_iface_, getBackgroundScanCapabilities);
127     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_caps.first.code);
128 }
129 
130 /*
131  * GetValidFrequenciesForBand:
132  * Ensures that we can retrieve valid frequencies for 2.4 GHz band.
133  */
TEST_P(WifiStaIfaceHidlTest,GetValidFrequenciesForBand)134 TEST_P(WifiStaIfaceHidlTest, GetValidFrequenciesForBand) {
135     const auto& status_and_freqs = HIDL_INVOKE(
136         wifi_sta_iface_, getValidFrequenciesForBand, WifiBand::BAND_24GHZ);
137     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_freqs.first.code);
138     EXPECT_GT(status_and_freqs.second.size(), 0u);
139 }
140 
141 /*
142  * LinkLayerStatsCollection:
143  * Ensures that calls to enable, disable, and retrieve link layer stats
144  * will return a success status code.
145  */
TEST_P(WifiStaIfaceHidlTest,LinkLayerStatsCollection)146 TEST_P(WifiStaIfaceHidlTest, LinkLayerStatsCollection) {
147     if (!isCapabilitySupported(
148             IWifiStaIface::StaIfaceCapabilityMask::LINK_LAYER_STATS)) {
149         // No-op if link layer stats is not supported.
150         return;
151     }
152 
153     sp<::android::hardware::wifi::V1_3::IWifiStaIface> iface_converted =
154         ::android::hardware::wifi::V1_3::IWifiStaIface::castFrom(
155             wifi_sta_iface_);
156     if (iface_converted != nullptr) {
157         // Skip this test since this API is deprecated in this newer HAL version
158         return;
159     }
160 
161     // Enable link layer stats collection.
162     EXPECT_EQ(WifiStatusCode::SUCCESS,
163               HIDL_INVOKE(wifi_sta_iface_, enableLinkLayerStatsCollection, true)
164                   .code);
165     // Retrieve link layer stats.
166     EXPECT_EQ(WifiStatusCode::SUCCESS,
167               HIDL_INVOKE(wifi_sta_iface_, getLinkLayerStats).first.code);
168     // Disable link layer stats collection.
169     EXPECT_EQ(
170         WifiStatusCode::SUCCESS,
171         HIDL_INVOKE(wifi_sta_iface_, disableLinkLayerStatsCollection).code);
172 }
173 
174 /*
175  * RSSIMonitoring:
176  * Ensures that calls to enable RSSI monitoring will return an error status
177  * code if device is not connected to an AP.
178  * Ensures that calls to disable RSSI monitoring will return an error status
179  * code if RSSI monitoring is not enabled.
180  */
TEST_P(WifiStaIfaceHidlTest,RSSIMonitoring)181 TEST_P(WifiStaIfaceHidlTest, RSSIMonitoring) {
182     if (!isCapabilitySupported(
183             IWifiStaIface::StaIfaceCapabilityMask::RSSI_MONITOR)) {
184         // No-op if RSSI monitor is not supported.
185         return;
186     }
187 
188     const CommandId kCmd = 1;
189     const Rssi kMaxRssi = -50;
190     const Rssi kMinRssi = -90;
191     // This is going to fail because device is not connected to an AP.
192     EXPECT_NE(WifiStatusCode::SUCCESS,
193               HIDL_INVOKE(wifi_sta_iface_, startRssiMonitoring, kCmd, kMaxRssi,
194                           kMinRssi)
195                   .code);
196     // This is going to fail because RSSI monitoring is not enabled.
197     EXPECT_NE(WifiStatusCode::SUCCESS,
198               HIDL_INVOKE(wifi_sta_iface_, stopRssiMonitoring, kCmd).code);
199 }
200 
201 /*
202  * RoamingControl:
203  * Ensures that calls to configure and enable roaming will return a success
204  * status code.
205  */
TEST_P(WifiStaIfaceHidlTest,RoamingControl)206 TEST_P(WifiStaIfaceHidlTest, RoamingControl) {
207     if (!isCapabilitySupported(
208             IWifiStaIface::StaIfaceCapabilityMask::CONTROL_ROAMING)) {
209         // No-op if roaming control is not supported.
210         return;
211     }
212 
213     // Retrieve roaming capabilities.
214     const auto& status_and_cap =
215         HIDL_INVOKE(wifi_sta_iface_, getRoamingCapabilities);
216     EXPECT_EQ(WifiStatusCode::SUCCESS, status_and_cap.first.code);
217 
218     // Setup roaming configuration based on roaming capabilities.
219     const auto& cap = status_and_cap.second;
220     StaRoamingConfig roaming_config;
221     if (cap.maxBlacklistSize > 0) {
222         Bssid black_list_bssid{
223             std::array<uint8_t, 6>{{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}}};
224         roaming_config.bssidBlacklist =
225             android::hardware::hidl_vec<Bssid>{black_list_bssid};
226     }
227     if (cap.maxWhitelistSize > 0) {
228         Ssid white_list_ssid{
229             std::array<uint8_t, 32>{{0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC}}};
230         roaming_config.ssidWhitelist =
231             android::hardware::hidl_vec<Ssid>{white_list_ssid};
232     }
233 
234     // Configure roaming.
235     EXPECT_EQ(
236         WifiStatusCode::SUCCESS,
237         HIDL_INVOKE(wifi_sta_iface_, configureRoaming, roaming_config).code);
238 
239     // Enable roaming.
240     EXPECT_EQ(
241         WifiStatusCode::SUCCESS,
242         HIDL_INVOKE(wifi_sta_iface_, setRoamingState, StaRoamingState::ENABLED)
243             .code);
244 }
245 
246 /*
247  * EnableNDOffload:
248  * Ensures that calls to enable neighbor discovery offload will return a success
249  * status code.
250  */
TEST_P(WifiStaIfaceHidlTest,EnableNDOffload)251 TEST_P(WifiStaIfaceHidlTest, EnableNDOffload) {
252     if (!isCapabilitySupported(
253             IWifiStaIface::StaIfaceCapabilityMask::ND_OFFLOAD)) {
254         // No-op if nd offload is not supported.
255         return;
256     }
257     EXPECT_EQ(WifiStatusCode::SUCCESS,
258               HIDL_INVOKE(wifi_sta_iface_, enableNdOffload, true).code);
259 }
260 
261 /*
262  * SetScanningMacOui:
263  * Ensures that calls to set scanning MAC OUI will return a NOT_SUPPORTED
264  * code since it is now deprecated.
265  */
TEST_P(WifiStaIfaceHidlTest,SetScanningMacOui)266 TEST_P(WifiStaIfaceHidlTest, SetScanningMacOui) {
267     if (!isCapabilitySupported(
268             IWifiStaIface::StaIfaceCapabilityMask::SCAN_RAND)) {
269         // No-op if SetScanningMacOui is not supported.
270         return;
271     }
272     const android::hardware::hidl_array<uint8_t, 3> kOui{
273         std::array<uint8_t, 3>{{0x10, 0x22, 0x33}}};
274     EXPECT_EQ(WifiStatusCode::ERROR_NOT_SUPPORTED,
275               HIDL_INVOKE(wifi_sta_iface_, setScanningMacOui, kOui).code);
276 }
277 
278 /*
279  * PacketFateMonitoring:
280  * Ensures that calls to start packet fate monitoring and retrieve TX/RX
281  * packets will return a success status code.
282  */
TEST_P(WifiStaIfaceHidlTest,PacketFateMonitoring)283 TEST_P(WifiStaIfaceHidlTest, PacketFateMonitoring) {
284     if (!isCapabilitySupported(
285             IWifiStaIface::StaIfaceCapabilityMask::DEBUG_PACKET_FATE)) {
286         // No-op if packet fate monitor is not supported.
287         return;
288     }
289     // Start packet fate monitoring.
290     EXPECT_EQ(
291         WifiStatusCode::SUCCESS,
292         HIDL_INVOKE(wifi_sta_iface_, startDebugPacketFateMonitoring).code);
293 
294     // Retrieve packets.
295     EXPECT_EQ(WifiStatusCode::SUCCESS,
296               HIDL_INVOKE(wifi_sta_iface_, getDebugTxPacketFates).first.code);
297     EXPECT_EQ(WifiStatusCode::SUCCESS,
298               HIDL_INVOKE(wifi_sta_iface_, getDebugRxPacketFates).first.code);
299 }
300 
301 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WifiStaIfaceHidlTest);
302 INSTANTIATE_TEST_SUITE_P(
303     PerInstance, WifiStaIfaceHidlTest,
304     testing::ValuesIn(
305         android::hardware::getAllHalInstanceNames(IWifi::descriptor)),
306     android::hardware::PrintInstanceNameToString);
307