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