blob: 5d640497ea662a9fab626e93be7621c37ca71312 [file] [log] [blame]
Roshan Piuscc817562017-12-22 14:45:05 -08001/*
2 * hidl interface for wpa_hostapd daemon
3 * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
5 *
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
8 */
Roshan Pius30b452e2017-12-27 13:36:21 -08009#include <iomanip>
10#include <sstream>
11#include <string>
12#include <vector>
lesl0cb0e272020-10-30 16:58:08 +080013#include <net/if.h>
14#include <sys/socket.h>
15#include <linux/if_bridge.h>
16
Roshan Pius30b452e2017-12-27 13:36:21 -080017
18#include <android-base/file.h>
19#include <android-base/stringprintf.h>
lesl0cb0e272020-10-30 16:58:08 +080020#include <android-base/unique_fd.h>
Roshan Piuscc817562017-12-22 14:45:05 -080021
22#include "hostapd.h"
23#include "hidl_return_util.h"
24
Roshan Pius3455af42018-02-01 09:19:49 -080025extern "C"
26{
lesldab91502020-08-17 18:29:47 +080027#include "common/wpa_ctrl.h"
lesl0cb0e272020-10-30 16:58:08 +080028#include "drivers/linux_ioctl.h"
Roshan Pius3455af42018-02-01 09:19:49 -080029}
30
Roshan Pius30b452e2017-12-27 13:36:21 -080031// The HIDL implementation for hostapd creates a hostapd.conf dynamically for
32// each interface. This file can then be used to hook onto the normal config
33// file parsing logic in hostapd code. Helps us to avoid duplication of code
34// in the HIDL interface.
35// TOOD(b/71872409): Add unit tests for this.
36namespace {
37constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
38
39using android::base::RemoveFileIfExists;
40using android::base::StringPrintf;
41using android::base::WriteStringToFile;
leslb0f4d542020-09-16 23:06:03 +080042using android::hardware::wifi::hostapd::V1_3::IHostapd;
lesldab91502020-08-17 18:29:47 +080043using android::hardware::wifi::hostapd::V1_3::Generation;
44using android::hardware::wifi::hostapd::V1_3::Bandwidth;
Roshan Pius30b452e2017-12-27 13:36:21 -080045
lesl0cb0e272020-10-30 16:58:08 +080046#define MAX_PORTS 1024
47bool GetInterfacesInBridge(std::string br_name,
48 std::vector<std::string>* interfaces) {
49 android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
50 if (sock.get() < 0) {
51 wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
52 strerror(errno), __FUNCTION__);
53 return false;
54 }
55
56 struct ifreq request;
57 int i, ifindices[MAX_PORTS];
58 char if_name[IFNAMSIZ];
59 unsigned long args[3];
60
61 memset(ifindices, 0, MAX_PORTS * sizeof(int));
62
63 args[0] = BRCTL_GET_PORT_LIST;
64 args[1] = (unsigned long) ifindices;
65 args[2] = MAX_PORTS;
66
67 strlcpy(request.ifr_name, br_name.c_str(), IFNAMSIZ);
68 request.ifr_data = (char *)args;
69
70 if (ioctl(sock.get(), SIOCDEVPRIVATE, &request) < 0) {
71 wpa_printf(MSG_ERROR, "Failed to ioctl SIOCDEVPRIVATE in %s",
72 __FUNCTION__);
73 return false;
74 }
75
76 for (i = 0; i < MAX_PORTS; i ++) {
77 memset(if_name, 0, IFNAMSIZ);
78 if (ifindices[i] == 0 || !if_indextoname(ifindices[i], if_name)) {
79 continue;
80 }
81 interfaces->push_back(if_name);
82 }
83 return true;
84}
85
Roshan Pius30b452e2017-12-27 13:36:21 -080086std::string WriteHostapdConfig(
87 const std::string& interface_name, const std::string& config)
88{
89 const std::string file_path =
90 StringPrintf(kConfFileNameFmt, interface_name.c_str());
91 if (WriteStringToFile(
92 config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
93 getuid(), getgid())) {
94 return file_path;
95 }
96 // Diagnose failure
97 int error = errno;
98 wpa_printf(
99 MSG_ERROR, "Cannot write hostapd config to %s, error: %s",
100 file_path.c_str(), strerror(error));
101 struct stat st;
102 int result = stat(file_path.c_str(), &st);
103 if (result == 0) {
104 wpa_printf(
105 MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",
106 st.st_uid, st.st_gid, st.st_mode);
107 } else {
108 wpa_printf(
109 MSG_ERROR,
110 "Error calling stat() on hostapd config file: %s",
111 strerror(errno));
112 }
113 return "";
114}
115
Ahmed ElArabawy7b4b40a2020-01-02 08:55:38 -0800116/*
117 * Get the op_class for a channel/band
118 * The logic here is based on Table E-4 in the 802.11 Specification
119 */
120int getOpClassForChannel(int channel, int band, bool support11n, bool support11ac) {
121 // 2GHz Band
122 if ((band & IHostapd::BandMask::BAND_2_GHZ) != 0) {
123 if (channel == 14) {
124 return 82;
125 }
126 if (channel >= 1 && channel <= 13) {
127 if (!support11n) {
128 //20MHz channel
129 return 81;
130 }
131 if (channel <= 9) {
132 // HT40 with secondary channel above primary
133 return 83;
134 }
135 // HT40 with secondary channel below primary
136 return 84;
137 }
138 // Error
139 return 0;
140 }
141
142 // 5GHz Band
143 if ((band & IHostapd::BandMask::BAND_5_GHZ) != 0) {
144 if (support11ac) {
145 switch (channel) {
146 case 42:
147 case 58:
148 case 106:
149 case 122:
150 case 138:
151 case 155:
152 // 80MHz channel
153 return 128;
154 case 50:
155 case 114:
156 // 160MHz channel
157 return 129;
158 }
159 }
160
161 if (!support11n) {
162 if (channel >= 36 && channel <= 48) {
163 return 115;
164 }
165 if (channel >= 52 && channel <= 64) {
166 return 118;
167 }
168 if (channel >= 100 && channel <= 144) {
169 return 121;
170 }
171 if (channel >= 149 && channel <= 161) {
172 return 124;
173 }
174 if (channel >= 165 && channel <= 169) {
175 return 125;
176 }
177 } else {
178 switch (channel) {
179 case 36:
180 case 44:
181 // HT40 with secondary channel above primary
182 return 116;
183 case 40:
184 case 48:
185 // HT40 with secondary channel below primary
186 return 117;
187 case 52:
188 case 60:
189 // HT40 with secondary channel above primary
190 return 119;
191 case 56:
192 case 64:
193 // HT40 with secondary channel below primary
194 return 120;
195 case 100:
196 case 108:
197 case 116:
198 case 124:
199 case 132:
200 case 140:
201 // HT40 with secondary channel above primary
202 return 122;
203 case 104:
204 case 112:
205 case 120:
206 case 128:
207 case 136:
208 case 144:
209 // HT40 with secondary channel below primary
210 return 123;
211 case 149:
212 case 157:
213 // HT40 with secondary channel above primary
214 return 126;
215 case 153:
216 case 161:
217 // HT40 with secondary channel below primary
218 return 127;
219 }
220 }
221 // Error
222 return 0;
223 }
224
225 // 6GHz Band
226 if ((band & IHostapd::BandMask::BAND_6_GHZ) != 0) {
227 // Channels 1, 5. 9, 13, ...
228 if ((channel & 0x03) == 0x01) {
229 // 20MHz channel
230 return 131;
231 }
232 // Channels 3, 11, 19, 27, ...
233 if ((channel & 0x07) == 0x03) {
234 // 40MHz channel
235 return 132;
236 }
237 // Channels 7, 23, 39, 55, ...
238 if ((channel & 0x0F) == 0x07) {
239 // 80MHz channel
240 return 133;
241 }
242 // Channels 15, 47, 69, ...
243 if ((channel & 0x1F) == 0x0F) {
244 // 160MHz channel
245 return 134;
246 }
Kai Shia0cfc142020-09-16 20:05:13 -0700247 if (channel == 2) {
248 // 20MHz channel
249 return 136;
250 }
Ahmed ElArabawy7b4b40a2020-01-02 08:55:38 -0800251 // Error
252 return 0;
253 }
254
255 return 0;
256}
257
lesldd48efd2019-12-26 15:13:51 +0800258bool validatePassphrase(int passphrase_len, int min_len, int max_len)
259{
260 if (min_len != -1 && passphrase_len < min_len) return false;
261 if (max_len != -1 && passphrase_len > max_len) return false;
262 return true;
263}
264
Roshan Pius30b452e2017-12-27 13:36:21 -0800265std::string CreateHostapdConfig(
lesl31294252020-11-06 17:06:03 +0800266 const android::hardware::wifi::hostapd::V1_3::IHostapd::IfaceParams& iface_params,
267 const android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams& channelParams,
lesl0cb0e272020-10-30 16:58:08 +0800268 const IHostapd::NetworkParams& nw_params,
269 const std::string br_name)
Roshan Pius30b452e2017-12-27 13:36:21 -0800270{
leslb0f4d542020-09-16 23:06:03 +0800271 if (nw_params.V1_2.V1_0.ssid.size() >
Roshan Pius30b452e2017-12-27 13:36:21 -0800272 static_cast<uint32_t>(
273 IHostapd::ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
274 wpa_printf(
leslb0f4d542020-09-16 23:06:03 +0800275 MSG_ERROR, "Invalid SSID size: %zu", nw_params.V1_2.V1_0.ssid.size());
Roshan Pius30b452e2017-12-27 13:36:21 -0800276 return "";
277 }
278
279 // SSID string
280 std::stringstream ss;
281 ss << std::hex;
282 ss << std::setfill('0');
leslb0f4d542020-09-16 23:06:03 +0800283 for (uint8_t b : nw_params.V1_2.V1_0.ssid) {
Roshan Pius30b452e2017-12-27 13:36:21 -0800284 ss << std::setw(2) << static_cast<unsigned int>(b);
285 }
286 const std::string ssid_as_string = ss.str();
287
288 // Encryption config string
Kai Shi35d8ea42020-10-07 15:24:01 -0700289 uint32_t band = 0;
lesl31294252020-11-06 17:06:03 +0800290 band |= channelParams.V1_2.bandMask;
Kai Shi35d8ea42020-10-07 15:24:01 -0700291 bool is_6Ghz_band_only = band == static_cast<uint32_t>(IHostapd::BandMask::BAND_6_GHZ);
Roshan Pius30b452e2017-12-27 13:36:21 -0800292 std::string encryption_config_as_string;
leslb0f4d542020-09-16 23:06:03 +0800293 switch (nw_params.V1_2.encryptionType) {
Roshan Pius30b452e2017-12-27 13:36:21 -0800294 case IHostapd::EncryptionType::NONE:
295 // no security params
296 break;
297 case IHostapd::EncryptionType::WPA:
lesldd48efd2019-12-26 15:13:51 +0800298 if (!validatePassphrase(
leslb0f4d542020-09-16 23:06:03 +0800299 nw_params.V1_2.passphrase.size(),
lesldd48efd2019-12-26 15:13:51 +0800300 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
301 WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
302 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
303 WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
304 return "";
305 }
Roshan Pius30b452e2017-12-27 13:36:21 -0800306 encryption_config_as_string = StringPrintf(
307 "wpa=3\n"
308 "wpa_pairwise=TKIP CCMP\n"
309 "wpa_passphrase=%s",
leslb0f4d542020-09-16 23:06:03 +0800310 nw_params.V1_2.passphrase.c_str());
Roshan Pius30b452e2017-12-27 13:36:21 -0800311 break;
312 case IHostapd::EncryptionType::WPA2:
lesldd48efd2019-12-26 15:13:51 +0800313 if (!validatePassphrase(
leslb0f4d542020-09-16 23:06:03 +0800314 nw_params.V1_2.passphrase.size(),
lesldd48efd2019-12-26 15:13:51 +0800315 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
316 WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
317 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
318 WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
319 return "";
320 }
Roshan Pius30b452e2017-12-27 13:36:21 -0800321 encryption_config_as_string = StringPrintf(
322 "wpa=2\n"
323 "rsn_pairwise=CCMP\n"
324 "wpa_passphrase=%s",
leslb0f4d542020-09-16 23:06:03 +0800325 nw_params.V1_2.passphrase.c_str());
lesldd48efd2019-12-26 15:13:51 +0800326 break;
327 case IHostapd::EncryptionType::WPA3_SAE_TRANSITION:
328 if (!validatePassphrase(
leslb0f4d542020-09-16 23:06:03 +0800329 nw_params.V1_2.passphrase.size(),
lesldd48efd2019-12-26 15:13:51 +0800330 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
331 WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
332 static_cast<uint32_t>(IHostapd::ParamSizeLimits::
333 WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
334 return "";
335 }
336 encryption_config_as_string = StringPrintf(
337 "wpa=2\n"
338 "rsn_pairwise=CCMP\n"
339 "wpa_key_mgmt=WPA-PSK SAE\n"
340 "ieee80211w=1\n"
341 "sae_require_mfp=1\n"
342 "wpa_passphrase=%s\n"
343 "sae_password=%s",
leslb0f4d542020-09-16 23:06:03 +0800344 nw_params.V1_2.passphrase.c_str(),
345 nw_params.V1_2.passphrase.c_str());
lesldd48efd2019-12-26 15:13:51 +0800346 break;
347 case IHostapd::EncryptionType::WPA3_SAE:
leslb0f4d542020-09-16 23:06:03 +0800348 if (!validatePassphrase(nw_params.V1_2.passphrase.size(), 1, -1)) {
lesldd48efd2019-12-26 15:13:51 +0800349 return "";
350 }
351 encryption_config_as_string = StringPrintf(
352 "wpa=2\n"
353 "rsn_pairwise=CCMP\n"
354 "wpa_key_mgmt=SAE\n"
355 "ieee80211w=2\n"
356 "sae_require_mfp=2\n"
Kai Shi35d8ea42020-10-07 15:24:01 -0700357 "sae_pwe=%d\n"
lesldd48efd2019-12-26 15:13:51 +0800358 "sae_password=%s",
Kai Shi35d8ea42020-10-07 15:24:01 -0700359 is_6Ghz_band_only ? 1 : 2,
leslb0f4d542020-09-16 23:06:03 +0800360 nw_params.V1_2.passphrase.c_str());
Roshan Pius30b452e2017-12-27 13:36:21 -0800361 break;
362 default:
363 wpa_printf(MSG_ERROR, "Unknown encryption type");
364 return "";
365 }
366
367 std::string channel_config_as_string;
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800368 bool isFirst = true;
lesl31294252020-11-06 17:06:03 +0800369 if (channelParams.enableAcs) {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800370 std::string freqList_as_string;
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900371 for (const auto &range :
lesl31294252020-11-06 17:06:03 +0800372 channelParams.V1_2.acsChannelFreqRangesMhz) {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800373 if (!isFirst) {
374 freqList_as_string += ",";
375 }
376 isFirst = false;
377
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900378 if (range.start != range.end) {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800379 freqList_as_string +=
380 StringPrintf("%d-%d", range.start, range.end);
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900381 } else {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800382 freqList_as_string += StringPrintf("%d", range.start);
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900383 }
384 }
Roshan Pius30b452e2017-12-27 13:36:21 -0800385 channel_config_as_string = StringPrintf(
386 "channel=0\n"
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900387 "acs_exclude_dfs=%d\n"
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800388 "freqlist=%s",
lesl31294252020-11-06 17:06:03 +0800389 iface_params.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs,
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800390 freqList_as_string.c_str());
Roshan Pius30b452e2017-12-27 13:36:21 -0800391 } else {
Ahmed ElArabawy7b4b40a2020-01-02 08:55:38 -0800392 int op_class = getOpClassForChannel(
lesl31294252020-11-06 17:06:03 +0800393 channelParams.channel,
Ahmed ElArabawy7b4b40a2020-01-02 08:55:38 -0800394 band,
lesl31294252020-11-06 17:06:03 +0800395 iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211N,
396 iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC);
Roshan Pius30b452e2017-12-27 13:36:21 -0800397 channel_config_as_string = StringPrintf(
Ahmed ElArabawy7b4b40a2020-01-02 08:55:38 -0800398 "channel=%d\n"
399 "op_class=%d",
lesl31294252020-11-06 17:06:03 +0800400 channelParams.channel, op_class);
Roshan Pius30b452e2017-12-27 13:36:21 -0800401 }
402
Roshan Pius30b452e2017-12-27 13:36:21 -0800403 std::string hw_mode_as_string;
Roshan Pius49446472018-03-07 10:23:46 -0800404 std::string ht_cap_vht_oper_chwidth_as_string;
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800405
406 if ((band & IHostapd::BandMask::BAND_2_GHZ) != 0) {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800407 if (((band & IHostapd::BandMask::BAND_5_GHZ) != 0)
408 || ((band & IHostapd::BandMask::BAND_6_GHZ) != 0)) {
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800409 hw_mode_as_string = "hw_mode=any";
lesl31294252020-11-06 17:06:03 +0800410 if (iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC) {
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800411 ht_cap_vht_oper_chwidth_as_string =
412 "ht_capab=[HT40+]\n"
413 "vht_oper_chwidth=1";
414 }
415 } else {
416 hw_mode_as_string = "hw_mode=g";
Roshan Pius49446472018-03-07 10:23:46 -0800417 }
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800418 } else {
Ahmed ElArabawya390f292019-12-21 13:07:02 -0800419 if (((band & IHostapd::BandMask::BAND_5_GHZ) != 0)
420 || ((band & IHostapd::BandMask::BAND_6_GHZ) != 0)) {
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800421 hw_mode_as_string = "hw_mode=a";
lesl31294252020-11-06 17:06:03 +0800422 if (iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC) {
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800423 ht_cap_vht_oper_chwidth_as_string =
424 "ht_capab=[HT40+]\n"
425 "vht_oper_chwidth=1";
426 }
427 } else {
428 wpa_printf(MSG_ERROR, "Invalid band");
429 return "";
Roshan Pius49446472018-03-07 10:23:46 -0800430 }
Roshan Pius30b452e2017-12-27 13:36:21 -0800431 }
432
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800433 std::string he_params_as_string;
Roshan Pius36510302020-05-09 21:01:01 -0700434#ifdef CONFIG_IEEE80211AX
lesl31294252020-11-06 17:06:03 +0800435 if (iface_params.V1_2.hwModeParams.enable80211AX) {
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800436 he_params_as_string = StringPrintf(
437 "ieee80211ax=1\n"
438 "he_su_beamformer=%d\n"
439 "he_su_beamformee=%d\n"
440 "he_mu_beamformer=%d\n"
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800441 "he_twt_required=%d\n",
lesl31294252020-11-06 17:06:03 +0800442 iface_params.V1_2.hwModeParams.enableHeSingleUserBeamformer ? 1 : 0,
443 iface_params.V1_2.hwModeParams.enableHeSingleUserBeamformee ? 1 : 0,
444 iface_params.V1_2.hwModeParams.enableHeMultiUserBeamformer ? 1 : 0,
445 iface_params.V1_2.hwModeParams.enableHeTargetWakeTime ? 1 : 0);
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800446 } else {
447 he_params_as_string = "ieee80211ax=0";
448 }
Roshan Pius36510302020-05-09 21:01:01 -0700449#endif /* CONFIG_IEEE80211AX */
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800450
leslb0f4d542020-09-16 23:06:03 +0800451#ifdef CONFIG_INTERWORKING
452 std::string access_network_params_as_string;
453 if (nw_params.isMetered) {
454 access_network_params_as_string = StringPrintf(
455 "interworking=1\n"
456 "access_network_type=2\n"); // CHARGEABLE_PUBLIC_NETWORK
457 } else {
458 access_network_params_as_string = StringPrintf(
459 "interworking=0\n");
460 }
461#endif /* CONFIG_INTERWORKING */
462
lesl0cb0e272020-10-30 16:58:08 +0800463 std::string bridge_as_string;
464 if (!br_name.empty()) {
465 bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
466 }
467
Roshan Pius30b452e2017-12-27 13:36:21 -0800468 return StringPrintf(
469 "interface=%s\n"
470 "driver=nl80211\n"
Daichi Ueuracaa74a82018-02-14 22:25:39 +0900471 "ctrl_interface=/data/vendor/wifi/hostapd/ctrl\n"
Roshan Pius30b452e2017-12-27 13:36:21 -0800472 // ssid2 signals to hostapd that the value is not a literal value
473 // for use as a SSID. In this case, we're giving it a hex
474 // std::string and hostapd needs to expect that.
475 "ssid2=%s\n"
476 "%s\n"
477 "ieee80211n=%d\n"
478 "ieee80211ac=%d\n"
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800479 "%s\n"
Roshan Piuse453f712018-02-09 15:49:57 -0800480 "%s\n"
Roshan Pius49446472018-03-07 10:23:46 -0800481 "%s\n"
Roshan Pius30b452e2017-12-27 13:36:21 -0800482 "ignore_broadcast_ssid=%d\n"
483 "wowlan_triggers=any\n"
leslb0f4d542020-09-16 23:06:03 +0800484#ifdef CONFIG_INTERWORKING
485 "%s\n"
486#endif /* CONFIG_INTERWORKING */
lesl0cb0e272020-10-30 16:58:08 +0800487 "%s\n"
Roshan Pius30b452e2017-12-27 13:36:21 -0800488 "%s\n",
lesl31294252020-11-06 17:06:03 +0800489 iface_params.V1_2.V1_1.V1_0.ifaceName.c_str(), ssid_as_string.c_str(),
Roshan Pius30b452e2017-12-27 13:36:21 -0800490 channel_config_as_string.c_str(),
lesl31294252020-11-06 17:06:03 +0800491 iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211N ? 1 : 0,
492 iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC ? 1 : 0,
Ahmed ElArabawy5362fb12020-01-02 15:01:31 -0800493 he_params_as_string.c_str(),
Roshan Pius49446472018-03-07 10:23:46 -0800494 hw_mode_as_string.c_str(), ht_cap_vht_oper_chwidth_as_string.c_str(),
leslb0f4d542020-09-16 23:06:03 +0800495 nw_params.V1_2.V1_0.isHidden ? 1 : 0,
496#ifdef CONFIG_INTERWORKING
lesl0cb0e272020-10-30 16:58:08 +0800497 access_network_params_as_string.c_str(),
leslb0f4d542020-09-16 23:06:03 +0800498#endif /* CONFIG_INTERWORKING */
lesl0cb0e272020-10-30 16:58:08 +0800499 encryption_config_as_string.c_str(),
500 bridge_as_string.c_str());
Roshan Pius30b452e2017-12-27 13:36:21 -0800501}
Roshan Piuse2d21012018-08-17 11:22:06 -0700502
lesldab91502020-08-17 18:29:47 +0800503Generation getGeneration(hostapd_hw_modes *current_mode)
504{
505 wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d, vht_enabled=%d",
506 current_mode->mode, current_mode->ht_capab != 0,
507 current_mode->vht_capab != 0);
508 switch (current_mode->mode) {
509 case HOSTAPD_MODE_IEEE80211B:
510 return Generation::WIFI_STANDARD_LEGACY;
511 case HOSTAPD_MODE_IEEE80211G:
512 return current_mode->ht_capab == 0 ?
513 Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
514 case HOSTAPD_MODE_IEEE80211A:
515 return current_mode->vht_capab == 0 ?
516 Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
517 // TODO: b/162484222 miss HOSTAPD_MODE_IEEE80211AX definition.
518 default:
519 return Generation::WIFI_STANDARD_UNKNOWN;
520 }
521}
522
523Bandwidth getBandwidth(struct hostapd_config *iconf)
524{
525 wpa_printf(MSG_DEBUG, "getBandwidth %d, isHT=%d, isHT40=%d",
526 iconf->vht_oper_chwidth, iconf->ieee80211n,
527 iconf->secondary_channel);
528 switch (iconf->vht_oper_chwidth) {
529 case CHANWIDTH_80MHZ:
530 return Bandwidth::WIFI_BANDWIDTH_80;
531 case CHANWIDTH_80P80MHZ:
532 return Bandwidth::WIFI_BANDWIDTH_80P80;
533 break;
534 case CHANWIDTH_160MHZ:
535 return Bandwidth::WIFI_BANDWIDTH_160;
536 break;
537 case CHANWIDTH_USE_HT:
538 if (iconf->ieee80211n) {
539 return iconf->secondary_channel != 0 ?
540 Bandwidth::WIFI_BANDWIDTH_40 : Bandwidth::WIFI_BANDWIDTH_20;
541 }
542 return Bandwidth::WIFI_BANDWIDTH_20_NOHT;
543 default:
544 return Bandwidth::WIFI_BANDWIDTH_INVALID;
545 }
546}
547
lesl8c282e52020-12-03 18:28:49 +0800548bool forceStaDisconnection(struct hostapd_data* hapd,
549 const std::array<uint8_t, 6>& client_address,
550 const uint16_t reason_code) {
551 struct sta_info *sta;
552 for (sta = hapd->sta_list; sta; sta = sta->next) {
553 int res;
554 res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
555 if (res == 0) {
556 wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
557 MAC2STR(client_address.data()), reason_code);
558 ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
559 return true;
560 }
561 }
562 return false;
563}
564
Roshan Piuse2d21012018-08-17 11:22:06 -0700565// hostapd core functions accept "C" style function pointers, so use global
566// functions to pass to the hostapd core function and store the corresponding
567// std::function methods to be invoked.
568//
569// NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
570//
571// Callback to be invoked once setup is complete
572std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
573void onAsyncSetupCompleteCb(void* ctx)
574{
575 struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
576 if (on_setup_complete_internal_callback) {
577 on_setup_complete_internal_callback(iface_hapd);
578 // Invalidate this callback since we don't want this firing
lesl0cb0e272020-10-30 16:58:08 +0800579 // again in single AP mode.
580 if (strlen(iface_hapd->conf->bridge) > 0) {
581 on_setup_complete_internal_callback = nullptr;
582 }
Roshan Piuse2d21012018-08-17 11:22:06 -0700583 }
584}
lesld0621052020-08-10 13:54:28 +0800585
586// Callback to be invoked on hotspot client connection/disconnection
587std::function<void(struct hostapd_data*, const u8 *mac_addr, int authorized,
588 const u8 *p2p_dev_addr)> on_sta_authorized_internal_callback;
589void onAsyncStaAuthorizedCb(void* ctx, const u8 *mac_addr, int authorized,
590 const u8 *p2p_dev_addr)
591{
592 struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
593 if (on_sta_authorized_internal_callback) {
594 on_sta_authorized_internal_callback(iface_hapd, mac_addr,
595 authorized, p2p_dev_addr);
596 }
597}
598
lesldab91502020-08-17 18:29:47 +0800599std::function<void(struct hostapd_data*, int level,
600 enum wpa_msg_type type, const char *txt,
601 size_t len)> on_wpa_msg_internal_callback;
602
603void onAsyncWpaEventCb(void *ctx, int level,
604 enum wpa_msg_type type, const char *txt,
605 size_t len)
606{
607 struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
608 if (on_wpa_msg_internal_callback) {
609 on_wpa_msg_internal_callback(iface_hapd, level,
610 type, txt, len);
611 }
612}
613
614
Roshan Pius30b452e2017-12-27 13:36:21 -0800615} // namespace
616
Roshan Piuscc817562017-12-22 14:45:05 -0800617namespace android {
618namespace hardware {
619namespace wifi {
620namespace hostapd {
leslf8b1b402020-08-04 17:09:39 +0800621namespace V1_3 {
Roshan Piuscc817562017-12-22 14:45:05 -0800622namespace implementation {
623using hidl_return_util::call;
Roshan Piuse2d21012018-08-17 11:22:06 -0700624using namespace android::hardware::wifi::hostapd::V1_0;
Roshan Piuscc817562017-12-22 14:45:05 -0800625
Roshan Pius80e5a0f2020-10-19 13:48:22 -0700626Hostapd::Hostapd(struct hapd_interfaces* interfaces)
627 : interfaces_(interfaces), death_notifier_(sp<DeathNotifier>::make())
Roshan Piuscc817562017-12-22 14:45:05 -0800628{}
629
630Return<void> Hostapd::addAccessPoint(
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900631 const V1_0::IHostapd::IfaceParams& iface_params,
lesldd48efd2019-12-26 15:13:51 +0800632 const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900633{
634 return call(
635 this, &Hostapd::addAccessPointInternal, _hidl_cb, iface_params,
636 nw_params);
637}
638
639Return<void> Hostapd::addAccessPoint_1_1(
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800640 const V1_1::IHostapd::IfaceParams& iface_params,
lesldd48efd2019-12-26 15:13:51 +0800641 const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
Roshan Piuscc817562017-12-22 14:45:05 -0800642{
643 return call(
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900644 this, &Hostapd::addAccessPointInternal_1_1, _hidl_cb, iface_params,
Roshan Piuscc817562017-12-22 14:45:05 -0800645 nw_params);
646}
647
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800648Return<void> Hostapd::addAccessPoint_1_2(
leslb0f4d542020-09-16 23:06:03 +0800649 const V1_2::IHostapd::IfaceParams& iface_params,
650 const V1_2::IHostapd::NetworkParams& nw_params,
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800651 addAccessPoint_1_2_cb _hidl_cb)
652{
653 return call(
654 this, &Hostapd::addAccessPointInternal_1_2, _hidl_cb, iface_params,
655 nw_params);
656}
657
leslb0f4d542020-09-16 23:06:03 +0800658Return<void> Hostapd::addAccessPoint_1_3(
659 const V1_3::IHostapd::IfaceParams& iface_params,
660 const V1_3::IHostapd::NetworkParams& nw_params,
661 addAccessPoint_1_3_cb _hidl_cb)
662{
663 return call(
664 this, &Hostapd::addAccessPointInternal_1_3, _hidl_cb, iface_params,
665 nw_params);
666}
667
Roshan Piuscc817562017-12-22 14:45:05 -0800668Return<void> Hostapd::removeAccessPoint(
669 const hidl_string& iface_name, removeAccessPoint_cb _hidl_cb)
670{
671 return call(
672 this, &Hostapd::removeAccessPointInternal, _hidl_cb, iface_name);
673}
674
Roshan Piuse2d21012018-08-17 11:22:06 -0700675Return<void> Hostapd::terminate()
676{
Roshan Pius3455af42018-02-01 09:19:49 -0800677 wpa_printf(MSG_INFO, "Terminating...");
lesl3b8cc0c2020-11-20 23:44:32 +0800678 // Clear the callback to avoid IPCThreadState shutdown during the
679 // callback event.
680 callbacks_.clear();
Roshan Pius3455af42018-02-01 09:19:49 -0800681 eloop_terminate();
682 return Void();
683}
684
Roshan Piuse2d21012018-08-17 11:22:06 -0700685Return<void> Hostapd::registerCallback(
lesl1a842e62019-12-02 19:00:37 +0800686 const sp<V1_1::IHostapdCallback>& callback, registerCallback_cb _hidl_cb)
Roshan Piuse2d21012018-08-17 11:22:06 -0700687{
688 return call(
689 this, &Hostapd::registerCallbackInternal, _hidl_cb, callback);
690}
691
leslf8b1b402020-08-04 17:09:39 +0800692Return<void> Hostapd::registerCallback_1_3(
693 const sp<V1_3::IHostapdCallback>& callback, registerCallback_1_3_cb _hidl_cb)
694{
695 return call(
696 this, &Hostapd::registerCallbackInternal_1_3, _hidl_cb, callback);
697}
698
lesl1a842e62019-12-02 19:00:37 +0800699Return<void> Hostapd::forceClientDisconnect(
700 const hidl_string& iface_name, const hidl_array<uint8_t, 6>& client_address,
701 V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb)
702{
703 return call(
704 this, &Hostapd::forceClientDisconnectInternal, _hidl_cb, iface_name,
705 client_address, reason_code);
706}
707
Roger Wangcede5062019-12-30 12:56:28 +0800708Return<void> Hostapd::setDebugParams(
leslf8b1b402020-08-04 17:09:39 +0800709 V1_2::DebugLevel level, setDebugParams_cb _hidl_cb)
Roger Wangcede5062019-12-30 12:56:28 +0800710{
711 return call(
712 this, &Hostapd::setDebugParamsInternal, _hidl_cb, level);
713}
lesl1a842e62019-12-02 19:00:37 +0800714
715V1_0::HostapdStatus Hostapd::addAccessPointInternal(
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900716 const V1_0::IHostapd::IfaceParams& iface_params,
lesldd48efd2019-12-26 15:13:51 +0800717 const V1_0::IHostapd::NetworkParams& nw_params)
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900718{
lesl1a842e62019-12-02 19:00:37 +0800719 return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
Daisuke Niwac1bd20f2019-01-09 13:51:02 +0900720}
721
lesl1a842e62019-12-02 19:00:37 +0800722V1_0::HostapdStatus Hostapd::addAccessPointInternal_1_1(
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800723 const V1_1::IHostapd::IfaceParams& iface_params,
lesldd48efd2019-12-26 15:13:51 +0800724 const V1_1::IHostapd::NetworkParams& nw_params)
Ahmed ElArabawy34982672019-12-06 10:10:17 -0800725{
726 return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
727}
728
leslf8b1b402020-08-04 17:09:39 +0800729V1_2::HostapdStatus Hostapd::addAccessPointInternal_1_2(
leslb0f4d542020-09-16 23:06:03 +0800730 const V1_2::IHostapd::IfaceParams& iface_params,
731 const V1_2::IHostapd::NetworkParams& nw_params) {
732 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
733}
734
735V1_2::HostapdStatus Hostapd::addAccessPointInternal_1_3(
lesl0cb0e272020-10-30 16:58:08 +0800736 const V1_3::IHostapd::IfaceParams& iface_params,
leslb0f4d542020-09-16 23:06:03 +0800737 const V1_3::IHostapd::NetworkParams& nw_params)
Roshan Piuscc817562017-12-22 14:45:05 -0800738{
lesl0cb0e272020-10-30 16:58:08 +0800739 int channelParamsListSize = iface_params.channelParamsList.size();
740 if (channelParamsListSize == 1) {
741 // Single AP
742 wpa_printf(MSG_INFO, "AddSingleAccessPoint, iface=%s",
743 iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
lesl31294252020-11-06 17:06:03 +0800744 return addSingleAccessPoint(iface_params, iface_params.channelParamsList[0],
lesl0cb0e272020-10-30 16:58:08 +0800745 nw_params, "");
746 } else if (channelParamsListSize == 2) {
747 // Concurrent APs
748 wpa_printf(MSG_INFO, "AddDualAccessPoint, iface=%s",
749 iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
750 return addConcurrentAccessPoints(iface_params, nw_params);
751 }
752 return {V1_2::HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
753}
754
755V1_2::HostapdStatus Hostapd::addConcurrentAccessPoints(
756 const V1_3::IHostapd::IfaceParams& iface_params, const V1_3::IHostapd::NetworkParams& nw_params)
757{
758 int channelParamsListSize = iface_params.channelParamsList.size();
759 // Get available interfaces in bridge
760 std::vector<std::string> managed_interfaces;
761 std::string br_name = StringPrintf(
762 "%s", iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
763 if (!GetInterfacesInBridge(br_name, &managed_interfaces)) {
764 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN,
765 "Get interfaces in bridge failed."};
766 }
767 if (managed_interfaces.size() < channelParamsListSize) {
768 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN,
769 "Available interfaces less than requested bands"};
770 }
771 // start BSS on specified bands
772 for (std::size_t i = 0; i < channelParamsListSize; i ++) {
lesl31294252020-11-06 17:06:03 +0800773 V1_3::IHostapd::IfaceParams iface_params_new = iface_params;
774 iface_params_new.V1_2.V1_1.V1_0.ifaceName = managed_interfaces[i];
lesl0cb0e272020-10-30 16:58:08 +0800775 V1_2::HostapdStatus status = addSingleAccessPoint(
lesl31294252020-11-06 17:06:03 +0800776 iface_params_new, iface_params.channelParamsList[i], nw_params, br_name);
lesl0cb0e272020-10-30 16:58:08 +0800777 if (status.code != V1_2::HostapdStatusCode::SUCCESS) {
778 wpa_printf(MSG_ERROR, "Failed to addAccessPoint %s",
779 managed_interfaces[i].c_str());
780 return status;
781 }
782 }
783 // Save bridge interface info
784 br_interfaces_[br_name] = managed_interfaces;
785 return {V1_2::HostapdStatusCode::SUCCESS, ""};
786}
787
788V1_2::HostapdStatus Hostapd::addSingleAccessPoint(
lesl31294252020-11-06 17:06:03 +0800789 const V1_3::IHostapd::IfaceParams& iface_params,
790 const V1_3::IHostapd::ChannelParams& channelParams,
lesl0cb0e272020-10-30 16:58:08 +0800791 const V1_3::IHostapd::NetworkParams& nw_params,
792 const std::string br_name)
793{
lesl31294252020-11-06 17:06:03 +0800794 if (hostapd_get_iface(interfaces_, iface_params.V1_2.V1_1.V1_0.ifaceName.c_str())) {
Roshan Pius087d8692017-12-27 14:11:44 -0800795 wpa_printf(
796 MSG_ERROR, "Interface %s already present",
lesl31294252020-11-06 17:06:03 +0800797 iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
leslf8b1b402020-08-04 17:09:39 +0800798 return {V1_2::HostapdStatusCode::FAILURE_IFACE_EXISTS, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800799 }
lesl31294252020-11-06 17:06:03 +0800800 const auto conf_params = CreateHostapdConfig(iface_params, channelParams, nw_params, br_name);
Roshan Pius087d8692017-12-27 14:11:44 -0800801 if (conf_params.empty()) {
802 wpa_printf(MSG_ERROR, "Failed to create config params");
leslf8b1b402020-08-04 17:09:39 +0800803 return {V1_2::HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800804 }
805 const auto conf_file_path =
lesl31294252020-11-06 17:06:03 +0800806 WriteHostapdConfig(iface_params.V1_2.V1_1.V1_0.ifaceName, conf_params);
Roshan Pius087d8692017-12-27 14:11:44 -0800807 if (conf_file_path.empty()) {
808 wpa_printf(MSG_ERROR, "Failed to write config file");
leslf8b1b402020-08-04 17:09:39 +0800809 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800810 }
811 std::string add_iface_param_str = StringPrintf(
lesl31294252020-11-06 17:06:03 +0800812 "%s config=%s", iface_params.V1_2.V1_1.V1_0.ifaceName.c_str(),
Roshan Pius087d8692017-12-27 14:11:44 -0800813 conf_file_path.c_str());
814 std::vector<char> add_iface_param_vec(
815 add_iface_param_str.begin(), add_iface_param_str.end() + 1);
816 if (hostapd_add_iface(interfaces_, add_iface_param_vec.data()) < 0) {
817 wpa_printf(
818 MSG_ERROR, "Adding interface %s failed",
819 add_iface_param_str.c_str());
leslf8b1b402020-08-04 17:09:39 +0800820 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800821 }
822 struct hostapd_data* iface_hapd =
lesl31294252020-11-06 17:06:03 +0800823 hostapd_get_iface(interfaces_, iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
Roshan Pius087d8692017-12-27 14:11:44 -0800824 WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
Roshan Piuse2d21012018-08-17 11:22:06 -0700825 // Register the setup complete callbacks
826 on_setup_complete_internal_callback =
827 [this](struct hostapd_data* iface_hapd) {
828 wpa_printf(
lesl0cb0e272020-10-30 16:58:08 +0800829 MSG_INFO, "AP interface setup completed - state %s",
Roshan Piuse2d21012018-08-17 11:22:06 -0700830 hostapd_state_text(iface_hapd->iface->state));
831 if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
832 // Invoke the failure callback on all registered
833 // clients.
834 for (const auto& callback : callbacks_) {
835 callback->onFailure(
836 iface_hapd->conf->iface);
837 }
838 }
839 };
lesld0621052020-08-10 13:54:28 +0800840
841 // Rgegister for new client connect/disconnect indication.
842 on_sta_authorized_internal_callback =
843 [this](struct hostapd_data* iface_hapd, const u8 *mac_addr,
844 int authorized, const u8 *p2p_dev_addr) {
845 wpa_printf(MSG_DEBUG, "notify client " MACSTR " %s",
846 MAC2STR(mac_addr),
847 (authorized) ? "Connected" : "Disconnected");
lesld0621052020-08-10 13:54:28 +0800848 for (const auto &callback : callbacks_) {
lesl0cb0e272020-10-30 16:58:08 +0800849 callback->onConnectedClientsChanged(strlen(iface_hapd->conf->bridge) > 0 ?
850 iface_hapd->conf->bridge : iface_hapd->conf->iface,
lesld0621052020-08-10 13:54:28 +0800851 iface_hapd->conf->iface, mac_addr, authorized);
852 }
853 };
854
lesldab91502020-08-17 18:29:47 +0800855 // Register for wpa_event which used to get channel switch event
856 on_wpa_msg_internal_callback =
857 [this](struct hostapd_data* iface_hapd, int level,
858 enum wpa_msg_type type, const char *txt,
859 size_t len) {
860 wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
lesleb250ff2020-11-25 12:53:12 +0800861 if (os_strncmp(txt, AP_EVENT_ENABLED,
862 strlen(AP_EVENT_ENABLED)) == 0 ||
863 os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
lesldab91502020-08-17 18:29:47 +0800864 strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
865 for (const auto &callback : callbacks_) {
866 callback->onApInstanceInfoChanged(
lesl0cb0e272020-10-30 16:58:08 +0800867 strlen(iface_hapd->conf->bridge) > 0 ?
868 iface_hapd->conf->bridge : iface_hapd->conf->iface,
869 iface_hapd->conf->iface, iface_hapd->iface->freq,
870 getBandwidth(iface_hapd->iconf),
lesl29973f82020-09-10 22:40:06 +0800871 getGeneration(iface_hapd->iface->current_mode),
872 iface_hapd->own_addr);
lesldab91502020-08-17 18:29:47 +0800873 }
874 }
875 };
lesld0621052020-08-10 13:54:28 +0800876
877 // Setup callback
Roshan Piuse2d21012018-08-17 11:22:06 -0700878 iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
879 iface_hapd->setup_complete_cb_ctx = iface_hapd;
lesld0621052020-08-10 13:54:28 +0800880 iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
881 iface_hapd->sta_authorized_cb_ctx = iface_hapd;
lesldab91502020-08-17 18:29:47 +0800882 wpa_msg_register_cb(onAsyncWpaEventCb);
lesld0621052020-08-10 13:54:28 +0800883
Roshan Pius087d8692017-12-27 14:11:44 -0800884 if (hostapd_enable_iface(iface_hapd->iface) < 0) {
885 wpa_printf(
886 MSG_ERROR, "Enabling interface %s failed",
lesl31294252020-11-06 17:06:03 +0800887 iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
leslf8b1b402020-08-04 17:09:39 +0800888 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800889 }
leslf8b1b402020-08-04 17:09:39 +0800890 return {V1_2::HostapdStatusCode::SUCCESS, ""};
Roshan Piuscc817562017-12-22 14:45:05 -0800891}
892
lesl1a842e62019-12-02 19:00:37 +0800893V1_0::HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
Roshan Piuscc817562017-12-22 14:45:05 -0800894{
Roshan Pius087d8692017-12-27 14:11:44 -0800895 std::vector<char> remove_iface_param_vec(
896 iface_name.begin(), iface_name.end() + 1);
897 if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <
898 0) {
899 wpa_printf(
900 MSG_ERROR, "Removing interface %s failed",
901 iface_name.c_str());
lesl1a842e62019-12-02 19:00:37 +0800902 return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
Roshan Pius087d8692017-12-27 14:11:44 -0800903 }
lesl1a842e62019-12-02 19:00:37 +0800904 return {V1_0::HostapdStatusCode::SUCCESS, ""};
Roshan Piuscc817562017-12-22 14:45:05 -0800905}
Roshan Piuse2d21012018-08-17 11:22:06 -0700906
lesl1a842e62019-12-02 19:00:37 +0800907V1_0::HostapdStatus Hostapd::registerCallbackInternal(
908 const sp<V1_1::IHostapdCallback>& callback)
Roshan Piuse2d21012018-08-17 11:22:06 -0700909{
leslf8b1b402020-08-04 17:09:39 +0800910 return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
911}
912
913V1_2::HostapdStatus Hostapd::registerCallbackInternal_1_3(
914 const sp<V1_3::IHostapdCallback>& callback)
915{
Roshan Pius80e5a0f2020-10-19 13:48:22 -0700916 if (!callback->linkToDeath(death_notifier_, 0)) {
917 wpa_printf(
918 MSG_ERROR,
919 "Error registering for death notification for "
920 "hostapd callback object");
921 return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
922 }
Roshan Piuse2d21012018-08-17 11:22:06 -0700923 callbacks_.push_back(callback);
leslf8b1b402020-08-04 17:09:39 +0800924 return {V1_2::HostapdStatusCode::SUCCESS, ""};
lesl1a842e62019-12-02 19:00:37 +0800925}
926
927V1_2::HostapdStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
928 const std::array<uint8_t, 6>& client_address, V1_2::Ieee80211ReasonCode reason_code)
929{
930 struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
lesl8c282e52020-12-03 18:28:49 +0800931 bool result;
932 if (!hapd) {
933 for (auto const& iface : br_interfaces_) {
934 if (iface.first == iface_name) {
935 for (auto const& instance : iface.second) {
936 hapd = hostapd_get_iface(interfaces_, instance.c_str());
937 if (hapd) {
938 result = forceStaDisconnection(hapd, client_address,
939 (uint16_t) reason_code);
940 if (result) break;
941 }
942 }
943 }
944 }
945 } else {
946 result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
947 }
lesl1a842e62019-12-02 19:00:37 +0800948 if (!hapd) {
949 wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
950 return {V1_2::HostapdStatusCode::FAILURE_IFACE_UNKNOWN, ""};
951 }
lesl8c282e52020-12-03 18:28:49 +0800952 if (result) {
953 return {V1_2::HostapdStatusCode::SUCCESS, ""};
lesl1a842e62019-12-02 19:00:37 +0800954 }
955 return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
Roshan Piuse2d21012018-08-17 11:22:06 -0700956}
957
leslf8b1b402020-08-04 17:09:39 +0800958V1_2::HostapdStatus Hostapd::setDebugParamsInternal(V1_2::DebugLevel level)
Roger Wangcede5062019-12-30 12:56:28 +0800959{
960 wpa_debug_level = static_cast<uint32_t>(level);
961 return {V1_2::HostapdStatusCode::SUCCESS, ""};
962}
963
Roshan Piuscc817562017-12-22 14:45:05 -0800964} // namespace implementation
leslf8b1b402020-08-04 17:09:39 +0800965} // namespace V1_3
Roshan Piuscc817562017-12-22 14:45:05 -0800966} // namespace hostapd
967} // namespace wifi
968} // namespace hardware
969} // namespace android