xref: /aosp_15_r20/external/wpa_supplicant_8/hostapd/aidl/hostapd.cpp (revision 03f9172ca588f91df233974f4258bab95191f931)
1*03f9172cSAndroid Build Coastguard Worker /*
2*03f9172cSAndroid Build Coastguard Worker  * aidl interface for wpa_hostapd daemon
3*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2004-2018, Jouni Malinen <[email protected]>
4*03f9172cSAndroid Build Coastguard Worker  * Copyright (c) 2004-2018, Roshan Pius <[email protected]>
5*03f9172cSAndroid Build Coastguard Worker  *
6*03f9172cSAndroid Build Coastguard Worker  * This software may be distributed under the terms of the BSD license.
7*03f9172cSAndroid Build Coastguard Worker  * See README for more details.
8*03f9172cSAndroid Build Coastguard Worker  */
9*03f9172cSAndroid Build Coastguard Worker #include <iomanip>
10*03f9172cSAndroid Build Coastguard Worker #include <sstream>
11*03f9172cSAndroid Build Coastguard Worker #include <string>
12*03f9172cSAndroid Build Coastguard Worker #include <vector>
13*03f9172cSAndroid Build Coastguard Worker #include <net/if.h>
14*03f9172cSAndroid Build Coastguard Worker #include <sys/socket.h>
15*03f9172cSAndroid Build Coastguard Worker #include <linux/if_bridge.h>
16*03f9172cSAndroid Build Coastguard Worker 
17*03f9172cSAndroid Build Coastguard Worker #include <android-base/file.h>
18*03f9172cSAndroid Build Coastguard Worker #include <android-base/stringprintf.h>
19*03f9172cSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
20*03f9172cSAndroid Build Coastguard Worker 
21*03f9172cSAndroid Build Coastguard Worker #include "hostapd.h"
22*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/ApInfo.h>
23*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/BandMask.h>
24*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/ChannelParams.h>
25*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/ClientInfo.h>
26*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/EncryptionType.h>
27*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/HostapdStatusCode.h>
28*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/IfaceParams.h>
29*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/NetworkParams.h>
30*03f9172cSAndroid Build Coastguard Worker #include <aidl/android/hardware/wifi/hostapd/ParamSizeLimits.h>
31*03f9172cSAndroid Build Coastguard Worker 
32*03f9172cSAndroid Build Coastguard Worker extern "C"
33*03f9172cSAndroid Build Coastguard Worker {
34*03f9172cSAndroid Build Coastguard Worker #include "common/wpa_ctrl.h"
35*03f9172cSAndroid Build Coastguard Worker #include "drivers/linux_ioctl.h"
36*03f9172cSAndroid Build Coastguard Worker }
37*03f9172cSAndroid Build Coastguard Worker 
38*03f9172cSAndroid Build Coastguard Worker 
39*03f9172cSAndroid Build Coastguard Worker #ifdef ANDROID_HOSTAPD_UNITTEST
40*03f9172cSAndroid Build Coastguard Worker #include "tests/unittest_overrides.h"
41*03f9172cSAndroid Build Coastguard Worker #endif
42*03f9172cSAndroid Build Coastguard Worker 
43*03f9172cSAndroid Build Coastguard Worker // The AIDL implementation for hostapd creates a hostapd.conf dynamically for
44*03f9172cSAndroid Build Coastguard Worker // each interface. This file can then be used to hook onto the normal config
45*03f9172cSAndroid Build Coastguard Worker // file parsing logic in hostapd code.  Helps us to avoid duplication of code
46*03f9172cSAndroid Build Coastguard Worker // in the AIDL interface.
47*03f9172cSAndroid Build Coastguard Worker // TOOD(b/71872409): Add unit tests for this.
48*03f9172cSAndroid Build Coastguard Worker namespace {
49*03f9172cSAndroid Build Coastguard Worker constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
50*03f9172cSAndroid Build Coastguard Worker 
51*03f9172cSAndroid Build Coastguard Worker /**
52*03f9172cSAndroid Build Coastguard Worker  * To add an overlay file, add
53*03f9172cSAndroid Build Coastguard Worker  *
54*03f9172cSAndroid Build Coastguard Worker  * PRODUCT_COPY_FILES += \
55*03f9172cSAndroid Build Coastguard Worker  *   <your/path/here>/hostapd_unmetered_overlay.conf:/vendor/etc/wifi/hostapd_unmetered_overlay.conf
56*03f9172cSAndroid Build Coastguard Worker  *
57*03f9172cSAndroid Build Coastguard Worker  * to the build file for your device, with the <your/path/here> being the path to your overlay in
58*03f9172cSAndroid Build Coastguard Worker  * your repo. See the resolveVendorConfPath function in this file for more specifics on where this
59*03f9172cSAndroid Build Coastguard Worker  * overlay file will wind up on your device.
60*03f9172cSAndroid Build Coastguard Worker  *
61*03f9172cSAndroid Build Coastguard Worker  * This overlay may configure any of the parameters listed in kOverlayableKeys. The kOverlayableKeys
62*03f9172cSAndroid Build Coastguard Worker  * list is subject to change over time, as certain parameters may be added as APIs instead in the
63*03f9172cSAndroid Build Coastguard Worker  * future.
64*03f9172cSAndroid Build Coastguard Worker  *
65*03f9172cSAndroid Build Coastguard Worker  * Example of what an overlay file might look like:
66*03f9172cSAndroid Build Coastguard Worker  * $> cat hostapd_unmetered_overlay.conf
67*03f9172cSAndroid Build Coastguard Worker  * dtim_period=2
68*03f9172cSAndroid Build Coastguard Worker  * ap_max_inactivity=300
69*03f9172cSAndroid Build Coastguard Worker  *
70*03f9172cSAndroid Build Coastguard Worker  * Anything added to this overlay will be prepended to the hostapd.conf for unmetered (typically
71*03f9172cSAndroid Build Coastguard Worker  * local only hotspots) interfaces.
72*03f9172cSAndroid Build Coastguard Worker  */
73*03f9172cSAndroid Build Coastguard Worker constexpr char kUnmeteredIfaceOverlayPath[] = "/etc/wifi/hostapd_unmetered_overlay.conf";
74*03f9172cSAndroid Build Coastguard Worker 
75*03f9172cSAndroid Build Coastguard Worker /**
76*03f9172cSAndroid Build Coastguard Worker  * Allow-list of hostapd.conf parameters (keys) that can be set via overlay.
77*03f9172cSAndroid Build Coastguard Worker  *
78*03f9172cSAndroid Build Coastguard Worker  * If introducing new APIs, be sure to remove keys from this list that would otherwise be
79*03f9172cSAndroid Build Coastguard Worker  * controlled by the new API. This way we can avoid conflicting settings.
80*03f9172cSAndroid Build Coastguard Worker  * Please file an FR to add new keys to this list.
81*03f9172cSAndroid Build Coastguard Worker  */
82*03f9172cSAndroid Build Coastguard Worker static const std::set<std::string> kOverlayableKeys = {
83*03f9172cSAndroid Build Coastguard Worker 	"ap_max_inactivity",
84*03f9172cSAndroid Build Coastguard Worker 	"assocresp_elements"
85*03f9172cSAndroid Build Coastguard Worker 	"beacon_int",
86*03f9172cSAndroid Build Coastguard Worker 	"disassoc_low_ack",
87*03f9172cSAndroid Build Coastguard Worker 	"dtim_period",
88*03f9172cSAndroid Build Coastguard Worker 	"fragm_threshold",
89*03f9172cSAndroid Build Coastguard Worker 	"max_listen_interval",
90*03f9172cSAndroid Build Coastguard Worker 	"max_num_sta",
91*03f9172cSAndroid Build Coastguard Worker 	"rts_threshold",
92*03f9172cSAndroid Build Coastguard Worker 	"skip_inactivity_poll",
93*03f9172cSAndroid Build Coastguard Worker 	"uapsd_advertisement_enabled",
94*03f9172cSAndroid Build Coastguard Worker 	"wmm_enabled",
95*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vo_aifs",
96*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vo_cwmin",
97*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vo_cwmax",
98*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vo_txop_limit",
99*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vo_acm",
100*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vi_aifs",
101*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vi_cwmin",
102*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vi_cwmax",
103*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vi_txop_limit",
104*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_vi_acm",
105*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_bk_cwmin"
106*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_bk_cwmax"
107*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_bk_aifs",
108*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_bk_txop_limit",
109*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_bk_acm",
110*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_be_aifs",
111*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_be_cwmin",
112*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_be_cwmax",
113*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_be_txop_limit",
114*03f9172cSAndroid Build Coastguard Worker 	"wmm_ac_be_acm",
115*03f9172cSAndroid Build Coastguard Worker };
116*03f9172cSAndroid Build Coastguard Worker 
117*03f9172cSAndroid Build Coastguard Worker using android::base::RemoveFileIfExists;
118*03f9172cSAndroid Build Coastguard Worker using android::base::StringPrintf;
119*03f9172cSAndroid Build Coastguard Worker #ifndef ANDROID_HOSTAPD_UNITTEST
120*03f9172cSAndroid Build Coastguard Worker using android::base::ReadFileToString;
121*03f9172cSAndroid Build Coastguard Worker using android::base::WriteStringToFile;
122*03f9172cSAndroid Build Coastguard Worker #endif
123*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::BandMask;
124*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::ChannelBandwidth;
125*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::ChannelParams;
126*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::EncryptionType;
127*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::Generation;
128*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::HostapdStatusCode;
129*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::IfaceParams;
130*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::NetworkParams;
131*03f9172cSAndroid Build Coastguard Worker using aidl::android::hardware::wifi::hostapd::ParamSizeLimits;
132*03f9172cSAndroid Build Coastguard Worker 
133*03f9172cSAndroid Build Coastguard Worker int band2Ghz = (int)BandMask::BAND_2_GHZ;
134*03f9172cSAndroid Build Coastguard Worker int band5Ghz = (int)BandMask::BAND_5_GHZ;
135*03f9172cSAndroid Build Coastguard Worker int band6Ghz = (int)BandMask::BAND_6_GHZ;
136*03f9172cSAndroid Build Coastguard Worker int band60Ghz = (int)BandMask::BAND_60_GHZ;
137*03f9172cSAndroid Build Coastguard Worker 
138*03f9172cSAndroid Build Coastguard Worker int32_t aidl_client_version = 0;
139*03f9172cSAndroid Build Coastguard Worker int32_t aidl_service_version = 0;
140*03f9172cSAndroid Build Coastguard Worker 
141*03f9172cSAndroid Build Coastguard Worker /**
142*03f9172cSAndroid Build Coastguard Worker  * Check that the AIDL service is running at least the expected version.
143*03f9172cSAndroid Build Coastguard Worker  * Use to avoid the case where the AIDL interface version
144*03f9172cSAndroid Build Coastguard Worker  * is greater than the version implemented by the service.
145*03f9172cSAndroid Build Coastguard Worker  */
isAidlServiceVersionAtLeast(int32_t expected_version)146*03f9172cSAndroid Build Coastguard Worker inline int32_t isAidlServiceVersionAtLeast(int32_t expected_version)
147*03f9172cSAndroid Build Coastguard Worker {
148*03f9172cSAndroid Build Coastguard Worker 	return expected_version <= aidl_service_version;
149*03f9172cSAndroid Build Coastguard Worker }
150*03f9172cSAndroid Build Coastguard Worker 
isAidlClientVersionAtLeast(int32_t expected_version)151*03f9172cSAndroid Build Coastguard Worker inline int32_t isAidlClientVersionAtLeast(int32_t expected_version)
152*03f9172cSAndroid Build Coastguard Worker {
153*03f9172cSAndroid Build Coastguard Worker 	return expected_version <= aidl_client_version;
154*03f9172cSAndroid Build Coastguard Worker }
155*03f9172cSAndroid Build Coastguard Worker 
areAidlServiceAndClientAtLeastVersion(int32_t expected_version)156*03f9172cSAndroid Build Coastguard Worker inline int32_t areAidlServiceAndClientAtLeastVersion(int32_t expected_version)
157*03f9172cSAndroid Build Coastguard Worker {
158*03f9172cSAndroid Build Coastguard Worker 	return isAidlServiceVersionAtLeast(expected_version)
159*03f9172cSAndroid Build Coastguard Worker 		&& isAidlClientVersionAtLeast(expected_version);
160*03f9172cSAndroid Build Coastguard Worker }
161*03f9172cSAndroid Build Coastguard Worker 
162*03f9172cSAndroid Build Coastguard Worker #define MAX_PORTS 1024
GetInterfacesInBridge(std::string br_name,std::vector<std::string> * interfaces)163*03f9172cSAndroid Build Coastguard Worker bool GetInterfacesInBridge(std::string br_name,
164*03f9172cSAndroid Build Coastguard Worker                            std::vector<std::string>* interfaces) {
165*03f9172cSAndroid Build Coastguard Worker 	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
166*03f9172cSAndroid Build Coastguard Worker 	if (sock.get() < 0) {
167*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
168*03f9172cSAndroid Build Coastguard Worker 			strerror(errno), __FUNCTION__);
169*03f9172cSAndroid Build Coastguard Worker 		return false;
170*03f9172cSAndroid Build Coastguard Worker 	}
171*03f9172cSAndroid Build Coastguard Worker 
172*03f9172cSAndroid Build Coastguard Worker 	struct ifreq request;
173*03f9172cSAndroid Build Coastguard Worker 	int i, ifindices[MAX_PORTS];
174*03f9172cSAndroid Build Coastguard Worker 	char if_name[IFNAMSIZ];
175*03f9172cSAndroid Build Coastguard Worker 	unsigned long args[3];
176*03f9172cSAndroid Build Coastguard Worker 
177*03f9172cSAndroid Build Coastguard Worker 	memset(ifindices, 0, MAX_PORTS * sizeof(int));
178*03f9172cSAndroid Build Coastguard Worker 
179*03f9172cSAndroid Build Coastguard Worker 	args[0] = BRCTL_GET_PORT_LIST;
180*03f9172cSAndroid Build Coastguard Worker 	args[1] = (unsigned long) ifindices;
181*03f9172cSAndroid Build Coastguard Worker 	args[2] = MAX_PORTS;
182*03f9172cSAndroid Build Coastguard Worker 
183*03f9172cSAndroid Build Coastguard Worker 	strlcpy(request.ifr_name, br_name.c_str(), IFNAMSIZ);
184*03f9172cSAndroid Build Coastguard Worker 	request.ifr_data = (char *)args;
185*03f9172cSAndroid Build Coastguard Worker 
186*03f9172cSAndroid Build Coastguard Worker 	if (ioctl(sock.get(), SIOCDEVPRIVATE, &request) < 0) {
187*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Failed to ioctl SIOCDEVPRIVATE in %s",
188*03f9172cSAndroid Build Coastguard Worker 			__FUNCTION__);
189*03f9172cSAndroid Build Coastguard Worker 		return false;
190*03f9172cSAndroid Build Coastguard Worker 	}
191*03f9172cSAndroid Build Coastguard Worker 
192*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < MAX_PORTS; i ++) {
193*03f9172cSAndroid Build Coastguard Worker 		memset(if_name, 0, IFNAMSIZ);
194*03f9172cSAndroid Build Coastguard Worker 		if (ifindices[i] == 0 || !if_indextoname(ifindices[i], if_name)) {
195*03f9172cSAndroid Build Coastguard Worker 			continue;
196*03f9172cSAndroid Build Coastguard Worker 		}
197*03f9172cSAndroid Build Coastguard Worker 		interfaces->push_back(if_name);
198*03f9172cSAndroid Build Coastguard Worker 	}
199*03f9172cSAndroid Build Coastguard Worker 	return true;
200*03f9172cSAndroid Build Coastguard Worker }
201*03f9172cSAndroid Build Coastguard Worker 
resolveVendorConfPath(const std::string & conf_path)202*03f9172cSAndroid Build Coastguard Worker std::string resolveVendorConfPath(const std::string& conf_path)
203*03f9172cSAndroid Build Coastguard Worker {
204*03f9172cSAndroid Build Coastguard Worker #if defined(__ANDROID_APEX__)
205*03f9172cSAndroid Build Coastguard Worker 	// returns "/apex/<apexname>" + conf_path
206*03f9172cSAndroid Build Coastguard Worker 	std::string path = android::base::GetExecutablePath();
207*03f9172cSAndroid Build Coastguard Worker 	return path.substr(0, path.find_first_of('/', strlen("/apex/"))) + conf_path;
208*03f9172cSAndroid Build Coastguard Worker #else
209*03f9172cSAndroid Build Coastguard Worker 	return std::string("/vendor") + conf_path;
210*03f9172cSAndroid Build Coastguard Worker #endif
211*03f9172cSAndroid Build Coastguard Worker }
212*03f9172cSAndroid Build Coastguard Worker 
logHostapdConfigError(int error,const std::string & file_path)213*03f9172cSAndroid Build Coastguard Worker void logHostapdConfigError(int error, const std::string& file_path) {
214*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_ERROR, "Cannot read/write hostapd config %s, error: %s", file_path.c_str(),
215*03f9172cSAndroid Build Coastguard Worker 			strerror(error));
216*03f9172cSAndroid Build Coastguard Worker 	struct stat st;
217*03f9172cSAndroid Build Coastguard Worker 	int result = stat(file_path.c_str(), &st);
218*03f9172cSAndroid Build Coastguard Worker 	if (result == 0) {
219*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",st.st_uid,
220*03f9172cSAndroid Build Coastguard Worker 				st.st_gid, st.st_mode);
221*03f9172cSAndroid Build Coastguard Worker 	} else {
222*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Error calling stat() on hostapd config file: %s",
223*03f9172cSAndroid Build Coastguard Worker 				strerror(errno));
224*03f9172cSAndroid Build Coastguard Worker 	}
225*03f9172cSAndroid Build Coastguard Worker }
226*03f9172cSAndroid Build Coastguard Worker 
WriteHostapdConfig(const std::string & instance_name,const std::string & config,const std::string br_name,const bool usesMlo)227*03f9172cSAndroid Build Coastguard Worker std::string WriteHostapdConfig(
228*03f9172cSAndroid Build Coastguard Worker     const std::string& instance_name, const std::string& config,
229*03f9172cSAndroid Build Coastguard Worker     const std::string br_name, const bool usesMlo)
230*03f9172cSAndroid Build Coastguard Worker {
231*03f9172cSAndroid Build Coastguard Worker 	std::string conf_name_as_string = instance_name;
232*03f9172cSAndroid Build Coastguard Worker 	if (usesMlo) {
233*03f9172cSAndroid Build Coastguard Worker 		conf_name_as_string = StringPrintf(
234*03f9172cSAndroid Build Coastguard Worker 				"%s-%s", br_name.c_str(), instance_name.c_str());
235*03f9172cSAndroid Build Coastguard Worker 	}
236*03f9172cSAndroid Build Coastguard Worker 	const std::string file_path =
237*03f9172cSAndroid Build Coastguard Worker 		StringPrintf(kConfFileNameFmt, conf_name_as_string.c_str());
238*03f9172cSAndroid Build Coastguard Worker 	if (WriteStringToFile(
239*03f9172cSAndroid Build Coastguard Worker 		config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
240*03f9172cSAndroid Build Coastguard Worker 		getuid(), getgid())) {
241*03f9172cSAndroid Build Coastguard Worker 		return file_path;
242*03f9172cSAndroid Build Coastguard Worker 	}
243*03f9172cSAndroid Build Coastguard Worker 	// Diagnose failure
244*03f9172cSAndroid Build Coastguard Worker 	int error = errno;
245*03f9172cSAndroid Build Coastguard Worker 	logHostapdConfigError(errno, file_path);
246*03f9172cSAndroid Build Coastguard Worker 	return "";
247*03f9172cSAndroid Build Coastguard Worker }
248*03f9172cSAndroid Build Coastguard Worker 
249*03f9172cSAndroid Build Coastguard Worker /*
250*03f9172cSAndroid Build Coastguard Worker  * Get the op_class for a channel/band
251*03f9172cSAndroid Build Coastguard Worker  * The logic here is based on Table E-4 in the 802.11 Specification
252*03f9172cSAndroid Build Coastguard Worker  */
getOpClassForChannel(int channel,int band,bool support11n,bool support11ac)253*03f9172cSAndroid Build Coastguard Worker int getOpClassForChannel(int channel, int band, bool support11n, bool support11ac) {
254*03f9172cSAndroid Build Coastguard Worker 	// 2GHz Band
255*03f9172cSAndroid Build Coastguard Worker 	if ((band & band2Ghz) != 0) {
256*03f9172cSAndroid Build Coastguard Worker 		if (channel == 14) {
257*03f9172cSAndroid Build Coastguard Worker 			return 82;
258*03f9172cSAndroid Build Coastguard Worker 		}
259*03f9172cSAndroid Build Coastguard Worker 		if (channel >= 1 && channel <= 13) {
260*03f9172cSAndroid Build Coastguard Worker 			if (!support11n) {
261*03f9172cSAndroid Build Coastguard Worker 				//20MHz channel
262*03f9172cSAndroid Build Coastguard Worker 				return 81;
263*03f9172cSAndroid Build Coastguard Worker 			}
264*03f9172cSAndroid Build Coastguard Worker 			if (channel <= 9) {
265*03f9172cSAndroid Build Coastguard Worker 				// HT40 with secondary channel above primary
266*03f9172cSAndroid Build Coastguard Worker 				return 83;
267*03f9172cSAndroid Build Coastguard Worker 			}
268*03f9172cSAndroid Build Coastguard Worker 			// HT40 with secondary channel below primary
269*03f9172cSAndroid Build Coastguard Worker 			return 84;
270*03f9172cSAndroid Build Coastguard Worker 		}
271*03f9172cSAndroid Build Coastguard Worker 		// Error
272*03f9172cSAndroid Build Coastguard Worker 		return 0;
273*03f9172cSAndroid Build Coastguard Worker 	}
274*03f9172cSAndroid Build Coastguard Worker 
275*03f9172cSAndroid Build Coastguard Worker 	// 5GHz Band
276*03f9172cSAndroid Build Coastguard Worker 	if ((band & band5Ghz) != 0) {
277*03f9172cSAndroid Build Coastguard Worker 		if (support11ac) {
278*03f9172cSAndroid Build Coastguard Worker 			switch (channel) {
279*03f9172cSAndroid Build Coastguard Worker 				case 42:
280*03f9172cSAndroid Build Coastguard Worker 				case 58:
281*03f9172cSAndroid Build Coastguard Worker 				case 106:
282*03f9172cSAndroid Build Coastguard Worker 				case 122:
283*03f9172cSAndroid Build Coastguard Worker 				case 138:
284*03f9172cSAndroid Build Coastguard Worker 				case 155:
285*03f9172cSAndroid Build Coastguard Worker 					// 80MHz channel
286*03f9172cSAndroid Build Coastguard Worker 					return 128;
287*03f9172cSAndroid Build Coastguard Worker 				case 50:
288*03f9172cSAndroid Build Coastguard Worker 				case 114:
289*03f9172cSAndroid Build Coastguard Worker 					// 160MHz channel
290*03f9172cSAndroid Build Coastguard Worker 					return 129;
291*03f9172cSAndroid Build Coastguard Worker 			}
292*03f9172cSAndroid Build Coastguard Worker 		}
293*03f9172cSAndroid Build Coastguard Worker 
294*03f9172cSAndroid Build Coastguard Worker 		if (!support11n) {
295*03f9172cSAndroid Build Coastguard Worker 			if (channel >= 36 && channel <= 48) {
296*03f9172cSAndroid Build Coastguard Worker 				return 115;
297*03f9172cSAndroid Build Coastguard Worker 			}
298*03f9172cSAndroid Build Coastguard Worker 			if (channel >= 52 && channel <= 64) {
299*03f9172cSAndroid Build Coastguard Worker 				return 118;
300*03f9172cSAndroid Build Coastguard Worker 			}
301*03f9172cSAndroid Build Coastguard Worker 			if (channel >= 100 && channel <= 144) {
302*03f9172cSAndroid Build Coastguard Worker 				return 121;
303*03f9172cSAndroid Build Coastguard Worker 			}
304*03f9172cSAndroid Build Coastguard Worker 			if (channel >= 149 && channel <= 161) {
305*03f9172cSAndroid Build Coastguard Worker 				return 124;
306*03f9172cSAndroid Build Coastguard Worker 			}
307*03f9172cSAndroid Build Coastguard Worker 			if (channel >= 165 && channel <= 169) {
308*03f9172cSAndroid Build Coastguard Worker 				return 125;
309*03f9172cSAndroid Build Coastguard Worker 			}
310*03f9172cSAndroid Build Coastguard Worker 		} else {
311*03f9172cSAndroid Build Coastguard Worker 			switch (channel) {
312*03f9172cSAndroid Build Coastguard Worker 				case 36:
313*03f9172cSAndroid Build Coastguard Worker 				case 44:
314*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel above primary
315*03f9172cSAndroid Build Coastguard Worker 					return 116;
316*03f9172cSAndroid Build Coastguard Worker 				case 40:
317*03f9172cSAndroid Build Coastguard Worker 				case 48:
318*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel below primary
319*03f9172cSAndroid Build Coastguard Worker 					return 117;
320*03f9172cSAndroid Build Coastguard Worker 				case 52:
321*03f9172cSAndroid Build Coastguard Worker 				case 60:
322*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel above primary
323*03f9172cSAndroid Build Coastguard Worker 					return  119;
324*03f9172cSAndroid Build Coastguard Worker 				case 56:
325*03f9172cSAndroid Build Coastguard Worker 				case 64:
326*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel below primary
327*03f9172cSAndroid Build Coastguard Worker 					return 120;
328*03f9172cSAndroid Build Coastguard Worker 				case 100:
329*03f9172cSAndroid Build Coastguard Worker 				case 108:
330*03f9172cSAndroid Build Coastguard Worker 				case 116:
331*03f9172cSAndroid Build Coastguard Worker 				case 124:
332*03f9172cSAndroid Build Coastguard Worker 				case 132:
333*03f9172cSAndroid Build Coastguard Worker 				case 140:
334*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel above primary
335*03f9172cSAndroid Build Coastguard Worker 					return 122;
336*03f9172cSAndroid Build Coastguard Worker 				case 104:
337*03f9172cSAndroid Build Coastguard Worker 				case 112:
338*03f9172cSAndroid Build Coastguard Worker 				case 120:
339*03f9172cSAndroid Build Coastguard Worker 				case 128:
340*03f9172cSAndroid Build Coastguard Worker 				case 136:
341*03f9172cSAndroid Build Coastguard Worker 				case 144:
342*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel below primary
343*03f9172cSAndroid Build Coastguard Worker 					return 123;
344*03f9172cSAndroid Build Coastguard Worker 				case 149:
345*03f9172cSAndroid Build Coastguard Worker 				case 157:
346*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel above primary
347*03f9172cSAndroid Build Coastguard Worker 					return 126;
348*03f9172cSAndroid Build Coastguard Worker 				case 153:
349*03f9172cSAndroid Build Coastguard Worker 				case 161:
350*03f9172cSAndroid Build Coastguard Worker 					// HT40 with secondary channel below primary
351*03f9172cSAndroid Build Coastguard Worker 					return 127;
352*03f9172cSAndroid Build Coastguard Worker 			}
353*03f9172cSAndroid Build Coastguard Worker 		}
354*03f9172cSAndroid Build Coastguard Worker 		// Error
355*03f9172cSAndroid Build Coastguard Worker 		return 0;
356*03f9172cSAndroid Build Coastguard Worker 	}
357*03f9172cSAndroid Build Coastguard Worker 
358*03f9172cSAndroid Build Coastguard Worker 	// 6GHz Band
359*03f9172cSAndroid Build Coastguard Worker 	if ((band & band6Ghz) != 0) {
360*03f9172cSAndroid Build Coastguard Worker 		// Channels 1, 5. 9, 13, ...
361*03f9172cSAndroid Build Coastguard Worker 		if ((channel & 0x03) == 0x01) {
362*03f9172cSAndroid Build Coastguard Worker 			// 20MHz channel
363*03f9172cSAndroid Build Coastguard Worker 			return 131;
364*03f9172cSAndroid Build Coastguard Worker 		}
365*03f9172cSAndroid Build Coastguard Worker 		// Channels 3, 11, 19, 27, ...
366*03f9172cSAndroid Build Coastguard Worker 		if ((channel & 0x07) == 0x03) {
367*03f9172cSAndroid Build Coastguard Worker 			// 40MHz channel
368*03f9172cSAndroid Build Coastguard Worker 			return 132;
369*03f9172cSAndroid Build Coastguard Worker 		}
370*03f9172cSAndroid Build Coastguard Worker 		// Channels 7, 23, 39, 55, ...
371*03f9172cSAndroid Build Coastguard Worker 		if ((channel & 0x0F) == 0x07) {
372*03f9172cSAndroid Build Coastguard Worker 			// 80MHz channel
373*03f9172cSAndroid Build Coastguard Worker 			return 133;
374*03f9172cSAndroid Build Coastguard Worker 		}
375*03f9172cSAndroid Build Coastguard Worker 		// Channels 15, 47, 69, ...
376*03f9172cSAndroid Build Coastguard Worker 		if ((channel & 0x1F) == 0x0F) {
377*03f9172cSAndroid Build Coastguard Worker 			// 160MHz channel
378*03f9172cSAndroid Build Coastguard Worker 			return 134;
379*03f9172cSAndroid Build Coastguard Worker 		}
380*03f9172cSAndroid Build Coastguard Worker 		if (channel == 2) {
381*03f9172cSAndroid Build Coastguard Worker 			// 20MHz channel
382*03f9172cSAndroid Build Coastguard Worker 			return 136;
383*03f9172cSAndroid Build Coastguard Worker 		}
384*03f9172cSAndroid Build Coastguard Worker 		// Error
385*03f9172cSAndroid Build Coastguard Worker 		return 0;
386*03f9172cSAndroid Build Coastguard Worker 	}
387*03f9172cSAndroid Build Coastguard Worker 
388*03f9172cSAndroid Build Coastguard Worker 	if ((band & band60Ghz) != 0) {
389*03f9172cSAndroid Build Coastguard Worker 		if (1 <= channel && channel <= 8) {
390*03f9172cSAndroid Build Coastguard Worker 			return 180;
391*03f9172cSAndroid Build Coastguard Worker 		} else if (9 <= channel && channel <= 15) {
392*03f9172cSAndroid Build Coastguard Worker 			return 181;
393*03f9172cSAndroid Build Coastguard Worker 		} else if (17 <= channel && channel <= 22) {
394*03f9172cSAndroid Build Coastguard Worker 			return 182;
395*03f9172cSAndroid Build Coastguard Worker 		} else if (25 <= channel && channel <= 29) {
396*03f9172cSAndroid Build Coastguard Worker 			return 183;
397*03f9172cSAndroid Build Coastguard Worker 		}
398*03f9172cSAndroid Build Coastguard Worker 		// Error
399*03f9172cSAndroid Build Coastguard Worker 		return 0;
400*03f9172cSAndroid Build Coastguard Worker 	}
401*03f9172cSAndroid Build Coastguard Worker 
402*03f9172cSAndroid Build Coastguard Worker 	return 0;
403*03f9172cSAndroid Build Coastguard Worker }
404*03f9172cSAndroid Build Coastguard Worker 
validatePassphrase(int passphrase_len,int min_len,int max_len)405*03f9172cSAndroid Build Coastguard Worker bool validatePassphrase(int passphrase_len, int min_len, int max_len)
406*03f9172cSAndroid Build Coastguard Worker {
407*03f9172cSAndroid Build Coastguard Worker 	if (min_len != -1 && passphrase_len < min_len) return false;
408*03f9172cSAndroid Build Coastguard Worker 	if (max_len != -1 && passphrase_len > max_len) return false;
409*03f9172cSAndroid Build Coastguard Worker 	return true;
410*03f9172cSAndroid Build Coastguard Worker }
411*03f9172cSAndroid Build Coastguard Worker 
getInterfaceMacAddress(const std::string & if_name)412*03f9172cSAndroid Build Coastguard Worker std::string getInterfaceMacAddress(const std::string& if_name)
413*03f9172cSAndroid Build Coastguard Worker {
414*03f9172cSAndroid Build Coastguard Worker 	u8 addr[ETH_ALEN] = {};
415*03f9172cSAndroid Build Coastguard Worker 	struct ifreq ifr;
416*03f9172cSAndroid Build Coastguard Worker 	std::string mac_addr;
417*03f9172cSAndroid Build Coastguard Worker 
418*03f9172cSAndroid Build Coastguard Worker 	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
419*03f9172cSAndroid Build Coastguard Worker 	if (sock.get() < 0) {
420*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
421*03f9172cSAndroid Build Coastguard Worker 			strerror(errno), __FUNCTION__);
422*03f9172cSAndroid Build Coastguard Worker 		return "";
423*03f9172cSAndroid Build Coastguard Worker 	}
424*03f9172cSAndroid Build Coastguard Worker 
425*03f9172cSAndroid Build Coastguard Worker 	memset(&ifr, 0, sizeof(ifr));
426*03f9172cSAndroid Build Coastguard Worker 	strlcpy(ifr.ifr_name, if_name.c_str(), IFNAMSIZ);
427*03f9172cSAndroid Build Coastguard Worker 	if (ioctl(sock.get(), SIOCGIFHWADDR, &ifr) < 0) {
428*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Could not get interface %s hwaddr: %s",
429*03f9172cSAndroid Build Coastguard Worker 			   if_name.c_str(), strerror(errno));
430*03f9172cSAndroid Build Coastguard Worker 		return "";
431*03f9172cSAndroid Build Coastguard Worker 	}
432*03f9172cSAndroid Build Coastguard Worker 
433*03f9172cSAndroid Build Coastguard Worker 	memcpy(addr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
434*03f9172cSAndroid Build Coastguard Worker 	mac_addr = StringPrintf("" MACSTR, MAC2STR(addr));
435*03f9172cSAndroid Build Coastguard Worker 
436*03f9172cSAndroid Build Coastguard Worker 	return mac_addr;
437*03f9172cSAndroid Build Coastguard Worker }
438*03f9172cSAndroid Build Coastguard Worker 
trimWhitespace(const std::string & str)439*03f9172cSAndroid Build Coastguard Worker std::string trimWhitespace(const std::string& str) {
440*03f9172cSAndroid Build Coastguard Worker 	size_t pos = 0;
441*03f9172cSAndroid Build Coastguard Worker 	size_t len = str.size();
442*03f9172cSAndroid Build Coastguard Worker 	for (pos; pos < str.size() && std::isspace(str[pos]); ++pos){}
443*03f9172cSAndroid Build Coastguard Worker 	for (len; len - 1 > 0 && std::isspace(str[len-1]); --len){}
444*03f9172cSAndroid Build Coastguard Worker 	return str.substr(pos, len);
445*03f9172cSAndroid Build Coastguard Worker }
446*03f9172cSAndroid Build Coastguard Worker 
CreateHostapdConfig(const IfaceParams & iface_params,const ChannelParams & channelParams,const NetworkParams & nw_params,const std::string br_name,const std::string owe_transition_ifname)447*03f9172cSAndroid Build Coastguard Worker std::string CreateHostapdConfig(
448*03f9172cSAndroid Build Coastguard Worker 	const IfaceParams& iface_params,
449*03f9172cSAndroid Build Coastguard Worker 	const ChannelParams& channelParams,
450*03f9172cSAndroid Build Coastguard Worker 	const NetworkParams& nw_params,
451*03f9172cSAndroid Build Coastguard Worker 	const std::string br_name,
452*03f9172cSAndroid Build Coastguard Worker 	const std::string owe_transition_ifname)
453*03f9172cSAndroid Build Coastguard Worker {
454*03f9172cSAndroid Build Coastguard Worker 	if (nw_params.ssid.size() >
455*03f9172cSAndroid Build Coastguard Worker 		static_cast<uint32_t>(
456*03f9172cSAndroid Build Coastguard Worker 		ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
457*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(
458*03f9172cSAndroid Build Coastguard Worker 			MSG_ERROR, "Invalid SSID size: %zu", nw_params.ssid.size());
459*03f9172cSAndroid Build Coastguard Worker 		return "";
460*03f9172cSAndroid Build Coastguard Worker 	}
461*03f9172cSAndroid Build Coastguard Worker 
462*03f9172cSAndroid Build Coastguard Worker 	// SSID string
463*03f9172cSAndroid Build Coastguard Worker 	std::stringstream ss;
464*03f9172cSAndroid Build Coastguard Worker 	ss << std::hex;
465*03f9172cSAndroid Build Coastguard Worker 	ss << std::setfill('0');
466*03f9172cSAndroid Build Coastguard Worker 	for (uint8_t b : nw_params.ssid) {
467*03f9172cSAndroid Build Coastguard Worker 		ss << std::setw(2) << static_cast<unsigned int>(b);
468*03f9172cSAndroid Build Coastguard Worker 	}
469*03f9172cSAndroid Build Coastguard Worker 	const std::string ssid_as_string = ss.str();
470*03f9172cSAndroid Build Coastguard Worker 
471*03f9172cSAndroid Build Coastguard Worker 	// Encryption config string
472*03f9172cSAndroid Build Coastguard Worker 	uint32_t band = 0;
473*03f9172cSAndroid Build Coastguard Worker 	band |= static_cast<uint32_t>(channelParams.bandMask);
474*03f9172cSAndroid Build Coastguard Worker 	bool is_2Ghz_band_only = band == static_cast<uint32_t>(band2Ghz);
475*03f9172cSAndroid Build Coastguard Worker 	bool is_6Ghz_band_only = band == static_cast<uint32_t>(band6Ghz);
476*03f9172cSAndroid Build Coastguard Worker 	bool is_60Ghz_band_only = band == static_cast<uint32_t>(band60Ghz);
477*03f9172cSAndroid Build Coastguard Worker 	std::string encryption_config_as_string;
478*03f9172cSAndroid Build Coastguard Worker 	switch (nw_params.encryptionType) {
479*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::NONE:
480*03f9172cSAndroid Build Coastguard Worker 		// no security params
481*03f9172cSAndroid Build Coastguard Worker 		break;
482*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA:
483*03f9172cSAndroid Build Coastguard Worker 		if (!validatePassphrase(
484*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.size(),
485*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
486*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
487*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
488*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
489*03f9172cSAndroid Build Coastguard Worker 			return "";
490*03f9172cSAndroid Build Coastguard Worker 		}
491*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string = StringPrintf(
492*03f9172cSAndroid Build Coastguard Worker 			"wpa=3\n"
493*03f9172cSAndroid Build Coastguard Worker 			"wpa_pairwise=%s\n"
494*03f9172cSAndroid Build Coastguard Worker 			"wpa_passphrase=%s",
495*03f9172cSAndroid Build Coastguard Worker 			is_60Ghz_band_only ? "GCMP" : "TKIP CCMP",
496*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.c_str());
497*03f9172cSAndroid Build Coastguard Worker 		break;
498*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA2:
499*03f9172cSAndroid Build Coastguard Worker 		if (!validatePassphrase(
500*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.size(),
501*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
502*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
503*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
504*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
505*03f9172cSAndroid Build Coastguard Worker 			return "";
506*03f9172cSAndroid Build Coastguard Worker 		}
507*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string = StringPrintf(
508*03f9172cSAndroid Build Coastguard Worker 			"wpa=2\n"
509*03f9172cSAndroid Build Coastguard Worker 			"rsn_pairwise=%s\n"
510*03f9172cSAndroid Build Coastguard Worker #ifdef ENABLE_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL
511*03f9172cSAndroid Build Coastguard Worker 			"ieee80211w=1\n"
512*03f9172cSAndroid Build Coastguard Worker #endif
513*03f9172cSAndroid Build Coastguard Worker 			"wpa_passphrase=%s",
514*03f9172cSAndroid Build Coastguard Worker 			is_60Ghz_band_only ? "GCMP" : "CCMP",
515*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.c_str());
516*03f9172cSAndroid Build Coastguard Worker 		break;
517*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA3_SAE_TRANSITION:
518*03f9172cSAndroid Build Coastguard Worker 		if (!validatePassphrase(
519*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.size(),
520*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
521*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
522*03f9172cSAndroid Build Coastguard Worker 			static_cast<uint32_t>(ParamSizeLimits::
523*03f9172cSAndroid Build Coastguard Worker 				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
524*03f9172cSAndroid Build Coastguard Worker 			return "";
525*03f9172cSAndroid Build Coastguard Worker 		}
526*03f9172cSAndroid Build Coastguard Worker 		// WPA3 transition mode or SAE+WPA_PSK key management(AKM) is not allowed in 6GHz.
527*03f9172cSAndroid Build Coastguard Worker 		// Auto-convert any such configurations to SAE.
528*03f9172cSAndroid Build Coastguard Worker 		if ((band & band6Ghz) != 0) {
529*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO, "WPA3_SAE_TRANSITION configured in 6GHz band."
530*03f9172cSAndroid Build Coastguard Worker 				   "Enable only SAE in key_mgmt");
531*03f9172cSAndroid Build Coastguard Worker 			encryption_config_as_string = StringPrintf(
532*03f9172cSAndroid Build Coastguard Worker 				"wpa=2\n"
533*03f9172cSAndroid Build Coastguard Worker 				"rsn_pairwise=CCMP\n"
534*03f9172cSAndroid Build Coastguard Worker 				"wpa_key_mgmt=%s\n"
535*03f9172cSAndroid Build Coastguard Worker 				"ieee80211w=2\n"
536*03f9172cSAndroid Build Coastguard Worker 				"sae_require_mfp=2\n"
537*03f9172cSAndroid Build Coastguard Worker 				"sae_pwe=%d\n"
538*03f9172cSAndroid Build Coastguard Worker 				"sae_password=%s",
539*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
540*03f9172cSAndroid Build Coastguard Worker 				iface_params.hwModeParams.enable80211BE ?
541*03f9172cSAndroid Build Coastguard Worker 					"SAE SAE-EXT-KEY" : "SAE",
542*03f9172cSAndroid Build Coastguard Worker #else
543*03f9172cSAndroid Build Coastguard Worker 					"SAE",
544*03f9172cSAndroid Build Coastguard Worker #endif
545*03f9172cSAndroid Build Coastguard Worker 				is_6Ghz_band_only ? 1 : 2,
546*03f9172cSAndroid Build Coastguard Worker 				nw_params.passphrase.c_str());
547*03f9172cSAndroid Build Coastguard Worker 		} else {
548*03f9172cSAndroid Build Coastguard Worker 			encryption_config_as_string = StringPrintf(
549*03f9172cSAndroid Build Coastguard Worker 				"wpa=2\n"
550*03f9172cSAndroid Build Coastguard Worker 				"rsn_pairwise=%s\n"
551*03f9172cSAndroid Build Coastguard Worker 				"wpa_key_mgmt=%s\n"
552*03f9172cSAndroid Build Coastguard Worker 				"ieee80211w=1\n"
553*03f9172cSAndroid Build Coastguard Worker 				"sae_require_mfp=1\n"
554*03f9172cSAndroid Build Coastguard Worker 				"wpa_passphrase=%s\n"
555*03f9172cSAndroid Build Coastguard Worker 				"sae_password=%s",
556*03f9172cSAndroid Build Coastguard Worker 				is_60Ghz_band_only ? "GCMP" : "CCMP",
557*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
558*03f9172cSAndroid Build Coastguard Worker 				iface_params.hwModeParams.enable80211BE ?
559*03f9172cSAndroid Build Coastguard Worker 					"WPA-PSK SAE SAE-EXT-KEY" : "WPA-PSK SAE",
560*03f9172cSAndroid Build Coastguard Worker #else
561*03f9172cSAndroid Build Coastguard Worker 					"WPA-PSK SAE",
562*03f9172cSAndroid Build Coastguard Worker #endif
563*03f9172cSAndroid Build Coastguard Worker 				nw_params.passphrase.c_str(),
564*03f9172cSAndroid Build Coastguard Worker 				nw_params.passphrase.c_str());
565*03f9172cSAndroid Build Coastguard Worker                 }
566*03f9172cSAndroid Build Coastguard Worker 		break;
567*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA3_SAE:
568*03f9172cSAndroid Build Coastguard Worker 		if (!validatePassphrase(nw_params.passphrase.size(), 1, -1)) {
569*03f9172cSAndroid Build Coastguard Worker 			return "";
570*03f9172cSAndroid Build Coastguard Worker 		}
571*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string = StringPrintf(
572*03f9172cSAndroid Build Coastguard Worker 			"wpa=2\n"
573*03f9172cSAndroid Build Coastguard Worker 			"rsn_pairwise=%s\n"
574*03f9172cSAndroid Build Coastguard Worker 			"wpa_key_mgmt=%s\n"
575*03f9172cSAndroid Build Coastguard Worker 			"ieee80211w=2\n"
576*03f9172cSAndroid Build Coastguard Worker 			"sae_require_mfp=2\n"
577*03f9172cSAndroid Build Coastguard Worker 			"sae_pwe=%d\n"
578*03f9172cSAndroid Build Coastguard Worker 			"sae_password=%s",
579*03f9172cSAndroid Build Coastguard Worker 			is_60Ghz_band_only ? "GCMP" : "CCMP",
580*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
581*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enable80211BE ? "SAE SAE-EXT-KEY" : "SAE",
582*03f9172cSAndroid Build Coastguard Worker #else
583*03f9172cSAndroid Build Coastguard Worker 			"SAE",
584*03f9172cSAndroid Build Coastguard Worker #endif
585*03f9172cSAndroid Build Coastguard Worker 			is_6Ghz_band_only ? 1 : 2,
586*03f9172cSAndroid Build Coastguard Worker 			nw_params.passphrase.c_str());
587*03f9172cSAndroid Build Coastguard Worker 		break;
588*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA3_OWE_TRANSITION:
589*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string = StringPrintf(
590*03f9172cSAndroid Build Coastguard Worker 			"wpa=2\n"
591*03f9172cSAndroid Build Coastguard Worker 			"rsn_pairwise=%s\n"
592*03f9172cSAndroid Build Coastguard Worker 			"wpa_key_mgmt=OWE\n"
593*03f9172cSAndroid Build Coastguard Worker 			"ieee80211w=2",
594*03f9172cSAndroid Build Coastguard Worker 			is_60Ghz_band_only ? "GCMP" : "CCMP");
595*03f9172cSAndroid Build Coastguard Worker 		break;
596*03f9172cSAndroid Build Coastguard Worker 	case EncryptionType::WPA3_OWE:
597*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string = StringPrintf(
598*03f9172cSAndroid Build Coastguard Worker 			"wpa=2\n"
599*03f9172cSAndroid Build Coastguard Worker 			"rsn_pairwise=%s\n"
600*03f9172cSAndroid Build Coastguard Worker 			"wpa_key_mgmt=OWE\n"
601*03f9172cSAndroid Build Coastguard Worker 			"ieee80211w=2",
602*03f9172cSAndroid Build Coastguard Worker 			is_60Ghz_band_only ? "GCMP" : "CCMP");
603*03f9172cSAndroid Build Coastguard Worker 		break;
604*03f9172cSAndroid Build Coastguard Worker 	default:
605*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Unknown encryption type");
606*03f9172cSAndroid Build Coastguard Worker 		return "";
607*03f9172cSAndroid Build Coastguard Worker 	}
608*03f9172cSAndroid Build Coastguard Worker 
609*03f9172cSAndroid Build Coastguard Worker 	std::string channel_config_as_string;
610*03f9172cSAndroid Build Coastguard Worker 	bool isFirst = true;
611*03f9172cSAndroid Build Coastguard Worker 	if (channelParams.enableAcs) {
612*03f9172cSAndroid Build Coastguard Worker 		std::string freqList_as_string;
613*03f9172cSAndroid Build Coastguard Worker 		for (const auto &range :
614*03f9172cSAndroid Build Coastguard Worker 			channelParams.acsChannelFreqRangesMhz) {
615*03f9172cSAndroid Build Coastguard Worker 			if (!isFirst) {
616*03f9172cSAndroid Build Coastguard Worker 				freqList_as_string += ",";
617*03f9172cSAndroid Build Coastguard Worker 			}
618*03f9172cSAndroid Build Coastguard Worker 			isFirst = false;
619*03f9172cSAndroid Build Coastguard Worker 
620*03f9172cSAndroid Build Coastguard Worker 			if (range.startMhz != range.endMhz) {
621*03f9172cSAndroid Build Coastguard Worker 				freqList_as_string +=
622*03f9172cSAndroid Build Coastguard Worker 					StringPrintf("%d-%d", range.startMhz, range.endMhz);
623*03f9172cSAndroid Build Coastguard Worker 			} else {
624*03f9172cSAndroid Build Coastguard Worker 				freqList_as_string += StringPrintf("%d", range.startMhz);
625*03f9172cSAndroid Build Coastguard Worker 			}
626*03f9172cSAndroid Build Coastguard Worker 		}
627*03f9172cSAndroid Build Coastguard Worker 		channel_config_as_string = StringPrintf(
628*03f9172cSAndroid Build Coastguard Worker 			"channel=0\n"
629*03f9172cSAndroid Build Coastguard Worker 			"acs_exclude_dfs=%d\n"
630*03f9172cSAndroid Build Coastguard Worker 			"freqlist=%s",
631*03f9172cSAndroid Build Coastguard Worker 			channelParams.acsShouldExcludeDfs,
632*03f9172cSAndroid Build Coastguard Worker 			freqList_as_string.c_str());
633*03f9172cSAndroid Build Coastguard Worker 	} else {
634*03f9172cSAndroid Build Coastguard Worker 		int op_class = getOpClassForChannel(
635*03f9172cSAndroid Build Coastguard Worker 			channelParams.channel,
636*03f9172cSAndroid Build Coastguard Worker 			band,
637*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enable80211N,
638*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enable80211AC);
639*03f9172cSAndroid Build Coastguard Worker 		channel_config_as_string = StringPrintf(
640*03f9172cSAndroid Build Coastguard Worker 			"channel=%d\n"
641*03f9172cSAndroid Build Coastguard Worker 			"op_class=%d",
642*03f9172cSAndroid Build Coastguard Worker 			channelParams.channel, op_class);
643*03f9172cSAndroid Build Coastguard Worker 	}
644*03f9172cSAndroid Build Coastguard Worker 
645*03f9172cSAndroid Build Coastguard Worker 	std::string hw_mode_as_string;
646*03f9172cSAndroid Build Coastguard Worker 	std::string enable_edmg_as_string;
647*03f9172cSAndroid Build Coastguard Worker 	std::string edmg_channel_as_string;
648*03f9172cSAndroid Build Coastguard Worker 	bool is_60Ghz_used = false;
649*03f9172cSAndroid Build Coastguard Worker 
650*03f9172cSAndroid Build Coastguard Worker 	if (((band & band60Ghz) != 0)) {
651*03f9172cSAndroid Build Coastguard Worker 		hw_mode_as_string = "hw_mode=ad";
652*03f9172cSAndroid Build Coastguard Worker 		if (iface_params.hwModeParams.enableEdmg) {
653*03f9172cSAndroid Build Coastguard Worker 			enable_edmg_as_string = "enable_edmg=1";
654*03f9172cSAndroid Build Coastguard Worker 			edmg_channel_as_string = StringPrintf(
655*03f9172cSAndroid Build Coastguard Worker 				"edmg_channel=%d",
656*03f9172cSAndroid Build Coastguard Worker 				channelParams.channel);
657*03f9172cSAndroid Build Coastguard Worker 		}
658*03f9172cSAndroid Build Coastguard Worker 		is_60Ghz_used = true;
659*03f9172cSAndroid Build Coastguard Worker 	} else if ((band & band2Ghz) != 0) {
660*03f9172cSAndroid Build Coastguard Worker 		if (((band & band5Ghz) != 0)
661*03f9172cSAndroid Build Coastguard Worker 		    || ((band & band6Ghz) != 0)) {
662*03f9172cSAndroid Build Coastguard Worker 			hw_mode_as_string = "hw_mode=any";
663*03f9172cSAndroid Build Coastguard Worker 		} else {
664*03f9172cSAndroid Build Coastguard Worker 			hw_mode_as_string = "hw_mode=g";
665*03f9172cSAndroid Build Coastguard Worker 		}
666*03f9172cSAndroid Build Coastguard Worker 	} else if (((band & band5Ghz) != 0)
667*03f9172cSAndroid Build Coastguard Worker 		    || ((band & band6Ghz) != 0)) {
668*03f9172cSAndroid Build Coastguard Worker 			hw_mode_as_string = "hw_mode=a";
669*03f9172cSAndroid Build Coastguard Worker 	} else {
670*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Invalid band");
671*03f9172cSAndroid Build Coastguard Worker 		return "";
672*03f9172cSAndroid Build Coastguard Worker 	}
673*03f9172cSAndroid Build Coastguard Worker 
674*03f9172cSAndroid Build Coastguard Worker 	std::string he_params_as_string;
675*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
676*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) {
677*03f9172cSAndroid Build Coastguard Worker 		he_params_as_string = StringPrintf(
678*03f9172cSAndroid Build Coastguard Worker 			"ieee80211ax=1\n"
679*03f9172cSAndroid Build Coastguard Worker 			"he_su_beamformer=%d\n"
680*03f9172cSAndroid Build Coastguard Worker 			"he_su_beamformee=%d\n"
681*03f9172cSAndroid Build Coastguard Worker 			"he_mu_beamformer=%d\n"
682*03f9172cSAndroid Build Coastguard Worker 			"he_twt_required=%d\n",
683*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enableHeSingleUserBeamformer ? 1 : 0,
684*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enableHeSingleUserBeamformee ? 1 : 0,
685*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enableHeMultiUserBeamformer ? 1 : 0,
686*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enableHeTargetWakeTime ? 1 : 0);
687*03f9172cSAndroid Build Coastguard Worker 	} else {
688*03f9172cSAndroid Build Coastguard Worker 		he_params_as_string = "ieee80211ax=0";
689*03f9172cSAndroid Build Coastguard Worker 	}
690*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211AX */
691*03f9172cSAndroid Build Coastguard Worker 	std::string eht_params_as_string;
692*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
693*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) {
694*03f9172cSAndroid Build Coastguard Worker 		eht_params_as_string = "ieee80211be=1\n";
695*03f9172cSAndroid Build Coastguard Worker 		if (areAidlServiceAndClientAtLeastVersion(2)) {
696*03f9172cSAndroid Build Coastguard Worker 			std::string interface_mac_addr = getInterfaceMacAddress(
697*03f9172cSAndroid Build Coastguard Worker 					iface_params.usesMlo ? br_name : iface_params.name);
698*03f9172cSAndroid Build Coastguard Worker 			if (interface_mac_addr.empty()) {
699*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR,
700*03f9172cSAndroid Build Coastguard Worker 				    "Unable to set interface mac address as bssid for 11BE SAP");
701*03f9172cSAndroid Build Coastguard Worker 				return "";
702*03f9172cSAndroid Build Coastguard Worker 			}
703*03f9172cSAndroid Build Coastguard Worker             if (iface_params.usesMlo) {
704*03f9172cSAndroid Build Coastguard Worker                 eht_params_as_string += StringPrintf(
705*03f9172cSAndroid Build Coastguard Worker                     "mld_addr=%s\n"
706*03f9172cSAndroid Build Coastguard Worker                     "mld_ap=1",
707*03f9172cSAndroid Build Coastguard Worker                     interface_mac_addr.c_str());
708*03f9172cSAndroid Build Coastguard Worker             } else {
709*03f9172cSAndroid Build Coastguard Worker                 eht_params_as_string += StringPrintf(
710*03f9172cSAndroid Build Coastguard Worker                     "bssid=%s\n"
711*03f9172cSAndroid Build Coastguard Worker                     "mld_ap=1",
712*03f9172cSAndroid Build Coastguard Worker                     interface_mac_addr.c_str());
713*03f9172cSAndroid Build Coastguard Worker             }
714*03f9172cSAndroid Build Coastguard Worker 		}
715*03f9172cSAndroid Build Coastguard Worker 		/* TODO set eht_su_beamformer, eht_su_beamformee, eht_mu_beamformer */
716*03f9172cSAndroid Build Coastguard Worker 	} else {
717*03f9172cSAndroid Build Coastguard Worker 		eht_params_as_string = "ieee80211be=0";
718*03f9172cSAndroid Build Coastguard Worker 	}
719*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
720*03f9172cSAndroid Build Coastguard Worker 
721*03f9172cSAndroid Build Coastguard Worker 	std::string ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string;
722*03f9172cSAndroid Build Coastguard Worker 	switch (iface_params.hwModeParams.maximumChannelBandwidth) {
723*03f9172cSAndroid Build Coastguard Worker 	case ChannelBandwidth::BANDWIDTH_20:
724*03f9172cSAndroid Build Coastguard Worker 		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
725*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
726*03f9172cSAndroid Build Coastguard Worker 			"eht_oper_chwidth=0\n"
727*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
728*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
729*03f9172cSAndroid Build Coastguard Worker 			"he_oper_chwidth=0\n"
730*03f9172cSAndroid Build Coastguard Worker #endif
731*03f9172cSAndroid Build Coastguard Worker 			"vht_oper_chwidth=0\n"
732*03f9172cSAndroid Build Coastguard Worker 			"%s", (band & band6Ghz) ? "op_class=131" : "");
733*03f9172cSAndroid Build Coastguard Worker 		break;
734*03f9172cSAndroid Build Coastguard Worker 	case ChannelBandwidth::BANDWIDTH_40:
735*03f9172cSAndroid Build Coastguard Worker 		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
736*03f9172cSAndroid Build Coastguard Worker 			"ht_capab=[HT40+]\n"
737*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
738*03f9172cSAndroid Build Coastguard Worker 			"eht_oper_chwidth=0\n"
739*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
740*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
741*03f9172cSAndroid Build Coastguard Worker 			"he_oper_chwidth=0\n"
742*03f9172cSAndroid Build Coastguard Worker #endif
743*03f9172cSAndroid Build Coastguard Worker 			"vht_oper_chwidth=0\n"
744*03f9172cSAndroid Build Coastguard Worker 			"%s", (band & band6Ghz) ? "op_class=132" : "");
745*03f9172cSAndroid Build Coastguard Worker 		break;
746*03f9172cSAndroid Build Coastguard Worker 	case ChannelBandwidth::BANDWIDTH_80:
747*03f9172cSAndroid Build Coastguard Worker 		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
748*03f9172cSAndroid Build Coastguard Worker 			"ht_capab=[HT40+]\n"
749*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
750*03f9172cSAndroid Build Coastguard Worker 			"eht_oper_chwidth=%d\n"
751*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
752*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
753*03f9172cSAndroid Build Coastguard Worker 			"he_oper_chwidth=%d\n"
754*03f9172cSAndroid Build Coastguard Worker #endif
755*03f9172cSAndroid Build Coastguard Worker 			"vht_oper_chwidth=%d\n"
756*03f9172cSAndroid Build Coastguard Worker 			"%s",
757*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
758*03f9172cSAndroid Build Coastguard Worker 			(iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) ? 1 : 0,
759*03f9172cSAndroid Build Coastguard Worker #endif
760*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
761*03f9172cSAndroid Build Coastguard Worker 			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 1 : 0,
762*03f9172cSAndroid Build Coastguard Worker #endif
763*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enable80211AC ? 1 : 0,
764*03f9172cSAndroid Build Coastguard Worker 			(band & band6Ghz) ? "op_class=133" : "");
765*03f9172cSAndroid Build Coastguard Worker 		break;
766*03f9172cSAndroid Build Coastguard Worker 	case ChannelBandwidth::BANDWIDTH_160:
767*03f9172cSAndroid Build Coastguard Worker 		ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string = StringPrintf(
768*03f9172cSAndroid Build Coastguard Worker 			"ht_capab=[HT40+]\n"
769*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
770*03f9172cSAndroid Build Coastguard Worker 			"eht_oper_chwidth=%d\n"
771*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
772*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
773*03f9172cSAndroid Build Coastguard Worker 			"he_oper_chwidth=%d\n"
774*03f9172cSAndroid Build Coastguard Worker #endif
775*03f9172cSAndroid Build Coastguard Worker 			"vht_oper_chwidth=%d\n"
776*03f9172cSAndroid Build Coastguard Worker 			"%s",
777*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
778*03f9172cSAndroid Build Coastguard Worker 			(iface_params.hwModeParams.enable80211BE && !is_60Ghz_used) ? 2 : 0,
779*03f9172cSAndroid Build Coastguard Worker #endif
780*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
781*03f9172cSAndroid Build Coastguard Worker 			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 2 : 0,
782*03f9172cSAndroid Build Coastguard Worker #endif
783*03f9172cSAndroid Build Coastguard Worker 			iface_params.hwModeParams.enable80211AC ? 2 : 0,
784*03f9172cSAndroid Build Coastguard Worker 			(band & band6Ghz) ? "op_class=134" : "");
785*03f9172cSAndroid Build Coastguard Worker 		break;
786*03f9172cSAndroid Build Coastguard Worker 	default:
787*03f9172cSAndroid Build Coastguard Worker 		if (!is_2Ghz_band_only && !is_60Ghz_used) {
788*03f9172cSAndroid Build Coastguard Worker 			if (iface_params.hwModeParams.enable80211AC) {
789*03f9172cSAndroid Build Coastguard Worker 				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string =
790*03f9172cSAndroid Build Coastguard Worker 					"ht_capab=[HT40+]\n"
791*03f9172cSAndroid Build Coastguard Worker 					"vht_oper_chwidth=1\n";
792*03f9172cSAndroid Build Coastguard Worker 			}
793*03f9172cSAndroid Build Coastguard Worker 			if (band & band6Ghz) {
794*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
795*03f9172cSAndroid Build Coastguard Worker 				if (iface_params.hwModeParams.enable80211BE)
796*03f9172cSAndroid Build Coastguard Worker 					ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=137\n";
797*03f9172cSAndroid Build Coastguard Worker 				else
798*03f9172cSAndroid Build Coastguard Worker 					ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=134\n";
799*03f9172cSAndroid Build Coastguard Worker #else /* CONFIG_IEEE80211BE */
800*03f9172cSAndroid Build Coastguard Worker 				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "op_class=134\n";
801*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_IEEE80211BE */
802*03f9172cSAndroid Build Coastguard Worker 			}
803*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211AX
804*03f9172cSAndroid Build Coastguard Worker 			if (iface_params.hwModeParams.enable80211AX) {
805*03f9172cSAndroid Build Coastguard Worker 				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "he_oper_chwidth=1\n";
806*03f9172cSAndroid Build Coastguard Worker 			}
807*03f9172cSAndroid Build Coastguard Worker #endif
808*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
809*03f9172cSAndroid Build Coastguard Worker 			if (iface_params.hwModeParams.enable80211BE) {
810*03f9172cSAndroid Build Coastguard Worker 				ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string += "eht_oper_chwidth=1";
811*03f9172cSAndroid Build Coastguard Worker 			}
812*03f9172cSAndroid Build Coastguard Worker #endif
813*03f9172cSAndroid Build Coastguard Worker 		}
814*03f9172cSAndroid Build Coastguard Worker 		break;
815*03f9172cSAndroid Build Coastguard Worker 	}
816*03f9172cSAndroid Build Coastguard Worker 
817*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_INTERWORKING
818*03f9172cSAndroid Build Coastguard Worker 	std::string access_network_params_as_string;
819*03f9172cSAndroid Build Coastguard Worker 	if (nw_params.isMetered) {
820*03f9172cSAndroid Build Coastguard Worker 		access_network_params_as_string = StringPrintf(
821*03f9172cSAndroid Build Coastguard Worker 			"interworking=1\n"
822*03f9172cSAndroid Build Coastguard Worker 			"access_network_type=2\n"); // CHARGEABLE_PUBLIC_NETWORK
823*03f9172cSAndroid Build Coastguard Worker 	} else {
824*03f9172cSAndroid Build Coastguard Worker 	    access_network_params_as_string = StringPrintf(
825*03f9172cSAndroid Build Coastguard Worker 			"interworking=0\n");
826*03f9172cSAndroid Build Coastguard Worker 	}
827*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_INTERWORKING */
828*03f9172cSAndroid Build Coastguard Worker 
829*03f9172cSAndroid Build Coastguard Worker 	std::string bridge_as_string;
830*03f9172cSAndroid Build Coastguard Worker 	if (!br_name.empty() && !iface_params.usesMlo) {
831*03f9172cSAndroid Build Coastguard Worker 		bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
832*03f9172cSAndroid Build Coastguard Worker 	}
833*03f9172cSAndroid Build Coastguard Worker 
834*03f9172cSAndroid Build Coastguard Worker 	// vendor_elements string
835*03f9172cSAndroid Build Coastguard Worker 	std::string vendor_elements_as_string;
836*03f9172cSAndroid Build Coastguard Worker 	if (nw_params.vendorElements.size() > 0) {
837*03f9172cSAndroid Build Coastguard Worker 		std::stringstream ss;
838*03f9172cSAndroid Build Coastguard Worker 		ss << std::hex;
839*03f9172cSAndroid Build Coastguard Worker 		ss << std::setfill('0');
840*03f9172cSAndroid Build Coastguard Worker 		for (uint8_t b : nw_params.vendorElements) {
841*03f9172cSAndroid Build Coastguard Worker 			ss << std::setw(2) << static_cast<unsigned int>(b);
842*03f9172cSAndroid Build Coastguard Worker 		}
843*03f9172cSAndroid Build Coastguard Worker 		vendor_elements_as_string = StringPrintf("vendor_elements=%s", ss.str().c_str());
844*03f9172cSAndroid Build Coastguard Worker 	}
845*03f9172cSAndroid Build Coastguard Worker 
846*03f9172cSAndroid Build Coastguard Worker 	std::string owe_transition_ifname_as_string;
847*03f9172cSAndroid Build Coastguard Worker 	if (!owe_transition_ifname.empty()) {
848*03f9172cSAndroid Build Coastguard Worker 		owe_transition_ifname_as_string = StringPrintf(
849*03f9172cSAndroid Build Coastguard Worker 			"owe_transition_ifname=%s", owe_transition_ifname.c_str());
850*03f9172cSAndroid Build Coastguard Worker 	}
851*03f9172cSAndroid Build Coastguard Worker 
852*03f9172cSAndroid Build Coastguard Worker 	std::string ap_isolation_as_string = StringPrintf("ap_isolate=%s",
853*03f9172cSAndroid Build Coastguard Worker 			isAidlServiceVersionAtLeast(3) && nw_params.isClientIsolationEnabled ?
854*03f9172cSAndroid Build Coastguard Worker 			"1" : "0");
855*03f9172cSAndroid Build Coastguard Worker 
856*03f9172cSAndroid Build Coastguard Worker 	// Overlay for LOHS (unmetered SoftAP)
857*03f9172cSAndroid Build Coastguard Worker 	std::string overlay_path = resolveVendorConfPath(kUnmeteredIfaceOverlayPath);
858*03f9172cSAndroid Build Coastguard Worker 	std::string overlay_string;
859*03f9172cSAndroid Build Coastguard Worker 	if (!nw_params.isMetered
860*03f9172cSAndroid Build Coastguard Worker 			&& 0 == access(overlay_path.c_str(), R_OK)
861*03f9172cSAndroid Build Coastguard Worker 			&& !ReadFileToString(overlay_path, &overlay_string)) {
862*03f9172cSAndroid Build Coastguard Worker 		logHostapdConfigError(errno, overlay_path);
863*03f9172cSAndroid Build Coastguard Worker 		return "";
864*03f9172cSAndroid Build Coastguard Worker 	}
865*03f9172cSAndroid Build Coastguard Worker 	std::string sanitized_overlay = "";
866*03f9172cSAndroid Build Coastguard Worker 	std::istringstream overlay_stream(overlay_string);
867*03f9172cSAndroid Build Coastguard Worker 	for (std::string line; std::getline(overlay_stream, line);) {
868*03f9172cSAndroid Build Coastguard Worker 		std::string overlay_key = trimWhitespace(line.substr(0, line.find("=")));
869*03f9172cSAndroid Build Coastguard Worker 		if (kOverlayableKeys.contains(overlay_key)) {
870*03f9172cSAndroid Build Coastguard Worker 			sanitized_overlay.append(line + "\n");
871*03f9172cSAndroid Build Coastguard Worker 		}
872*03f9172cSAndroid Build Coastguard Worker 	}
873*03f9172cSAndroid Build Coastguard Worker 
874*03f9172cSAndroid Build Coastguard Worker 	return StringPrintf(
875*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
876*03f9172cSAndroid Build Coastguard Worker 		"interface=%s\n"
877*03f9172cSAndroid Build Coastguard Worker 		"driver=nl80211\n"
878*03f9172cSAndroid Build Coastguard Worker 		"ctrl_interface=/data/vendor/wifi/hostapd/ctrl_%s\n"
879*03f9172cSAndroid Build Coastguard Worker 		// ssid2 signals to hostapd that the value is not a literal value
880*03f9172cSAndroid Build Coastguard Worker 		// for use as a SSID.  In this case, we're giving it a hex
881*03f9172cSAndroid Build Coastguard Worker 		// std::string and hostapd needs to expect that.
882*03f9172cSAndroid Build Coastguard Worker 		"ssid2=%s\n"
883*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
884*03f9172cSAndroid Build Coastguard Worker 		"ieee80211n=%d\n"
885*03f9172cSAndroid Build Coastguard Worker 		"ieee80211ac=%d\n"
886*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
887*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
888*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
889*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
890*03f9172cSAndroid Build Coastguard Worker 		"ignore_broadcast_ssid=%d\n"
891*03f9172cSAndroid Build Coastguard Worker 		"wowlan_triggers=any\n"
892*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_INTERWORKING
893*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
894*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_INTERWORKING */
895*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
896*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
897*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
898*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
899*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
900*03f9172cSAndroid Build Coastguard Worker 		"%s\n"
901*03f9172cSAndroid Build Coastguard Worker 		"%s\n",
902*03f9172cSAndroid Build Coastguard Worker 		sanitized_overlay.c_str(),
903*03f9172cSAndroid Build Coastguard Worker 		iface_params.usesMlo ? br_name.c_str() : iface_params.name.c_str(),
904*03f9172cSAndroid Build Coastguard Worker 		iface_params.name.c_str(),
905*03f9172cSAndroid Build Coastguard Worker 		ssid_as_string.c_str(),
906*03f9172cSAndroid Build Coastguard Worker 		channel_config_as_string.c_str(),
907*03f9172cSAndroid Build Coastguard Worker 		iface_params.hwModeParams.enable80211N ? 1 : 0,
908*03f9172cSAndroid Build Coastguard Worker 		iface_params.hwModeParams.enable80211AC ? 1 : 0,
909*03f9172cSAndroid Build Coastguard Worker 		he_params_as_string.c_str(),
910*03f9172cSAndroid Build Coastguard Worker 		eht_params_as_string.c_str(),
911*03f9172cSAndroid Build Coastguard Worker 		hw_mode_as_string.c_str(), ht_cap_vht_oper_he_oper_eht_oper_chwidth_as_string.c_str(),
912*03f9172cSAndroid Build Coastguard Worker 		nw_params.isHidden ? 1 : 0,
913*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_INTERWORKING
914*03f9172cSAndroid Build Coastguard Worker 		access_network_params_as_string.c_str(),
915*03f9172cSAndroid Build Coastguard Worker #endif /* CONFIG_INTERWORKING */
916*03f9172cSAndroid Build Coastguard Worker 		encryption_config_as_string.c_str(),
917*03f9172cSAndroid Build Coastguard Worker 		bridge_as_string.c_str(),
918*03f9172cSAndroid Build Coastguard Worker 		owe_transition_ifname_as_string.c_str(),
919*03f9172cSAndroid Build Coastguard Worker 		enable_edmg_as_string.c_str(),
920*03f9172cSAndroid Build Coastguard Worker 		edmg_channel_as_string.c_str(),
921*03f9172cSAndroid Build Coastguard Worker 		vendor_elements_as_string.c_str(),
922*03f9172cSAndroid Build Coastguard Worker 		ap_isolation_as_string.c_str());
923*03f9172cSAndroid Build Coastguard Worker }
924*03f9172cSAndroid Build Coastguard Worker 
getGeneration(hostapd_hw_modes * current_mode)925*03f9172cSAndroid Build Coastguard Worker Generation getGeneration(hostapd_hw_modes *current_mode)
926*03f9172cSAndroid Build Coastguard Worker {
927*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d,"
928*03f9172cSAndroid Build Coastguard Worker 		   " vht_enabled=%d, he_supported=%d",
929*03f9172cSAndroid Build Coastguard Worker 		   current_mode->mode, current_mode->ht_capab != 0,
930*03f9172cSAndroid Build Coastguard Worker 		   current_mode->vht_capab != 0, current_mode->he_capab->he_supported);
931*03f9172cSAndroid Build Coastguard Worker 	switch (current_mode->mode) {
932*03f9172cSAndroid Build Coastguard Worker 	case HOSTAPD_MODE_IEEE80211B:
933*03f9172cSAndroid Build Coastguard Worker 		return Generation::WIFI_STANDARD_LEGACY;
934*03f9172cSAndroid Build Coastguard Worker 	case HOSTAPD_MODE_IEEE80211G:
935*03f9172cSAndroid Build Coastguard Worker 		return current_mode->ht_capab == 0 ?
936*03f9172cSAndroid Build Coastguard Worker 				Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
937*03f9172cSAndroid Build Coastguard Worker 	case HOSTAPD_MODE_IEEE80211A:
938*03f9172cSAndroid Build Coastguard Worker 		if (current_mode->he_capab->he_supported) {
939*03f9172cSAndroid Build Coastguard Worker 			return Generation::WIFI_STANDARD_11AX;
940*03f9172cSAndroid Build Coastguard Worker 		}
941*03f9172cSAndroid Build Coastguard Worker 		return current_mode->vht_capab == 0 ?
942*03f9172cSAndroid Build Coastguard Worker 		       Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
943*03f9172cSAndroid Build Coastguard Worker 	case HOSTAPD_MODE_IEEE80211AD:
944*03f9172cSAndroid Build Coastguard Worker 		return Generation::WIFI_STANDARD_11AD;
945*03f9172cSAndroid Build Coastguard Worker 	default:
946*03f9172cSAndroid Build Coastguard Worker 		return Generation::WIFI_STANDARD_UNKNOWN;
947*03f9172cSAndroid Build Coastguard Worker 	}
948*03f9172cSAndroid Build Coastguard Worker }
949*03f9172cSAndroid Build Coastguard Worker 
getChannelBandwidth(struct hostapd_config * iconf)950*03f9172cSAndroid Build Coastguard Worker ChannelBandwidth getChannelBandwidth(struct hostapd_config *iconf)
951*03f9172cSAndroid Build Coastguard Worker {
952*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_DEBUG, "getChannelBandwidth %d, isHT=%d, isHT40=%d",
953*03f9172cSAndroid Build Coastguard Worker 		   iconf->vht_oper_chwidth, iconf->ieee80211n,
954*03f9172cSAndroid Build Coastguard Worker 		   iconf->secondary_channel);
955*03f9172cSAndroid Build Coastguard Worker 	switch (iconf->vht_oper_chwidth) {
956*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_80MHZ:
957*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_80;
958*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_80P80MHZ:
959*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_80P80;
960*03f9172cSAndroid Build Coastguard Worker 		break;
961*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_160MHZ:
962*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_160;
963*03f9172cSAndroid Build Coastguard Worker 		break;
964*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_USE_HT:
965*03f9172cSAndroid Build Coastguard Worker 		if (iconf->ieee80211n) {
966*03f9172cSAndroid Build Coastguard Worker 			return iconf->secondary_channel != 0 ?
967*03f9172cSAndroid Build Coastguard Worker 				ChannelBandwidth::BANDWIDTH_40 : ChannelBandwidth::BANDWIDTH_20;
968*03f9172cSAndroid Build Coastguard Worker 		}
969*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_20_NOHT;
970*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_2160MHZ:
971*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_2160;
972*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_4320MHZ:
973*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_4320;
974*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_6480MHZ:
975*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_6480;
976*03f9172cSAndroid Build Coastguard Worker 	case CONF_OPER_CHWIDTH_8640MHZ:
977*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_8640;
978*03f9172cSAndroid Build Coastguard Worker 	default:
979*03f9172cSAndroid Build Coastguard Worker 		return ChannelBandwidth::BANDWIDTH_INVALID;
980*03f9172cSAndroid Build Coastguard Worker 	}
981*03f9172cSAndroid Build Coastguard Worker }
982*03f9172cSAndroid Build Coastguard Worker 
getStaInfoByMacAddr(const struct hostapd_data * iface_hapd,const u8 * mac_addr)983*03f9172cSAndroid Build Coastguard Worker std::optional<struct sta_info*> getStaInfoByMacAddr(const struct hostapd_data* iface_hapd,
984*03f9172cSAndroid Build Coastguard Worker 		const u8 *mac_addr) {
985*03f9172cSAndroid Build Coastguard Worker 	if (iface_hapd == nullptr || mac_addr == nullptr){
986*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "nullptr passsed to getStaInfoByMacAddr!");
987*03f9172cSAndroid Build Coastguard Worker 		return std::nullopt;
988*03f9172cSAndroid Build Coastguard Worker 	}
989*03f9172cSAndroid Build Coastguard Worker 
990*03f9172cSAndroid Build Coastguard Worker 	for (struct sta_info* sta_ptr = iface_hapd->sta_list; sta_ptr; sta_ptr = sta_ptr->next) {
991*03f9172cSAndroid Build Coastguard Worker 		int res;
992*03f9172cSAndroid Build Coastguard Worker 		res = memcmp(sta_ptr->addr, mac_addr, ETH_ALEN);
993*03f9172cSAndroid Build Coastguard Worker 		if (res == 0) {
994*03f9172cSAndroid Build Coastguard Worker 			return sta_ptr;
995*03f9172cSAndroid Build Coastguard Worker 		}
996*03f9172cSAndroid Build Coastguard Worker 	}
997*03f9172cSAndroid Build Coastguard Worker 	return std::nullopt;
998*03f9172cSAndroid Build Coastguard Worker }
999*03f9172cSAndroid Build Coastguard Worker 
forceStaDisconnection(struct hostapd_data * hapd,const std::vector<uint8_t> & client_address,const uint16_t reason_code)1000*03f9172cSAndroid Build Coastguard Worker bool forceStaDisconnection(struct hostapd_data* hapd,
1001*03f9172cSAndroid Build Coastguard Worker 			   const std::vector<uint8_t>& client_address,
1002*03f9172cSAndroid Build Coastguard Worker 			   const uint16_t reason_code) {
1003*03f9172cSAndroid Build Coastguard Worker 	if (client_address.size() != ETH_ALEN) {
1004*03f9172cSAndroid Build Coastguard Worker 		return false;
1005*03f9172cSAndroid Build Coastguard Worker 	}
1006*03f9172cSAndroid Build Coastguard Worker 
1007*03f9172cSAndroid Build Coastguard Worker 	auto sta_ptr_optional = getStaInfoByMacAddr(hapd, client_address.data());
1008*03f9172cSAndroid Build Coastguard Worker 	if (sta_ptr_optional.has_value()) {
1009*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
1010*03f9172cSAndroid Build Coastguard Worker 				MAC2STR(client_address.data()), reason_code);
1011*03f9172cSAndroid Build Coastguard Worker 		ap_sta_disconnect(hapd, sta_ptr_optional.value(), sta_ptr_optional.value()->addr,
1012*03f9172cSAndroid Build Coastguard Worker 				reason_code);
1013*03f9172cSAndroid Build Coastguard Worker 		return true;
1014*03f9172cSAndroid Build Coastguard Worker 	}
1015*03f9172cSAndroid Build Coastguard Worker 
1016*03f9172cSAndroid Build Coastguard Worker 	return false;
1017*03f9172cSAndroid Build Coastguard Worker }
1018*03f9172cSAndroid Build Coastguard Worker 
1019*03f9172cSAndroid Build Coastguard Worker // hostapd core functions accept "C" style function pointers, so use global
1020*03f9172cSAndroid Build Coastguard Worker // functions to pass to the hostapd core function and store the corresponding
1021*03f9172cSAndroid Build Coastguard Worker // std::function methods to be invoked.
1022*03f9172cSAndroid Build Coastguard Worker //
1023*03f9172cSAndroid Build Coastguard Worker // NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
1024*03f9172cSAndroid Build Coastguard Worker //
1025*03f9172cSAndroid Build Coastguard Worker // Callback to be invoked once setup is complete
1026*03f9172cSAndroid Build Coastguard Worker std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
onAsyncSetupCompleteCb(void * ctx)1027*03f9172cSAndroid Build Coastguard Worker void onAsyncSetupCompleteCb(void* ctx)
1028*03f9172cSAndroid Build Coastguard Worker {
1029*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
1030*03f9172cSAndroid Build Coastguard Worker 	if (on_setup_complete_internal_callback) {
1031*03f9172cSAndroid Build Coastguard Worker 		on_setup_complete_internal_callback(iface_hapd);
1032*03f9172cSAndroid Build Coastguard Worker 		// Invalidate this callback since we don't want this firing
1033*03f9172cSAndroid Build Coastguard Worker 		// again in single AP mode.
1034*03f9172cSAndroid Build Coastguard Worker 		if (strlen(iface_hapd->conf->bridge) > 0) {
1035*03f9172cSAndroid Build Coastguard Worker 			on_setup_complete_internal_callback = nullptr;
1036*03f9172cSAndroid Build Coastguard Worker 		}
1037*03f9172cSAndroid Build Coastguard Worker 	}
1038*03f9172cSAndroid Build Coastguard Worker }
1039*03f9172cSAndroid Build Coastguard Worker 
1040*03f9172cSAndroid Build Coastguard Worker // Callback to be invoked on hotspot client connection/disconnection
1041*03f9172cSAndroid Build Coastguard Worker std::function<void(struct hostapd_data*, const u8 *mac_addr, int authorized,
1042*03f9172cSAndroid Build Coastguard Worker 		const u8 *p2p_dev_addr)> on_sta_authorized_internal_callback;
onAsyncStaAuthorizedCb(void * ctx,const u8 * mac_addr,int authorized,const u8 * p2p_dev_addr,const u8 * ip)1043*03f9172cSAndroid Build Coastguard Worker void onAsyncStaAuthorizedCb(void* ctx, const u8 *mac_addr, int authorized,
1044*03f9172cSAndroid Build Coastguard Worker 		const u8 *p2p_dev_addr, const u8 *ip)
1045*03f9172cSAndroid Build Coastguard Worker {
1046*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
1047*03f9172cSAndroid Build Coastguard Worker 	if (on_sta_authorized_internal_callback) {
1048*03f9172cSAndroid Build Coastguard Worker 		on_sta_authorized_internal_callback(iface_hapd, mac_addr,
1049*03f9172cSAndroid Build Coastguard Worker 			authorized, p2p_dev_addr);
1050*03f9172cSAndroid Build Coastguard Worker 	}
1051*03f9172cSAndroid Build Coastguard Worker }
1052*03f9172cSAndroid Build Coastguard Worker 
1053*03f9172cSAndroid Build Coastguard Worker std::function<void(struct hostapd_data*, int level,
1054*03f9172cSAndroid Build Coastguard Worker 			enum wpa_msg_type type, const char *txt,
1055*03f9172cSAndroid Build Coastguard Worker 			size_t len)> on_wpa_msg_internal_callback;
1056*03f9172cSAndroid Build Coastguard Worker 
onAsyncWpaEventCb(void * ctx,int level,enum wpa_msg_type type,const char * txt,size_t len)1057*03f9172cSAndroid Build Coastguard Worker void onAsyncWpaEventCb(void *ctx, int level,
1058*03f9172cSAndroid Build Coastguard Worker 			enum wpa_msg_type type, const char *txt,
1059*03f9172cSAndroid Build Coastguard Worker 			size_t len)
1060*03f9172cSAndroid Build Coastguard Worker {
1061*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
1062*03f9172cSAndroid Build Coastguard Worker 	if (on_wpa_msg_internal_callback) {
1063*03f9172cSAndroid Build Coastguard Worker 		on_wpa_msg_internal_callback(iface_hapd, level,
1064*03f9172cSAndroid Build Coastguard Worker 					type, txt, len);
1065*03f9172cSAndroid Build Coastguard Worker 	}
1066*03f9172cSAndroid Build Coastguard Worker }
1067*03f9172cSAndroid Build Coastguard Worker 
createStatus(HostapdStatusCode status_code)1068*03f9172cSAndroid Build Coastguard Worker inline ndk::ScopedAStatus createStatus(HostapdStatusCode status_code) {
1069*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::fromServiceSpecificError(
1070*03f9172cSAndroid Build Coastguard Worker 		static_cast<int32_t>(status_code));
1071*03f9172cSAndroid Build Coastguard Worker }
1072*03f9172cSAndroid Build Coastguard Worker 
createStatusWithMsg(HostapdStatusCode status_code,std::string msg)1073*03f9172cSAndroid Build Coastguard Worker inline ndk::ScopedAStatus createStatusWithMsg(
1074*03f9172cSAndroid Build Coastguard Worker 	HostapdStatusCode status_code, std::string msg)
1075*03f9172cSAndroid Build Coastguard Worker {
1076*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
1077*03f9172cSAndroid Build Coastguard Worker 		static_cast<int32_t>(status_code), msg.c_str());
1078*03f9172cSAndroid Build Coastguard Worker }
1079*03f9172cSAndroid Build Coastguard Worker 
1080*03f9172cSAndroid Build Coastguard Worker // Method called by death_notifier_ on client death.
onDeath(void * cookie)1081*03f9172cSAndroid Build Coastguard Worker void onDeath(void* cookie) {
1082*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_ERROR, "Client died. Terminating...");
1083*03f9172cSAndroid Build Coastguard Worker 	eloop_terminate();
1084*03f9172cSAndroid Build Coastguard Worker }
1085*03f9172cSAndroid Build Coastguard Worker 
1086*03f9172cSAndroid Build Coastguard Worker }  // namespace
1087*03f9172cSAndroid Build Coastguard Worker 
1088*03f9172cSAndroid Build Coastguard Worker namespace aidl {
1089*03f9172cSAndroid Build Coastguard Worker namespace android {
1090*03f9172cSAndroid Build Coastguard Worker namespace hardware {
1091*03f9172cSAndroid Build Coastguard Worker namespace wifi {
1092*03f9172cSAndroid Build Coastguard Worker namespace hostapd {
1093*03f9172cSAndroid Build Coastguard Worker 
Hostapd(struct hapd_interfaces * interfaces)1094*03f9172cSAndroid Build Coastguard Worker Hostapd::Hostapd(struct hapd_interfaces* interfaces)
1095*03f9172cSAndroid Build Coastguard Worker 	: interfaces_(interfaces)
1096*03f9172cSAndroid Build Coastguard Worker {
1097*03f9172cSAndroid Build Coastguard Worker 	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
1098*03f9172cSAndroid Build Coastguard Worker }
1099*03f9172cSAndroid Build Coastguard Worker 
addAccessPoint(const IfaceParams & iface_params,const NetworkParams & nw_params)1100*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::addAccessPoint(
1101*03f9172cSAndroid Build Coastguard Worker 	const IfaceParams& iface_params, const NetworkParams& nw_params)
1102*03f9172cSAndroid Build Coastguard Worker {
1103*03f9172cSAndroid Build Coastguard Worker 	return addAccessPointInternal(iface_params, nw_params);
1104*03f9172cSAndroid Build Coastguard Worker }
1105*03f9172cSAndroid Build Coastguard Worker 
removeAccessPoint(const std::string & iface_name)1106*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::removeAccessPoint(const std::string& iface_name)
1107*03f9172cSAndroid Build Coastguard Worker {
1108*03f9172cSAndroid Build Coastguard Worker 	return removeAccessPointInternal(iface_name);
1109*03f9172cSAndroid Build Coastguard Worker }
1110*03f9172cSAndroid Build Coastguard Worker 
terminate()1111*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::terminate()
1112*03f9172cSAndroid Build Coastguard Worker {
1113*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Terminating...");
1114*03f9172cSAndroid Build Coastguard Worker 	// Clear the callback to avoid IPCThreadState shutdown during the
1115*03f9172cSAndroid Build Coastguard Worker 	// callback event.
1116*03f9172cSAndroid Build Coastguard Worker 	callbacks_.clear();
1117*03f9172cSAndroid Build Coastguard Worker 	eloop_terminate();
1118*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1119*03f9172cSAndroid Build Coastguard Worker }
1120*03f9172cSAndroid Build Coastguard Worker 
registerCallback(const std::shared_ptr<IHostapdCallback> & callback)1121*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::registerCallback(
1122*03f9172cSAndroid Build Coastguard Worker 	const std::shared_ptr<IHostapdCallback>& callback)
1123*03f9172cSAndroid Build Coastguard Worker {
1124*03f9172cSAndroid Build Coastguard Worker 	return registerCallbackInternal(callback);
1125*03f9172cSAndroid Build Coastguard Worker }
1126*03f9172cSAndroid Build Coastguard Worker 
forceClientDisconnect(const std::string & iface_name,const std::vector<uint8_t> & client_address,Ieee80211ReasonCode reason_code)1127*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::forceClientDisconnect(
1128*03f9172cSAndroid Build Coastguard Worker 	const std::string& iface_name, const std::vector<uint8_t>& client_address,
1129*03f9172cSAndroid Build Coastguard Worker 	Ieee80211ReasonCode reason_code)
1130*03f9172cSAndroid Build Coastguard Worker {
1131*03f9172cSAndroid Build Coastguard Worker 	return forceClientDisconnectInternal(iface_name, client_address, reason_code);
1132*03f9172cSAndroid Build Coastguard Worker }
1133*03f9172cSAndroid Build Coastguard Worker 
setDebugParams(DebugLevel level)1134*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::setDebugParams(DebugLevel level)
1135*03f9172cSAndroid Build Coastguard Worker {
1136*03f9172cSAndroid Build Coastguard Worker 	return setDebugParamsInternal(level);
1137*03f9172cSAndroid Build Coastguard Worker }
1138*03f9172cSAndroid Build Coastguard Worker 
removeLinkFromMultipleLinkBridgedApIface(const std::string & iface_name,const std::string & linkIdentity)1139*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::removeLinkFromMultipleLinkBridgedApIface(
1140*03f9172cSAndroid Build Coastguard Worker         const std::string& iface_name, const std::string& linkIdentity)
1141*03f9172cSAndroid Build Coastguard Worker {
1142*03f9172cSAndroid Build Coastguard Worker 	return removeLinkFromMultipleLinkBridgedApIfaceInternal(iface_name, linkIdentity);
1143*03f9172cSAndroid Build Coastguard Worker }
1144*03f9172cSAndroid Build Coastguard Worker 
addAccessPointInternal(const IfaceParams & iface_params,const NetworkParams & nw_params)1145*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::addAccessPointInternal(
1146*03f9172cSAndroid Build Coastguard Worker 	const IfaceParams& iface_params,
1147*03f9172cSAndroid Build Coastguard Worker 	const NetworkParams& nw_params)
1148*03f9172cSAndroid Build Coastguard Worker {
1149*03f9172cSAndroid Build Coastguard Worker 	int channelParamsSize = iface_params.channelParams.size();
1150*03f9172cSAndroid Build Coastguard Worker 	if (channelParamsSize == 1) {
1151*03f9172cSAndroid Build Coastguard Worker 		// Single AP
1152*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_INFO, "AddSingleAccessPoint, iface=%s",
1153*03f9172cSAndroid Build Coastguard Worker 			iface_params.name.c_str());
1154*03f9172cSAndroid Build Coastguard Worker 		return addSingleAccessPoint(iface_params, iface_params.channelParams[0],
1155*03f9172cSAndroid Build Coastguard Worker 		    nw_params, "", "");
1156*03f9172cSAndroid Build Coastguard Worker 	} else if (channelParamsSize == 2) {
1157*03f9172cSAndroid Build Coastguard Worker 		// Concurrent APs
1158*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_INFO, "AddDualAccessPoint, iface=%s",
1159*03f9172cSAndroid Build Coastguard Worker 			iface_params.name.c_str());
1160*03f9172cSAndroid Build Coastguard Worker 		return addConcurrentAccessPoints(iface_params, nw_params);
1161*03f9172cSAndroid Build Coastguard Worker 	}
1162*03f9172cSAndroid Build Coastguard Worker 	return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
1163*03f9172cSAndroid Build Coastguard Worker }
1164*03f9172cSAndroid Build Coastguard Worker 
generateRandomOweSsid()1165*03f9172cSAndroid Build Coastguard Worker std::vector<uint8_t>  generateRandomOweSsid()
1166*03f9172cSAndroid Build Coastguard Worker {
1167*03f9172cSAndroid Build Coastguard Worker 	u8 random[8] = {0};
1168*03f9172cSAndroid Build Coastguard Worker 	os_get_random(random, 8);
1169*03f9172cSAndroid Build Coastguard Worker 
1170*03f9172cSAndroid Build Coastguard Worker 	std::string ssid = StringPrintf("Owe-%s", random);
1171*03f9172cSAndroid Build Coastguard Worker 	wpa_printf(MSG_INFO, "Generated OWE SSID: %s", ssid.c_str());
1172*03f9172cSAndroid Build Coastguard Worker 	std::vector<uint8_t> vssid(ssid.begin(), ssid.end());
1173*03f9172cSAndroid Build Coastguard Worker 
1174*03f9172cSAndroid Build Coastguard Worker 	return vssid;
1175*03f9172cSAndroid Build Coastguard Worker }
1176*03f9172cSAndroid Build Coastguard Worker 
1177*03f9172cSAndroid Build Coastguard Worker 
1178*03f9172cSAndroid Build Coastguard Worker // Both of bridged dual APs and MLO AP will be treated as concurrenct APs.
1179*03f9172cSAndroid Build Coastguard Worker // -----------------------------------------
1180*03f9172cSAndroid Build Coastguard Worker //                  | br_name     |  instance#1 | instance#2 |
1181*03f9172cSAndroid Build Coastguard Worker // ___________________________________________________________
1182*03f9172cSAndroid Build Coastguard Worker // bridged dual APs | ap_br_wlanX |   wlan X    |   wlanY    |
1183*03f9172cSAndroid Build Coastguard Worker // ___________________________________________________________
1184*03f9172cSAndroid Build Coastguard Worker // MLO AP           | wlanX       |     0       |     1      |
1185*03f9172cSAndroid Build Coastguard Worker // ___________________________________________________________
1186*03f9172cSAndroid Build Coastguard Worker // Both will be added in br_interfaces_[$br_name] and use instance's name
1187*03f9172cSAndroid Build Coastguard Worker // to be iface_params_new.name to create single Access point.
addConcurrentAccessPoints(const IfaceParams & iface_params,const NetworkParams & nw_params)1188*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::addConcurrentAccessPoints(
1189*03f9172cSAndroid Build Coastguard Worker 	const IfaceParams& iface_params, const NetworkParams& nw_params)
1190*03f9172cSAndroid Build Coastguard Worker {
1191*03f9172cSAndroid Build Coastguard Worker 	int channelParamsListSize = iface_params.channelParams.size();
1192*03f9172cSAndroid Build Coastguard Worker 	// Get available interfaces in bridge
1193*03f9172cSAndroid Build Coastguard Worker 	std::vector<std::string> managed_instances;
1194*03f9172cSAndroid Build Coastguard Worker 	std::string br_name = StringPrintf("%s", iface_params.name.c_str());
1195*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.usesMlo) {
1196*03f9172cSAndroid Build Coastguard Worker 		// MLO AP is using link id as instance.
1197*03f9172cSAndroid Build Coastguard Worker 		for (std::size_t i = 0; i < iface_params.instanceIdentities->size(); i++) {
1198*03f9172cSAndroid Build Coastguard Worker 			managed_instances.push_back(iface_params.instanceIdentities->at(i)->c_str());
1199*03f9172cSAndroid Build Coastguard Worker 		}
1200*03f9172cSAndroid Build Coastguard Worker 	} else {
1201*03f9172cSAndroid Build Coastguard Worker 		if (!GetInterfacesInBridge(br_name, &managed_instances)) {
1202*03f9172cSAndroid Build Coastguard Worker 			return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
1203*03f9172cSAndroid Build Coastguard Worker 					"Get interfaces in bridge failed.");
1204*03f9172cSAndroid Build Coastguard Worker 		}
1205*03f9172cSAndroid Build Coastguard Worker 	}
1206*03f9172cSAndroid Build Coastguard Worker 	// Either bridged AP or MLO AP should have two instances.
1207*03f9172cSAndroid Build Coastguard Worker 	if (managed_instances.size() < channelParamsListSize) {
1208*03f9172cSAndroid Build Coastguard Worker 		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
1209*03f9172cSAndroid Build Coastguard Worker 				"Available interfaces less than requested bands");
1210*03f9172cSAndroid Build Coastguard Worker 	}
1211*03f9172cSAndroid Build Coastguard Worker 
1212*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.usesMlo
1213*03f9172cSAndroid Build Coastguard Worker 				&& nw_params.encryptionType == EncryptionType::WPA3_OWE_TRANSITION) {
1214*03f9172cSAndroid Build Coastguard Worker 		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
1215*03f9172cSAndroid Build Coastguard Worker 				"Invalid encryptionType (OWE transition) for MLO SAP.");
1216*03f9172cSAndroid Build Coastguard Worker 	}
1217*03f9172cSAndroid Build Coastguard Worker 	// start BSS on specified bands
1218*03f9172cSAndroid Build Coastguard Worker 	for (std::size_t i = 0; i < channelParamsListSize; i ++) {
1219*03f9172cSAndroid Build Coastguard Worker 		IfaceParams iface_params_new = iface_params;
1220*03f9172cSAndroid Build Coastguard Worker 		NetworkParams nw_params_new = nw_params;
1221*03f9172cSAndroid Build Coastguard Worker 		std::string owe_transition_ifname = "";
1222*03f9172cSAndroid Build Coastguard Worker 		iface_params_new.name = managed_instances[i];
1223*03f9172cSAndroid Build Coastguard Worker 		if (nw_params.encryptionType == EncryptionType::WPA3_OWE_TRANSITION) {
1224*03f9172cSAndroid Build Coastguard Worker 			if (i == 0 && i+1 < channelParamsListSize) {
1225*03f9172cSAndroid Build Coastguard Worker 				owe_transition_ifname = managed_instances[i+1];
1226*03f9172cSAndroid Build Coastguard Worker 				nw_params_new.encryptionType = EncryptionType::NONE;
1227*03f9172cSAndroid Build Coastguard Worker 			} else {
1228*03f9172cSAndroid Build Coastguard Worker 				owe_transition_ifname = managed_instances[0];
1229*03f9172cSAndroid Build Coastguard Worker 				nw_params_new.isHidden = true;
1230*03f9172cSAndroid Build Coastguard Worker 				nw_params_new.ssid = generateRandomOweSsid();
1231*03f9172cSAndroid Build Coastguard Worker 			}
1232*03f9172cSAndroid Build Coastguard Worker 		}
1233*03f9172cSAndroid Build Coastguard Worker 
1234*03f9172cSAndroid Build Coastguard Worker 		ndk::ScopedAStatus status = addSingleAccessPoint(
1235*03f9172cSAndroid Build Coastguard Worker 		    iface_params_new, iface_params.channelParams[i], nw_params_new,
1236*03f9172cSAndroid Build Coastguard Worker 		    br_name, owe_transition_ifname);
1237*03f9172cSAndroid Build Coastguard Worker 		if (!status.isOk()) {
1238*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_ERROR, "Failed to addAccessPoint %s",
1239*03f9172cSAndroid Build Coastguard Worker 				   managed_instances[i].c_str());
1240*03f9172cSAndroid Build Coastguard Worker 			return status;
1241*03f9172cSAndroid Build Coastguard Worker 		}
1242*03f9172cSAndroid Build Coastguard Worker 	}
1243*03f9172cSAndroid Build Coastguard Worker 
1244*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.usesMlo) {
1245*03f9172cSAndroid Build Coastguard Worker 		std::size_t i = 0;
1246*03f9172cSAndroid Build Coastguard Worker 		std::size_t j = 0;
1247*03f9172cSAndroid Build Coastguard Worker 		for (i = 0; i < interfaces_->count; i++) {
1248*03f9172cSAndroid Build Coastguard Worker 			struct hostapd_iface *iface = interfaces_->iface[i];
1249*03f9172cSAndroid Build Coastguard Worker 
1250*03f9172cSAndroid Build Coastguard Worker 			for (j = 0; j < iface->num_bss; j++) {
1251*03f9172cSAndroid Build Coastguard Worker 				struct hostapd_data *iface_hapd = iface->bss[j];
1252*03f9172cSAndroid Build Coastguard Worker 				if (hostapd_enable_iface(iface_hapd->iface) < 0) {
1253*03f9172cSAndroid Build Coastguard Worker 					wpa_printf(
1254*03f9172cSAndroid Build Coastguard Worker 					MSG_ERROR, "Enabling interface %s failed on %zu",
1255*03f9172cSAndroid Build Coastguard Worker 						iface_params.name.c_str(), i);
1256*03f9172cSAndroid Build Coastguard Worker 					return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1257*03f9172cSAndroid Build Coastguard Worker 				}
1258*03f9172cSAndroid Build Coastguard Worker 			}
1259*03f9172cSAndroid Build Coastguard Worker 		}
1260*03f9172cSAndroid Build Coastguard Worker     }
1261*03f9172cSAndroid Build Coastguard Worker 	// Save bridge interface info
1262*03f9172cSAndroid Build Coastguard Worker 	br_interfaces_[br_name] = managed_instances;
1263*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1264*03f9172cSAndroid Build Coastguard Worker }
1265*03f9172cSAndroid Build Coastguard Worker 
hostapd_get_iface_by_link_id(struct hapd_interfaces * interfaces,const size_t link_id)1266*03f9172cSAndroid Build Coastguard Worker struct hostapd_data * hostapd_get_iface_by_link_id(struct hapd_interfaces *interfaces,
1267*03f9172cSAndroid Build Coastguard Worker 					const size_t link_id)
1268*03f9172cSAndroid Build Coastguard Worker {
1269*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
1270*03f9172cSAndroid Build Coastguard Worker 	size_t i, j;
1271*03f9172cSAndroid Build Coastguard Worker 
1272*03f9172cSAndroid Build Coastguard Worker 	for (i = 0; i < interfaces->count; i++) {
1273*03f9172cSAndroid Build Coastguard Worker 		struct hostapd_iface *iface = interfaces->iface[i];
1274*03f9172cSAndroid Build Coastguard Worker 
1275*03f9172cSAndroid Build Coastguard Worker 		for (j = 0; j < iface->num_bss; j++) {
1276*03f9172cSAndroid Build Coastguard Worker 			struct hostapd_data *hapd = iface->bss[j];
1277*03f9172cSAndroid Build Coastguard Worker 
1278*03f9172cSAndroid Build Coastguard Worker 			if (link_id == hapd->mld_link_id)
1279*03f9172cSAndroid Build Coastguard Worker 				return hapd;
1280*03f9172cSAndroid Build Coastguard Worker 		}
1281*03f9172cSAndroid Build Coastguard Worker 	}
1282*03f9172cSAndroid Build Coastguard Worker #endif
1283*03f9172cSAndroid Build Coastguard Worker 	return NULL;
1284*03f9172cSAndroid Build Coastguard Worker }
1285*03f9172cSAndroid Build Coastguard Worker 
1286*03f9172cSAndroid Build Coastguard Worker // Both of bridged dual APs and MLO AP will be treated as concurrenct APs.
1287*03f9172cSAndroid Build Coastguard Worker // -----------------------------------------
1288*03f9172cSAndroid Build Coastguard Worker //                  | br_name                 |  iface_params.name
1289*03f9172cSAndroid Build Coastguard Worker // _______________________________________________________________
1290*03f9172cSAndroid Build Coastguard Worker // bridged dual APs | bridged interface name  |  interface name
1291*03f9172cSAndroid Build Coastguard Worker // _______________________________________________________________
1292*03f9172cSAndroid Build Coastguard Worker // MLO AP           | AP interface name       |  mld link id as instance name
1293*03f9172cSAndroid Build Coastguard Worker // _______________________________________________________________
addSingleAccessPoint(const IfaceParams & iface_params,const ChannelParams & channelParams,const NetworkParams & nw_params,const std::string br_name,const std::string owe_transition_ifname)1294*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::addSingleAccessPoint(
1295*03f9172cSAndroid Build Coastguard Worker 	const IfaceParams& iface_params,
1296*03f9172cSAndroid Build Coastguard Worker 	const ChannelParams& channelParams,
1297*03f9172cSAndroid Build Coastguard Worker 	const NetworkParams& nw_params,
1298*03f9172cSAndroid Build Coastguard Worker 	const std::string br_name,
1299*03f9172cSAndroid Build Coastguard Worker 	const std::string owe_transition_ifname)
1300*03f9172cSAndroid Build Coastguard Worker {
1301*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.usesMlo) { // the mlo case, iface name is instance name which is mld_link_id
1302*03f9172cSAndroid Build Coastguard Worker 		if (hostapd_get_iface_by_link_id(interfaces_, (size_t) iface_params.name.c_str())) {
1303*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(
1304*03f9172cSAndroid Build Coastguard Worker 				MSG_ERROR, "Instance link id %s already present",
1305*03f9172cSAndroid Build Coastguard Worker 				iface_params.name.c_str());
1306*03f9172cSAndroid Build Coastguard Worker 			return createStatus(HostapdStatusCode::FAILURE_IFACE_EXISTS);
1307*03f9172cSAndroid Build Coastguard Worker 		}
1308*03f9172cSAndroid Build Coastguard Worker 	}
1309*03f9172cSAndroid Build Coastguard Worker 	if (hostapd_get_iface(interfaces_,
1310*03f9172cSAndroid Build Coastguard Worker 			iface_params.usesMlo ? br_name.c_str() : iface_params.name.c_str())) {
1311*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(
1312*03f9172cSAndroid Build Coastguard Worker 			MSG_ERROR, "Instance interface %s already present",
1313*03f9172cSAndroid Build Coastguard Worker 			iface_params.usesMlo ? br_name.c_str() : iface_params.name.c_str());
1314*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_IFACE_EXISTS);
1315*03f9172cSAndroid Build Coastguard Worker 	}
1316*03f9172cSAndroid Build Coastguard Worker 	const auto conf_params = CreateHostapdConfig(iface_params, channelParams, nw_params,
1317*03f9172cSAndroid Build Coastguard Worker 					br_name, owe_transition_ifname);
1318*03f9172cSAndroid Build Coastguard Worker 	if (conf_params.empty()) {
1319*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Failed to create config params");
1320*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
1321*03f9172cSAndroid Build Coastguard Worker 	}
1322*03f9172cSAndroid Build Coastguard Worker 	const auto conf_file_path =
1323*03f9172cSAndroid Build Coastguard Worker 		WriteHostapdConfig(iface_params.name, conf_params, br_name, iface_params.usesMlo);
1324*03f9172cSAndroid Build Coastguard Worker 	if (conf_file_path.empty()) {
1325*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Failed to write config file");
1326*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1327*03f9172cSAndroid Build Coastguard Worker 	}
1328*03f9172cSAndroid Build Coastguard Worker 	std::string add_iface_param_str = StringPrintf(
1329*03f9172cSAndroid Build Coastguard Worker 		"%s config=%s", iface_params.usesMlo ? br_name.c_str(): iface_params.name.c_str(),
1330*03f9172cSAndroid Build Coastguard Worker 		conf_file_path.c_str());
1331*03f9172cSAndroid Build Coastguard Worker 	std::vector<char> add_iface_param_vec(
1332*03f9172cSAndroid Build Coastguard Worker 		add_iface_param_str.begin(), add_iface_param_str.end() + 1);
1333*03f9172cSAndroid Build Coastguard Worker 	if (hostapd_add_iface(interfaces_, add_iface_param_vec.data()) < 0) {
1334*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(
1335*03f9172cSAndroid Build Coastguard Worker 			MSG_ERROR, "Adding hostapd iface %s failed",
1336*03f9172cSAndroid Build Coastguard Worker 			add_iface_param_str.c_str());
1337*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1338*03f9172cSAndroid Build Coastguard Worker 	}
1339*03f9172cSAndroid Build Coastguard Worker 
1340*03f9172cSAndroid Build Coastguard Worker 	// find the iface and set up callback.
1341*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data* iface_hapd = iface_params.usesMlo ?
1342*03f9172cSAndroid Build Coastguard Worker 		hostapd_get_iface_by_link_id(interfaces_, (size_t) iface_params.name.c_str()) :
1343*03f9172cSAndroid Build Coastguard Worker 		hostapd_get_iface(interfaces_, iface_params.name.c_str());
1344*03f9172cSAndroid Build Coastguard Worker 	WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
1345*03f9172cSAndroid Build Coastguard Worker 	if (iface_params.usesMlo) {
1346*03f9172cSAndroid Build Coastguard Worker 		memcmp(iface_hapd->conf->iface, br_name.c_str(), br_name.size());
1347*03f9172cSAndroid Build Coastguard Worker 	}
1348*03f9172cSAndroid Build Coastguard Worker 
1349*03f9172cSAndroid Build Coastguard Worker 	// Callback discrepancy between bridged dual APs and MLO AP
1350*03f9172cSAndroid Build Coastguard Worker 	// Note: Only bridged dual APs will have "iface_hapd->conf->bridge" and
1351*03f9172cSAndroid Build Coastguard Worker 	// Only MLO AP will have "iface_hapd->mld_link_id"
1352*03f9172cSAndroid Build Coastguard Worker 	// Register the setup complete callbacks
1353*03f9172cSAndroid Build Coastguard Worker 	// -----------------------------------------
1354*03f9172cSAndroid Build Coastguard Worker 	//                    |   bridged dual APs     | bridged single link MLO | MLO SAP
1355*03f9172cSAndroid Build Coastguard Worker 	// _________________________________________________________________________________________
1356*03f9172cSAndroid Build Coastguard Worker 	// hapd->conf->bridge | bridged interface name |  bridged interface nam  | N/A
1357*03f9172cSAndroid Build Coastguard Worker 	// _________________________________________________________________________________________
1358*03f9172cSAndroid Build Coastguard Worker 	// hapd->conf->iface  | AP interface name      |  AP interface name      | AP interface name
1359*03f9172cSAndroid Build Coastguard Worker 	// _________________________________________________________________________________________
1360*03f9172cSAndroid Build Coastguard Worker 	// hapd->mld_link_id  | 0 (default value)      |      link id (0)        | link id (0 or 1)
1361*03f9172cSAndroid Build Coastguard Worker 	// _________________________________________________________________________________________
1362*03f9172cSAndroid Build Coastguard Worker 	// hapd->mld_ap       |         0              |            1            |     1
1363*03f9172cSAndroid Build Coastguard Worker 	on_setup_complete_internal_callback =
1364*03f9172cSAndroid Build Coastguard Worker 		[this](struct hostapd_data* iface_hapd) {
1365*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(
1366*03f9172cSAndroid Build Coastguard Worker 			MSG_INFO, "AP interface setup completed - state %s",
1367*03f9172cSAndroid Build Coastguard Worker 			hostapd_state_text(iface_hapd->iface->state));
1368*03f9172cSAndroid Build Coastguard Worker 			if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
1369*03f9172cSAndroid Build Coastguard Worker 				// Invoke the failure callback on all registered
1370*03f9172cSAndroid Build Coastguard Worker 				// clients.
1371*03f9172cSAndroid Build Coastguard Worker 				std::string instanceName = iface_hapd->conf->iface;
1372*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
1373*03f9172cSAndroid Build Coastguard Worker 				if (iface_hapd->conf->mld_ap
1374*03f9172cSAndroid Build Coastguard Worker 						&& strlen(iface_hapd->conf->bridge) == 0) {
1375*03f9172cSAndroid Build Coastguard Worker 					instanceName = std::to_string(iface_hapd->mld_link_id);
1376*03f9172cSAndroid Build Coastguard Worker 				}
1377*03f9172cSAndroid Build Coastguard Worker #endif
1378*03f9172cSAndroid Build Coastguard Worker 				for (const auto& callback : callbacks_) {
1379*03f9172cSAndroid Build Coastguard Worker 					auto status = callback->onFailure(
1380*03f9172cSAndroid Build Coastguard Worker 						strlen(iface_hapd->conf->bridge) > 0 ?
1381*03f9172cSAndroid Build Coastguard Worker 						iface_hapd->conf->bridge : iface_hapd->conf->iface,
1382*03f9172cSAndroid Build Coastguard Worker 							    instanceName);
1383*03f9172cSAndroid Build Coastguard Worker 					if (!status.isOk()) {
1384*03f9172cSAndroid Build Coastguard Worker 						wpa_printf(MSG_ERROR, "Failed to invoke onFailure");
1385*03f9172cSAndroid Build Coastguard Worker 					}
1386*03f9172cSAndroid Build Coastguard Worker 				}
1387*03f9172cSAndroid Build Coastguard Worker 			}
1388*03f9172cSAndroid Build Coastguard Worker 		};
1389*03f9172cSAndroid Build Coastguard Worker 
1390*03f9172cSAndroid Build Coastguard Worker 	// Register for new client connect/disconnect indication.
1391*03f9172cSAndroid Build Coastguard Worker 	on_sta_authorized_internal_callback =
1392*03f9172cSAndroid Build Coastguard Worker 		[this](struct hostapd_data* iface_hapd, const u8 *mac_addr,
1393*03f9172cSAndroid Build Coastguard Worker 			int authorized, const u8 *p2p_dev_addr) {
1394*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "notify client " MACSTR " %s",
1395*03f9172cSAndroid Build Coastguard Worker 				MAC2STR(mac_addr),
1396*03f9172cSAndroid Build Coastguard Worker 				(authorized) ? "Connected" : "Disconnected");
1397*03f9172cSAndroid Build Coastguard Worker 		ClientInfo info;
1398*03f9172cSAndroid Build Coastguard Worker 		info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
1399*03f9172cSAndroid Build Coastguard Worker 			iface_hapd->conf->bridge : iface_hapd->conf->iface;
1400*03f9172cSAndroid Build Coastguard Worker 		std::string instanceName = iface_hapd->conf->iface;
1401*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
1402*03f9172cSAndroid Build Coastguard Worker 		if (iface_hapd->conf->mld_ap
1403*03f9172cSAndroid Build Coastguard Worker 				&& strlen(iface_hapd->conf->bridge) == 0) {
1404*03f9172cSAndroid Build Coastguard Worker 			instanceName = std::to_string(iface_hapd->mld_link_id);
1405*03f9172cSAndroid Build Coastguard Worker 		}
1406*03f9172cSAndroid Build Coastguard Worker #endif
1407*03f9172cSAndroid Build Coastguard Worker 		info.apIfaceInstance = instanceName;
1408*03f9172cSAndroid Build Coastguard Worker 		info.clientAddress.assign(mac_addr, mac_addr + ETH_ALEN);
1409*03f9172cSAndroid Build Coastguard Worker 		info.isConnected = authorized;
1410*03f9172cSAndroid Build Coastguard Worker 		if(isAidlServiceVersionAtLeast(3) && !authorized) {
1411*03f9172cSAndroid Build Coastguard Worker 			u16 disconnect_reason_code = WLAN_REASON_UNSPECIFIED;
1412*03f9172cSAndroid Build Coastguard Worker 			auto sta_ptr_optional = getStaInfoByMacAddr(iface_hapd, mac_addr);
1413*03f9172cSAndroid Build Coastguard Worker 			if (sta_ptr_optional.has_value()){
1414*03f9172cSAndroid Build Coastguard Worker 				disconnect_reason_code = sta_ptr_optional.value()->deauth_reason;
1415*03f9172cSAndroid Build Coastguard Worker 			}
1416*03f9172cSAndroid Build Coastguard Worker 			info.disconnectReasonCode =
1417*03f9172cSAndroid Build Coastguard Worker 					static_cast<common::DeauthenticationReasonCode>(disconnect_reason_code);
1418*03f9172cSAndroid Build Coastguard Worker 		}
1419*03f9172cSAndroid Build Coastguard Worker 		for (const auto &callback : callbacks_) {
1420*03f9172cSAndroid Build Coastguard Worker 			auto status = callback->onConnectedClientsChanged(info);
1421*03f9172cSAndroid Build Coastguard Worker 			if (!status.isOk()) {
1422*03f9172cSAndroid Build Coastguard Worker 				wpa_printf(MSG_ERROR, "Failed to invoke onConnectedClientsChanged");
1423*03f9172cSAndroid Build Coastguard Worker 			}
1424*03f9172cSAndroid Build Coastguard Worker 		}
1425*03f9172cSAndroid Build Coastguard Worker 		};
1426*03f9172cSAndroid Build Coastguard Worker 
1427*03f9172cSAndroid Build Coastguard Worker 	// Register for wpa_event which used to get channel switch event
1428*03f9172cSAndroid Build Coastguard Worker 	on_wpa_msg_internal_callback =
1429*03f9172cSAndroid Build Coastguard Worker 		[this](struct hostapd_data* iface_hapd, int level,
1430*03f9172cSAndroid Build Coastguard Worker 			enum wpa_msg_type type, const char *txt,
1431*03f9172cSAndroid Build Coastguard Worker 			size_t len) {
1432*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
1433*03f9172cSAndroid Build Coastguard Worker 		if (os_strncmp(txt, AP_EVENT_ENABLED,
1434*03f9172cSAndroid Build Coastguard Worker 					strlen(AP_EVENT_ENABLED)) == 0 ||
1435*03f9172cSAndroid Build Coastguard Worker 			os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
1436*03f9172cSAndroid Build Coastguard Worker 					strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
1437*03f9172cSAndroid Build Coastguard Worker 			std::string instanceName = iface_hapd->conf->iface;
1438*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
1439*03f9172cSAndroid Build Coastguard Worker 			if (iface_hapd->conf->mld_ap && strlen(iface_hapd->conf->bridge) == 0) {
1440*03f9172cSAndroid Build Coastguard Worker 				instanceName = std::to_string(iface_hapd->mld_link_id);
1441*03f9172cSAndroid Build Coastguard Worker 			}
1442*03f9172cSAndroid Build Coastguard Worker #endif
1443*03f9172cSAndroid Build Coastguard Worker 			ApInfo info;
1444*03f9172cSAndroid Build Coastguard Worker 			info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
1445*03f9172cSAndroid Build Coastguard Worker 				iface_hapd->conf->bridge : iface_hapd->conf->iface,
1446*03f9172cSAndroid Build Coastguard Worker 			info.apIfaceInstance = instanceName;
1447*03f9172cSAndroid Build Coastguard Worker 			info.freqMhz = iface_hapd->iface->freq;
1448*03f9172cSAndroid Build Coastguard Worker 			info.channelBandwidth = getChannelBandwidth(iface_hapd->iconf);
1449*03f9172cSAndroid Build Coastguard Worker 			info.generation = getGeneration(iface_hapd->iface->current_mode);
1450*03f9172cSAndroid Build Coastguard Worker 			info.apIfaceInstanceMacAddress.assign(iface_hapd->own_addr,
1451*03f9172cSAndroid Build Coastguard Worker 				iface_hapd->own_addr + ETH_ALEN);
1452*03f9172cSAndroid Build Coastguard Worker 			for (const auto &callback : callbacks_) {
1453*03f9172cSAndroid Build Coastguard Worker 				auto status = callback->onApInstanceInfoChanged(info);
1454*03f9172cSAndroid Build Coastguard Worker 				if (!status.isOk()) {
1455*03f9172cSAndroid Build Coastguard Worker 					wpa_printf(MSG_ERROR,
1456*03f9172cSAndroid Build Coastguard Worker 						   "Failed to invoke onApInstanceInfoChanged");
1457*03f9172cSAndroid Build Coastguard Worker 				}
1458*03f9172cSAndroid Build Coastguard Worker 			}
1459*03f9172cSAndroid Build Coastguard Worker 		} else if (os_strncmp(txt, AP_EVENT_DISABLED, strlen(AP_EVENT_DISABLED)) == 0
1460*03f9172cSAndroid Build Coastguard Worker                            || os_strncmp(txt, INTERFACE_DISABLED, strlen(INTERFACE_DISABLED)) == 0)
1461*03f9172cSAndroid Build Coastguard Worker 		{
1462*03f9172cSAndroid Build Coastguard Worker 			std::string instanceName = iface_hapd->conf->iface;
1463*03f9172cSAndroid Build Coastguard Worker #ifdef CONFIG_IEEE80211BE
1464*03f9172cSAndroid Build Coastguard Worker 			if (iface_hapd->conf->mld_ap && strlen(iface_hapd->conf->bridge) == 0) {
1465*03f9172cSAndroid Build Coastguard Worker 				instanceName = std::to_string(iface_hapd->mld_link_id);
1466*03f9172cSAndroid Build Coastguard Worker 			}
1467*03f9172cSAndroid Build Coastguard Worker #endif
1468*03f9172cSAndroid Build Coastguard Worker 			// Invoke the failure callback on all registered clients.
1469*03f9172cSAndroid Build Coastguard Worker 			for (const auto& callback : callbacks_) {
1470*03f9172cSAndroid Build Coastguard Worker 				auto status =
1471*03f9172cSAndroid Build Coastguard Worker 					callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
1472*03f9172cSAndroid Build Coastguard Worker 					iface_hapd->conf->bridge : iface_hapd->conf->iface,
1473*03f9172cSAndroid Build Coastguard Worker 						instanceName);
1474*03f9172cSAndroid Build Coastguard Worker 				if (!status.isOk()) {
1475*03f9172cSAndroid Build Coastguard Worker 					wpa_printf(MSG_ERROR, "Failed to invoke onFailure");
1476*03f9172cSAndroid Build Coastguard Worker 				}
1477*03f9172cSAndroid Build Coastguard Worker 			}
1478*03f9172cSAndroid Build Coastguard Worker 		}
1479*03f9172cSAndroid Build Coastguard Worker 	};
1480*03f9172cSAndroid Build Coastguard Worker 
1481*03f9172cSAndroid Build Coastguard Worker 	// Setup callback
1482*03f9172cSAndroid Build Coastguard Worker 	iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
1483*03f9172cSAndroid Build Coastguard Worker 	iface_hapd->setup_complete_cb_ctx = iface_hapd;
1484*03f9172cSAndroid Build Coastguard Worker 	iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
1485*03f9172cSAndroid Build Coastguard Worker 	iface_hapd->sta_authorized_cb_ctx = iface_hapd;
1486*03f9172cSAndroid Build Coastguard Worker 	wpa_msg_register_aidl_cb(onAsyncWpaEventCb);
1487*03f9172cSAndroid Build Coastguard Worker 
1488*03f9172cSAndroid Build Coastguard Worker 	// Multi-link MLO should enable iface after both links have been set.
1489*03f9172cSAndroid Build Coastguard Worker 	if (!iface_params.usesMlo && hostapd_enable_iface(iface_hapd->iface) < 0) {
1490*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(
1491*03f9172cSAndroid Build Coastguard Worker 			MSG_ERROR, "Enabling interface %s failed",
1492*03f9172cSAndroid Build Coastguard Worker 			iface_params.name.c_str());
1493*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1494*03f9172cSAndroid Build Coastguard Worker 	}
1495*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1496*03f9172cSAndroid Build Coastguard Worker }
1497*03f9172cSAndroid Build Coastguard Worker 
removeAccessPointInternal(const std::string & iface_name)1498*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
1499*03f9172cSAndroid Build Coastguard Worker {
1500*03f9172cSAndroid Build Coastguard Worker 	// interfaces to be removed
1501*03f9172cSAndroid Build Coastguard Worker 	std::vector<std::string> interfaces;
1502*03f9172cSAndroid Build Coastguard Worker 	bool is_error = false;
1503*03f9172cSAndroid Build Coastguard Worker 
1504*03f9172cSAndroid Build Coastguard Worker 	const auto it = br_interfaces_.find(iface_name);
1505*03f9172cSAndroid Build Coastguard Worker 	if (it != br_interfaces_.end()) {
1506*03f9172cSAndroid Build Coastguard Worker 		// In case bridge, remove managed interfaces
1507*03f9172cSAndroid Build Coastguard Worker 		interfaces = it->second;
1508*03f9172cSAndroid Build Coastguard Worker 		br_interfaces_.erase(iface_name);
1509*03f9172cSAndroid Build Coastguard Worker 	} else {
1510*03f9172cSAndroid Build Coastguard Worker 		// else remove current interface
1511*03f9172cSAndroid Build Coastguard Worker 		interfaces.push_back(iface_name);
1512*03f9172cSAndroid Build Coastguard Worker 	}
1513*03f9172cSAndroid Build Coastguard Worker 
1514*03f9172cSAndroid Build Coastguard Worker 	for (auto& iface : interfaces) {
1515*03f9172cSAndroid Build Coastguard Worker 		std::vector<char> remove_iface_param_vec(
1516*03f9172cSAndroid Build Coastguard Worker 		    iface.begin(), iface.end() + 1);
1517*03f9172cSAndroid Build Coastguard Worker 		if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <  0) {
1518*03f9172cSAndroid Build Coastguard Worker 			wpa_printf(MSG_INFO, "Remove interface %s failed", iface.c_str());
1519*03f9172cSAndroid Build Coastguard Worker 			is_error = true;
1520*03f9172cSAndroid Build Coastguard Worker 		}
1521*03f9172cSAndroid Build Coastguard Worker 	}
1522*03f9172cSAndroid Build Coastguard Worker 	if (is_error) {
1523*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1524*03f9172cSAndroid Build Coastguard Worker 	}
1525*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1526*03f9172cSAndroid Build Coastguard Worker }
1527*03f9172cSAndroid Build Coastguard Worker 
registerCallbackInternal(const std::shared_ptr<IHostapdCallback> & callback)1528*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::registerCallbackInternal(
1529*03f9172cSAndroid Build Coastguard Worker 	const std::shared_ptr<IHostapdCallback>& callback)
1530*03f9172cSAndroid Build Coastguard Worker {
1531*03f9172cSAndroid Build Coastguard Worker 	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
1532*03f9172cSAndroid Build Coastguard Worker 			death_notifier_, this /* cookie */);
1533*03f9172cSAndroid Build Coastguard Worker 	if (status != STATUS_OK) {
1534*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(
1535*03f9172cSAndroid Build Coastguard Worker 			MSG_ERROR,
1536*03f9172cSAndroid Build Coastguard Worker 			"Error registering for death notification for "
1537*03f9172cSAndroid Build Coastguard Worker 			"hostapd callback object");
1538*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
1539*03f9172cSAndroid Build Coastguard Worker 	}
1540*03f9172cSAndroid Build Coastguard Worker 	callbacks_.push_back(callback);
1541*03f9172cSAndroid Build Coastguard Worker 	if (aidl_service_version == 0) {
1542*03f9172cSAndroid Build Coastguard Worker 	    aidl_service_version = Hostapd::version;
1543*03f9172cSAndroid Build Coastguard Worker 	    wpa_printf(MSG_INFO, "AIDL service version: %d", aidl_service_version);
1544*03f9172cSAndroid Build Coastguard Worker 	}
1545*03f9172cSAndroid Build Coastguard Worker 	if (aidl_client_version == 0) {
1546*03f9172cSAndroid Build Coastguard Worker 	    callback->getInterfaceVersion(&aidl_client_version);
1547*03f9172cSAndroid Build Coastguard Worker 	    wpa_printf(MSG_INFO, "AIDL client version: %d", aidl_client_version);
1548*03f9172cSAndroid Build Coastguard Worker 	}
1549*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1550*03f9172cSAndroid Build Coastguard Worker }
1551*03f9172cSAndroid Build Coastguard Worker 
forceClientDisconnectInternal(const std::string & iface_name,const std::vector<uint8_t> & client_address,Ieee80211ReasonCode reason_code)1552*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
1553*03f9172cSAndroid Build Coastguard Worker 	const std::vector<uint8_t>& client_address, Ieee80211ReasonCode reason_code)
1554*03f9172cSAndroid Build Coastguard Worker {
1555*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
1556*03f9172cSAndroid Build Coastguard Worker 	bool result;
1557*03f9172cSAndroid Build Coastguard Worker 	if (!hapd) {
1558*03f9172cSAndroid Build Coastguard Worker 		for (auto const& iface : br_interfaces_) {
1559*03f9172cSAndroid Build Coastguard Worker 			if (iface.first == iface_name) {
1560*03f9172cSAndroid Build Coastguard Worker 				for (auto const& instance : iface.second) {
1561*03f9172cSAndroid Build Coastguard Worker 					hapd = hostapd_get_iface(interfaces_, instance.c_str());
1562*03f9172cSAndroid Build Coastguard Worker 					if (hapd) {
1563*03f9172cSAndroid Build Coastguard Worker 						result = forceStaDisconnection(hapd, client_address,
1564*03f9172cSAndroid Build Coastguard Worker 								(uint16_t) reason_code);
1565*03f9172cSAndroid Build Coastguard Worker 						if (result) break;
1566*03f9172cSAndroid Build Coastguard Worker 					}
1567*03f9172cSAndroid Build Coastguard Worker 				}
1568*03f9172cSAndroid Build Coastguard Worker 			}
1569*03f9172cSAndroid Build Coastguard Worker 		}
1570*03f9172cSAndroid Build Coastguard Worker 	} else {
1571*03f9172cSAndroid Build Coastguard Worker 		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
1572*03f9172cSAndroid Build Coastguard Worker 	}
1573*03f9172cSAndroid Build Coastguard Worker 	if (!hapd) {
1574*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
1575*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_IFACE_UNKNOWN);
1576*03f9172cSAndroid Build Coastguard Worker 	}
1577*03f9172cSAndroid Build Coastguard Worker 	if (result) {
1578*03f9172cSAndroid Build Coastguard Worker 		return ndk::ScopedAStatus::ok();
1579*03f9172cSAndroid Build Coastguard Worker 	}
1580*03f9172cSAndroid Build Coastguard Worker 	return createStatus(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN);
1581*03f9172cSAndroid Build Coastguard Worker }
1582*03f9172cSAndroid Build Coastguard Worker 
setDebugParamsInternal(DebugLevel level)1583*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::setDebugParamsInternal(DebugLevel level)
1584*03f9172cSAndroid Build Coastguard Worker {
1585*03f9172cSAndroid Build Coastguard Worker 	wpa_debug_level = static_cast<uint32_t>(level);
1586*03f9172cSAndroid Build Coastguard Worker 	return ndk::ScopedAStatus::ok();
1587*03f9172cSAndroid Build Coastguard Worker }
1588*03f9172cSAndroid Build Coastguard Worker 
removeLinkFromMultipleLinkBridgedApIfaceInternal(const std::string & iface_name,const std::string & linkIdentity)1589*03f9172cSAndroid Build Coastguard Worker ::ndk::ScopedAStatus Hostapd::removeLinkFromMultipleLinkBridgedApIfaceInternal(
1590*03f9172cSAndroid Build Coastguard Worker const std::string& iface_name, const std::string& linkIdentity)
1591*03f9172cSAndroid Build Coastguard Worker {
1592*03f9172cSAndroid Build Coastguard Worker 	if (!hostapd_get_iface(interfaces_, iface_name.c_str())) {
1593*03f9172cSAndroid Build Coastguard Worker 		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
1594*03f9172cSAndroid Build Coastguard Worker 		return createStatus(HostapdStatusCode::FAILURE_IFACE_UNKNOWN);
1595*03f9172cSAndroid Build Coastguard Worker 	}
1596*03f9172cSAndroid Build Coastguard Worker 	struct hostapd_data* iface_hapd =
1597*03f9172cSAndroid Build Coastguard Worker 		hostapd_get_iface_by_link_id(interfaces_, (size_t) linkIdentity.c_str());
1598*03f9172cSAndroid Build Coastguard Worker 	if (iface_hapd) {
1599*03f9172cSAndroid Build Coastguard Worker 		if (0 == hostapd_link_remove(iface_hapd, 1)) {
1600*03f9172cSAndroid Build Coastguard Worker 			return ndk::ScopedAStatus::ok();
1601*03f9172cSAndroid Build Coastguard Worker 		}
1602*03f9172cSAndroid Build Coastguard Worker 	}
1603*03f9172cSAndroid Build Coastguard Worker 	return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
1604*03f9172cSAndroid Build Coastguard Worker }
1605*03f9172cSAndroid Build Coastguard Worker 
1606*03f9172cSAndroid Build Coastguard Worker }  // namespace hostapd
1607*03f9172cSAndroid Build Coastguard Worker }  // namespace wifi
1608*03f9172cSAndroid Build Coastguard Worker }  // namespace hardware
1609*03f9172cSAndroid Build Coastguard Worker }  // namespace android
1610*03f9172cSAndroid Build Coastguard Worker }  // namespace aidl
1611