xref: /aosp_15_r20/external/wpa_supplicant_8/hostapd/aidl/tests/unittests.cpp (revision 03f9172ca588f91df233974f4258bab95191f931)
1 /*
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 
22 namespace aidl::android::hardware::wifi::hostapd {
23 unsigned char kTestSsid[] = {0x31, 0x32, 0x33, 0x61, 0x62, 0x63, 0x64};
24 
25 class HostapdConfigTest : public testing::Test {
26 	protected:
SetUp()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 };
128 
129 /**
130  * Null hostapd_data* and null mac address (u8*)
131  * There's an || check on these that should return nullopt
132  */
TEST(getStaInfoByMacAddrTest,NullArguments)133 TEST(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  */
TEST(getStaInfoByMacAddrTest,NullStaList)142 TEST(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  */
TEST(getStaInfoByMacAddrTest,NoMatchingMac)152 TEST(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  */
TEST(getStaInfoByMacAddrTest,MatchingMac)167 TEST(getStaInfoByMacAddrTest, MatchingMac) {
168 	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 
185 
TEST_F(HostapdConfigTest,tetheredApConfig)186 TEST_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 
TEST_F(HostapdConfigTest,tetheredApConfigStatFails)194 TEST_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 
TEST_F(HostapdConfigTest,tetheredApConfigWriteFails)203 TEST_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 
TEST_F(HostapdConfigTest,tetheredAp)211 TEST_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 
TEST_F(HostapdConfigTest,lohsAp)217 TEST_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 
TEST_F(HostapdConfigTest,lohsApAccessFails)230 TEST_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 
TEST_F(HostapdConfigTest,lohsApReadFails)238 TEST_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 
246 }  // namespace aidl::android::hardware::wifi::hostapd
247