blob: 696e1239400975aef3d4e357c80d5f8035db796e [file] [log] [blame]
Chris Weir5031a042024-10-21 13:31:20 -07001/*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache 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 <cstring>
18
19#include <gtest/gtest.h>
20#include "../hostapd.cpp"
21
22namespace aidl::android::hardware::wifi::hostapd {
Chris Weird41879a2024-10-30 15:53:24 -070023unsigned char kTestSsid[] = {0x31, 0x32, 0x33, 0x61, 0x62, 0x63, 0x64};
24
25class HostapdConfigTest : public testing::Test {
26 protected:
27 void SetUp() override {
28 resetOverrides();
29
30 mIface_params = {
31 .name = "wlan42",
32 .hwModeParams = {
33 .enable80211N = true,
34 .enable80211AC = false,
35 .enable80211AX = false,
36 .enable6GhzBand = false,
37 .enableHeSingleUserBeamformer = false,
38 .enableHeSingleUserBeamformee = false,
39 .enableHeMultiUserBeamformer = false,
40 .enableHeTargetWakeTime = false,
41 .enableEdmg = false,
42 .enable80211BE = false,
43 .maximumChannelBandwidth = ChannelBandwidth::BANDWIDTH_AUTO,
44 },
45 .channelParams = {}, // not used in config creation
46 .vendorData = {}, // not used in config creation
47 .instanceIdentities = {}, // not used in config creation
48 .usesMlo = false,
49 };
50 mChannel_params = {
51 .bandMask = BandMask::BAND_2_GHZ,
52 .acsChannelFreqRangesMhz = {},
53 .enableAcs = false,
54 .acsShouldExcludeDfs = false,
55 .channel = 6,
56 };
57 mNetwork_params = {
58 .ssid = std::vector<uint8_t>(kTestSsid, kTestSsid + sizeof(kTestSsid)),
59 .isHidden = false,
60 .encryptionType = EncryptionType::WPA2,
61 .passphrase = "verysecurewowe",
62 .isMetered = true, // default for tethered softap, change to false for lohs.
63 .vendorElements = {},
64 };
65 }
66
67 std::string mWlan42_tethered_config = "\ninterface=wlan42\n"
68 "driver=nl80211\n"
69 "ctrl_interface=/data/vendor/wifi/hostapd/ctrl_wlan42\n"
70 "ssid2=31323361626364\n"
71 "channel=6\n"
72 "op_class=83\n"
73 "ieee80211n=1\n"
74 "ieee80211ac=0\n\n\n"
75 "hw_mode=g\n\n"
76 "ignore_broadcast_ssid=0\n"
77 "wowlan_triggers=any\n"
78 "interworking=1\n"
79 "access_network_type=2\n\n"
80 "wpa=2\n"
81 "rsn_pairwise=CCMP\n"
82 "wpa_passphrase=verysecurewowe\n\n\n\n\n\n"
83 "ap_isolate=0\n";
84
85 std::string mWlan42_lohs_config = "dtim_period=2 \n"
86 " ap_max_inactivity=300\n"
87 "skip_inactivity_poll = 1\n\n"
88 "interface=wlan42\n"
89 "driver=nl80211\n"
90 "ctrl_interface=/data/vendor/wifi/hostapd/ctrl_wlan42\n"
91 "ssid2=31323361626364\n"
92 "channel=6\n"
93 "op_class=83\n"
94 "ieee80211n=1\n"
95 "ieee80211ac=0\n\n\n"
96 "hw_mode=g\n\n"
97 "ignore_broadcast_ssid=0\n"
98 "wowlan_triggers=any\n"
99 "interworking=0\n\n"
100 "wpa=2\n"
101 "rsn_pairwise=CCMP\n"
102 "wpa_passphrase=verysecurewowe\n\n\n\n\n\n"
103 "ap_isolate=0\n";
104
105 std::string mWlan42_lohs_config_no_overlay = "\ninterface=wlan42\n"
106 "driver=nl80211\n"
107 "ctrl_interface=/data/vendor/wifi/hostapd/ctrl_wlan42\n"
108 "ssid2=31323361626364\n"
109 "channel=6\n"
110 "op_class=83\n"
111 "ieee80211n=1\n"
112 "ieee80211ac=0\n\n\n"
113 "hw_mode=g\n\n"
114 "ignore_broadcast_ssid=0\n"
115 "wowlan_triggers=any\n"
116 "interworking=0\n\n"
117 "wpa=2\n"
118 "rsn_pairwise=CCMP\n"
119 "wpa_passphrase=verysecurewowe\n\n\n\n\n\n"
120 "ap_isolate=0\n";
121
122 IfaceParams mIface_params;
123 ChannelParams mChannel_params;
124 NetworkParams mNetwork_params;
125 std::string mBr_name = "";
126 std::string mOwe_transition_ifname = "";
127};
Chris Weir5031a042024-10-21 13:31:20 -0700128
129/**
130 * Null hostapd_data* and null mac address (u8*)
131 * There's an || check on these that should return nullopt
132 */
133TEST(getStaInfoByMacAddrTest, NullArguments) {
134 EXPECT_EQ(std::nullopt, getStaInfoByMacAddr(nullptr, nullptr));
135}
136
137
138/**
139 * We pass valid arguments to get past the nullptr check, but hostapd_data->sta_list is nullptr.
140 * Don't loop through the sta_info* list, just return nullopt.
141 */
142TEST(getStaInfoByMacAddrTest, NullStaList) {
143 struct hostapd_data iface_hapd = {};
144 u8 mac_addr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xD0, 0x0D};
145 EXPECT_EQ(std::nullopt, getStaInfoByMacAddr(&iface_hapd, mac_addr));
146}
147
148/**
149 * Mac doesn't match, and we hit the end of the sta_info list.
150 * Don't run over the end of the list and return nullopt.
151 */
152TEST(getStaInfoByMacAddrTest, NoMatchingMac) {
153 struct hostapd_data iface_hapd = {};
154 struct sta_info sta0 = {};
155 struct sta_info sta1 = {};
156 struct sta_info sta2 = {};
157 iface_hapd.sta_list = &sta0;
158 sta0.next = &sta1;
159 sta1.next = &sta2;
160 u8 mac_addr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xD0, 0x0D};
161 EXPECT_EQ(std::nullopt, getStaInfoByMacAddr(&iface_hapd, mac_addr));
162}
163
164/**
165 * There is a matching address and we return it.
166 */
Chris Weird41879a2024-10-30 15:53:24 -0700167TEST(getStaInfoByMacAddrTest, MatchingMac) {
Chris Weir5031a042024-10-21 13:31:20 -0700168 struct hostapd_data iface_hapd = {};
169 struct sta_info sta0 = {};
170 struct sta_info sta1 = {};
171 struct sta_info sta2 = {};
172 iface_hapd.sta_list = &sta0;
173 sta0.next = &sta1;
174 sta1.next = &sta2;
175 u8 sta0_addr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xD0, 0x0C}; // off by 1 bit
176 std::memcpy(sta0.addr, sta0_addr, ETH_ALEN);
177 u8 sta1_addr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xD0, 0x0D};
178 std::memcpy(sta1.addr, sta1_addr, ETH_ALEN);
179 u8 mac_addr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xD0, 0x0D};
180 auto sta_ptr_optional = getStaInfoByMacAddr(&iface_hapd, mac_addr);
181 EXPECT_TRUE(sta_ptr_optional.has_value());
182 EXPECT_EQ(0, std::memcmp(sta_ptr_optional.value()->addr, sta1_addr, ETH_ALEN));
183}
184
Chris Weird41879a2024-10-30 15:53:24 -0700185
186TEST_F(HostapdConfigTest, tetheredApConfig) {
187 // instance name, config string, br_name, usesMlo
188 std::string config_path = WriteHostapdConfig("wlan42", mWlan42_tethered_config, "", false);
189 std::string expected_path = "/data/vendor/wifi/hostapd/hostapd_wlan42.conf";
190 EXPECT_EQ(expected_path, config_path);
191 EXPECT_EQ(mWlan42_tethered_config, hostapd_unittest_config_output);
192}
193
194TEST_F(HostapdConfigTest, tetheredApConfigStatFails) {
195 hostapd_unittest_WriteStringToFileRet = false;
196 hostapd_unittest_stat_ret = -1;
197 // instance name, config string, br_name, usesMlo
198 std::string config_path = WriteHostapdConfig("wlan42", mWlan42_tethered_config, "", false);
199 std::string expected_path = "";
200 EXPECT_EQ(expected_path, config_path);
201}
202
203TEST_F(HostapdConfigTest, tetheredApConfigWriteFails) {
204 hostapd_unittest_WriteStringToFileRet = false;
205 // instance name, config string, br_name, usesMlo
206 std::string config_path = WriteHostapdConfig("wlan42", mWlan42_tethered_config, "", false);
207 std::string expected_path = "";
208 EXPECT_EQ(expected_path, config_path);
209}
210
211TEST_F(HostapdConfigTest, tetheredAp) {
212 std::string config_string = CreateHostapdConfig(mIface_params, mChannel_params, mNetwork_params,
213 mBr_name, mOwe_transition_ifname);
214 EXPECT_EQ(mWlan42_tethered_config, config_string);
215}
216
217TEST_F(HostapdConfigTest, lohsAp) {
218 mNetwork_params.isMetered = false;
219 hostapd_unittest_overlay_content =
220 "invalid_key=this_should_not_be_here\n"
221 "dtim_period=2 \n"
222 " ap_max_inactivity=300\n"
223 "another_invalid_key_dtim_period=-10000\n"
224 "skip_inactivity_poll = 1";
225 std::string config_string = CreateHostapdConfig(mIface_params, mChannel_params, mNetwork_params,
226 mBr_name, mOwe_transition_ifname);
227 EXPECT_EQ(mWlan42_lohs_config, config_string);
228}
229
230TEST_F(HostapdConfigTest, lohsApAccessFails) {
231 mNetwork_params.isMetered = false;
232 hostapd_unittest_accessRet = -1;
233 std::string config_string = CreateHostapdConfig(mIface_params, mChannel_params, mNetwork_params,
234 mBr_name, mOwe_transition_ifname);
235 EXPECT_EQ(mWlan42_lohs_config_no_overlay, config_string);
236}
237
238TEST_F(HostapdConfigTest, lohsApReadFails) {
239 mNetwork_params.isMetered = false;
240 hostapd_unittest_ReadFileToStringRet = false;
241 std::string config_string = CreateHostapdConfig(mIface_params, mChannel_params, mNetwork_params,
242 mBr_name, mOwe_transition_ifname);
243 EXPECT_EQ("", config_string);
244}
245
Chris Weir5031a042024-10-21 13:31:20 -0700246} // namespace aidl::android::hardware::wifi::hostapd