]> git.ipfire.org Git - thirdparty/hostap.git/blame - wpa_supplicant/ap.c
dbus: Export BSS Transition Management status
[thirdparty/hostap.git] / wpa_supplicant / ap.c
CommitLineData
f1a48710
JM
1/*
2 * WPA Supplicant - Basic AP mode support routines
3 * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
4 * Copyright (c) 2009, Atheros Communications
5 *
0f3d578e
JM
6 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
f1a48710
JM
8 */
9
6226e38d 10#include "utils/includes.h"
f1a48710 11
6226e38d 12#include "utils/common.h"
70d84f11 13#include "utils/eloop.h"
ab45223b 14#include "utils/uuid.h"
58c26600 15#include "common/ieee802_11_defs.h"
a0dee797 16#include "common/wpa_ctrl.h"
25a8f9e3 17#include "eapol_supp/eapol_supp_sm.h"
db6ae69e 18#include "crypto/dh_group5.h"
1057d78e 19#include "ap/hostapd.h"
6226e38d 20#include "ap/ap_config.h"
fe99fb74 21#include "ap/ap_drv_ops.h"
fe6bdb77 22#ifdef NEED_AP_MLME
1057d78e 23#include "ap/ieee802_11.h"
fe6bdb77 24#endif /* NEED_AP_MLME */
b22128ef 25#include "ap/beacon.h"
a8e0505b 26#include "ap/ieee802_1x.h"
363b9e60 27#include "ap/wps_hostapd.h"
0e2d35c6 28#include "ap/ctrl_iface_ap.h"
bd0f68c4 29#include "ap/dfs.h"
3ec97afe 30#include "wps/wps.h"
e44f8bf2 31#include "common/ieee802_11_defs.h"
1f1b62a0 32#include "config_ssid.h"
094393b1 33#include "config.h"
1f1b62a0 34#include "wpa_supplicant_i.h"
2d5b792d 35#include "driver_i.h"
e44f8bf2 36#include "p2p_supplicant.h"
2d5b792d 37#include "ap.h"
2f9929ff 38#include "ap/sta_info.h"
d8a43924 39#include "notify.h"
f1a48710
JM
40
41
0fe620de 42#ifdef CONFIG_WPS
70d84f11 43static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
0fe620de 44#endif /* CONFIG_WPS */
70d84f11
JM
45
46
c20bc9d4 47#ifdef CONFIG_IEEE80211N
ca9bc5b5 48static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
2124a615 49 struct wpa_ssid *ssid,
ca9bc5b5
EP
50 struct hostapd_config *conf,
51 struct hostapd_hw_modes *mode)
52{
fbba28f8 53#ifdef CONFIG_P2P
ca9bc5b5
EP
54 u8 center_chan = 0;
55 u8 channel = conf->channel;
fbba28f8 56#endif /* CONFIG_P2P */
ca9bc5b5
EP
57
58 if (!conf->secondary_channel)
59 goto no_vht;
60
2124a615
JB
61 /* Use the maximum oper channel width if it's given. */
62 if (ssid->max_oper_chwidth)
63 conf->vht_oper_chwidth = ssid->max_oper_chwidth;
64
65 ieee80211_freq_to_chan(ssid->vht_center_freq2,
66 &conf->vht_oper_centr_freq_seg1_idx);
67
68 if (!ssid->p2p_group) {
69 if (!ssid->vht_center_freq1 ||
70 conf->vht_oper_chwidth == VHT_CHANWIDTH_USE_HT)
71 goto no_vht;
72 ieee80211_freq_to_chan(ssid->vht_center_freq1,
73 &conf->vht_oper_centr_freq_seg0_idx);
616178a2
JM
74 wpa_printf(MSG_DEBUG, "VHT seg0 index %d for AP",
75 conf->vht_oper_centr_freq_seg0_idx);
2124a615
JB
76 return;
77 }
78
79#ifdef CONFIG_P2P
c27f4c90
AK
80 switch (conf->vht_oper_chwidth) {
81 case VHT_CHANWIDTH_80MHZ:
82 case VHT_CHANWIDTH_80P80MHZ:
83 center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
616178a2
JM
84 wpa_printf(MSG_DEBUG,
85 "VHT center channel %u for 80 or 80+80 MHz bandwidth",
86 center_chan);
c27f4c90
AK
87 break;
88 case VHT_CHANWIDTH_160MHZ:
89 center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
616178a2
JM
90 wpa_printf(MSG_DEBUG,
91 "VHT center channel %u for 160 MHz bandwidth",
92 center_chan);
c27f4c90
AK
93 break;
94 default:
95 /*
96 * conf->vht_oper_chwidth might not be set for non-P2P GO cases,
97 * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
98 * not supported.
99 */
100 conf->vht_oper_chwidth = VHT_CHANWIDTH_160MHZ;
101 center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
616178a2
JM
102 if (center_chan) {
103 wpa_printf(MSG_DEBUG,
104 "VHT center channel %u for auto-selected 160 MHz bandwidth",
105 center_chan);
106 } else {
c27f4c90
AK
107 conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
108 center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
109 channel);
616178a2
JM
110 wpa_printf(MSG_DEBUG,
111 "VHT center channel %u for auto-selected 80 MHz bandwidth",
112 center_chan);
c27f4c90
AK
113 }
114 break;
115 }
ca9bc5b5
EP
116 if (!center_chan)
117 goto no_vht;
118
ca9bc5b5 119 conf->vht_oper_centr_freq_seg0_idx = center_chan;
616178a2
JM
120 wpa_printf(MSG_DEBUG, "VHT seg0 index %d for P2P GO",
121 conf->vht_oper_centr_freq_seg0_idx);
ca9bc5b5 122 return;
2124a615 123#endif /* CONFIG_P2P */
ca9bc5b5
EP
124
125no_vht:
616178a2
JM
126 wpa_printf(MSG_DEBUG,
127 "No VHT higher bandwidth support for the selected channel %d",
128 conf->channel);
f8b10c17
JM
129 conf->vht_oper_centr_freq_seg0_idx =
130 conf->channel + conf->secondary_channel * 2;
83fe38b0 131 conf->vht_oper_chwidth = VHT_CHANWIDTH_USE_HT;
ca9bc5b5 132}
c20bc9d4 133#endif /* CONFIG_IEEE80211N */
ca9bc5b5
EP
134
135
73afc20d
AO
136int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
137 struct wpa_ssid *ssid,
138 struct hostapd_config *conf)
07f117ed 139{
73afc20d
AO
140 conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
141 &conf->channel);
142
143 if (conf->hw_mode == NUM_HOSTAPD_MODES) {
144 wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
145 ssid->frequency);
146 return -1;
147 }
148
2db91745 149 /* TODO: enable HT40 if driver supports it;
07f117ed
JM
150 * drop to 11b if driver does not support 11g */
151
2db91745
AC
152#ifdef CONFIG_IEEE80211N
153 /*
79b8c60f
AN
154 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
155 * and a mask of allowed capabilities within conf->ht_capab.
2db91745 156 * Using default config settings for: conf->ht_op_mode_fixed,
79b8c60f 157 * conf->secondary_channel, conf->require_ht
2db91745 158 */
6bf731e8 159 if (wpa_s->hw.modes) {
2db91745 160 struct hostapd_hw_modes *mode = NULL;
5cbf5fd9 161 int i, no_ht = 0;
616178a2
JM
162
163 wpa_printf(MSG_DEBUG,
164 "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
165 ssid->frequency, conf->channel);
166
6bf731e8
CL
167 for (i = 0; i < wpa_s->hw.num_modes; i++) {
168 if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
169 mode = &wpa_s->hw.modes[i];
2db91745
AC
170 break;
171 }
172 }
5cbf5fd9
VT
173
174#ifdef CONFIG_HT_OVERRIDES
b07ff9cb
JB
175 if (ssid->disable_ht)
176 ssid->ht = 0;
177#endif /* CONFIG_HT_OVERRIDES */
178
179 if (!ssid->ht) {
616178a2
JM
180 wpa_printf(MSG_DEBUG,
181 "HT not enabled in network profile");
5cbf5fd9
VT
182 conf->ieee80211n = 0;
183 conf->ht_capab = 0;
184 no_ht = 1;
185 }
5cbf5fd9
VT
186
187 if (!no_ht && mode && mode->ht_capab) {
616178a2
JM
188 wpa_printf(MSG_DEBUG,
189 "Enable HT support (p2p_group=%d 11a=%d ht40_hw_capab=%d ssid->ht40=%d)",
190 ssid->p2p_group,
191 conf->hw_mode == HOSTAPD_MODE_IEEE80211A,
192 !!(mode->ht_capab &
193 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
194 ssid->ht40);
2db91745 195 conf->ieee80211n = 1;
7aeac985 196#ifdef CONFIG_P2P
2124a615
JB
197 if (ssid->p2p_group &&
198 conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
7aeac985
RM
199 (mode->ht_capab &
200 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
616178a2 201 ssid->ht40) {
7aeac985
RM
202 conf->secondary_channel =
203 wpas_p2p_get_ht40_mode(wpa_s, mode,
204 conf->channel);
616178a2
JM
205 wpa_printf(MSG_DEBUG,
206 "HT secondary channel offset %d for P2P group",
207 conf->secondary_channel);
208 }
2124a615
JB
209#endif /* CONFIG_P2P */
210
211 if (!ssid->p2p_group &&
212 (mode->ht_capab &
616178a2 213 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
2124a615 214 conf->secondary_channel = ssid->ht40;
616178a2
JM
215 wpa_printf(MSG_DEBUG,
216 "HT secondary channel offset %d for AP",
217 conf->secondary_channel);
218 }
2124a615 219
7aeac985
RM
220 if (conf->secondary_channel)
221 conf->ht_capab |=
222 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
79b8c60f
AN
223
224 /*
225 * white-list capabilities that won't cause issues
226 * to connecting stations, while leaving the current
227 * capabilities intact (currently disabled SMPS).
228 */
229 conf->ht_capab |= mode->ht_capab &
230 (HT_CAP_INFO_GREEN_FIELD |
231 HT_CAP_INFO_SHORT_GI20MHZ |
232 HT_CAP_INFO_SHORT_GI40MHZ |
233 HT_CAP_INFO_RX_STBC_MASK |
fd83335f 234 HT_CAP_INFO_TX_STBC |
79b8c60f 235 HT_CAP_INFO_MAX_AMSDU_SIZE);
ca9bc5b5
EP
236
237 if (mode->vht_capab && ssid->vht) {
238 conf->ieee80211ac = 1;
f3e15705 239 conf->vht_capab |= mode->vht_capab;
2124a615 240 wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
ca9bc5b5 241 }
79b8c60f 242 }
2db91745 243 }
55413ce0
JM
244
245 if (conf->secondary_channel) {
246 struct wpa_supplicant *iface;
247
248 for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
249 {
250 if (iface == wpa_s ||
251 iface->wpa_state < WPA_AUTHENTICATING ||
252 (int) iface->assoc_freq != ssid->frequency)
253 continue;
254
255 /*
256 * Do not allow 40 MHz co-ex PRI/SEC switch to force us
257 * to change our PRI channel since we have an existing,
258 * concurrent connection on that channel and doing
259 * multi-channel concurrency is likely to cause more
260 * harm than using different PRI/SEC selection in
261 * environment with multiple BSSes on these two channels
262 * with mixed 20 MHz or PRI channel selection.
263 */
264 conf->no_pri_sec_switch = 1;
265 }
266 }
2db91745 267#endif /* CONFIG_IEEE80211N */
73afc20d
AO
268
269 return 0;
5cfb672d
JM
270}
271
272
273static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
274 struct wpa_ssid *ssid,
275 struct hostapd_config *conf)
276{
277 struct hostapd_bss_config *bss = conf->bss[0];
278
279 conf->driver = wpa_s->driver;
280
281 os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
282
73afc20d 283 if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf))
5cfb672d 284 return -1;
2db91745 285
90f14962
LD
286 if (ssid->pbss > 1) {
287 wpa_printf(MSG_ERROR, "Invalid pbss value(%d) for AP mode",
288 ssid->pbss);
289 return -1;
290 }
291 bss->pbss = ssid->pbss;
292
d9909717
TB
293#ifdef CONFIG_ACS
294 if (ssid->acs) {
295 /* Setting channel to 0 in order to enable ACS */
296 conf->channel = 0;
297 wpa_printf(MSG_DEBUG, "Use automatic channel selection");
298 }
299#endif /* CONFIG_ACS */
300
d239ab39 301 if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
302 wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
6e9023ea
JM
303 conf->ieee80211h = 1;
304 conf->ieee80211d = 1;
305 conf->country[0] = wpa_s->conf->country[0];
306 conf->country[1] = wpa_s->conf->country[1];
8f315d05 307 conf->country[2] = ' ';
6e9023ea
JM
308 }
309
4c2c3028 310#ifdef CONFIG_P2P
1e0e943e
AB
311 if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
312 (ssid->mode == WPAS_MODE_P2P_GO ||
313 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
4c2c3028
JM
314 /* Remove 802.11b rates from supported and basic rate sets */
315 int *list = os_malloc(4 * sizeof(int));
316 if (list) {
317 list[0] = 60;
318 list[1] = 120;
319 list[2] = 240;
320 list[3] = -1;
321 }
322 conf->basic_rates = list;
323
324 list = os_malloc(9 * sizeof(int));
325 if (list) {
326 list[0] = 60;
327 list[1] = 90;
328 list[2] = 120;
329 list[3] = 180;
330 list[4] = 240;
331 list[5] = 360;
332 list[6] = 480;
333 list[7] = 540;
334 list[8] = -1;
335 }
336 conf->supported_rates = list;
337 }
6cd930cb
JB
338
339 bss->isolate = !wpa_s->conf->p2p_intra_bss;
05766ed8 340 bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
25ef8529
JM
341
342 if (ssid->p2p_group) {
ba307f85
LD
343 os_memcpy(bss->ip_addr_go, wpa_s->p2pdev->conf->ip_addr_go, 4);
344 os_memcpy(bss->ip_addr_mask, wpa_s->p2pdev->conf->ip_addr_mask,
25ef8529
JM
345 4);
346 os_memcpy(bss->ip_addr_start,
ba307f85
LD
347 wpa_s->p2pdev->conf->ip_addr_start, 4);
348 os_memcpy(bss->ip_addr_end, wpa_s->p2pdev->conf->ip_addr_end,
25ef8529
JM
349 4);
350 }
4c2c3028
JM
351#endif /* CONFIG_P2P */
352
07f117ed
JM
353 if (ssid->ssid_len == 0) {
354 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
355 return -1;
356 }
357 os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
07f117ed
JM
358 bss->ssid.ssid_len = ssid->ssid_len;
359 bss->ssid.ssid_set = 1;
360
e62f4ed0
VN
361 bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
362
0399f2e4
VT
363 if (ssid->auth_alg)
364 bss->auth_algs = ssid->auth_alg;
365
07f117ed
JM
366 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
367 bss->wpa = ssid->proto;
66419543
JM
368 if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
369 bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
370 else
371 bss->wpa_key_mgmt = ssid->key_mgmt;
07f117ed 372 bss->wpa_pairwise = ssid->pairwise_cipher;
30c371e8 373 if (ssid->psk_set) {
ce52d031 374 bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk));
07f117ed
JM
375 bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
376 if (bss->ssid.wpa_psk == NULL)
377 return -1;
378 os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
379 bss->ssid.wpa_psk->group = 1;
23d71a02 380 bss->ssid.wpa_psk_set = 1;
30c371e8
MH
381 } else if (ssid->passphrase) {
382 bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
6bcb1c2b
JM
383 } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
384 ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
385 struct hostapd_wep_keys *wep = &bss->ssid.wep;
386 int i;
387 for (i = 0; i < NUM_WEP_KEYS; i++) {
388 if (ssid->wep_key_len[i] == 0)
389 continue;
a1f11e34
JB
390 wep->key[i] = os_memdup(ssid->wep_key[i],
391 ssid->wep_key_len[i]);
6bcb1c2b
JM
392 if (wep->key[i] == NULL)
393 return -1;
6bcb1c2b
JM
394 wep->len[i] = ssid->wep_key_len[i];
395 }
396 wep->idx = ssid->wep_tx_keyidx;
397 wep->keys_set = 1;
07f117ed
JM
398 }
399
63bc0ab0
SD
400 if (wpa_s->conf->go_interworking) {
401 wpa_printf(MSG_DEBUG,
402 "P2P: Enable Interworking with access_network_type: %d",
403 wpa_s->conf->go_access_network_type);
404 bss->interworking = wpa_s->conf->go_interworking;
405 bss->access_network_type = wpa_s->conf->go_access_network_type;
406 bss->internet = wpa_s->conf->go_internet;
407 if (wpa_s->conf->go_venue_group) {
408 wpa_printf(MSG_DEBUG,
409 "P2P: Venue group: %d Venue type: %d",
410 wpa_s->conf->go_venue_group,
411 wpa_s->conf->go_venue_type);
412 bss->venue_group = wpa_s->conf->go_venue_group;
413 bss->venue_type = wpa_s->conf->go_venue_type;
414 bss->venue_info_set = 1;
415 }
416 }
417
07f53b8c
VT
418 if (ssid->ap_max_inactivity)
419 bss->ap_max_inactivity = ssid->ap_max_inactivity;
420
fdfb1c8b
EL
421 if (ssid->dtim_period)
422 bss->dtim_period = ssid->dtim_period;
18206e02
JM
423 else if (wpa_s->conf->dtim_period)
424 bss->dtim_period = wpa_s->conf->dtim_period;
425
426 if (ssid->beacon_int)
427 conf->beacon_int = ssid->beacon_int;
428 else if (wpa_s->conf->beacon_int)
429 conf->beacon_int = wpa_s->conf->beacon_int;
fdfb1c8b 430
0b8bcaa5 431#ifdef CONFIG_P2P
0aed3f5a
AS
432 if (ssid->mode == WPAS_MODE_P2P_GO ||
433 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
434 if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) {
435 wpa_printf(MSG_INFO,
436 "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it",
437 wpa_s->conf->p2p_go_ctwindow,
438 conf->beacon_int);
439 conf->p2p_go_ctwindow = 0;
440 } else {
441 conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow;
442 }
0b8bcaa5
EP
443 }
444#endif /* CONFIG_P2P */
445
cf830c1c
JM
446 if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
447 bss->rsn_pairwise = bss->wpa_pairwise;
448 bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
449 bss->rsn_pairwise);
07d9a552
JM
450
451 if (bss->wpa && bss->ieee802_1x)
452 bss->ssid.security_policy = SECURITY_WPA;
453 else if (bss->wpa)
454 bss->ssid.security_policy = SECURITY_WPA_PSK;
455 else if (bss->ieee802_1x) {
697cd03f 456 int cipher = WPA_CIPHER_NONE;
07d9a552
JM
457 bss->ssid.security_policy = SECURITY_IEEE_802_1X;
458 bss->ssid.wep.default_len = bss->default_wep_key_len;
697cd03f
JM
459 if (bss->default_wep_key_len)
460 cipher = bss->default_wep_key_len >= 13 ?
461 WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
462 bss->wpa_group = cipher;
463 bss->wpa_pairwise = cipher;
464 bss->rsn_pairwise = cipher;
465 } else if (bss->ssid.wep.keys_set) {
466 int cipher = WPA_CIPHER_WEP40;
467 if (bss->ssid.wep.len[0] >= 13)
468 cipher = WPA_CIPHER_WEP104;
07d9a552 469 bss->ssid.security_policy = SECURITY_STATIC_WEP;
697cd03f
JM
470 bss->wpa_group = cipher;
471 bss->wpa_pairwise = cipher;
472 bss->rsn_pairwise = cipher;
473 } else {
07d9a552 474 bss->ssid.security_policy = SECURITY_PLAINTEXT;
697cd03f
JM
475 bss->wpa_group = WPA_CIPHER_NONE;
476 bss->wpa_pairwise = WPA_CIPHER_NONE;
477 bss->rsn_pairwise = WPA_CIPHER_NONE;
478 }
07d9a552 479
2a07a276
JM
480 if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
481 (bss->wpa_group == WPA_CIPHER_CCMP ||
30675c34
JM
482 bss->wpa_group == WPA_CIPHER_GCMP ||
483 bss->wpa_group == WPA_CIPHER_CCMP_256 ||
484 bss->wpa_group == WPA_CIPHER_GCMP_256)) {
2a07a276
JM
485 /*
486 * Strong ciphers do not need frequent rekeying, so increase
487 * the default GTK rekeying period to 24 hours.
488 */
489 bss->wpa_group_rekey = 86400;
490 }
491
9a1a538f
JM
492#ifdef CONFIG_IEEE80211W
493 if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
494 bss->ieee80211w = ssid->ieee80211w;
495#endif /* CONFIG_IEEE80211W */
875ab60d
MV
496
497#ifdef CONFIG_OCV
498 bss->ocv = ssid->ocv;
499#endif /* CONFIG_OCV */
9a1a538f 500
3ec97afe
JM
501#ifdef CONFIG_WPS
502 /*
04ed4e98
JM
503 * Enable WPS by default for open and WPA/WPA2-Personal network, but
504 * require user interaction to actually use it. Only the internal
505 * Registrar is supported.
3ec97afe 506 */
04ed4e98
JM
507 if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
508 bss->ssid.security_policy != SECURITY_PLAINTEXT)
509 goto no_wps;
c0f83f31 510 if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
d77419d2
AM
511 (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) ||
512 !(bss->wpa & 2)))
c0f83f31
JM
513 goto no_wps; /* WPS2 does not allow WPA/TKIP-only
514 * configuration */
b6317b41
LD
515 if (ssid->wps_disabled)
516 goto no_wps;
3ec97afe 517 bss->eap_server = 1;
e62f4ed0
VN
518
519 if (!ssid->ignore_broadcast_ssid)
520 bss->wps_state = 2;
521
9dd7d6b0 522 bss->ap_setup_locked = 2;
094393b1
JM
523 if (wpa_s->conf->config_methods)
524 bss->config_methods = os_strdup(wpa_s->conf->config_methods);
2f646b6e
JB
525 os_memcpy(bss->device_type, wpa_s->conf->device_type,
526 WPS_DEV_TYPE_LEN);
e44f8bf2
JM
527 if (wpa_s->conf->device_name) {
528 bss->device_name = os_strdup(wpa_s->conf->device_name);
529 bss->friendly_name = os_strdup(wpa_s->conf->device_name);
530 }
56815b2b
JM
531 if (wpa_s->conf->manufacturer)
532 bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
533 if (wpa_s->conf->model_name)
534 bss->model_name = os_strdup(wpa_s->conf->model_name);
535 if (wpa_s->conf->model_number)
536 bss->model_number = os_strdup(wpa_s->conf->model_number);
537 if (wpa_s->conf->serial_number)
538 bss->serial_number = os_strdup(wpa_s->conf->serial_number);
ab45223b
JM
539 if (is_nil_uuid(wpa_s->conf->uuid))
540 os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
541 else
542 os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
56815b2b 543 os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
1298c145 544 bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
b94fff1d
LD
545 if (ssid->eap.fragment_size != DEFAULT_FRAGMENT_SIZE)
546 bss->fragment_size = ssid->eap.fragment_size;
04ed4e98 547no_wps:
56815b2b 548#endif /* CONFIG_WPS */
e44f8bf2 549
de979d8f
JM
550 if (wpa_s->max_stations &&
551 wpa_s->max_stations < wpa_s->conf->max_num_sta)
552 bss->max_num_sta = wpa_s->max_stations;
553 else
554 bss->max_num_sta = wpa_s->conf->max_num_sta;
dae608d5 555
19e20c14
DR
556 if (!bss->isolate)
557 bss->isolate = wpa_s->conf->ap_isolate;
558
0d7e5a3a
JB
559 bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
560
18a2eaab
JM
561 if (wpa_s->conf->ap_vendor_elements) {
562 bss->vendor_elements =
563 wpabuf_dup(wpa_s->conf->ap_vendor_elements);
564 }
565
d1723c55
LD
566 bss->ftm_responder = wpa_s->conf->ftm_responder;
567 bss->ftm_initiator = wpa_s->conf->ftm_initiator;
568
07f117ed
JM
569 return 0;
570}
571
572
c706d5aa
JM
573static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
574{
e44f8bf2
JM
575#ifdef CONFIG_P2P
576 struct wpa_supplicant *wpa_s = ctx;
577 const struct ieee80211_mgmt *mgmt;
e44f8bf2
JM
578
579 mgmt = (const struct ieee80211_mgmt *) buf;
35c03184 580 if (len < IEEE80211_HDRLEN + 1)
e44f8bf2 581 return;
5ce00d09
JM
582 if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
583 return;
e44f8bf2
JM
584 wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
585 mgmt->u.action.category,
35c03184
JM
586 buf + IEEE80211_HDRLEN + 1,
587 len - IEEE80211_HDRLEN - 1, freq);
e44f8bf2
JM
588#endif /* CONFIG_P2P */
589}
590
591
a0dee797
AGS
592static void ap_wps_event_cb(void *ctx, enum wps_event event,
593 union wps_event_data *data)
594{
ca806fb5 595#ifdef CONFIG_P2P
a0dee797 596 struct wpa_supplicant *wpa_s = ctx;
8be6450c
JMB
597
598 if (event == WPS_EV_FAIL) {
599 struct wps_event_fail *fail = &data->fail;
600
ba307f85 601 if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s &&
8be6450c
JMB
602 wpa_s == wpa_s->global->p2p_group_formation) {
603 /*
604 * src/ap/wps_hostapd.c has already sent this on the
605 * main interface, so only send on the parent interface
606 * here if needed.
607 */
ba307f85 608 wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
8be6450c
JMB
609 "msg=%d config_error=%d",
610 fail->msg, fail->config_error);
611 }
612 wpas_p2p_wps_failed(wpa_s, fail);
a0dee797 613 }
ca806fb5 614#endif /* CONFIG_P2P */
a0dee797
AGS
615}
616
617
d8a43924 618static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
fbdcfd57 619 int authorized, const u8 *p2p_dev_addr)
d8a43924 620{
fbdcfd57 621 wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
d8a43924
JB
622}
623
624
01a57fe4
JM
625#ifdef CONFIG_P2P
626static void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
627 const u8 *psk, size_t psk_len)
628{
629
630 struct wpa_supplicant *wpa_s = ctx;
631 if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
632 return;
633 wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
634}
635#endif /* CONFIG_P2P */
636
637
e44f8bf2
JM
638static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
639{
640#ifdef CONFIG_P2P
641 struct wpa_supplicant *wpa_s = ctx;
642 const struct ieee80211_mgmt *mgmt;
e44f8bf2
JM
643
644 mgmt = (const struct ieee80211_mgmt *) buf;
fb5d4171 645 if (len < IEEE80211_HDRLEN + 1)
e44f8bf2
JM
646 return -1;
647 wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
648 mgmt->u.action.category,
fb5d4171
JM
649 buf + IEEE80211_HDRLEN + 1,
650 len - IEEE80211_HDRLEN - 1, freq);
e44f8bf2
JM
651#endif /* CONFIG_P2P */
652 return 0;
c706d5aa
JM
653}
654
655
04a85e44 656static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
baf513d6
JB
657 const u8 *bssid, const u8 *ie, size_t ie_len,
658 int ssi_signal)
c706d5aa 659{
e44f8bf2 660 struct wpa_supplicant *wpa_s = ctx;
0799b3f8
AO
661 unsigned int freq = 0;
662
663 if (wpa_s->ap_iface)
664 freq = wpa_s->ap_iface->freq;
665
baf513d6 666 return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
0799b3f8 667 freq, ssi_signal);
c706d5aa
JM
668}
669
670
671static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
672 const u8 *uuid_e)
673{
e44f8bf2
JM
674 struct wpa_supplicant *wpa_s = ctx;
675 wpas_p2p_wps_success(wpa_s, mac_addr, 1);
c706d5aa
JM
676}
677
678
c76e5d7f
JB
679static void wpas_ap_configured_cb(void *ctx)
680{
681 struct wpa_supplicant *wpa_s = ctx;
682
c4315e66
TM
683 wpa_printf(MSG_DEBUG, "AP interface setup completed - state %s",
684 hostapd_state_text(wpa_s->ap_iface->state));
685 if (wpa_s->ap_iface->state == HAPD_IFACE_DISABLED) {
686 wpa_supplicant_ap_deinit(wpa_s);
687 return;
688 }
689
d9909717 690#ifdef CONFIG_ACS
37ed3254 691 if (wpa_s->current_ssid && wpa_s->current_ssid->acs) {
d9909717 692 wpa_s->assoc_freq = wpa_s->ap_iface->freq;
37ed3254
SD
693 wpa_s->current_ssid->frequency = wpa_s->ap_iface->freq;
694 }
d9909717
TB
695#endif /* CONFIG_ACS */
696
c76e5d7f
JB
697 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
698
699 if (wpa_s->ap_configured_cb)
700 wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
701 wpa_s->ap_configured_cb_data);
702}
703
704
2d5b792d
JM
705int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
706 struct wpa_ssid *ssid)
707{
708 struct wpa_driver_associate_params params;
709 struct hostapd_iface *hapd_iface;
710 struct hostapd_config *conf;
711 size_t i;
f1a48710 712
2d5b792d
JM
713 if (ssid->ssid == NULL || ssid->ssid_len == 0) {
714 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
715 return -1;
f1a48710
JM
716 }
717
2d5b792d 718 wpa_supplicant_ap_deinit(wpa_s);
d2440ba0
JM
719
720 wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
721 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
722
723 os_memset(&params, 0, sizeof(params));
724 params.ssid = ssid->ssid;
725 params.ssid_len = ssid->ssid_len;
d7dcba70 726 switch (ssid->mode) {
d7dcba70 727 case WPAS_MODE_AP:
2c5d725c
JM
728 case WPAS_MODE_P2P_GO:
729 case WPAS_MODE_P2P_GROUP_FORMATION:
d7dcba70
JM
730 params.mode = IEEE80211_MODE_AP;
731 break;
94ff22ea
JM
732 default:
733 return -1;
d7dcba70 734 }
973622cd
AS
735 if (ssid->frequency == 0)
736 ssid->frequency = 2462; /* default channel 11 */
4ec68377 737 params.freq.freq = ssid->frequency;
d2440ba0 738
64fa840a 739 params.wpa_proto = ssid->proto;
508545f3
JM
740 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
741 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
742 else
743 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
4848a38d 744 params.key_mgmt_suite = wpa_s->key_mgmt;
508545f3 745
edbd2a19
JM
746 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
747 1);
748 if (wpa_s->pairwise_cipher < 0) {
508545f3
JM
749 wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
750 "cipher.");
751 return -1;
752 }
4848a38d 753 params.pairwise_suite = wpa_s->pairwise_cipher;
508545f3
JM
754 params.group_suite = params.pairwise_suite;
755
6e3f4b89
JM
756#ifdef CONFIG_P2P
757 if (ssid->mode == WPAS_MODE_P2P_GO ||
758 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
759 params.p2p = 1;
760#endif /* CONFIG_P2P */
761
ba307f85
LD
762 if (wpa_s->p2pdev->set_ap_uapsd)
763 params.uapsd = wpa_s->p2pdev->ap_uapsd;
94a3df50
JM
764 else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
765 params.uapsd = 1; /* mandatory for P2P GO */
eea2fd9e
JM
766 else
767 params.uapsd = -1;
768
d239ab39 769 if (ieee80211_is_dfs(params.freq.freq, wpa_s->hw.modes,
770 wpa_s->hw.num_modes))
6e9023ea
JM
771 params.freq.freq = 0; /* set channel after CAC */
772
cc9a2575
KV
773 if (params.p2p)
774 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_GO);
775 else
776 wpa_drv_get_ext_capa(wpa_s, WPA_IF_AP_BSS);
777
d2440ba0
JM
778 if (wpa_drv_associate(wpa_s, &params) < 0) {
779 wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
780 return -1;
781 }
782
5e993390 783 wpa_s->ap_iface = hapd_iface = hostapd_alloc_iface();
2d5b792d
JM
784 if (hapd_iface == NULL)
785 return -1;
0f2b2c19 786 hapd_iface->owner = wpa_s;
a57db49c 787 hapd_iface->drv_flags = wpa_s->drv_flags;
04ee647d 788 hapd_iface->smps_modes = wpa_s->drv_smps_modes;
4f73d88a 789 hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
8cd6b7bc
JB
790 hapd_iface->extended_capa = wpa_s->extended_capa;
791 hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
792 hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
1f1b62a0 793
2d5b792d
JM
794 wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
795 if (conf == NULL) {
796 wpa_supplicant_ap_deinit(wpa_s);
797 return -1;
798 }
1f1b62a0 799
c26effe1
YD
800 os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
801 wpa_s->conf->wmm_ac_params,
802 sizeof(wpa_s->conf->wmm_ac_params));
803
d26e45a4 804 if (params.uapsd > 0) {
ebd79f07
JM
805 conf->bss[0]->wmm_enabled = 1;
806 conf->bss[0]->wmm_uapsd = 1;
d26e45a4
EP
807 }
808
07f117ed
JM
809 if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
810 wpa_printf(MSG_ERROR, "Failed to create AP configuration");
811 wpa_supplicant_ap_deinit(wpa_s);
812 return -1;
813 }
814
e44f8bf2
JM
815#ifdef CONFIG_P2P
816 if (ssid->mode == WPAS_MODE_P2P_GO)
ebd79f07 817 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
e44f8bf2 818 else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
ebd79f07 819 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
e44f8bf2
JM
820 P2P_GROUP_FORMATION;
821#endif /* CONFIG_P2P */
822
2d5b792d 823 hapd_iface->num_bss = conf->num_bss;
f9884c09 824 hapd_iface->bss = os_calloc(conf->num_bss,
2d5b792d
JM
825 sizeof(struct hostapd_data *));
826 if (hapd_iface->bss == NULL) {
827 wpa_supplicant_ap_deinit(wpa_s);
828 return -1;
829 }
1f1b62a0 830
2d5b792d
JM
831 for (i = 0; i < conf->num_bss; i++) {
832 hapd_iface->bss[i] =
833 hostapd_alloc_bss_data(hapd_iface, conf,
ebd79f07 834 conf->bss[i]);
2d5b792d
JM
835 if (hapd_iface->bss[i] == NULL) {
836 wpa_supplicant_ap_deinit(wpa_s);
837 return -1;
838 }
4f760fcc
JM
839
840 hapd_iface->bss[i]->msg_ctx = wpa_s;
ba307f85 841 hapd_iface->bss[i]->msg_ctx_parent = wpa_s->p2pdev;
c706d5aa
JM
842 hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
843 hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
e44f8bf2
JM
844 hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
845 hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
c706d5aa
JM
846 hostapd_register_probereq_cb(hapd_iface->bss[i],
847 ap_probe_req_rx, wpa_s);
848 hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
849 hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
a0dee797
AGS
850 hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
851 hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
d8a43924
JB
852 hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
853 hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
e44f8bf2 854#ifdef CONFIG_P2P
01a57fe4
JM
855 hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
856 hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
e44f8bf2 857 hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
6f251b6b
JM
858 hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
859 ssid);
e44f8bf2 860#endif /* CONFIG_P2P */
c76e5d7f
JB
861 hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
862 hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
9d4ff04a
JM
863#ifdef CONFIG_TESTING_OPTIONS
864 hapd_iface->bss[i]->ext_eapol_frame_io =
865 wpa_s->ext_eapol_frame_io;
866#endif /* CONFIG_TESTING_OPTIONS */
2d5b792d
JM
867 }
868
a911a6e6
JM
869 os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
870 hapd_iface->bss[0]->driver = wpa_s->driver;
871 hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
872
e73edcaa 873 wpa_s->current_ssid = ssid;
25a8f9e3 874 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
e73edcaa
JM
875 os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
876 wpa_s->assoc_freq = ssid->frequency;
877
37ed3254
SD
878#if defined(CONFIG_P2P) && defined(CONFIG_ACS)
879 if (wpa_s->p2p_go_do_acs) {
880 wpa_s->ap_iface->conf->channel = 0;
881 wpa_s->ap_iface->conf->hw_mode = wpa_s->p2p_go_acs_band;
882 ssid->acs = 1;
883 }
884#endif /* CONFIG_P2P && CONFIG_ACS */
885
a911a6e6 886 if (hostapd_setup_interface(wpa_s->ap_iface)) {
2d5b792d
JM
887 wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
888 wpa_supplicant_ap_deinit(wpa_s);
889 return -1;
1f1b62a0
JM
890 }
891
2d5b792d
JM
892 return 0;
893}
894
895
896void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
897{
0fe620de 898#ifdef CONFIG_WPS
70d84f11 899 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
0fe620de 900#endif /* CONFIG_WPS */
70d84f11 901
2d5b792d
JM
902 if (wpa_s->ap_iface == NULL)
903 return;
904
7a649c7d 905 wpa_s->current_ssid = NULL;
25a8f9e3 906 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
3c85f144 907 wpa_s->assoc_freq = 0;
bd10d938 908 wpas_p2p_ap_deinit(wpa_s);
354c903f
MB
909 wpa_s->ap_iface->driver_ap_teardown =
910 !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
911
2d5b792d 912 hostapd_interface_deinit(wpa_s->ap_iface);
f7c47833 913 hostapd_interface_free(wpa_s->ap_iface);
2d5b792d 914 wpa_s->ap_iface = NULL;
7a649c7d 915 wpa_drv_deinit_ap(wpa_s);
f10487e1
JM
916 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
917 " reason=%d locally_generated=1",
918 MAC2STR(wpa_s->own_addr), WLAN_REASON_DEAUTH_LEAVING);
1f1b62a0 919}
0915d02c
JM
920
921
922void ap_tx_status(void *ctx, const u8 *addr,
923 const u8 *buf, size_t len, int ack)
924{
f8b1f695 925#ifdef NEED_AP_MLME
0915d02c
JM
926 struct wpa_supplicant *wpa_s = ctx;
927 hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
f8b1f695 928#endif /* NEED_AP_MLME */
0915d02c
JM
929}
930
931
dd840f79
JB
932void ap_eapol_tx_status(void *ctx, const u8 *dst,
933 const u8 *data, size_t len, int ack)
934{
935#ifdef NEED_AP_MLME
936 struct wpa_supplicant *wpa_s = ctx;
6fc61e18
JM
937 if (!wpa_s->ap_iface)
938 return;
dd840f79
JB
939 hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
940#endif /* NEED_AP_MLME */
941}
942
943
bcf24348
JB
944void ap_client_poll_ok(void *ctx, const u8 *addr)
945{
946#ifdef NEED_AP_MLME
947 struct wpa_supplicant *wpa_s = ctx;
948 if (wpa_s->ap_iface)
949 hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
950#endif /* NEED_AP_MLME */
951}
952
953
9b90955e 954void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
0915d02c 955{
f8b1f695 956#ifdef NEED_AP_MLME
0915d02c 957 struct wpa_supplicant *wpa_s = ctx;
9b90955e 958 ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
f8b1f695 959#endif /* NEED_AP_MLME */
0915d02c
JM
960}
961
962
2a8b7416 963void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
0915d02c 964{
f8b1f695 965#ifdef NEED_AP_MLME
0915d02c 966 struct wpa_supplicant *wpa_s = ctx;
2a8b7416
JM
967 struct hostapd_frame_info fi;
968 os_memset(&fi, 0, sizeof(fi));
969 fi.datarate = rx_mgmt->datarate;
970 fi.ssi_signal = rx_mgmt->ssi_signal;
971 ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
972 rx_mgmt->frame_len, &fi);
f8b1f695 973#endif /* NEED_AP_MLME */
0915d02c
JM
974}
975
976
f8b1f695 977void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
0915d02c 978{
f8b1f695 979#ifdef NEED_AP_MLME
0915d02c
JM
980 struct wpa_supplicant *wpa_s = ctx;
981 ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
fe6bdb77 982#endif /* NEED_AP_MLME */
f8b1f695 983}
db149ac9
JM
984
985
986void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
987 const u8 *src_addr, const u8 *buf, size_t len)
988{
a8e0505b 989 ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
db149ac9 990}
3ec97afe
JM
991
992
993#ifdef CONFIG_WPS
994
d601247c
JM
995int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
996 const u8 *p2p_dev_addr)
3ec97afe 997{
48b357a9
JM
998 if (!wpa_s->ap_iface)
999 return -1;
d601247c
JM
1000 return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
1001 p2p_dev_addr);
3ec97afe
JM
1002}
1003
1004
2f9929ff
AC
1005int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
1006{
1007 struct wps_registrar *reg;
1008 int reg_sel = 0, wps_sta = 0;
1009
1010 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
1011 return -1;
1012
1013 reg = wpa_s->ap_iface->bss[0]->wps->registrar;
1014 reg_sel = wps_registrar_wps_cancel(reg);
1015 wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
4c374cde 1016 ap_sta_wps_cancel, NULL);
2f9929ff
AC
1017
1018 if (!reg_sel && !wps_sta) {
1019 wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
1020 "time");
1021 return -1;
1022 }
1023
1024 /*
1025 * There are 2 cases to return wps cancel as success:
1026 * 1. When wps cancel was initiated but no connection has been
1027 * established with client yet.
1028 * 2. Client is in the middle of exchanging WPS messages.
1029 */
1030
1031 return 0;
1032}
1033
1034
3ec97afe 1035int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
c423708f
JM
1036 const char *pin, char *buf, size_t buflen,
1037 int timeout)
3ec97afe
JM
1038{
1039 int ret, ret_len = 0;
1040
48b357a9
JM
1041 if (!wpa_s->ap_iface)
1042 return -1;
1043
3ec97afe 1044 if (pin == NULL) {
98a516ea
NL
1045 unsigned int rpin;
1046
1047 if (wps_generate_pin(&rpin) < 0)
1048 return -1;
9337e876 1049 ret_len = os_snprintf(buf, buflen, "%08d", rpin);
aaadd727
JM
1050 if (os_snprintf_error(buflen, ret_len))
1051 return -1;
3ec97afe 1052 pin = buf;
aaadd727 1053 } else if (buf) {
f80a2237 1054 ret_len = os_snprintf(buf, buflen, "%s", pin);
aaadd727
JM
1055 if (os_snprintf_error(buflen, ret_len))
1056 return -1;
1057 }
3ec97afe 1058
31fcea93 1059 ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
c423708f 1060 timeout);
3ec97afe
JM
1061 if (ret)
1062 return -1;
1063 return ret_len;
1064}
1065
70d84f11
JM
1066
1067static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
1068{
1069 struct wpa_supplicant *wpa_s = eloop_data;
1070 wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
1071 wpas_wps_ap_pin_disable(wpa_s);
1072}
1073
1074
1075static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
1076{
1077 struct hostapd_data *hapd;
1078
1079 if (wpa_s->ap_iface == NULL)
1080 return;
1081 hapd = wpa_s->ap_iface->bss[0];
1082 wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
1083 hapd->ap_pin_failures = 0;
1084 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
1085 if (timeout > 0)
1086 eloop_register_timeout(timeout, 0,
1087 wpas_wps_ap_pin_timeout, wpa_s, NULL);
1088}
1089
1090
1091void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
1092{
1093 struct hostapd_data *hapd;
1094
1095 if (wpa_s->ap_iface == NULL)
1096 return;
1097 wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
1098 hapd = wpa_s->ap_iface->bss[0];
1099 os_free(hapd->conf->ap_pin);
1100 hapd->conf->ap_pin = NULL;
1101 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
1102}
1103
1104
1105const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
1106{
1107 struct hostapd_data *hapd;
1108 unsigned int pin;
1109 char pin_txt[9];
1110
1111 if (wpa_s->ap_iface == NULL)
1112 return NULL;
1113 hapd = wpa_s->ap_iface->bss[0];
98a516ea
NL
1114 if (wps_generate_pin(&pin) < 0)
1115 return NULL;
9337e876 1116 os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
70d84f11
JM
1117 os_free(hapd->conf->ap_pin);
1118 hapd->conf->ap_pin = os_strdup(pin_txt);
1119 if (hapd->conf->ap_pin == NULL)
1120 return NULL;
1121 wpas_wps_ap_pin_enable(wpa_s, timeout);
1122
1123 return hapd->conf->ap_pin;
1124}
1125
1126
1127const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
1128{
1129 struct hostapd_data *hapd;
1130 if (wpa_s->ap_iface == NULL)
1131 return NULL;
1132 hapd = wpa_s->ap_iface->bss[0];
1133 return hapd->conf->ap_pin;
1134}
1135
1136
1137int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
1138 int timeout)
1139{
1140 struct hostapd_data *hapd;
1141 char pin_txt[9];
1142 int ret;
1143
1144 if (wpa_s->ap_iface == NULL)
1145 return -1;
1146 hapd = wpa_s->ap_iface->bss[0];
1147 ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
d85e1fc8 1148 if (os_snprintf_error(sizeof(pin_txt), ret))
70d84f11
JM
1149 return -1;
1150 os_free(hapd->conf->ap_pin);
1151 hapd->conf->ap_pin = os_strdup(pin_txt);
1152 if (hapd->conf->ap_pin == NULL)
1153 return -1;
1154 wpas_wps_ap_pin_enable(wpa_s, timeout);
1155
1156 return 0;
1157}
1158
1159
1160void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
1161{
1162 struct hostapd_data *hapd;
1163
1164 if (wpa_s->ap_iface == NULL)
1165 return;
1166 hapd = wpa_s->ap_iface->bss[0];
1167
1168 /*
1169 * Registrar failed to prove its knowledge of the AP PIN. Disable AP
1170 * PIN if this happens multiple times to slow down brute force attacks.
1171 */
1172 hapd->ap_pin_failures++;
1173 wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
1174 hapd->ap_pin_failures);
1175 if (hapd->ap_pin_failures < 3)
1176 return;
1177
1178 wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
1179 hapd->ap_pin_failures = 0;
1180 os_free(hapd->conf->ap_pin);
1181 hapd->conf->ap_pin = NULL;
1182}
1183
bbf41865 1184
87470ea2
JM
1185#ifdef CONFIG_WPS_NFC
1186
bbf41865
JM
1187struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
1188 int ndef)
1189{
1190 struct hostapd_data *hapd;
1191
1192 if (wpa_s->ap_iface == NULL)
1193 return NULL;
1194 hapd = wpa_s->ap_iface->bss[0];
1195 return hostapd_wps_nfc_config_token(hapd, ndef);
1196}
1197
5ab9a6a5
JM
1198
1199struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
1200 int ndef)
1201{
1202 struct hostapd_data *hapd;
1203
1204 if (wpa_s->ap_iface == NULL)
1205 return NULL;
1206 hapd = wpa_s->ap_iface->bss[0];
1207 return hostapd_wps_nfc_hs_cr(hapd, ndef);
1208}
1209
d9507936
JM
1210
1211int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
1212 const struct wpabuf *req,
1213 const struct wpabuf *sel)
1214{
1215 struct hostapd_data *hapd;
1216
1217 if (wpa_s->ap_iface == NULL)
1218 return -1;
1219 hapd = wpa_s->ap_iface->bss[0];
1220 return hostapd_wps_nfc_report_handover(hapd, req, sel);
1221}
1222
87470ea2
JM
1223#endif /* CONFIG_WPS_NFC */
1224
3ec97afe 1225#endif /* CONFIG_WPS */
e653b622
JM
1226
1227
35deb646
JM
1228#ifdef CONFIG_CTRL_IFACE
1229
e653b622
JM
1230int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
1231 char *buf, size_t buflen)
1232{
e7700713
JM
1233 struct hostapd_data *hapd;
1234
1235 if (wpa_s->ap_iface)
1236 hapd = wpa_s->ap_iface->bss[0];
1237 else if (wpa_s->ifmsh)
1238 hapd = wpa_s->ifmsh->bss[0];
1239 else
e653b622 1240 return -1;
e7700713 1241 return hostapd_ctrl_iface_sta_first(hapd, buf, buflen);
e653b622
JM
1242}
1243
1244
1245int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
1246 char *buf, size_t buflen)
1247{
e7700713
JM
1248 struct hostapd_data *hapd;
1249
1250 if (wpa_s->ap_iface)
1251 hapd = wpa_s->ap_iface->bss[0];
1252 else if (wpa_s->ifmsh)
1253 hapd = wpa_s->ifmsh->bss[0];
1254 else
e653b622 1255 return -1;
e7700713 1256 return hostapd_ctrl_iface_sta(hapd, txtaddr, buf, buflen);
e653b622
JM
1257}
1258
1259
1260int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
1261 char *buf, size_t buflen)
1262{
e7700713
JM
1263 struct hostapd_data *hapd;
1264
1265 if (wpa_s->ap_iface)
1266 hapd = wpa_s->ap_iface->bss[0];
1267 else if (wpa_s->ifmsh)
1268 hapd = wpa_s->ifmsh->bss[0];
1269 else
e653b622 1270 return -1;
e7700713 1271 return hostapd_ctrl_iface_sta_next(hapd, txtaddr, buf, buflen);
e653b622 1272}
35deb646 1273
43fb5297 1274
e60b2951
JJ
1275int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
1276 const char *txtaddr)
1277{
1278 if (wpa_s->ap_iface == NULL)
1279 return -1;
1280 return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
1281 txtaddr);
1282}
1283
1284
1285int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
1286 const char *txtaddr)
1287{
1288 if (wpa_s->ap_iface == NULL)
1289 return -1;
1290 return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
1291 txtaddr);
1292}
1293
1294
43fb5297
JM
1295int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
1296 size_t buflen, int verbose)
1297{
1298 char *pos = buf, *end = buf + buflen;
1299 int ret;
1300 struct hostapd_bss_config *conf;
1301
1302 if (wpa_s->ap_iface == NULL)
1303 return -1;
1304
1305 conf = wpa_s->ap_iface->bss[0]->conf;
1306 if (conf->wpa == 0)
1307 return 0;
1308
1309 ret = os_snprintf(pos, end - pos,
1310 "pairwise_cipher=%s\n"
1311 "group_cipher=%s\n"
1312 "key_mgmt=%s\n",
1313 wpa_cipher_txt(conf->rsn_pairwise),
1314 wpa_cipher_txt(conf->wpa_group),
1315 wpa_key_mgmt_txt(conf->wpa_key_mgmt,
1316 conf->wpa));
d85e1fc8 1317 if (os_snprintf_error(end - pos, ret))
43fb5297
JM
1318 return pos - buf;
1319 pos += ret;
1320 return pos - buf;
1321}
1322
35deb646 1323#endif /* CONFIG_CTRL_IFACE */
f90ceeaa
JM
1324
1325
b22128ef
JM
1326int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
1327{
1328 struct hostapd_iface *iface = wpa_s->ap_iface;
1329 struct wpa_ssid *ssid = wpa_s->current_ssid;
1330 struct hostapd_data *hapd;
1331
72d48a80
JM
1332 if (ssid == NULL || wpa_s->ap_iface == NULL ||
1333 ssid->mode == WPAS_MODE_INFRA ||
1334 ssid->mode == WPAS_MODE_IBSS)
b22128ef
JM
1335 return -1;
1336
e44f8bf2
JM
1337#ifdef CONFIG_P2P
1338 if (ssid->mode == WPAS_MODE_P2P_GO)
ebd79f07 1339 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
e44f8bf2 1340 else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
ebd79f07 1341 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
e44f8bf2
JM
1342 P2P_GROUP_FORMATION;
1343#endif /* CONFIG_P2P */
1344
b22128ef 1345 hapd = iface->bss[0];
72d48a80
JM
1346 if (hapd->drv_priv == NULL)
1347 return -1;
1348 ieee802_11_set_beacons(iface);
fe99fb74 1349 hostapd_set_ap_wps_ie(hapd);
b22128ef
JM
1350
1351 return 0;
1352}
1353
1354
bf281c12
AO
1355int ap_switch_channel(struct wpa_supplicant *wpa_s,
1356 struct csa_settings *settings)
1357{
1358#ifdef NEED_AP_MLME
1359 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1360 return -1;
1361
1362 return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
1363#else /* NEED_AP_MLME */
1364 return -1;
1365#endif /* NEED_AP_MLME */
1366}
1367
1368
b7991185 1369#ifdef CONFIG_CTRL_IFACE
334bf36a
AO
1370int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1371{
1372 struct csa_settings settings;
1373 int ret = hostapd_parse_csa_settings(pos, &settings);
1374
1375 if (ret)
1376 return ret;
1377
1378 return ap_switch_channel(wpa_s, &settings);
1379}
b7991185 1380#endif /* CONFIG_CTRL_IFACE */
334bf36a
AO
1381
1382
1b487b8b 1383void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
8d1fdde7 1384 int offset, int width, int cf1, int cf2)
1b487b8b
TP
1385{
1386 if (!wpa_s->ap_iface)
1387 return;
1388
1389 wpa_s->assoc_freq = freq;
d7ded547
AO
1390 if (wpa_s->current_ssid)
1391 wpa_s->current_ssid->frequency = freq;
55b4cc6d
AO
1392 hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht,
1393 offset, width, cf1, cf2);
1b487b8b
TP
1394}
1395
1396
f90ceeaa
JM
1397int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
1398 const u8 *addr)
1399{
1400 struct hostapd_data *hapd;
1401 struct hostapd_bss_config *conf;
1402
1403 if (!wpa_s->ap_iface)
1404 return -1;
1405
1406 if (addr)
1407 wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
1408 MAC2STR(addr));
1409 else
1410 wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
1411
1412 hapd = wpa_s->ap_iface->bss[0];
1413 conf = hapd->conf;
1414
1415 os_free(conf->accept_mac);
1416 conf->accept_mac = NULL;
1417 conf->num_accept_mac = 0;
1418 os_free(conf->deny_mac);
1419 conf->deny_mac = NULL;
1420 conf->num_deny_mac = 0;
1421
1422 if (addr == NULL) {
1423 conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
1424 return 0;
1425 }
1426
1427 conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
1428 conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
1429 if (conf->accept_mac == NULL)
1430 return -1;
1431 os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
1432 conf->num_accept_mac = 1;
1433
1434 return 0;
1435}
db6ae69e
JM
1436
1437
1438#ifdef CONFIG_WPS_NFC
1439int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
1440 const struct wpabuf *pw, const u8 *pubkey_hash)
1441{
1442 struct hostapd_data *hapd;
1443 struct wps_context *wps;
1444
1445 if (!wpa_s->ap_iface)
1446 return -1;
1447 hapd = wpa_s->ap_iface->bss[0];
1448 wps = hapd->wps;
1449
ba307f85
LD
1450 if (wpa_s->p2pdev->conf->wps_nfc_dh_pubkey == NULL ||
1451 wpa_s->p2pdev->conf->wps_nfc_dh_privkey == NULL) {
db6ae69e
JM
1452 wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
1453 return -1;
1454 }
1455
1456 dh5_free(wps->dh_ctx);
1457 wpabuf_free(wps->dh_pubkey);
1458 wpabuf_free(wps->dh_privkey);
1459 wps->dh_privkey = wpabuf_dup(
ba307f85 1460 wpa_s->p2pdev->conf->wps_nfc_dh_privkey);
db6ae69e 1461 wps->dh_pubkey = wpabuf_dup(
ba307f85 1462 wpa_s->p2pdev->conf->wps_nfc_dh_pubkey);
db6ae69e
JM
1463 if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
1464 wps->dh_ctx = NULL;
1465 wpabuf_free(wps->dh_pubkey);
1466 wps->dh_pubkey = NULL;
1467 wpabuf_free(wps->dh_privkey);
1468 wps->dh_privkey = NULL;
1469 return -1;
1470 }
1471 wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
1472 if (wps->dh_ctx == NULL)
1473 return -1;
1474
1475 return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
1476 pw_id,
1477 pw ? wpabuf_head(pw) : NULL,
1478 pw ? wpabuf_len(pw) : 0, 1);
1479}
1480#endif /* CONFIG_WPS_NFC */
99650cad
JM
1481
1482
b7991185 1483#ifdef CONFIG_CTRL_IFACE
99650cad
JM
1484int wpas_ap_stop_ap(struct wpa_supplicant *wpa_s)
1485{
1486 struct hostapd_data *hapd;
1487
1488 if (!wpa_s->ap_iface)
1489 return -1;
1490 hapd = wpa_s->ap_iface->bss[0];
1491 return hostapd_ctrl_iface_stop_ap(hapd);
1492}
bd0f68c4
AK
1493
1494
b8daac18
MH
1495int wpas_ap_pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf,
1496 size_t len)
1497{
1498 size_t reply_len = 0, i;
1499 char ap_delimiter[] = "---- AP ----\n";
1500 char mesh_delimiter[] = "---- mesh ----\n";
1501 size_t dlen;
1502
1503 if (wpa_s->ap_iface) {
1504 dlen = os_strlen(ap_delimiter);
1505 if (dlen > len - reply_len)
1506 return reply_len;
1507 os_memcpy(&buf[reply_len], ap_delimiter, dlen);
1508 reply_len += dlen;
1509
1510 for (i = 0; i < wpa_s->ap_iface->num_bss; i++) {
1511 reply_len += hostapd_ctrl_iface_pmksa_list(
1512 wpa_s->ap_iface->bss[i],
1513 &buf[reply_len], len - reply_len);
1514 }
1515 }
1516
1517 if (wpa_s->ifmsh) {
1518 dlen = os_strlen(mesh_delimiter);
1519 if (dlen > len - reply_len)
1520 return reply_len;
1521 os_memcpy(&buf[reply_len], mesh_delimiter, dlen);
1522 reply_len += dlen;
1523
1524 reply_len += hostapd_ctrl_iface_pmksa_list(
1525 wpa_s->ifmsh->bss[0], &buf[reply_len],
1526 len - reply_len);
1527 }
1528
1529 return reply_len;
1530}
1531
1532
4c522c77
MH
1533void wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
1534{
1535 size_t i;
1536
1537 if (wpa_s->ap_iface) {
1538 for (i = 0; i < wpa_s->ap_iface->num_bss; i++)
1539 hostapd_ctrl_iface_pmksa_flush(wpa_s->ap_iface->bss[i]);
1540 }
1541
1542 if (wpa_s->ifmsh)
1543 hostapd_ctrl_iface_pmksa_flush(wpa_s->ifmsh->bss[0]);
1544}
4d77d80e
MH
1545
1546
1547#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
1548#ifdef CONFIG_MESH
1549
1550int wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
1551 char *buf, size_t len)
1552{
1553 return hostapd_ctrl_iface_pmksa_list_mesh(wpa_s->ifmsh->bss[0], addr,
1554 &buf[0], len);
1555}
1556
1557
1558int wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd)
1559{
1560 struct external_pmksa_cache *entry;
1561 void *pmksa_cache;
1562
1563 pmksa_cache = hostapd_ctrl_iface_pmksa_create_entry(wpa_s->own_addr,
1564 cmd);
1565 if (!pmksa_cache)
1566 return -1;
1567
1568 entry = os_zalloc(sizeof(struct external_pmksa_cache));
1569 if (!entry)
1570 return -1;
1571
1572 entry->pmksa_cache = pmksa_cache;
1573
1574 dl_list_add(&wpa_s->mesh_external_pmksa_cache, &entry->list);
1575
1576 return 0;
1577}
1578
1579#endif /* CONFIG_MESH */
1580#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
1581
3dd0e9e4 1582#endif /* CONFIG_CTRL_IFACE */
4c522c77
MH
1583
1584
bd0f68c4 1585#ifdef NEED_AP_MLME
2dd5fbbf
DL
1586void wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
1587 struct dfs_event *radar)
bd0f68c4
AK
1588{
1589 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1590 return;
1591 wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
1592 hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq,
1593 radar->ht_enabled, radar->chan_offset,
1594 radar->chan_width,
1595 radar->cf1, radar->cf2);
1596}
1597
1598
2dd5fbbf
DL
1599void wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
1600 struct dfs_event *radar)
bd0f68c4
AK
1601{
1602 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1603 return;
1604 wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
1605 hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq,
1606 radar->ht_enabled, radar->chan_offset,
1607 radar->chan_width, radar->cf1, radar->cf2);
1608}
1609
1610
2dd5fbbf
DL
1611void wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
1612 struct dfs_event *radar)
bd0f68c4
AK
1613{
1614 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1615 return;
1616 wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
1617 hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq,
1618 radar->ht_enabled, radar->chan_offset,
1619 radar->chan_width, radar->cf1, radar->cf2);
1620}
1621
1622
2dd5fbbf
DL
1623void wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
1624 struct dfs_event *radar)
bd0f68c4
AK
1625{
1626 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1627 return;
1628 wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
1629 hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq,
1630 radar->ht_enabled, radar->chan_offset,
1631 radar->chan_width, radar->cf1, radar->cf2);
1632}
1633
1634
2dd5fbbf
DL
1635void wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
1636 struct dfs_event *radar)
bd0f68c4
AK
1637{
1638 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1639 return;
1640 wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
1641 hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq,
1642 radar->ht_enabled, radar->chan_offset,
1643 radar->chan_width, radar->cf1, radar->cf2);
1644}
1645#endif /* NEED_AP_MLME */
3188aaba
JM
1646
1647
1648void ap_periodic(struct wpa_supplicant *wpa_s)
1649{
1650 if (wpa_s->ap_iface)
1651 hostapd_periodic_iface(wpa_s->ap_iface);
1652}