blob: 27fa2a9b28b68bbf68d6c6a07b084565fce15a5f [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
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 *
Dmitry Shmidtc5ec7f52012-03-06 16:33:24 -08006 * This software may be distributed under the terms of the BSD license.
7 * See README for more details.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07008 */
9
10#include "utils/includes.h"
11
12#include "utils/common.h"
13#include "utils/eloop.h"
14#include "utils/uuid.h"
15#include "common/ieee802_11_defs.h"
16#include "common/wpa_ctrl.h"
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -070017#include "eapol_supp/eapol_supp_sm.h"
Dmitry Shmidtcf32e602014-01-28 10:57:39 -080018#include "crypto/dh_group5.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070019#include "ap/hostapd.h"
20#include "ap/ap_config.h"
21#include "ap/ap_drv_ops.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080022#ifdef NEED_AP_MLME
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070023#include "ap/ieee802_11.h"
24#endif /* NEED_AP_MLME */
25#include "ap/beacon.h"
26#include "ap/ieee802_1x.h"
27#include "ap/wps_hostapd.h"
28#include "ap/ctrl_iface_ap.h"
Dmitry Shmidt203eadb2015-03-05 14:16:04 -080029#include "ap/dfs.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070030#include "wps/wps.h"
31#include "common/ieee802_11_defs.h"
32#include "config_ssid.h"
33#include "config.h"
34#include "wpa_supplicant_i.h"
35#include "driver_i.h"
36#include "p2p_supplicant.h"
37#include "ap.h"
38#include "ap/sta_info.h"
39#include "notify.h"
40
41
42#ifdef CONFIG_WPS
43static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
44#endif /* CONFIG_WPS */
45
46
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -070047#ifdef CONFIG_IEEE80211N
48static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
49 struct hostapd_config *conf,
50 struct hostapd_hw_modes *mode)
51{
Dmitry Shmidt21de2142014-04-08 10:50:52 -070052#ifdef CONFIG_P2P
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -070053 u8 center_chan = 0;
54 u8 channel = conf->channel;
55
56 if (!conf->secondary_channel)
57 goto no_vht;
58
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -080059 switch (conf->vht_oper_chwidth) {
60 case VHT_CHANWIDTH_80MHZ:
61 case VHT_CHANWIDTH_80P80MHZ:
62 center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
63 break;
64 case VHT_CHANWIDTH_160MHZ:
65 center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
66 break;
67 default:
68 /*
69 * conf->vht_oper_chwidth might not be set for non-P2P GO cases,
70 * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
71 * not supported.
72 */
73 conf->vht_oper_chwidth = VHT_CHANWIDTH_160MHZ;
74 center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
75 if (!center_chan) {
76 conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
77 center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
78 channel);
79 }
80 break;
81 }
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -070082 if (!center_chan)
83 goto no_vht;
84
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -070085 conf->vht_oper_centr_freq_seg0_idx = center_chan;
86 return;
87
88no_vht:
89 conf->vht_oper_centr_freq_seg0_idx =
90 channel + conf->secondary_channel * 2;
Dmitry Shmidt21de2142014-04-08 10:50:52 -070091#else /* CONFIG_P2P */
92 conf->vht_oper_centr_freq_seg0_idx =
93 conf->channel + conf->secondary_channel * 2;
94#endif /* CONFIG_P2P */
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -070095}
96#endif /* CONFIG_IEEE80211N */
97
98
Dmitry Shmidtd80a4012015-11-05 16:35:40 -080099int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
100 struct wpa_ssid *ssid,
101 struct hostapd_config *conf)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700102{
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800103 conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
104 &conf->channel);
105
106 if (conf->hw_mode == NUM_HOSTAPD_MODES) {
107 wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
108 ssid->frequency);
109 return -1;
110 }
111
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700112 /* TODO: enable HT40 if driver supports it;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700113 * drop to 11b if driver does not support 11g */
114
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700115#ifdef CONFIG_IEEE80211N
116 /*
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800117 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
118 * and a mask of allowed capabilities within conf->ht_capab.
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700119 * Using default config settings for: conf->ht_op_mode_fixed,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800120 * conf->secondary_channel, conf->require_ht
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700121 */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800122 if (wpa_s->hw.modes) {
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700123 struct hostapd_hw_modes *mode = NULL;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700124 int i, no_ht = 0;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800125 for (i = 0; i < wpa_s->hw.num_modes; i++) {
126 if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
127 mode = &wpa_s->hw.modes[i];
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700128 break;
129 }
130 }
Dmitry Shmidt04949592012-07-19 12:16:46 -0700131
132#ifdef CONFIG_HT_OVERRIDES
133 if (ssid->disable_ht) {
134 conf->ieee80211n = 0;
135 conf->ht_capab = 0;
136 no_ht = 1;
137 }
138#endif /* CONFIG_HT_OVERRIDES */
139
140 if (!no_ht && mode && mode->ht_capab) {
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700141 conf->ieee80211n = 1;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700142#ifdef CONFIG_P2P
143 if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
144 (mode->ht_capab &
145 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
146 ssid->ht40)
147 conf->secondary_channel =
148 wpas_p2p_get_ht40_mode(wpa_s, mode,
149 conf->channel);
150 if (conf->secondary_channel)
151 conf->ht_capab |=
152 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
153#endif /* CONFIG_P2P */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800154
155 /*
156 * white-list capabilities that won't cause issues
157 * to connecting stations, while leaving the current
158 * capabilities intact (currently disabled SMPS).
159 */
160 conf->ht_capab |= mode->ht_capab &
161 (HT_CAP_INFO_GREEN_FIELD |
162 HT_CAP_INFO_SHORT_GI20MHZ |
163 HT_CAP_INFO_SHORT_GI40MHZ |
164 HT_CAP_INFO_RX_STBC_MASK |
Dmitry Shmidt2f74e362015-01-21 13:19:05 -0800165 HT_CAP_INFO_TX_STBC |
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800166 HT_CAP_INFO_MAX_AMSDU_SIZE);
Dmitry Shmidt68d0e3e2013-10-28 17:59:21 -0700167
168 if (mode->vht_capab && ssid->vht) {
169 conf->ieee80211ac = 1;
170 wpas_conf_ap_vht(wpa_s, conf, mode);
171 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800172 }
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700173 }
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800174
175 if (conf->secondary_channel) {
176 struct wpa_supplicant *iface;
177
178 for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
179 {
180 if (iface == wpa_s ||
181 iface->wpa_state < WPA_AUTHENTICATING ||
182 (int) iface->assoc_freq != ssid->frequency)
183 continue;
184
185 /*
186 * Do not allow 40 MHz co-ex PRI/SEC switch to force us
187 * to change our PRI channel since we have an existing,
188 * concurrent connection on that channel and doing
189 * multi-channel concurrency is likely to cause more
190 * harm than using different PRI/SEC selection in
191 * environment with multiple BSSes on these two channels
192 * with mixed 20 MHz or PRI channel selection.
193 */
194 conf->no_pri_sec_switch = 1;
195 }
196 }
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700197#endif /* CONFIG_IEEE80211N */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800198
199 return 0;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800200}
201
202
203static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
204 struct wpa_ssid *ssid,
205 struct hostapd_config *conf)
206{
207 struct hostapd_bss_config *bss = conf->bss[0];
208
209 conf->driver = wpa_s->driver;
210
211 os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
212
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800213 if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf))
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800214 return -1;
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700215
Dmitry Shmidt203eadb2015-03-05 14:16:04 -0800216 if (ieee80211_is_dfs(ssid->frequency) && wpa_s->conf->country[0]) {
217 conf->ieee80211h = 1;
218 conf->ieee80211d = 1;
219 conf->country[0] = wpa_s->conf->country[0];
220 conf->country[1] = wpa_s->conf->country[1];
221 }
222
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700223#ifdef CONFIG_P2P
Dmitry Shmidt34af3062013-07-11 10:46:32 -0700224 if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
225 (ssid->mode == WPAS_MODE_P2P_GO ||
226 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700227 /* Remove 802.11b rates from supported and basic rate sets */
228 int *list = os_malloc(4 * sizeof(int));
229 if (list) {
230 list[0] = 60;
231 list[1] = 120;
232 list[2] = 240;
233 list[3] = -1;
234 }
235 conf->basic_rates = list;
236
237 list = os_malloc(9 * sizeof(int));
238 if (list) {
239 list[0] = 60;
240 list[1] = 90;
241 list[2] = 120;
242 list[3] = 180;
243 list[4] = 240;
244 list[5] = 360;
245 list[6] = 480;
246 list[7] = 540;
247 list[8] = -1;
248 }
249 conf->supported_rates = list;
250 }
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800251
252 bss->isolate = !wpa_s->conf->p2p_intra_bss;
Dmitry Shmidt391c59f2013-09-03 12:16:28 -0700253 bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
Dmitry Shmidtcf32e602014-01-28 10:57:39 -0800254
255 if (ssid->p2p_group) {
256 os_memcpy(bss->ip_addr_go, wpa_s->parent->conf->ip_addr_go, 4);
257 os_memcpy(bss->ip_addr_mask, wpa_s->parent->conf->ip_addr_mask,
258 4);
259 os_memcpy(bss->ip_addr_start,
260 wpa_s->parent->conf->ip_addr_start, 4);
261 os_memcpy(bss->ip_addr_end, wpa_s->parent->conf->ip_addr_end,
262 4);
263 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700264#endif /* CONFIG_P2P */
265
266 if (ssid->ssid_len == 0) {
267 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
268 return -1;
269 }
270 os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700271 bss->ssid.ssid_len = ssid->ssid_len;
272 bss->ssid.ssid_set = 1;
273
Dmitry Shmidt04949592012-07-19 12:16:46 -0700274 bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
275
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800276 if (ssid->auth_alg)
277 bss->auth_algs = ssid->auth_alg;
278
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700279 if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
280 bss->wpa = ssid->proto;
281 bss->wpa_key_mgmt = ssid->key_mgmt;
282 bss->wpa_pairwise = ssid->pairwise_cipher;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800283 if (ssid->psk_set) {
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800284 bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk));
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700285 bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
286 if (bss->ssid.wpa_psk == NULL)
287 return -1;
288 os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
289 bss->ssid.wpa_psk->group = 1;
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800290 } else if (ssid->passphrase) {
291 bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800292 } else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
293 ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
294 struct hostapd_wep_keys *wep = &bss->ssid.wep;
295 int i;
296 for (i = 0; i < NUM_WEP_KEYS; i++) {
297 if (ssid->wep_key_len[i] == 0)
298 continue;
299 wep->key[i] = os_malloc(ssid->wep_key_len[i]);
300 if (wep->key[i] == NULL)
301 return -1;
302 os_memcpy(wep->key[i], ssid->wep_key[i],
303 ssid->wep_key_len[i]);
304 wep->len[i] = ssid->wep_key_len[i];
305 }
306 wep->idx = ssid->wep_tx_keyidx;
307 wep->keys_set = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700308 }
309
Dmitry Shmidt04949592012-07-19 12:16:46 -0700310 if (ssid->ap_max_inactivity)
311 bss->ap_max_inactivity = ssid->ap_max_inactivity;
312
313 if (ssid->dtim_period)
314 bss->dtim_period = ssid->dtim_period;
Dmitry Shmidt7a5e50a2013-03-05 12:37:16 -0800315 else if (wpa_s->conf->dtim_period)
316 bss->dtim_period = wpa_s->conf->dtim_period;
317
318 if (ssid->beacon_int)
319 conf->beacon_int = ssid->beacon_int;
320 else if (wpa_s->conf->beacon_int)
321 conf->beacon_int = wpa_s->conf->beacon_int;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700322
Dmitry Shmidt7f656022015-02-25 14:36:37 -0800323#ifdef CONFIG_P2P
Dmitry Shmidtd80a4012015-11-05 16:35:40 -0800324 if (ssid->mode == WPAS_MODE_P2P_GO ||
325 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
326 if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) {
327 wpa_printf(MSG_INFO,
328 "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it",
329 wpa_s->conf->p2p_go_ctwindow,
330 conf->beacon_int);
331 conf->p2p_go_ctwindow = 0;
332 } else {
333 conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow;
334 }
Dmitry Shmidt7f656022015-02-25 14:36:37 -0800335 }
336#endif /* CONFIG_P2P */
337
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -0800338 if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
339 bss->rsn_pairwise = bss->wpa_pairwise;
340 bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
341 bss->rsn_pairwise);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700342
343 if (bss->wpa && bss->ieee802_1x)
344 bss->ssid.security_policy = SECURITY_WPA;
345 else if (bss->wpa)
346 bss->ssid.security_policy = SECURITY_WPA_PSK;
347 else if (bss->ieee802_1x) {
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800348 int cipher = WPA_CIPHER_NONE;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700349 bss->ssid.security_policy = SECURITY_IEEE_802_1X;
350 bss->ssid.wep.default_len = bss->default_wep_key_len;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800351 if (bss->default_wep_key_len)
352 cipher = bss->default_wep_key_len >= 13 ?
353 WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
354 bss->wpa_group = cipher;
355 bss->wpa_pairwise = cipher;
356 bss->rsn_pairwise = cipher;
357 } else if (bss->ssid.wep.keys_set) {
358 int cipher = WPA_CIPHER_WEP40;
359 if (bss->ssid.wep.len[0] >= 13)
360 cipher = WPA_CIPHER_WEP104;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700361 bss->ssid.security_policy = SECURITY_STATIC_WEP;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800362 bss->wpa_group = cipher;
363 bss->wpa_pairwise = cipher;
364 bss->rsn_pairwise = cipher;
365 } else {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700366 bss->ssid.security_policy = SECURITY_PLAINTEXT;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800367 bss->wpa_group = WPA_CIPHER_NONE;
368 bss->wpa_pairwise = WPA_CIPHER_NONE;
369 bss->rsn_pairwise = WPA_CIPHER_NONE;
370 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700371
Dmitry Shmidt8da800a2013-04-24 12:57:01 -0700372 if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
373 (bss->wpa_group == WPA_CIPHER_CCMP ||
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800374 bss->wpa_group == WPA_CIPHER_GCMP ||
375 bss->wpa_group == WPA_CIPHER_CCMP_256 ||
376 bss->wpa_group == WPA_CIPHER_GCMP_256)) {
Dmitry Shmidt8da800a2013-04-24 12:57:01 -0700377 /*
378 * Strong ciphers do not need frequent rekeying, so increase
379 * the default GTK rekeying period to 24 hours.
380 */
381 bss->wpa_group_rekey = 86400;
382 }
383
Dmitry Shmidtb36ed7c2014-03-17 10:57:26 -0700384#ifdef CONFIG_IEEE80211W
385 if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
386 bss->ieee80211w = ssid->ieee80211w;
387#endif /* CONFIG_IEEE80211W */
388
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700389#ifdef CONFIG_WPS
390 /*
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800391 * Enable WPS by default for open and WPA/WPA2-Personal network, but
392 * require user interaction to actually use it. Only the internal
393 * Registrar is supported.
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700394 */
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800395 if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
396 bss->ssid.security_policy != SECURITY_PLAINTEXT)
397 goto no_wps;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800398 if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800399 (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) ||
400 !(bss->wpa & 2)))
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800401 goto no_wps; /* WPS2 does not allow WPA/TKIP-only
402 * configuration */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700403 bss->eap_server = 1;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700404
405 if (!ssid->ignore_broadcast_ssid)
406 bss->wps_state = 2;
407
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700408 bss->ap_setup_locked = 2;
409 if (wpa_s->conf->config_methods)
410 bss->config_methods = os_strdup(wpa_s->conf->config_methods);
411 os_memcpy(bss->device_type, wpa_s->conf->device_type,
412 WPS_DEV_TYPE_LEN);
413 if (wpa_s->conf->device_name) {
414 bss->device_name = os_strdup(wpa_s->conf->device_name);
415 bss->friendly_name = os_strdup(wpa_s->conf->device_name);
416 }
417 if (wpa_s->conf->manufacturer)
418 bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
419 if (wpa_s->conf->model_name)
420 bss->model_name = os_strdup(wpa_s->conf->model_name);
421 if (wpa_s->conf->model_number)
422 bss->model_number = os_strdup(wpa_s->conf->model_number);
423 if (wpa_s->conf->serial_number)
424 bss->serial_number = os_strdup(wpa_s->conf->serial_number);
425 if (is_nil_uuid(wpa_s->conf->uuid))
426 os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
427 else
428 os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
429 os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
Dmitry Shmidt04949592012-07-19 12:16:46 -0700430 bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800431no_wps:
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700432#endif /* CONFIG_WPS */
433
434 if (wpa_s->max_stations &&
435 wpa_s->max_stations < wpa_s->conf->max_num_sta)
436 bss->max_num_sta = wpa_s->max_stations;
437 else
438 bss->max_num_sta = wpa_s->conf->max_num_sta;
439
440 bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
441
Dmitry Shmidt0ccb66e2013-03-29 16:41:28 -0700442 if (wpa_s->conf->ap_vendor_elements) {
443 bss->vendor_elements =
444 wpabuf_dup(wpa_s->conf->ap_vendor_elements);
445 }
446
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700447 return 0;
448}
449
450
451static void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
452{
453#ifdef CONFIG_P2P
454 struct wpa_supplicant *wpa_s = ctx;
455 const struct ieee80211_mgmt *mgmt;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700456
457 mgmt = (const struct ieee80211_mgmt *) buf;
Dmitry Shmidt623d63a2014-06-13 11:05:14 -0700458 if (len < IEEE80211_HDRLEN + 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700459 return;
Dmitry Shmidt18463232014-01-24 12:29:41 -0800460 if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
461 return;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700462 wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
463 mgmt->u.action.category,
Dmitry Shmidt623d63a2014-06-13 11:05:14 -0700464 buf + IEEE80211_HDRLEN + 1,
465 len - IEEE80211_HDRLEN - 1, freq);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700466#endif /* CONFIG_P2P */
467}
468
469
470static void ap_wps_event_cb(void *ctx, enum wps_event event,
471 union wps_event_data *data)
472{
473#ifdef CONFIG_P2P
474 struct wpa_supplicant *wpa_s = ctx;
475
Jouni Malinen75ecf522011-06-27 15:19:46 -0700476 if (event == WPS_EV_FAIL) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700477 struct wps_event_fail *fail = &data->fail;
478
Jouni Malinen75ecf522011-06-27 15:19:46 -0700479 if (wpa_s->parent && wpa_s->parent != wpa_s &&
480 wpa_s == wpa_s->global->p2p_group_formation) {
481 /*
482 * src/ap/wps_hostapd.c has already sent this on the
483 * main interface, so only send on the parent interface
484 * here if needed.
485 */
486 wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
487 "msg=%d config_error=%d",
488 fail->msg, fail->config_error);
489 }
490 wpas_p2p_wps_failed(wpa_s, fail);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700491 }
492#endif /* CONFIG_P2P */
493}
494
495
496static void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800497 int authorized, const u8 *p2p_dev_addr)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700498{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800499 wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700500}
501
502
Dmitry Shmidt391c59f2013-09-03 12:16:28 -0700503#ifdef CONFIG_P2P
504static void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
505 const u8 *psk, size_t psk_len)
506{
507
508 struct wpa_supplicant *wpa_s = ctx;
509 if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
510 return;
511 wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
512}
513#endif /* CONFIG_P2P */
514
515
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700516static int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
517{
518#ifdef CONFIG_P2P
519 struct wpa_supplicant *wpa_s = ctx;
520 const struct ieee80211_mgmt *mgmt;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700521
522 mgmt = (const struct ieee80211_mgmt *) buf;
Dmitry Shmidt623d63a2014-06-13 11:05:14 -0700523 if (len < IEEE80211_HDRLEN + 1)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700524 return -1;
525 wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
526 mgmt->u.action.category,
Dmitry Shmidt623d63a2014-06-13 11:05:14 -0700527 buf + IEEE80211_HDRLEN + 1,
528 len - IEEE80211_HDRLEN - 1, freq);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700529#endif /* CONFIG_P2P */
530 return 0;
531}
532
533
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800534static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
Dmitry Shmidt04949592012-07-19 12:16:46 -0700535 const u8 *bssid, const u8 *ie, size_t ie_len,
536 int ssi_signal)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700537{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700538 struct wpa_supplicant *wpa_s = ctx;
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700539 unsigned int freq = 0;
540
541 if (wpa_s->ap_iface)
542 freq = wpa_s->ap_iface->freq;
543
Dmitry Shmidt04949592012-07-19 12:16:46 -0700544 return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
Dmitry Shmidta3dc3092015-06-23 11:21:28 -0700545 freq, ssi_signal);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700546}
547
548
549static void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
550 const u8 *uuid_e)
551{
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700552 struct wpa_supplicant *wpa_s = ctx;
553 wpas_p2p_wps_success(wpa_s, mac_addr, 1);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700554}
555
556
557static void wpas_ap_configured_cb(void *ctx)
558{
559 struct wpa_supplicant *wpa_s = ctx;
560
561 wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
562
563 if (wpa_s->ap_configured_cb)
564 wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
565 wpa_s->ap_configured_cb_data);
566}
567
568
569int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
570 struct wpa_ssid *ssid)
571{
572 struct wpa_driver_associate_params params;
573 struct hostapd_iface *hapd_iface;
574 struct hostapd_config *conf;
575 size_t i;
576
577 if (ssid->ssid == NULL || ssid->ssid_len == 0) {
578 wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
579 return -1;
580 }
581
582 wpa_supplicant_ap_deinit(wpa_s);
583
584 wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
585 wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
586
587 os_memset(&params, 0, sizeof(params));
588 params.ssid = ssid->ssid;
589 params.ssid_len = ssid->ssid_len;
590 switch (ssid->mode) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700591 case WPAS_MODE_AP:
592 case WPAS_MODE_P2P_GO:
593 case WPAS_MODE_P2P_GROUP_FORMATION:
594 params.mode = IEEE80211_MODE_AP;
595 break;
Dmitry Shmidt3c479372014-02-04 10:50:36 -0800596 default:
597 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700598 }
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -0700599 if (ssid->frequency == 0)
600 ssid->frequency = 2462; /* default channel 11 */
Dmitry Shmidt9ead16e2014-10-07 13:15:23 -0700601 params.freq.freq = ssid->frequency;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700602
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800603 params.wpa_proto = ssid->proto;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700604 if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
605 wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
606 else
607 wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800608 params.key_mgmt_suite = wpa_s->key_mgmt;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700609
Dmitry Shmidta54fa5f2013-01-15 13:53:35 -0800610 wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
611 1);
612 if (wpa_s->pairwise_cipher < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700613 wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
614 "cipher.");
615 return -1;
616 }
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800617 params.pairwise_suite = wpa_s->pairwise_cipher;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700618 params.group_suite = params.pairwise_suite;
619
620#ifdef CONFIG_P2P
621 if (ssid->mode == WPAS_MODE_P2P_GO ||
622 ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
623 params.p2p = 1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700624#endif /* CONFIG_P2P */
625
626 if (wpa_s->parent->set_ap_uapsd)
627 params.uapsd = wpa_s->parent->ap_uapsd;
Dmitry Shmidtec58b162014-02-19 12:44:18 -0800628 else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
629 params.uapsd = 1; /* mandatory for P2P GO */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700630 else
631 params.uapsd = -1;
632
Dmitry Shmidt203eadb2015-03-05 14:16:04 -0800633 if (ieee80211_is_dfs(params.freq.freq))
634 params.freq.freq = 0; /* set channel after CAC */
635
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700636 if (wpa_drv_associate(wpa_s, &params) < 0) {
637 wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
638 return -1;
639 }
640
641 wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface));
642 if (hapd_iface == NULL)
643 return -1;
644 hapd_iface->owner = wpa_s;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800645 hapd_iface->drv_flags = wpa_s->drv_flags;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800646 hapd_iface->smps_modes = wpa_s->drv_smps_modes;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800647 hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
Dmitry Shmidt444d5672013-04-01 13:08:44 -0700648 hapd_iface->extended_capa = wpa_s->extended_capa;
649 hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
650 hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700651
652 wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
653 if (conf == NULL) {
654 wpa_supplicant_ap_deinit(wpa_s);
655 return -1;
656 }
657
Dmitry Shmidtd7ff03d2015-12-04 14:49:35 -0800658 /* Use the maximum oper channel width if it's given. */
659 if (ssid->max_oper_chwidth)
660 conf->vht_oper_chwidth = ssid->max_oper_chwidth;
661
662 ieee80211_freq_to_chan(ssid->vht_center_freq2,
663 &conf->vht_oper_centr_freq_seg1_idx);
664
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700665 os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
666 wpa_s->conf->wmm_ac_params,
667 sizeof(wpa_s->conf->wmm_ac_params));
668
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800669 if (params.uapsd > 0) {
Dmitry Shmidtcce06662013-11-04 18:44:24 -0800670 conf->bss[0]->wmm_enabled = 1;
671 conf->bss[0]->wmm_uapsd = 1;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800672 }
673
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700674 if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
675 wpa_printf(MSG_ERROR, "Failed to create AP configuration");
676 wpa_supplicant_ap_deinit(wpa_s);
677 return -1;
678 }
679
680#ifdef CONFIG_P2P
681 if (ssid->mode == WPAS_MODE_P2P_GO)
Dmitry Shmidtcce06662013-11-04 18:44:24 -0800682 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700683 else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
Dmitry Shmidtcce06662013-11-04 18:44:24 -0800684 conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700685 P2P_GROUP_FORMATION;
686#endif /* CONFIG_P2P */
687
688 hapd_iface->num_bss = conf->num_bss;
Dmitry Shmidt61d9df32012-08-29 16:22:06 -0700689 hapd_iface->bss = os_calloc(conf->num_bss,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700690 sizeof(struct hostapd_data *));
691 if (hapd_iface->bss == NULL) {
692 wpa_supplicant_ap_deinit(wpa_s);
693 return -1;
694 }
695
696 for (i = 0; i < conf->num_bss; i++) {
697 hapd_iface->bss[i] =
698 hostapd_alloc_bss_data(hapd_iface, conf,
Dmitry Shmidtcce06662013-11-04 18:44:24 -0800699 conf->bss[i]);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700700 if (hapd_iface->bss[i] == NULL) {
701 wpa_supplicant_ap_deinit(wpa_s);
702 return -1;
703 }
704
705 hapd_iface->bss[i]->msg_ctx = wpa_s;
Dmitry Shmidt497c1d52011-07-21 15:19:46 -0700706 hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700707 hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
708 hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
709 hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
710 hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
711 hostapd_register_probereq_cb(hapd_iface->bss[i],
712 ap_probe_req_rx, wpa_s);
713 hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
714 hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
715 hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
716 hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
717 hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
718 hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
719#ifdef CONFIG_P2P
Dmitry Shmidt391c59f2013-09-03 12:16:28 -0700720 hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
721 hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700722 hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
Dmitry Shmidt04949592012-07-19 12:16:46 -0700723 hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
724 ssid);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700725#endif /* CONFIG_P2P */
726 hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
727 hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800728#ifdef CONFIG_TESTING_OPTIONS
729 hapd_iface->bss[i]->ext_eapol_frame_io =
730 wpa_s->ext_eapol_frame_io;
731#endif /* CONFIG_TESTING_OPTIONS */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700732 }
733
734 os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
735 hapd_iface->bss[0]->driver = wpa_s->driver;
736 hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
737
738 wpa_s->current_ssid = ssid;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -0700739 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700740 os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
741 wpa_s->assoc_freq = ssid->frequency;
742
743 if (hostapd_setup_interface(wpa_s->ap_iface)) {
744 wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
745 wpa_supplicant_ap_deinit(wpa_s);
746 return -1;
747 }
748
749 return 0;
750}
751
752
753void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
754{
755#ifdef CONFIG_WPS
756 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
757#endif /* CONFIG_WPS */
758
759 if (wpa_s->ap_iface == NULL)
760 return;
761
762 wpa_s->current_ssid = NULL;
Dmitry Shmidtb7b4d0e2013-08-26 12:09:05 -0700763 eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700764 wpa_s->assoc_freq = 0;
Dmitry Shmidt43cb5782014-06-16 16:23:22 -0700765 wpas_p2p_ap_deinit(wpa_s);
Dmitry Shmidta38abf92014-03-06 13:38:44 -0800766 wpa_s->ap_iface->driver_ap_teardown =
767 !!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
768
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700769 hostapd_interface_deinit(wpa_s->ap_iface);
770 hostapd_interface_free(wpa_s->ap_iface);
771 wpa_s->ap_iface = NULL;
772 wpa_drv_deinit_ap(wpa_s);
Dmitry Shmidtf73259c2015-03-17 11:00:54 -0700773 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
774 " reason=%d locally_generated=1",
775 MAC2STR(wpa_s->own_addr), WLAN_REASON_DEAUTH_LEAVING);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700776}
777
778
779void ap_tx_status(void *ctx, const u8 *addr,
780 const u8 *buf, size_t len, int ack)
781{
782#ifdef NEED_AP_MLME
783 struct wpa_supplicant *wpa_s = ctx;
784 hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
785#endif /* NEED_AP_MLME */
786}
787
788
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800789void ap_eapol_tx_status(void *ctx, const u8 *dst,
790 const u8 *data, size_t len, int ack)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700791{
792#ifdef NEED_AP_MLME
793 struct wpa_supplicant *wpa_s = ctx;
Dmitry Shmidtfb79edc2014-01-10 10:45:54 -0800794 if (!wpa_s->ap_iface)
795 return;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800796 hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
797#endif /* NEED_AP_MLME */
798}
799
800
801void ap_client_poll_ok(void *ctx, const u8 *addr)
802{
803#ifdef NEED_AP_MLME
804 struct wpa_supplicant *wpa_s = ctx;
805 if (wpa_s->ap_iface)
806 hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
807#endif /* NEED_AP_MLME */
808}
809
810
811void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
812{
813#ifdef NEED_AP_MLME
814 struct wpa_supplicant *wpa_s = ctx;
815 ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700816#endif /* NEED_AP_MLME */
817}
818
819
820void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
821{
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800822#ifdef NEED_AP_MLME
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700823 struct wpa_supplicant *wpa_s = ctx;
824 struct hostapd_frame_info fi;
825 os_memset(&fi, 0, sizeof(fi));
826 fi.datarate = rx_mgmt->datarate;
827 fi.ssi_signal = rx_mgmt->ssi_signal;
828 ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
829 rx_mgmt->frame_len, &fi);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800830#endif /* NEED_AP_MLME */
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700831}
832
833
834void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
835{
836#ifdef NEED_AP_MLME
837 struct wpa_supplicant *wpa_s = ctx;
838 ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
839#endif /* NEED_AP_MLME */
840}
841
842
843void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
844 const u8 *src_addr, const u8 *buf, size_t len)
845{
846 ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
847}
848
849
850#ifdef CONFIG_WPS
851
852int wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
853 const u8 *p2p_dev_addr)
854{
855 if (!wpa_s->ap_iface)
856 return -1;
857 return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
858 p2p_dev_addr);
859}
860
861
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700862int wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
863{
864 struct wps_registrar *reg;
865 int reg_sel = 0, wps_sta = 0;
866
867 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
868 return -1;
869
870 reg = wpa_s->ap_iface->bss[0]->wps->registrar;
871 reg_sel = wps_registrar_wps_cancel(reg);
872 wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
Dmitry Shmidt04949592012-07-19 12:16:46 -0700873 ap_sta_wps_cancel, NULL);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700874
875 if (!reg_sel && !wps_sta) {
876 wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
877 "time");
878 return -1;
879 }
880
881 /*
882 * There are 2 cases to return wps cancel as success:
883 * 1. When wps cancel was initiated but no connection has been
884 * established with client yet.
885 * 2. Client is in the middle of exchanging WPS messages.
886 */
887
888 return 0;
889}
890
891
892int wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800893 const char *pin, char *buf, size_t buflen,
894 int timeout)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700895{
896 int ret, ret_len = 0;
897
898 if (!wpa_s->ap_iface)
899 return -1;
900
901 if (pin == NULL) {
902 unsigned int rpin = wps_generate_pin();
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800903 ret_len = os_snprintf(buf, buflen, "%08d", rpin);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800904 if (os_snprintf_error(buflen, ret_len))
905 return -1;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700906 pin = buf;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800907 } else if (buf) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700908 ret_len = os_snprintf(buf, buflen, "%s", pin);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -0800909 if (os_snprintf_error(buflen, ret_len))
910 return -1;
911 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700912
913 ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
Dmitry Shmidtd5e49232012-12-03 15:08:10 -0800914 timeout);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700915 if (ret)
916 return -1;
917 return ret_len;
918}
919
920
921static void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
922{
923 struct wpa_supplicant *wpa_s = eloop_data;
924 wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
925 wpas_wps_ap_pin_disable(wpa_s);
926}
927
928
929static void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
930{
931 struct hostapd_data *hapd;
932
933 if (wpa_s->ap_iface == NULL)
934 return;
935 hapd = wpa_s->ap_iface->bss[0];
936 wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
937 hapd->ap_pin_failures = 0;
938 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
939 if (timeout > 0)
940 eloop_register_timeout(timeout, 0,
941 wpas_wps_ap_pin_timeout, wpa_s, NULL);
942}
943
944
945void wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
946{
947 struct hostapd_data *hapd;
948
949 if (wpa_s->ap_iface == NULL)
950 return;
951 wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
952 hapd = wpa_s->ap_iface->bss[0];
953 os_free(hapd->conf->ap_pin);
954 hapd->conf->ap_pin = NULL;
955 eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
956}
957
958
959const char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
960{
961 struct hostapd_data *hapd;
962 unsigned int pin;
963 char pin_txt[9];
964
965 if (wpa_s->ap_iface == NULL)
966 return NULL;
967 hapd = wpa_s->ap_iface->bss[0];
968 pin = wps_generate_pin();
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800969 os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700970 os_free(hapd->conf->ap_pin);
971 hapd->conf->ap_pin = os_strdup(pin_txt);
972 if (hapd->conf->ap_pin == NULL)
973 return NULL;
974 wpas_wps_ap_pin_enable(wpa_s, timeout);
975
976 return hapd->conf->ap_pin;
977}
978
979
980const char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
981{
982 struct hostapd_data *hapd;
983 if (wpa_s->ap_iface == NULL)
984 return NULL;
985 hapd = wpa_s->ap_iface->bss[0];
986 return hapd->conf->ap_pin;
987}
988
989
990int wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
991 int timeout)
992{
993 struct hostapd_data *hapd;
994 char pin_txt[9];
995 int ret;
996
997 if (wpa_s->ap_iface == NULL)
998 return -1;
999 hapd = wpa_s->ap_iface->bss[0];
1000 ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001001 if (os_snprintf_error(sizeof(pin_txt), ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001002 return -1;
1003 os_free(hapd->conf->ap_pin);
1004 hapd->conf->ap_pin = os_strdup(pin_txt);
1005 if (hapd->conf->ap_pin == NULL)
1006 return -1;
1007 wpas_wps_ap_pin_enable(wpa_s, timeout);
1008
1009 return 0;
1010}
1011
1012
1013void wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
1014{
1015 struct hostapd_data *hapd;
1016
1017 if (wpa_s->ap_iface == NULL)
1018 return;
1019 hapd = wpa_s->ap_iface->bss[0];
1020
1021 /*
1022 * Registrar failed to prove its knowledge of the AP PIN. Disable AP
1023 * PIN if this happens multiple times to slow down brute force attacks.
1024 */
1025 hapd->ap_pin_failures++;
1026 wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
1027 hapd->ap_pin_failures);
1028 if (hapd->ap_pin_failures < 3)
1029 return;
1030
1031 wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
1032 hapd->ap_pin_failures = 0;
1033 os_free(hapd->conf->ap_pin);
1034 hapd->conf->ap_pin = NULL;
1035}
1036
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001037
1038#ifdef CONFIG_WPS_NFC
1039
1040struct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
1041 int ndef)
1042{
1043 struct hostapd_data *hapd;
1044
1045 if (wpa_s->ap_iface == NULL)
1046 return NULL;
1047 hapd = wpa_s->ap_iface->bss[0];
1048 return hostapd_wps_nfc_config_token(hapd, ndef);
1049}
1050
1051
1052struct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
1053 int ndef)
1054{
1055 struct hostapd_data *hapd;
1056
1057 if (wpa_s->ap_iface == NULL)
1058 return NULL;
1059 hapd = wpa_s->ap_iface->bss[0];
1060 return hostapd_wps_nfc_hs_cr(hapd, ndef);
1061}
1062
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001063
1064int wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
1065 const struct wpabuf *req,
1066 const struct wpabuf *sel)
1067{
1068 struct hostapd_data *hapd;
1069
1070 if (wpa_s->ap_iface == NULL)
1071 return -1;
1072 hapd = wpa_s->ap_iface->bss[0];
1073 return hostapd_wps_nfc_report_handover(hapd, req, sel);
1074}
1075
Dmitry Shmidtf8623282013-02-20 14:34:59 -08001076#endif /* CONFIG_WPS_NFC */
1077
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001078#endif /* CONFIG_WPS */
1079
1080
1081#ifdef CONFIG_CTRL_IFACE
1082
1083int ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
1084 char *buf, size_t buflen)
1085{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001086 struct hostapd_data *hapd;
1087
1088 if (wpa_s->ap_iface)
1089 hapd = wpa_s->ap_iface->bss[0];
1090 else if (wpa_s->ifmsh)
1091 hapd = wpa_s->ifmsh->bss[0];
1092 else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001093 return -1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001094 return hostapd_ctrl_iface_sta_first(hapd, buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001095}
1096
1097
1098int ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
1099 char *buf, size_t buflen)
1100{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001101 struct hostapd_data *hapd;
1102
1103 if (wpa_s->ap_iface)
1104 hapd = wpa_s->ap_iface->bss[0];
1105 else if (wpa_s->ifmsh)
1106 hapd = wpa_s->ifmsh->bss[0];
1107 else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001108 return -1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001109 return hostapd_ctrl_iface_sta(hapd, txtaddr, buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001110}
1111
1112
1113int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
1114 char *buf, size_t buflen)
1115{
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001116 struct hostapd_data *hapd;
1117
1118 if (wpa_s->ap_iface)
1119 hapd = wpa_s->ap_iface->bss[0];
1120 else if (wpa_s->ifmsh)
1121 hapd = wpa_s->ifmsh->bss[0];
1122 else
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001123 return -1;
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001124 return hostapd_ctrl_iface_sta_next(hapd, txtaddr, buf, buflen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001125}
1126
1127
Dmitry Shmidt04949592012-07-19 12:16:46 -07001128int ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
1129 const char *txtaddr)
1130{
1131 if (wpa_s->ap_iface == NULL)
1132 return -1;
1133 return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
1134 txtaddr);
1135}
1136
1137
1138int ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
1139 const char *txtaddr)
1140{
1141 if (wpa_s->ap_iface == NULL)
1142 return -1;
1143 return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
1144 txtaddr);
1145}
1146
1147
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001148int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
1149 size_t buflen, int verbose)
1150{
1151 char *pos = buf, *end = buf + buflen;
1152 int ret;
1153 struct hostapd_bss_config *conf;
1154
1155 if (wpa_s->ap_iface == NULL)
1156 return -1;
1157
1158 conf = wpa_s->ap_iface->bss[0]->conf;
1159 if (conf->wpa == 0)
1160 return 0;
1161
1162 ret = os_snprintf(pos, end - pos,
1163 "pairwise_cipher=%s\n"
1164 "group_cipher=%s\n"
1165 "key_mgmt=%s\n",
1166 wpa_cipher_txt(conf->rsn_pairwise),
1167 wpa_cipher_txt(conf->wpa_group),
1168 wpa_key_mgmt_txt(conf->wpa_key_mgmt,
1169 conf->wpa));
Dmitry Shmidt6c0da2b2015-01-05 13:08:17 -08001170 if (os_snprintf_error(end - pos, ret))
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001171 return pos - buf;
1172 pos += ret;
1173 return pos - buf;
1174}
1175
1176#endif /* CONFIG_CTRL_IFACE */
1177
1178
1179int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
1180{
1181 struct hostapd_iface *iface = wpa_s->ap_iface;
1182 struct wpa_ssid *ssid = wpa_s->current_ssid;
1183 struct hostapd_data *hapd;
1184
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001185 if (ssid == NULL || wpa_s->ap_iface == NULL ||
1186 ssid->mode == WPAS_MODE_INFRA ||
1187 ssid->mode == WPAS_MODE_IBSS)
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001188 return -1;
1189
1190#ifdef CONFIG_P2P
1191 if (ssid->mode == WPAS_MODE_P2P_GO)
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001192 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001193 else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
Dmitry Shmidtcce06662013-11-04 18:44:24 -08001194 iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001195 P2P_GROUP_FORMATION;
1196#endif /* CONFIG_P2P */
1197
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001198 hapd = iface->bss[0];
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001199 if (hapd->drv_priv == NULL)
1200 return -1;
1201 ieee802_11_set_beacons(iface);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001202 hostapd_set_ap_wps_ie(hapd);
1203
1204 return 0;
1205}
1206
1207
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -08001208int ap_switch_channel(struct wpa_supplicant *wpa_s,
1209 struct csa_settings *settings)
1210{
1211#ifdef NEED_AP_MLME
1212 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1213 return -1;
1214
1215 return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
1216#else /* NEED_AP_MLME */
1217 return -1;
1218#endif /* NEED_AP_MLME */
1219}
1220
1221
Dmitry Shmidt83474442015-04-15 13:47:09 -07001222#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -08001223int ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1224{
1225 struct csa_settings settings;
1226 int ret = hostapd_parse_csa_settings(pos, &settings);
1227
1228 if (ret)
1229 return ret;
1230
1231 return ap_switch_channel(wpa_s, &settings);
1232}
Dmitry Shmidt83474442015-04-15 13:47:09 -07001233#endif /* CONFIG_CTRL_IFACE */
Dmitry Shmidte0e48dc2013-11-18 12:00:06 -08001234
1235
Dmitry Shmidt04949592012-07-19 12:16:46 -07001236void wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
Dmitry Shmidt04f534e2013-12-09 15:50:16 -08001237 int offset, int width, int cf1, int cf2)
Dmitry Shmidt04949592012-07-19 12:16:46 -07001238{
1239 if (!wpa_s->ap_iface)
1240 return;
1241
1242 wpa_s->assoc_freq = freq;
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001243 if (wpa_s->current_ssid)
1244 wpa_s->current_ssid->frequency = freq;
1245 hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht,
1246 offset, width, cf1, cf2);
Dmitry Shmidt04949592012-07-19 12:16:46 -07001247}
1248
1249
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001250int wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
1251 const u8 *addr)
1252{
1253 struct hostapd_data *hapd;
1254 struct hostapd_bss_config *conf;
1255
1256 if (!wpa_s->ap_iface)
1257 return -1;
1258
1259 if (addr)
1260 wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
1261 MAC2STR(addr));
1262 else
1263 wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
1264
1265 hapd = wpa_s->ap_iface->bss[0];
1266 conf = hapd->conf;
1267
1268 os_free(conf->accept_mac);
1269 conf->accept_mac = NULL;
1270 conf->num_accept_mac = 0;
1271 os_free(conf->deny_mac);
1272 conf->deny_mac = NULL;
1273 conf->num_deny_mac = 0;
1274
1275 if (addr == NULL) {
1276 conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
1277 return 0;
1278 }
1279
1280 conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
1281 conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
1282 if (conf->accept_mac == NULL)
1283 return -1;
1284 os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
1285 conf->num_accept_mac = 1;
1286
1287 return 0;
1288}
Dmitry Shmidtcf32e602014-01-28 10:57:39 -08001289
1290
1291#ifdef CONFIG_WPS_NFC
1292int wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
1293 const struct wpabuf *pw, const u8 *pubkey_hash)
1294{
1295 struct hostapd_data *hapd;
1296 struct wps_context *wps;
1297
1298 if (!wpa_s->ap_iface)
1299 return -1;
1300 hapd = wpa_s->ap_iface->bss[0];
1301 wps = hapd->wps;
1302
1303 if (wpa_s->parent->conf->wps_nfc_dh_pubkey == NULL ||
1304 wpa_s->parent->conf->wps_nfc_dh_privkey == NULL) {
1305 wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
1306 return -1;
1307 }
1308
1309 dh5_free(wps->dh_ctx);
1310 wpabuf_free(wps->dh_pubkey);
1311 wpabuf_free(wps->dh_privkey);
1312 wps->dh_privkey = wpabuf_dup(
1313 wpa_s->parent->conf->wps_nfc_dh_privkey);
1314 wps->dh_pubkey = wpabuf_dup(
1315 wpa_s->parent->conf->wps_nfc_dh_pubkey);
1316 if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
1317 wps->dh_ctx = NULL;
1318 wpabuf_free(wps->dh_pubkey);
1319 wps->dh_pubkey = NULL;
1320 wpabuf_free(wps->dh_privkey);
1321 wps->dh_privkey = NULL;
1322 return -1;
1323 }
1324 wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
1325 if (wps->dh_ctx == NULL)
1326 return -1;
1327
1328 return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
1329 pw_id,
1330 pw ? wpabuf_head(pw) : NULL,
1331 pw ? wpabuf_len(pw) : 0, 1);
1332}
1333#endif /* CONFIG_WPS_NFC */
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001334
1335
Dmitry Shmidt83474442015-04-15 13:47:09 -07001336#ifdef CONFIG_CTRL_IFACE
Dmitry Shmidt7f656022015-02-25 14:36:37 -08001337int wpas_ap_stop_ap(struct wpa_supplicant *wpa_s)
1338{
1339 struct hostapd_data *hapd;
1340
1341 if (!wpa_s->ap_iface)
1342 return -1;
1343 hapd = wpa_s->ap_iface->bss[0];
1344 return hostapd_ctrl_iface_stop_ap(hapd);
1345}
Dmitry Shmidt83474442015-04-15 13:47:09 -07001346#endif /* CONFIG_CTRL_IFACE */
Dmitry Shmidt203eadb2015-03-05 14:16:04 -08001347
1348
1349#ifdef NEED_AP_MLME
1350void wpas_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
1351 struct dfs_event *radar)
1352{
1353 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1354 return;
1355 wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
1356 hostapd_dfs_radar_detected(wpa_s->ap_iface, radar->freq,
1357 radar->ht_enabled, radar->chan_offset,
1358 radar->chan_width,
1359 radar->cf1, radar->cf2);
1360}
1361
1362
1363void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
1364 struct dfs_event *radar)
1365{
1366 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1367 return;
1368 wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
1369 hostapd_dfs_start_cac(wpa_s->ap_iface, radar->freq,
1370 radar->ht_enabled, radar->chan_offset,
1371 radar->chan_width, radar->cf1, radar->cf2);
1372}
1373
1374
1375void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
1376 struct dfs_event *radar)
1377{
1378 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1379 return;
1380 wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
1381 hostapd_dfs_complete_cac(wpa_s->ap_iface, 1, radar->freq,
1382 radar->ht_enabled, radar->chan_offset,
1383 radar->chan_width, radar->cf1, radar->cf2);
1384}
1385
1386
1387void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
1388 struct dfs_event *radar)
1389{
1390 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1391 return;
1392 wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
1393 hostapd_dfs_complete_cac(wpa_s->ap_iface, 0, radar->freq,
1394 radar->ht_enabled, radar->chan_offset,
1395 radar->chan_width, radar->cf1, radar->cf2);
1396}
1397
1398
1399void wpas_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
1400 struct dfs_event *radar)
1401{
1402 if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1403 return;
1404 wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
1405 hostapd_dfs_nop_finished(wpa_s->ap_iface, radar->freq,
1406 radar->ht_enabled, radar->chan_offset,
1407 radar->chan_width, radar->cf1, radar->cf2);
1408}
1409#endif /* NEED_AP_MLME */
Dmitry Shmidtd80a4012015-11-05 16:35:40 -08001410
1411
1412void ap_periodic(struct wpa_supplicant *wpa_s)
1413{
1414 if (wpa_s->ap_iface)
1415 hostapd_periodic_iface(wpa_s->ap_iface);
1416}