]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/ap_drv_ops.c
OpenSSL: Support OpenSSL 1.1.0 DH opacity
[thirdparty/hostap.git] / src / ap / ap_drv_ops.c
CommitLineData
bf65bc63
JM
1/*
2 * hostapd - Driver operations
ef580012 3 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
bf65bc63 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
bf65bc63
JM
7 */
8
8b06c1ed 9#include "utils/includes.h"
bf65bc63 10
8b06c1ed 11#include "utils/common.h"
ef580012 12#include "common/ieee802_11_defs.h"
ada157f3 13#include "common/hw_features_common.h"
0e2e565a 14#include "wps/wps.h"
9675ce35 15#include "p2p/p2p.h"
8b06c1ed
JM
16#include "hostapd.h"
17#include "ieee802_11.h"
18#include "sta_info.h"
19#include "ap_config.h"
dce044cc 20#include "p2p_hostapd.h"
19a8ad99 21#include "hs20.h"
a4f21109 22#include "ap_drv_ops.h"
bf65bc63
JM
23
24
4378fc14 25u32 hostapd_sta_flags_to_drv(u32 flags)
4c2ddda4
JM
26{
27 int res = 0;
28 if (flags & WLAN_STA_AUTHORIZED)
29 res |= WPA_STA_AUTHORIZED;
30 if (flags & WLAN_STA_WMM)
31 res |= WPA_STA_WMM;
32 if (flags & WLAN_STA_SHORT_PREAMBLE)
33 res |= WPA_STA_SHORT_PREAMBLE;
34 if (flags & WLAN_STA_MFP)
35 res |= WPA_STA_MFP;
bb598c3b
AB
36 if (flags & WLAN_STA_AUTH)
37 res |= WPA_STA_AUTHENTICATED;
38 if (flags & WLAN_STA_ASSOC)
39 res |= WPA_STA_ASSOCIATED;
4c2ddda4
JM
40 return res;
41}
42
43
990b7b6f
JM
44static int add_buf(struct wpabuf **dst, const struct wpabuf *src)
45{
46 if (!src)
47 return 0;
48 if (wpabuf_resize(dst, wpabuf_len(src)) != 0)
49 return -1;
50 wpabuf_put_buf(*dst, src);
51 return 0;
52}
53
54
55static int add_buf_data(struct wpabuf **dst, const u8 *data, size_t len)
56{
57 if (!data || !len)
58 return 0;
59 if (wpabuf_resize(dst, len) != 0)
60 return -1;
61 wpabuf_put_data(*dst, data, len);
62 return 0;
63}
64
65
fb91db56 66int hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
c2ff13c5
JM
67 struct wpabuf **beacon_ret,
68 struct wpabuf **proberesp_ret,
69 struct wpabuf **assocresp_ret)
bf65bc63 70{
c2ff13c5 71 struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
4b2a77ab 72 u8 buf[200], *pos;
c2ff13c5
JM
73
74 *beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
75
39b97072
JM
76 pos = buf;
77 pos = hostapd_eid_time_adv(hapd, pos);
990b7b6f
JM
78 if (add_buf_data(&beacon, buf, pos - buf) < 0)
79 goto fail;
39b97072 80 pos = hostapd_eid_time_zone(hapd, pos);
990b7b6f
JM
81 if (add_buf_data(&proberesp, buf, pos - buf) < 0)
82 goto fail;
39b97072 83
a194b06c
JM
84 pos = buf;
85 pos = hostapd_eid_ext_capab(hapd, pos);
990b7b6f
JM
86 if (add_buf_data(&assocresp, buf, pos - buf) < 0)
87 goto fail;
a194b06c 88 pos = hostapd_eid_interworking(hapd, pos);
c7c178e1 89 pos = hostapd_eid_adv_proto(hapd, pos);
4b2a77ab 90 pos = hostapd_eid_roaming_consortium(hapd, pos);
990b7b6f
JM
91 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
92 add_buf_data(&proberesp, buf, pos - buf) < 0)
93 goto fail;
a194b06c 94
347827ff 95#ifdef CONFIG_FST
990b7b6f
JM
96 if (add_buf(&beacon, hapd->iface->fst_ies) < 0 ||
97 add_buf(&proberesp, hapd->iface->fst_ies) < 0 ||
98 add_buf(&assocresp, hapd->iface->fst_ies) < 0)
99 goto fail;
347827ff
AN
100#endif /* CONFIG_FST */
101
990b7b6f
JM
102 if (add_buf(&beacon, hapd->wps_beacon_ie) < 0 ||
103 add_buf(&proberesp, hapd->wps_probe_resp_ie) < 0)
104 goto fail;
b3db190f 105
c2af2afb 106#ifdef CONFIG_P2P
990b7b6f
JM
107 if (add_buf(&beacon, hapd->p2p_beacon_ie) < 0 ||
108 add_buf(&proberesp, hapd->p2p_probe_resp_ie) < 0)
109 goto fail;
c2af2afb
JM
110#endif /* CONFIG_P2P */
111
dce044cc
JM
112#ifdef CONFIG_P2P_MANAGER
113 if (hapd->conf->p2p & P2P_MANAGE) {
c2ff13c5 114 if (wpabuf_resize(&beacon, 100) == 0) {
dce044cc 115 u8 *start, *p;
c2ff13c5 116 start = wpabuf_put(beacon, 0);
dce044cc 117 p = hostapd_eid_p2p_manage(hapd, start);
c2ff13c5 118 wpabuf_put(beacon, p - start);
dce044cc
JM
119 }
120
c2ff13c5 121 if (wpabuf_resize(&proberesp, 100) == 0) {
dce044cc 122 u8 *start, *p;
c2ff13c5 123 start = wpabuf_put(proberesp, 0);
dce044cc 124 p = hostapd_eid_p2p_manage(hapd, start);
c2ff13c5 125 wpabuf_put(proberesp, p - start);
dce044cc
JM
126 }
127 }
128#endif /* CONFIG_P2P_MANAGER */
129
c201f93a 130#ifdef CONFIG_WPS
c2ff13c5
JM
131 if (hapd->conf->wps_state) {
132 struct wpabuf *a = wps_build_assoc_resp_ie();
990b7b6f 133 add_buf(&assocresp, a);
c2ff13c5
JM
134 wpabuf_free(a);
135 }
c201f93a 136#endif /* CONFIG_WPS */
0e2e565a 137
dce044cc
JM
138#ifdef CONFIG_P2P_MANAGER
139 if (hapd->conf->p2p & P2P_MANAGE) {
c2ff13c5 140 if (wpabuf_resize(&assocresp, 100) == 0) {
dce044cc 141 u8 *start, *p;
c2ff13c5 142 start = wpabuf_put(assocresp, 0);
dce044cc 143 p = hostapd_eid_p2p_manage(hapd, start);
c2ff13c5 144 wpabuf_put(assocresp, p - start);
dce044cc
JM
145 }
146 }
147#endif /* CONFIG_P2P_MANAGER */
148
9675ce35
JM
149#ifdef CONFIG_WIFI_DISPLAY
150 if (hapd->p2p_group) {
151 struct wpabuf *a;
152 a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
990b7b6f 153 add_buf(&assocresp, a);
9675ce35
JM
154 wpabuf_free(a);
155 }
156#endif /* CONFIG_WIFI_DISPLAY */
157
19a8ad99 158#ifdef CONFIG_HS20
990b7b6f
JM
159 pos = hostapd_eid_hs20_indication(hapd, buf);
160 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
161 add_buf_data(&proberesp, buf, pos - buf) < 0)
162 goto fail;
a14896e8
JM
163
164 pos = hostapd_eid_osen(hapd, buf);
990b7b6f
JM
165 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
166 add_buf_data(&proberesp, buf, pos - buf) < 0)
167 goto fail;
19a8ad99
JK
168#endif /* CONFIG_HS20 */
169
fb9a1c3e
AS
170#ifdef CONFIG_MBO
171 if (hapd->conf->mbo_enabled) {
172 pos = hostapd_eid_mbo(hapd, buf, sizeof(buf));
990b7b6f
JM
173 if (add_buf_data(&beacon, buf, pos - buf) < 0 ||
174 add_buf_data(&proberesp, buf, pos - buf) < 0 ||
175 add_buf_data(&assocresp, buf, pos - buf) < 0)
176 goto fail;
fb9a1c3e
AS
177 }
178#endif /* CONFIG_MBO */
179
990b7b6f
JM
180 add_buf(&beacon, hapd->conf->vendor_elements);
181 add_buf(&proberesp, hapd->conf->vendor_elements);
b084df8b 182
c2ff13c5
JM
183 *beacon_ret = beacon;
184 *proberesp_ret = proberesp;
185 *assocresp_ret = assocresp;
186
fb91db56 187 return 0;
c2ff13c5
JM
188
189fail:
190 wpabuf_free(beacon);
191 wpabuf_free(proberesp);
192 wpabuf_free(assocresp);
193 return -1;
fb91db56
JM
194}
195
b3db190f 196
c2ff13c5
JM
197void hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
198 struct wpabuf *beacon,
fb91db56
JM
199 struct wpabuf *proberesp,
200 struct wpabuf *assocresp)
201{
c2ff13c5
JM
202 wpabuf_free(beacon);
203 wpabuf_free(proberesp);
0e2e565a 204 wpabuf_free(assocresp);
fb91db56
JM
205}
206
207
1de07100
AKP
208int hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
209{
210 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
211 return 0;
212
213 return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
214}
215
216
fb91db56
JM
217int hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
218{
219 struct wpabuf *beacon, *proberesp, *assocresp;
220 int ret;
221
222 if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
223 return 0;
224
225 if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
226 0)
227 return -1;
228
229 ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
230 assocresp);
231
232 hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
c2af2afb 233
b3db190f 234 return ret;
bf65bc63
JM
235}
236
237
0e8a96a9
JM
238int hostapd_set_authorized(struct hostapd_data *hapd,
239 struct sta_info *sta, int authorized)
45cefa0b
JM
240{
241 if (authorized) {
242 return hostapd_sta_set_flags(hapd, sta->addr,
243 hostapd_sta_flags_to_drv(
244 sta->flags),
245 WPA_STA_AUTHORIZED, ~0);
246 }
247
248 return hostapd_sta_set_flags(hapd, sta->addr,
249 hostapd_sta_flags_to_drv(sta->flags),
250 0, ~WPA_STA_AUTHORIZED);
251}
252
253
0e8a96a9 254int hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
4c2ddda4
JM
255{
256 int set_flags, total_flags, flags_and, flags_or;
257 total_flags = hostapd_sta_flags_to_drv(sta->flags);
258 set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
ef580012
JM
259 if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
260 sta->auth_alg == WLAN_AUTH_FT) &&
4c2ddda4
JM
261 sta->flags & WLAN_STA_AUTHORIZED)
262 set_flags |= WPA_STA_AUTHORIZED;
263 flags_or = total_flags & set_flags;
264 flags_and = total_flags | ~set_flags;
265 return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
266 flags_or, flags_and);
267}
268
269
0e8a96a9
JM
270int hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
271 int enabled)
010401fe
JM
272{
273 struct wpa_bss_params params;
274 os_memset(&params, 0, sizeof(params));
275 params.ifname = ifname;
276 params.enabled = enabled;
277 if (enabled) {
278 params.wpa = hapd->conf->wpa;
279 params.ieee802_1x = hapd->conf->ieee802_1x;
280 params.wpa_group = hapd->conf->wpa_group;
e19c1d2c
JM
281 if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
282 (WPA_PROTO_WPA | WPA_PROTO_RSN))
283 params.wpa_pairwise = hapd->conf->wpa_pairwise |
284 hapd->conf->rsn_pairwise;
285 else if (hapd->conf->wpa & WPA_PROTO_RSN)
286 params.wpa_pairwise = hapd->conf->rsn_pairwise;
287 else if (hapd->conf->wpa & WPA_PROTO_WPA)
288 params.wpa_pairwise = hapd->conf->wpa_pairwise;
010401fe
JM
289 params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
290 params.rsn_preauth = hapd->conf->rsn_preauth;
a1ca0292
MP
291#ifdef CONFIG_IEEE80211W
292 params.ieee80211w = hapd->conf->ieee80211w;
293#endif /* CONFIG_IEEE80211W */
010401fe
JM
294 }
295 return hostapd_set_ieee8021x(hapd, &params);
296}
297
298
0e8a96a9 299int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
36592d31 300{
f3585c8a
JM
301 char force_ifname[IFNAMSIZ];
302 u8 if_addr[ETH_ALEN];
e926bcff 303 return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
2aec4f3c 304 NULL, NULL, force_ifname, if_addr, NULL, 0);
36592d31
JM
305}
306
0e8a96a9
JM
307
308int hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
36592d31
JM
309{
310 return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
311}
312
313
69dd2967
SM
314int hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
315 const u8 *addr, int aid, int val)
bdee6fce 316{
d38ae2ea
FF
317 const char *bridge = NULL;
318
bdee6fce 319 if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
69dd2967 320 return -1;
d38ae2ea
FF
321 if (hapd->conf->wds_bridge[0])
322 bridge = hapd->conf->wds_bridge;
323 else if (hapd->conf->bridge[0])
324 bridge = hapd->conf->bridge;
0e8a96a9 325 return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
69dd2967 326 bridge, ifname_wds);
bdee6fce
JM
327}
328
329
a52eba0f
SP
330int hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
331 u16 auth_alg)
332{
333 if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
334 return 0;
335 return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
336}
337
338
339int hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
340 u16 seq, u16 status, const u8 *ie, size_t len)
341{
342 if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
343 return 0;
344 return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
345 seq, status, ie, len);
346}
347
348
349int hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
350 int reassoc, u16 status, const u8 *ie, size_t len)
351{
352 if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
353 return 0;
354 return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
355 reassoc, status, ie, len);
356}
357
358
0e8a96a9
JM
359int hostapd_sta_add(struct hostapd_data *hapd,
360 const u8 *addr, u16 aid, u16 capability,
361 const u8 *supp_rates, size_t supp_rates_len,
362 u16 listen_interval,
d83ab1fe 363 const struct ieee80211_ht_capabilities *ht_capab,
a9a1d0f0 364 const struct ieee80211_vht_capabilities *vht_capab,
ae33239c
AB
365 u32 flags, u8 qosinfo, u8 vht_opmode, int supp_p2p_ps,
366 int set)
2ce86d9d
JM
367{
368 struct hostapd_sta_add_params params;
369
370 if (hapd->driver == NULL)
371 return 0;
372 if (hapd->driver->sta_add == NULL)
373 return 0;
374
375 os_memset(&params, 0, sizeof(params));
376 params.addr = addr;
377 params.aid = aid;
378 params.capability = capability;
379 params.supp_rates = supp_rates;
380 params.supp_rates_len = supp_rates_len;
381 params.listen_interval = listen_interval;
382 params.ht_capabilities = ht_capab;
a9a1d0f0 383 params.vht_capabilities = vht_capab;
8a458116
MK
384 params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
385 params.vht_opmode = vht_opmode;
d83ab1fe 386 params.flags = hostapd_sta_flags_to_drv(flags);
5d061637 387 params.qosinfo = qosinfo;
ae33239c 388 params.support_p2p_ps = supp_p2p_ps;
bb598c3b 389 params.set = set;
62847751 390 return hapd->driver->sta_add(hapd->drv_priv, &params);
2ce86d9d
JM
391}
392
393
a52eba0f
SP
394int hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
395 u8 *tspec_ie, size_t tspec_ielen)
396{
397 if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
398 return 0;
399 return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
400 tspec_ielen);
401}
402
403
8b06c1ed
JM
404int hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
405{
406 if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
407 return 0;
d5dd016a 408 return hapd->driver->set_privacy(hapd->drv_priv, enabled);
8b06c1ed
JM
409}
410
411
412int hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
413 size_t elem_len)
414{
415 if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
416 return 0;
aa484516 417 return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
8b06c1ed
JM
418}
419
420
421int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
422{
423 if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
424 return 0;
8709de1a 425 return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
8b06c1ed
JM
426}
427
428
429int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
430{
431 if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
432 return 0;
8709de1a 433 return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
8b06c1ed
JM
434}
435
436
437int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
a2e40bb6 438 const char *ifname, const u8 *addr, void *bss_ctx,
e17a2477 439 void **drv_priv, char *force_ifname, u8 *if_addr,
2aec4f3c 440 const char *bridge, int use_existing)
8b06c1ed
JM
441{
442 if (hapd->driver == NULL || hapd->driver->if_add == NULL)
443 return -1;
7ab68865 444 return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
e17a2477 445 bss_ctx, drv_priv, force_ifname, if_addr,
d8a3b66d 446 bridge, use_existing, 1);
8b06c1ed
JM
447}
448
449
450int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
451 const char *ifname)
452{
71cdf6b6
JM
453 if (hapd->driver == NULL || hapd->drv_priv == NULL ||
454 hapd->driver->if_remove == NULL)
8b06c1ed
JM
455 return -1;
456 return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
457}
6e6e8c31
JM
458
459
460int hostapd_set_ieee8021x(struct hostapd_data *hapd,
461 struct wpa_bss_params *params)
462{
463 if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
464 return 0;
465 return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
466}
467
468
469int hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
470 const u8 *addr, int idx, u8 *seq)
471{
472 if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
473 return 0;
474 return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
475 seq);
476}
477
478
479int hostapd_flush(struct hostapd_data *hapd)
480{
481 if (hapd->driver == NULL || hapd->driver->flush == NULL)
482 return 0;
483 return hapd->driver->flush(hapd->drv_priv);
484}
485
486
4e8f31e2
JM
487int hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
488 int freq, int channel, int ht_enabled, int vht_enabled,
72c753d7
JD
489 int sec_channel_offset, int vht_oper_chwidth,
490 int center_segment0, int center_segment1)
491{
492 struct hostapd_freq_params data;
493
494 if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
495 vht_enabled, sec_channel_offset,
496 vht_oper_chwidth,
7f0303d5 497 center_segment0, center_segment1,
e9b783d5
JM
498 hapd->iface->current_mode ?
499 hapd->iface->current_mode->vht_capab : 0))
72c753d7
JD
500 return -1;
501
fa476336
JB
502 if (hapd->driver == NULL)
503 return 0;
504 if (hapd->driver->set_freq == NULL)
505 return 0;
6e6e8c31
JM
506 return hapd->driver->set_freq(hapd->drv_priv, &data);
507}
508
509int hostapd_set_rts(struct hostapd_data *hapd, int rts)
510{
511 if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
512 return 0;
513 return hapd->driver->set_rts(hapd->drv_priv, rts);
514}
515
516
517int hostapd_set_frag(struct hostapd_data *hapd, int frag)
518{
519 if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
520 return 0;
521 return hapd->driver->set_frag(hapd->drv_priv, frag);
522}
523
524
525int hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
526 int total_flags, int flags_or, int flags_and)
527{
528 if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
529 return 0;
3234cba4 530 return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
6e6e8c31
JM
531 flags_or, flags_and);
532}
533
534
6e6e8c31
JM
535int hostapd_set_country(struct hostapd_data *hapd, const char *country)
536{
537 if (hapd->driver == NULL ||
538 hapd->driver->set_country == NULL)
539 return 0;
540 return hapd->driver->set_country(hapd->drv_priv, country);
541}
542
543
6e6e8c31
JM
544int hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
545 int cw_min, int cw_max, int burst_time)
546{
547 if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
548 return 0;
549 return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
550 cw_min, cw_max, burst_time);
551}
552
553
6e6e8c31
JM
554struct hostapd_hw_modes *
555hostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
556 u16 *flags)
557{
558 if (hapd->driver == NULL ||
559 hapd->driver->get_hw_feature_data == NULL)
560 return NULL;
561 return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
562 flags);
563}
564
565
566int hostapd_driver_commit(struct hostapd_data *hapd)
567{
568 if (hapd->driver == NULL || hapd->driver->commit == NULL)
569 return 0;
570 return hapd->driver->commit(hapd->drv_priv);
571}
572
573
6e6e8c31
JM
574int hostapd_drv_none(struct hostapd_data *hapd)
575{
576 return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
577}
578
579
580int hostapd_driver_scan(struct hostapd_data *hapd,
581 struct wpa_driver_scan_params *params)
582{
583 if (hapd->driver && hapd->driver->scan2)
584 return hapd->driver->scan2(hapd->drv_priv, params);
585 return -1;
586}
587
588
589struct wpa_scan_results * hostapd_driver_get_scan_results(
590 struct hostapd_data *hapd)
591{
592 if (hapd->driver && hapd->driver->get_scan_results2)
593 return hapd->driver->get_scan_results2(hapd->drv_priv);
594 return NULL;
595}
aefb53bd
JM
596
597
598int hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
599 int duration)
600{
601 if (hapd->driver && hapd->driver->set_noa)
602 return hapd->driver->set_noa(hapd->drv_priv, count, start,
603 duration);
604 return -1;
605}
7392f11e
JM
606
607
608int hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
609 enum wpa_alg alg, const u8 *addr,
610 int key_idx, int set_tx,
611 const u8 *seq, size_t seq_len,
612 const u8 *key, size_t key_len)
613{
614 if (hapd->driver == NULL || hapd->driver->set_key == NULL)
615 return 0;
616 return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
617 key_idx, set_tx, seq, seq_len, key,
618 key_len);
619}
620
621
622int hostapd_drv_send_mlme(struct hostapd_data *hapd,
8cfa3527 623 const void *msg, size_t len, int noack)
7392f11e
JM
624{
625 if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
626 return 0;
2d3943ce
AO
627 return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
628 NULL, 0);
629}
630
631
632int hostapd_drv_send_mlme_csa(struct hostapd_data *hapd,
633 const void *msg, size_t len, int noack,
634 const u16 *csa_offs, size_t csa_offs_len)
635{
636 if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
637 return 0;
638 return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0,
639 csa_offs, csa_offs_len);
7392f11e
JM
640}
641
642
643int hostapd_drv_sta_deauth(struct hostapd_data *hapd,
644 const u8 *addr, int reason)
645{
646 if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
647 return 0;
648 return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
649 reason);
650}
651
652
653int hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
654 const u8 *addr, int reason)
655{
656 if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
657 return 0;
658 return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
659 reason);
660}
fb80e86e
JK
661
662
a884be9d
XC
663int hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
664 const u8 *peer, u8 *buf, u16 *buf_len)
665{
666 if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
47768978 667 return -1;
a884be9d
XC
668 return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
669 buf_len);
670}
671
672
fb80e86e
JK
673int hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
674 unsigned int wait, const u8 *dst, const u8 *data,
675 size_t len)
676{
677 if (hapd->driver == NULL || hapd->driver->send_action == NULL)
678 return 0;
679 return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
680 hapd->own_addr, hapd->own_addr, data,
681 len, 0);
682}
e76da505 683
dc036d9e 684
4e8f31e2
JM
685int hostapd_start_dfs_cac(struct hostapd_iface *iface,
686 enum hostapd_hw_mode mode, int freq,
58b73e3d
JD
687 int channel, int ht_enabled, int vht_enabled,
688 int sec_channel_offset, int vht_oper_chwidth,
689 int center_segment0, int center_segment1)
e76da505 690{
dc036d9e 691 struct hostapd_data *hapd = iface->bss[0];
04e8003c 692 struct hostapd_freq_params data;
2e946249 693 int res;
04e8003c 694
e76da505
JD
695 if (!hapd->driver || !hapd->driver->start_dfs_cac)
696 return 0;
697
dc036d9e 698 if (!iface->conf->ieee80211h) {
e76da505
JD
699 wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
700 "is not enabled");
701 return -1;
702 }
703
58b73e3d
JD
704 if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
705 vht_enabled, sec_channel_offset,
706 vht_oper_chwidth, center_segment0,
7f0303d5 707 center_segment1,
1f374834
JD
708 iface->current_mode->vht_capab)) {
709 wpa_printf(MSG_ERROR, "Can't set freq params");
04e8003c 710 return -1;
1f374834 711 }
04e8003c 712
2e946249 713 res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
bbbacbf2 714 if (!res) {
dc036d9e 715 iface->cac_started = 1;
bbbacbf2
JD
716 os_get_reltime(&iface->dfs_cac_start);
717 }
2e946249
JD
718
719 return res;
e76da505 720}
c551700f
KP
721
722
723int hostapd_drv_set_qos_map(struct hostapd_data *hapd,
724 const u8 *qos_map_set, u8 qos_map_set_len)
725{
726 if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
727 return 0;
728 return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
729 qos_map_set_len);
730}
16689c7c
PX
731
732
d0cdccd3
PX
733static void hostapd_get_hw_mode_any_channels(struct hostapd_data *hapd,
734 struct hostapd_hw_modes *mode,
735 int acs_ch_list_all,
736 int **freq_list)
737{
738 int i;
739
740 for (i = 0; i < mode->num_channels; i++) {
741 struct hostapd_channel_data *chan = &mode->channels[i];
742
743 if ((acs_ch_list_all ||
744 freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
745 chan->chan)) &&
746 !(chan->flag & HOSTAPD_CHAN_DISABLED))
747 int_array_add_unique(freq_list, chan->freq);
748 }
749}
750
751
16689c7c
PX
752int hostapd_drv_do_acs(struct hostapd_data *hapd)
753{
754 struct drv_acs_params params;
857d9422
MM
755 int ret, i, acs_ch_list_all = 0;
756 u8 *channels = NULL;
757 unsigned int num_channels = 0;
758 struct hostapd_hw_modes *mode;
d0cdccd3 759 int *freq_list = NULL;
16689c7c
PX
760
761 if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
762 return 0;
857d9422 763
16689c7c
PX
764 os_memset(&params, 0, sizeof(params));
765 params.hw_mode = hapd->iface->conf->hw_mode;
857d9422
MM
766
767 /*
768 * If no chanlist config parameter is provided, include all enabled
769 * channels of the selected hw_mode.
770 */
771 if (!hapd->iface->conf->acs_ch_list.num)
772 acs_ch_list_all = 1;
773
774 mode = hapd->iface->current_mode;
d0cdccd3
PX
775 if (mode) {
776 channels = os_malloc(mode->num_channels);
777 if (channels == NULL)
778 return -1;
779
780 for (i = 0; i < mode->num_channels; i++) {
781 struct hostapd_channel_data *chan = &mode->channels[i];
782 if (!acs_ch_list_all &&
783 !freq_range_list_includes(
784 &hapd->iface->conf->acs_ch_list,
785 chan->chan))
786 continue;
787 if (!(chan->flag & HOSTAPD_CHAN_DISABLED)) {
788 channels[num_channels++] = chan->chan;
789 int_array_add_unique(&freq_list, chan->freq);
790 }
791 }
792 } else {
793 for (i = 0; i < hapd->iface->num_hw_features; i++) {
794 mode = &hapd->iface->hw_features[i];
795 hostapd_get_hw_mode_any_channels(hapd, mode,
796 acs_ch_list_all,
797 &freq_list);
798 }
857d9422
MM
799 }
800
801 params.ch_list = channels;
802 params.ch_list_len = num_channels;
d0cdccd3 803 params.freq_list = freq_list;
857d9422 804
16689c7c 805 params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
5085ffb8 806 params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
16689c7c 807 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
857d9422
MM
808 params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
809 params.ch_width = 20;
810 if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
811 params.ch_width = 40;
812
813 /* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
814 */
815 if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) {
816 if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
817 params.ch_width = 80;
818 else if (hapd->iface->conf->vht_oper_chwidth ==
819 VHT_CHANWIDTH_160MHZ ||
820 hapd->iface->conf->vht_oper_chwidth ==
821 VHT_CHANWIDTH_80P80MHZ)
822 params.ch_width = 160;
823 }
824
825 ret = hapd->driver->do_acs(hapd->drv_priv, &params);
826 os_free(channels);
827
828 return ret;
16689c7c 829}