2 * hostapd - Driver operations
3 * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #include "utils/common.h"
12 #include "common/ieee802_11_defs.h"
13 #include "common/hw_features_common.h"
17 #include "ieee802_11.h"
19 #include "ap_config.h"
20 #include "p2p_hostapd.h"
23 #include "ap_drv_ops.h"
26 u32
hostapd_sta_flags_to_drv(u32 flags
)
29 if (flags
& WLAN_STA_AUTHORIZED
)
30 res
|= WPA_STA_AUTHORIZED
;
31 if (flags
& WLAN_STA_WMM
)
33 if (flags
& WLAN_STA_SHORT_PREAMBLE
)
34 res
|= WPA_STA_SHORT_PREAMBLE
;
35 if (flags
& WLAN_STA_MFP
)
37 if (flags
& WLAN_STA_AUTH
)
38 res
|= WPA_STA_AUTHENTICATED
;
39 if (flags
& WLAN_STA_ASSOC
)
40 res
|= WPA_STA_ASSOCIATED
;
45 static int add_buf(struct wpabuf
**dst
, const struct wpabuf
*src
)
49 if (wpabuf_resize(dst
, wpabuf_len(src
)) != 0)
51 wpabuf_put_buf(*dst
, src
);
56 static int add_buf_data(struct wpabuf
**dst
, const u8
*data
, size_t len
)
60 if (wpabuf_resize(dst
, len
) != 0)
62 wpabuf_put_data(*dst
, data
, len
);
67 int hostapd_build_ap_extra_ies(struct hostapd_data
*hapd
,
68 struct wpabuf
**beacon_ret
,
69 struct wpabuf
**proberesp_ret
,
70 struct wpabuf
**assocresp_ret
)
72 struct wpabuf
*beacon
= NULL
, *proberesp
= NULL
, *assocresp
= NULL
;
75 *beacon_ret
= *proberesp_ret
= *assocresp_ret
= NULL
;
78 pos
= hostapd_eid_time_adv(hapd
, pos
);
79 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0)
81 pos
= hostapd_eid_time_zone(hapd
, pos
);
82 if (add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
86 pos
= hostapd_eid_ext_capab(hapd
, pos
);
87 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
89 pos
= hostapd_eid_interworking(hapd
, pos
);
90 pos
= hostapd_eid_adv_proto(hapd
, pos
);
91 pos
= hostapd_eid_roaming_consortium(hapd
, pos
);
92 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
93 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
97 if (add_buf(&beacon
, hapd
->iface
->fst_ies
) < 0 ||
98 add_buf(&proberesp
, hapd
->iface
->fst_ies
) < 0 ||
99 add_buf(&assocresp
, hapd
->iface
->fst_ies
) < 0)
101 #endif /* CONFIG_FST */
104 pos
= hostapd_eid_fils_indic(hapd
, buf
, 0);
105 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
106 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
108 #endif /* CONFIG_FILS */
110 if (add_buf(&beacon
, hapd
->wps_beacon_ie
) < 0 ||
111 add_buf(&proberesp
, hapd
->wps_probe_resp_ie
) < 0)
115 if (add_buf(&beacon
, hapd
->p2p_beacon_ie
) < 0 ||
116 add_buf(&proberesp
, hapd
->p2p_probe_resp_ie
) < 0)
118 #endif /* CONFIG_P2P */
120 #ifdef CONFIG_P2P_MANAGER
121 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
122 if (wpabuf_resize(&beacon
, 100) == 0) {
124 start
= wpabuf_put(beacon
, 0);
125 p
= hostapd_eid_p2p_manage(hapd
, start
);
126 wpabuf_put(beacon
, p
- start
);
129 if (wpabuf_resize(&proberesp
, 100) == 0) {
131 start
= wpabuf_put(proberesp
, 0);
132 p
= hostapd_eid_p2p_manage(hapd
, start
);
133 wpabuf_put(proberesp
, p
- start
);
136 #endif /* CONFIG_P2P_MANAGER */
139 if (hapd
->conf
->wps_state
) {
140 struct wpabuf
*a
= wps_build_assoc_resp_ie();
141 add_buf(&assocresp
, a
);
144 #endif /* CONFIG_WPS */
146 #ifdef CONFIG_P2P_MANAGER
147 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
148 if (wpabuf_resize(&assocresp
, 100) == 0) {
150 start
= wpabuf_put(assocresp
, 0);
151 p
= hostapd_eid_p2p_manage(hapd
, start
);
152 wpabuf_put(assocresp
, p
- start
);
155 #endif /* CONFIG_P2P_MANAGER */
157 #ifdef CONFIG_WIFI_DISPLAY
158 if (hapd
->p2p_group
) {
160 a
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, P2P_SC_SUCCESS
);
161 add_buf(&assocresp
, a
);
164 #endif /* CONFIG_WIFI_DISPLAY */
167 pos
= hostapd_eid_hs20_indication(hapd
, buf
);
168 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
169 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
172 pos
= hostapd_eid_osen(hapd
, buf
);
173 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
174 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
176 #endif /* CONFIG_HS20 */
179 if (hapd
->conf
->mbo_enabled
||
180 OCE_STA_CFON_ENABLED(hapd
) || OCE_AP_ENABLED(hapd
)) {
181 pos
= hostapd_eid_mbo(hapd
, buf
, sizeof(buf
));
182 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
183 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0 ||
184 add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
187 #endif /* CONFIG_MBO */
190 pos
= hostapd_eid_owe_trans(hapd
, buf
, sizeof(buf
));
191 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
192 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
194 #endif /* CONFIG_OWE */
196 add_buf(&beacon
, hapd
->conf
->vendor_elements
);
197 add_buf(&proberesp
, hapd
->conf
->vendor_elements
);
198 add_buf(&assocresp
, hapd
->conf
->assocresp_elements
);
200 *beacon_ret
= beacon
;
201 *proberesp_ret
= proberesp
;
202 *assocresp_ret
= assocresp
;
208 wpabuf_free(proberesp
);
209 wpabuf_free(assocresp
);
214 void hostapd_free_ap_extra_ies(struct hostapd_data
*hapd
,
215 struct wpabuf
*beacon
,
216 struct wpabuf
*proberesp
,
217 struct wpabuf
*assocresp
)
220 wpabuf_free(proberesp
);
221 wpabuf_free(assocresp
);
225 int hostapd_reset_ap_wps_ie(struct hostapd_data
*hapd
)
227 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
230 return hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, NULL
, NULL
, NULL
);
234 int hostapd_set_ap_wps_ie(struct hostapd_data
*hapd
)
236 struct wpabuf
*beacon
, *proberesp
, *assocresp
;
239 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
242 if (hostapd_build_ap_extra_ies(hapd
, &beacon
, &proberesp
, &assocresp
) <
246 ret
= hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, beacon
, proberesp
,
249 hostapd_free_ap_extra_ies(hapd
, beacon
, proberesp
, assocresp
);
255 int hostapd_set_authorized(struct hostapd_data
*hapd
,
256 struct sta_info
*sta
, int authorized
)
259 return hostapd_sta_set_flags(hapd
, sta
->addr
,
260 hostapd_sta_flags_to_drv(
262 WPA_STA_AUTHORIZED
, ~0);
265 return hostapd_sta_set_flags(hapd
, sta
->addr
,
266 hostapd_sta_flags_to_drv(sta
->flags
),
267 0, ~WPA_STA_AUTHORIZED
);
271 int hostapd_set_sta_flags(struct hostapd_data
*hapd
, struct sta_info
*sta
)
273 int set_flags
, total_flags
, flags_and
, flags_or
;
274 total_flags
= hostapd_sta_flags_to_drv(sta
->flags
);
275 set_flags
= WPA_STA_SHORT_PREAMBLE
| WPA_STA_WMM
| WPA_STA_MFP
;
276 if (((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
277 sta
->auth_alg
== WLAN_AUTH_FT
) &&
278 sta
->flags
& WLAN_STA_AUTHORIZED
)
279 set_flags
|= WPA_STA_AUTHORIZED
;
280 flags_or
= total_flags
& set_flags
;
281 flags_and
= total_flags
| ~set_flags
;
282 return hostapd_sta_set_flags(hapd
, sta
->addr
, total_flags
,
283 flags_or
, flags_and
);
287 int hostapd_set_drv_ieee8021x(struct hostapd_data
*hapd
, const char *ifname
,
290 struct wpa_bss_params params
;
291 os_memset(¶ms
, 0, sizeof(params
));
292 params
.ifname
= ifname
;
293 params
.enabled
= enabled
;
295 params
.wpa
= hapd
->conf
->wpa
;
296 params
.ieee802_1x
= hapd
->conf
->ieee802_1x
;
297 params
.wpa_group
= hapd
->conf
->wpa_group
;
298 if ((hapd
->conf
->wpa
& (WPA_PROTO_WPA
| WPA_PROTO_RSN
)) ==
299 (WPA_PROTO_WPA
| WPA_PROTO_RSN
))
300 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
|
301 hapd
->conf
->rsn_pairwise
;
302 else if (hapd
->conf
->wpa
& WPA_PROTO_RSN
)
303 params
.wpa_pairwise
= hapd
->conf
->rsn_pairwise
;
304 else if (hapd
->conf
->wpa
& WPA_PROTO_WPA
)
305 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
;
306 params
.wpa_key_mgmt
= hapd
->conf
->wpa_key_mgmt
;
307 params
.rsn_preauth
= hapd
->conf
->rsn_preauth
;
308 #ifdef CONFIG_IEEE80211W
309 params
.ieee80211w
= hapd
->conf
->ieee80211w
;
310 #endif /* CONFIG_IEEE80211W */
312 return hostapd_set_ieee8021x(hapd
, ¶ms
);
316 int hostapd_vlan_if_add(struct hostapd_data
*hapd
, const char *ifname
)
318 char force_ifname
[IFNAMSIZ
];
319 u8 if_addr
[ETH_ALEN
];
320 return hostapd_if_add(hapd
, WPA_IF_AP_VLAN
, ifname
, hapd
->own_addr
,
321 NULL
, NULL
, force_ifname
, if_addr
, NULL
, 0);
325 int hostapd_vlan_if_remove(struct hostapd_data
*hapd
, const char *ifname
)
327 return hostapd_if_remove(hapd
, WPA_IF_AP_VLAN
, ifname
);
331 int hostapd_set_wds_sta(struct hostapd_data
*hapd
, char *ifname_wds
,
332 const u8
*addr
, int aid
, int val
)
334 const char *bridge
= NULL
;
336 if (hapd
->driver
== NULL
|| hapd
->driver
->set_wds_sta
== NULL
)
338 if (hapd
->conf
->wds_bridge
[0])
339 bridge
= hapd
->conf
->wds_bridge
;
340 else if (hapd
->conf
->bridge
[0])
341 bridge
= hapd
->conf
->bridge
;
342 return hapd
->driver
->set_wds_sta(hapd
->drv_priv
, addr
, aid
, val
,
347 int hostapd_add_sta_node(struct hostapd_data
*hapd
, const u8
*addr
,
350 if (hapd
->driver
== NULL
|| hapd
->driver
->add_sta_node
== NULL
)
352 return hapd
->driver
->add_sta_node(hapd
->drv_priv
, addr
, auth_alg
);
356 int hostapd_sta_auth(struct hostapd_data
*hapd
, const u8
*addr
,
357 u16 seq
, u16 status
, const u8
*ie
, size_t len
)
359 struct wpa_driver_sta_auth_params params
;
361 struct sta_info
*sta
;
362 #endif /* CONFIG_FILS */
364 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_auth
== NULL
)
367 os_memset(¶ms
, 0, sizeof(params
));
370 sta
= ap_get_sta(hapd
, addr
);
372 wpa_printf(MSG_DEBUG
, "Station " MACSTR
373 " not found for sta_auth processing",
378 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
379 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
380 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
381 params
.fils_auth
= 1;
382 wpa_auth_get_fils_aead_params(sta
->wpa_sm
, params
.fils_anonce
,
385 ¶ms
.fils_kek_len
);
387 #endif /* CONFIG_FILS */
389 params
.own_addr
= hapd
->own_addr
;
392 params
.status
= status
;
396 return hapd
->driver
->sta_auth(hapd
->drv_priv
, ¶ms
);
400 int hostapd_sta_assoc(struct hostapd_data
*hapd
, const u8
*addr
,
401 int reassoc
, u16 status
, const u8
*ie
, size_t len
)
403 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_assoc
== NULL
)
405 return hapd
->driver
->sta_assoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
406 reassoc
, status
, ie
, len
);
410 int hostapd_sta_add(struct hostapd_data
*hapd
,
411 const u8
*addr
, u16 aid
, u16 capability
,
412 const u8
*supp_rates
, size_t supp_rates_len
,
414 const struct ieee80211_ht_capabilities
*ht_capab
,
415 const struct ieee80211_vht_capabilities
*vht_capab
,
416 const struct ieee80211_he_capabilities
*he_capab
,
418 u32 flags
, u8 qosinfo
, u8 vht_opmode
, int supp_p2p_ps
,
421 struct hostapd_sta_add_params params
;
423 if (hapd
->driver
== NULL
)
425 if (hapd
->driver
->sta_add
== NULL
)
428 os_memset(¶ms
, 0, sizeof(params
));
431 params
.capability
= capability
;
432 params
.supp_rates
= supp_rates
;
433 params
.supp_rates_len
= supp_rates_len
;
434 params
.listen_interval
= listen_interval
;
435 params
.ht_capabilities
= ht_capab
;
436 params
.vht_capabilities
= vht_capab
;
437 params
.he_capab
= he_capab
;
438 params
.he_capab_len
= he_capab_len
;
439 params
.vht_opmode_enabled
= !!(flags
& WLAN_STA_VHT_OPMODE_ENABLED
);
440 params
.vht_opmode
= vht_opmode
;
441 params
.flags
= hostapd_sta_flags_to_drv(flags
);
442 params
.qosinfo
= qosinfo
;
443 params
.support_p2p_ps
= supp_p2p_ps
;
445 return hapd
->driver
->sta_add(hapd
->drv_priv
, ¶ms
);
449 int hostapd_add_tspec(struct hostapd_data
*hapd
, const u8
*addr
,
450 u8
*tspec_ie
, size_t tspec_ielen
)
452 if (hapd
->driver
== NULL
|| hapd
->driver
->add_tspec
== NULL
)
454 return hapd
->driver
->add_tspec(hapd
->drv_priv
, addr
, tspec_ie
,
459 int hostapd_set_privacy(struct hostapd_data
*hapd
, int enabled
)
461 if (hapd
->driver
== NULL
|| hapd
->driver
->set_privacy
== NULL
)
463 return hapd
->driver
->set_privacy(hapd
->drv_priv
, enabled
);
467 int hostapd_set_generic_elem(struct hostapd_data
*hapd
, const u8
*elem
,
470 if (hapd
->driver
== NULL
|| hapd
->driver
->set_generic_elem
== NULL
)
472 return hapd
->driver
->set_generic_elem(hapd
->drv_priv
, elem
, elem_len
);
476 int hostapd_get_ssid(struct hostapd_data
*hapd
, u8
*buf
, size_t len
)
478 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_get_ssid
== NULL
)
480 return hapd
->driver
->hapd_get_ssid(hapd
->drv_priv
, buf
, len
);
484 int hostapd_set_ssid(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
)
486 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_set_ssid
== NULL
)
488 return hapd
->driver
->hapd_set_ssid(hapd
->drv_priv
, buf
, len
);
492 int hostapd_if_add(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
493 const char *ifname
, const u8
*addr
, void *bss_ctx
,
494 void **drv_priv
, char *force_ifname
, u8
*if_addr
,
495 const char *bridge
, int use_existing
)
497 if (hapd
->driver
== NULL
|| hapd
->driver
->if_add
== NULL
)
499 return hapd
->driver
->if_add(hapd
->drv_priv
, type
, ifname
, addr
,
500 bss_ctx
, drv_priv
, force_ifname
, if_addr
,
501 bridge
, use_existing
, 1);
505 int hostapd_if_remove(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
508 if (hapd
->driver
== NULL
|| hapd
->drv_priv
== NULL
||
509 hapd
->driver
->if_remove
== NULL
)
511 return hapd
->driver
->if_remove(hapd
->drv_priv
, type
, ifname
);
515 int hostapd_set_ieee8021x(struct hostapd_data
*hapd
,
516 struct wpa_bss_params
*params
)
518 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ieee8021x
== NULL
)
520 return hapd
->driver
->set_ieee8021x(hapd
->drv_priv
, params
);
524 int hostapd_get_seqnum(const char *ifname
, struct hostapd_data
*hapd
,
525 const u8
*addr
, int idx
, u8
*seq
)
527 if (hapd
->driver
== NULL
|| hapd
->driver
->get_seqnum
== NULL
)
529 return hapd
->driver
->get_seqnum(ifname
, hapd
->drv_priv
, addr
, idx
,
534 int hostapd_flush(struct hostapd_data
*hapd
)
536 if (hapd
->driver
== NULL
|| hapd
->driver
->flush
== NULL
)
538 return hapd
->driver
->flush(hapd
->drv_priv
);
542 int hostapd_set_freq(struct hostapd_data
*hapd
, enum hostapd_hw_mode mode
,
543 int freq
, int channel
, int ht_enabled
, int vht_enabled
,
545 int sec_channel_offset
, int oper_chwidth
,
546 int center_segment0
, int center_segment1
)
548 struct hostapd_freq_params data
;
550 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, ht_enabled
,
551 vht_enabled
, he_enabled
, sec_channel_offset
,
553 center_segment0
, center_segment1
,
554 hapd
->iface
->current_mode
?
555 hapd
->iface
->current_mode
->vht_capab
: 0,
556 &hapd
->iface
->current_mode
->he_capab
))
559 if (hapd
->driver
== NULL
)
561 if (hapd
->driver
->set_freq
== NULL
)
563 return hapd
->driver
->set_freq(hapd
->drv_priv
, &data
);
566 int hostapd_set_rts(struct hostapd_data
*hapd
, int rts
)
568 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rts
== NULL
)
570 return hapd
->driver
->set_rts(hapd
->drv_priv
, rts
);
574 int hostapd_set_frag(struct hostapd_data
*hapd
, int frag
)
576 if (hapd
->driver
== NULL
|| hapd
->driver
->set_frag
== NULL
)
578 return hapd
->driver
->set_frag(hapd
->drv_priv
, frag
);
582 int hostapd_sta_set_flags(struct hostapd_data
*hapd
, u8
*addr
,
583 int total_flags
, int flags_or
, int flags_and
)
585 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_set_flags
== NULL
)
587 return hapd
->driver
->sta_set_flags(hapd
->drv_priv
, addr
, total_flags
,
588 flags_or
, flags_and
);
592 int hostapd_sta_set_airtime_weight(struct hostapd_data
*hapd
, const u8
*addr
,
595 if (!hapd
->driver
|| !hapd
->driver
->sta_set_airtime_weight
)
597 return hapd
->driver
->sta_set_airtime_weight(hapd
->drv_priv
, addr
,
602 int hostapd_set_country(struct hostapd_data
*hapd
, const char *country
)
604 if (hapd
->driver
== NULL
||
605 hapd
->driver
->set_country
== NULL
)
607 return hapd
->driver
->set_country(hapd
->drv_priv
, country
);
611 int hostapd_set_tx_queue_params(struct hostapd_data
*hapd
, int queue
, int aifs
,
612 int cw_min
, int cw_max
, int burst_time
)
614 if (hapd
->driver
== NULL
|| hapd
->driver
->set_tx_queue_params
== NULL
)
616 return hapd
->driver
->set_tx_queue_params(hapd
->drv_priv
, queue
, aifs
,
617 cw_min
, cw_max
, burst_time
);
621 struct hostapd_hw_modes
*
622 hostapd_get_hw_feature_data(struct hostapd_data
*hapd
, u16
*num_modes
,
623 u16
*flags
, u8
*dfs_domain
)
625 if (hapd
->driver
== NULL
||
626 hapd
->driver
->get_hw_feature_data
== NULL
)
628 return hapd
->driver
->get_hw_feature_data(hapd
->drv_priv
, num_modes
,
633 int hostapd_driver_commit(struct hostapd_data
*hapd
)
635 if (hapd
->driver
== NULL
|| hapd
->driver
->commit
== NULL
)
637 return hapd
->driver
->commit(hapd
->drv_priv
);
641 int hostapd_drv_none(struct hostapd_data
*hapd
)
643 return hapd
->driver
&& os_strcmp(hapd
->driver
->name
, "none") == 0;
647 int hostapd_driver_scan(struct hostapd_data
*hapd
,
648 struct wpa_driver_scan_params
*params
)
650 if (hapd
->driver
&& hapd
->driver
->scan2
)
651 return hapd
->driver
->scan2(hapd
->drv_priv
, params
);
656 struct wpa_scan_results
* hostapd_driver_get_scan_results(
657 struct hostapd_data
*hapd
)
659 if (hapd
->driver
&& hapd
->driver
->get_scan_results2
)
660 return hapd
->driver
->get_scan_results2(hapd
->drv_priv
);
665 int hostapd_driver_set_noa(struct hostapd_data
*hapd
, u8 count
, int start
,
668 if (hapd
->driver
&& hapd
->driver
->set_noa
)
669 return hapd
->driver
->set_noa(hapd
->drv_priv
, count
, start
,
675 int hostapd_drv_set_key(const char *ifname
, struct hostapd_data
*hapd
,
676 enum wpa_alg alg
, const u8
*addr
,
677 int key_idx
, int set_tx
,
678 const u8
*seq
, size_t seq_len
,
679 const u8
*key
, size_t key_len
)
681 if (hapd
->driver
== NULL
|| hapd
->driver
->set_key
== NULL
)
683 return hapd
->driver
->set_key(ifname
, hapd
->drv_priv
, alg
, addr
,
684 key_idx
, set_tx
, seq
, seq_len
, key
,
689 int hostapd_drv_send_mlme(struct hostapd_data
*hapd
,
690 const void *msg
, size_t len
, int noack
)
692 if (!hapd
->driver
|| !hapd
->driver
->send_mlme
|| !hapd
->drv_priv
)
694 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
699 int hostapd_drv_send_mlme_csa(struct hostapd_data
*hapd
,
700 const void *msg
, size_t len
, int noack
,
701 const u16
*csa_offs
, size_t csa_offs_len
)
703 if (hapd
->driver
== NULL
|| hapd
->driver
->send_mlme
== NULL
)
705 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
706 csa_offs
, csa_offs_len
);
710 int hostapd_drv_sta_deauth(struct hostapd_data
*hapd
,
711 const u8
*addr
, int reason
)
713 if (!hapd
->driver
|| !hapd
->driver
->sta_deauth
|| !hapd
->drv_priv
)
715 return hapd
->driver
->sta_deauth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
720 int hostapd_drv_sta_disassoc(struct hostapd_data
*hapd
,
721 const u8
*addr
, int reason
)
723 if (!hapd
->driver
|| !hapd
->driver
->sta_disassoc
|| !hapd
->drv_priv
)
725 return hapd
->driver
->sta_disassoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
730 int hostapd_drv_wnm_oper(struct hostapd_data
*hapd
, enum wnm_oper oper
,
731 const u8
*peer
, u8
*buf
, u16
*buf_len
)
733 if (hapd
->driver
== NULL
|| hapd
->driver
->wnm_oper
== NULL
)
735 return hapd
->driver
->wnm_oper(hapd
->drv_priv
, oper
, peer
, buf
,
740 int hostapd_drv_send_action(struct hostapd_data
*hapd
, unsigned int freq
,
741 unsigned int wait
, const u8
*dst
, const u8
*data
,
745 const u8 wildcard_bssid
[ETH_ALEN
] = {
746 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
749 if (!hapd
->driver
|| !hapd
->driver
->send_action
|| !hapd
->drv_priv
)
751 bssid
= hapd
->own_addr
;
752 if (!is_multicast_ether_addr(dst
) &&
753 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
754 struct sta_info
*sta
;
757 * Public Action frames to a STA that is not a member of the BSS
758 * shall use wildcard BSSID value.
760 sta
= ap_get_sta(hapd
, dst
);
761 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
))
762 bssid
= wildcard_bssid
;
763 } else if (is_broadcast_ether_addr(dst
) &&
764 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
766 * The only current use case of Public Action frames with
767 * broadcast destination address is DPP PKEX. That case is
768 * directing all devices and not just the STAs within the BSS,
769 * so have to use the wildcard BSSID value.
771 bssid
= wildcard_bssid
;
773 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
774 hapd
->own_addr
, bssid
, data
, len
, 0);
778 int hostapd_drv_send_action_addr3_ap(struct hostapd_data
*hapd
,
780 unsigned int wait
, const u8
*dst
,
781 const u8
*data
, size_t len
)
783 if (hapd
->driver
== NULL
|| hapd
->driver
->send_action
== NULL
)
785 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
786 hapd
->own_addr
, hapd
->own_addr
, data
,
791 int hostapd_start_dfs_cac(struct hostapd_iface
*iface
,
792 enum hostapd_hw_mode mode
, int freq
,
793 int channel
, int ht_enabled
, int vht_enabled
,
795 int sec_channel_offset
, int oper_chwidth
,
796 int center_segment0
, int center_segment1
)
798 struct hostapd_data
*hapd
= iface
->bss
[0];
799 struct hostapd_freq_params data
;
802 if (!hapd
->driver
|| !hapd
->driver
->start_dfs_cac
)
805 if (!iface
->conf
->ieee80211h
) {
806 wpa_printf(MSG_ERROR
, "Can't start DFS CAC, DFS functionality "
811 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, ht_enabled
,
812 vht_enabled
, he_enabled
, sec_channel_offset
,
813 oper_chwidth
, center_segment0
,
815 iface
->current_mode
->vht_capab
,
816 &iface
->current_mode
->he_capab
)) {
817 wpa_printf(MSG_ERROR
, "Can't set freq params");
821 res
= hapd
->driver
->start_dfs_cac(hapd
->drv_priv
, &data
);
823 iface
->cac_started
= 1;
824 os_get_reltime(&iface
->dfs_cac_start
);
831 int hostapd_drv_set_qos_map(struct hostapd_data
*hapd
,
832 const u8
*qos_map_set
, u8 qos_map_set_len
)
834 if (!hapd
->driver
|| !hapd
->driver
->set_qos_map
|| !hapd
->drv_priv
)
836 return hapd
->driver
->set_qos_map(hapd
->drv_priv
, qos_map_set
,
841 static void hostapd_get_hw_mode_any_channels(struct hostapd_data
*hapd
,
842 struct hostapd_hw_modes
*mode
,
848 for (i
= 0; i
< mode
->num_channels
; i
++) {
849 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
851 if ((acs_ch_list_all
||
852 freq_range_list_includes(&hapd
->iface
->conf
->acs_ch_list
,
854 !(chan
->flag
& HOSTAPD_CHAN_DISABLED
) &&
855 !(hapd
->iface
->conf
->acs_exclude_dfs
&&
856 (chan
->flag
& HOSTAPD_CHAN_RADAR
)))
857 int_array_add_unique(freq_list
, chan
->freq
);
862 void hostapd_get_ext_capa(struct hostapd_iface
*iface
)
864 struct hostapd_data
*hapd
= iface
->bss
[0];
866 if (!hapd
->driver
|| !hapd
->driver
->get_ext_capab
)
869 hapd
->driver
->get_ext_capab(hapd
->drv_priv
, WPA_IF_AP_BSS
,
870 &iface
->extended_capa
,
871 &iface
->extended_capa_mask
,
872 &iface
->extended_capa_len
);
876 int hostapd_drv_do_acs(struct hostapd_data
*hapd
)
878 struct drv_acs_params params
;
879 int ret
, i
, acs_ch_list_all
= 0;
881 unsigned int num_channels
= 0;
882 struct hostapd_hw_modes
*mode
;
883 int *freq_list
= NULL
;
885 if (hapd
->driver
== NULL
|| hapd
->driver
->do_acs
== NULL
)
888 os_memset(¶ms
, 0, sizeof(params
));
889 params
.hw_mode
= hapd
->iface
->conf
->hw_mode
;
892 * If no chanlist config parameter is provided, include all enabled
893 * channels of the selected hw_mode.
895 if (!hapd
->iface
->conf
->acs_ch_list
.num
)
898 mode
= hapd
->iface
->current_mode
;
900 channels
= os_malloc(mode
->num_channels
);
901 if (channels
== NULL
)
904 for (i
= 0; i
< mode
->num_channels
; i
++) {
905 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
906 if (!acs_ch_list_all
&&
907 !freq_range_list_includes(
908 &hapd
->iface
->conf
->acs_ch_list
,
911 if (hapd
->iface
->conf
->acs_exclude_dfs
&&
912 (chan
->flag
& HOSTAPD_CHAN_RADAR
))
914 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
)) {
915 channels
[num_channels
++] = chan
->chan
;
916 int_array_add_unique(&freq_list
, chan
->freq
);
920 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
921 mode
= &hapd
->iface
->hw_features
[i
];
922 hostapd_get_hw_mode_any_channels(hapd
, mode
,
928 params
.ch_list
= channels
;
929 params
.ch_list_len
= num_channels
;
930 params
.freq_list
= freq_list
;
932 params
.ht_enabled
= !!(hapd
->iface
->conf
->ieee80211n
);
933 params
.ht40_enabled
= !!(hapd
->iface
->conf
->ht_capab
&
934 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
);
935 params
.vht_enabled
= !!(hapd
->iface
->conf
->ieee80211ac
);
936 params
.ch_width
= 20;
937 if (hapd
->iface
->conf
->ieee80211n
&& params
.ht40_enabled
)
938 params
.ch_width
= 40;
940 /* Note: VHT20 is defined by combination of ht_capab & oper_chwidth
942 if ((hapd
->iface
->conf
->ieee80211ax
||
943 hapd
->iface
->conf
->ieee80211ac
) &&
944 params
.ht40_enabled
) {
945 u8 oper_chwidth
= hostapd_get_oper_chwidth(hapd
->iface
->conf
);
947 if (oper_chwidth
== CHANWIDTH_80MHZ
)
948 params
.ch_width
= 80;
949 else if (oper_chwidth
== CHANWIDTH_160MHZ
||
950 oper_chwidth
== CHANWIDTH_80P80MHZ
)
951 params
.ch_width
= 160;
954 ret
= hapd
->driver
->do_acs(hapd
->drv_priv
, ¶ms
);