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"
22 #include "ap_drv_ops.h"
25 u32
hostapd_sta_flags_to_drv(u32 flags
)
28 if (flags
& WLAN_STA_AUTHORIZED
)
29 res
|= WPA_STA_AUTHORIZED
;
30 if (flags
& WLAN_STA_WMM
)
32 if (flags
& WLAN_STA_SHORT_PREAMBLE
)
33 res
|= WPA_STA_SHORT_PREAMBLE
;
34 if (flags
& WLAN_STA_MFP
)
36 if (flags
& WLAN_STA_AUTH
)
37 res
|= WPA_STA_AUTHENTICATED
;
38 if (flags
& WLAN_STA_ASSOC
)
39 res
|= WPA_STA_ASSOCIATED
;
44 static int add_buf(struct wpabuf
**dst
, const struct wpabuf
*src
)
48 if (wpabuf_resize(dst
, wpabuf_len(src
)) != 0)
50 wpabuf_put_buf(*dst
, src
);
55 static int add_buf_data(struct wpabuf
**dst
, const u8
*data
, size_t len
)
59 if (wpabuf_resize(dst
, len
) != 0)
61 wpabuf_put_data(*dst
, data
, len
);
66 int hostapd_build_ap_extra_ies(struct hostapd_data
*hapd
,
67 struct wpabuf
**beacon_ret
,
68 struct wpabuf
**proberesp_ret
,
69 struct wpabuf
**assocresp_ret
)
71 struct wpabuf
*beacon
= NULL
, *proberesp
= NULL
, *assocresp
= NULL
;
74 *beacon_ret
= *proberesp_ret
= *assocresp_ret
= NULL
;
77 pos
= hostapd_eid_time_adv(hapd
, pos
);
78 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0)
80 pos
= hostapd_eid_time_zone(hapd
, pos
);
81 if (add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
85 pos
= hostapd_eid_ext_capab(hapd
, pos
);
86 if (add_buf_data(&assocresp
, buf
, pos
- buf
) < 0)
88 pos
= hostapd_eid_interworking(hapd
, pos
);
89 pos
= hostapd_eid_adv_proto(hapd
, pos
);
90 pos
= hostapd_eid_roaming_consortium(hapd
, pos
);
91 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
92 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
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)
100 #endif /* CONFIG_FST */
102 if (add_buf(&beacon
, hapd
->wps_beacon_ie
) < 0 ||
103 add_buf(&proberesp
, hapd
->wps_probe_resp_ie
) < 0)
107 if (add_buf(&beacon
, hapd
->p2p_beacon_ie
) < 0 ||
108 add_buf(&proberesp
, hapd
->p2p_probe_resp_ie
) < 0)
110 #endif /* CONFIG_P2P */
112 #ifdef CONFIG_P2P_MANAGER
113 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
114 if (wpabuf_resize(&beacon
, 100) == 0) {
116 start
= wpabuf_put(beacon
, 0);
117 p
= hostapd_eid_p2p_manage(hapd
, start
);
118 wpabuf_put(beacon
, p
- start
);
121 if (wpabuf_resize(&proberesp
, 100) == 0) {
123 start
= wpabuf_put(proberesp
, 0);
124 p
= hostapd_eid_p2p_manage(hapd
, start
);
125 wpabuf_put(proberesp
, p
- start
);
128 #endif /* CONFIG_P2P_MANAGER */
131 if (hapd
->conf
->wps_state
) {
132 struct wpabuf
*a
= wps_build_assoc_resp_ie();
133 add_buf(&assocresp
, a
);
136 #endif /* CONFIG_WPS */
138 #ifdef CONFIG_P2P_MANAGER
139 if (hapd
->conf
->p2p
& P2P_MANAGE
) {
140 if (wpabuf_resize(&assocresp
, 100) == 0) {
142 start
= wpabuf_put(assocresp
, 0);
143 p
= hostapd_eid_p2p_manage(hapd
, start
);
144 wpabuf_put(assocresp
, p
- start
);
147 #endif /* CONFIG_P2P_MANAGER */
149 #ifdef CONFIG_WIFI_DISPLAY
150 if (hapd
->p2p_group
) {
152 a
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, P2P_SC_SUCCESS
);
153 add_buf(&assocresp
, a
);
156 #endif /* CONFIG_WIFI_DISPLAY */
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)
164 pos
= hostapd_eid_osen(hapd
, buf
);
165 if (add_buf_data(&beacon
, buf
, pos
- buf
) < 0 ||
166 add_buf_data(&proberesp
, buf
, pos
- buf
) < 0)
168 #endif /* CONFIG_HS20 */
171 if (hapd
->conf
->mbo_enabled
) {
172 pos
= hostapd_eid_mbo(hapd
, buf
, sizeof(buf
));
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)
178 #endif /* CONFIG_MBO */
180 add_buf(&beacon
, hapd
->conf
->vendor_elements
);
181 add_buf(&proberesp
, hapd
->conf
->vendor_elements
);
182 add_buf(&assocresp
, hapd
->conf
->assocresp_elements
);
184 *beacon_ret
= beacon
;
185 *proberesp_ret
= proberesp
;
186 *assocresp_ret
= assocresp
;
192 wpabuf_free(proberesp
);
193 wpabuf_free(assocresp
);
198 void hostapd_free_ap_extra_ies(struct hostapd_data
*hapd
,
199 struct wpabuf
*beacon
,
200 struct wpabuf
*proberesp
,
201 struct wpabuf
*assocresp
)
204 wpabuf_free(proberesp
);
205 wpabuf_free(assocresp
);
209 int hostapd_reset_ap_wps_ie(struct hostapd_data
*hapd
)
211 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
214 return hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, NULL
, NULL
, NULL
);
218 int hostapd_set_ap_wps_ie(struct hostapd_data
*hapd
)
220 struct wpabuf
*beacon
, *proberesp
, *assocresp
;
223 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ap_wps_ie
== NULL
)
226 if (hostapd_build_ap_extra_ies(hapd
, &beacon
, &proberesp
, &assocresp
) <
230 ret
= hapd
->driver
->set_ap_wps_ie(hapd
->drv_priv
, beacon
, proberesp
,
233 hostapd_free_ap_extra_ies(hapd
, beacon
, proberesp
, assocresp
);
239 int hostapd_set_authorized(struct hostapd_data
*hapd
,
240 struct sta_info
*sta
, int authorized
)
243 return hostapd_sta_set_flags(hapd
, sta
->addr
,
244 hostapd_sta_flags_to_drv(
246 WPA_STA_AUTHORIZED
, ~0);
249 return hostapd_sta_set_flags(hapd
, sta
->addr
,
250 hostapd_sta_flags_to_drv(sta
->flags
),
251 0, ~WPA_STA_AUTHORIZED
);
255 int hostapd_set_sta_flags(struct hostapd_data
*hapd
, struct sta_info
*sta
)
257 int set_flags
, total_flags
, flags_and
, flags_or
;
258 total_flags
= hostapd_sta_flags_to_drv(sta
->flags
);
259 set_flags
= WPA_STA_SHORT_PREAMBLE
| WPA_STA_WMM
| WPA_STA_MFP
;
260 if (((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
) ||
261 sta
->auth_alg
== WLAN_AUTH_FT
) &&
262 sta
->flags
& WLAN_STA_AUTHORIZED
)
263 set_flags
|= WPA_STA_AUTHORIZED
;
264 flags_or
= total_flags
& set_flags
;
265 flags_and
= total_flags
| ~set_flags
;
266 return hostapd_sta_set_flags(hapd
, sta
->addr
, total_flags
,
267 flags_or
, flags_and
);
271 int hostapd_set_drv_ieee8021x(struct hostapd_data
*hapd
, const char *ifname
,
274 struct wpa_bss_params params
;
275 os_memset(¶ms
, 0, sizeof(params
));
276 params
.ifname
= ifname
;
277 params
.enabled
= enabled
;
279 params
.wpa
= hapd
->conf
->wpa
;
280 params
.ieee802_1x
= hapd
->conf
->ieee802_1x
;
281 params
.wpa_group
= hapd
->conf
->wpa_group
;
282 if ((hapd
->conf
->wpa
& (WPA_PROTO_WPA
| WPA_PROTO_RSN
)) ==
283 (WPA_PROTO_WPA
| WPA_PROTO_RSN
))
284 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
|
285 hapd
->conf
->rsn_pairwise
;
286 else if (hapd
->conf
->wpa
& WPA_PROTO_RSN
)
287 params
.wpa_pairwise
= hapd
->conf
->rsn_pairwise
;
288 else if (hapd
->conf
->wpa
& WPA_PROTO_WPA
)
289 params
.wpa_pairwise
= hapd
->conf
->wpa_pairwise
;
290 params
.wpa_key_mgmt
= hapd
->conf
->wpa_key_mgmt
;
291 params
.rsn_preauth
= hapd
->conf
->rsn_preauth
;
292 #ifdef CONFIG_IEEE80211W
293 params
.ieee80211w
= hapd
->conf
->ieee80211w
;
294 #endif /* CONFIG_IEEE80211W */
296 return hostapd_set_ieee8021x(hapd
, ¶ms
);
300 int hostapd_vlan_if_add(struct hostapd_data
*hapd
, const char *ifname
)
302 char force_ifname
[IFNAMSIZ
];
303 u8 if_addr
[ETH_ALEN
];
304 return hostapd_if_add(hapd
, WPA_IF_AP_VLAN
, ifname
, hapd
->own_addr
,
305 NULL
, NULL
, force_ifname
, if_addr
, NULL
, 0);
309 int hostapd_vlan_if_remove(struct hostapd_data
*hapd
, const char *ifname
)
311 return hostapd_if_remove(hapd
, WPA_IF_AP_VLAN
, ifname
);
315 int hostapd_set_wds_sta(struct hostapd_data
*hapd
, char *ifname_wds
,
316 const u8
*addr
, int aid
, int val
)
318 const char *bridge
= NULL
;
320 if (hapd
->driver
== NULL
|| hapd
->driver
->set_wds_sta
== NULL
)
322 if (hapd
->conf
->wds_bridge
[0])
323 bridge
= hapd
->conf
->wds_bridge
;
324 else if (hapd
->conf
->bridge
[0])
325 bridge
= hapd
->conf
->bridge
;
326 return hapd
->driver
->set_wds_sta(hapd
->drv_priv
, addr
, aid
, val
,
331 int hostapd_add_sta_node(struct hostapd_data
*hapd
, const u8
*addr
,
334 if (hapd
->driver
== NULL
|| hapd
->driver
->add_sta_node
== NULL
)
336 return hapd
->driver
->add_sta_node(hapd
->drv_priv
, addr
, auth_alg
);
340 int hostapd_sta_auth(struct hostapd_data
*hapd
, const u8
*addr
,
341 u16 seq
, u16 status
, const u8
*ie
, size_t len
)
343 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_auth
== NULL
)
345 return hapd
->driver
->sta_auth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
346 seq
, status
, ie
, len
);
350 int hostapd_sta_assoc(struct hostapd_data
*hapd
, const u8
*addr
,
351 int reassoc
, u16 status
, const u8
*ie
, size_t len
)
353 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_assoc
== NULL
)
355 return hapd
->driver
->sta_assoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
356 reassoc
, status
, ie
, len
);
360 int hostapd_sta_add(struct hostapd_data
*hapd
,
361 const u8
*addr
, u16 aid
, u16 capability
,
362 const u8
*supp_rates
, size_t supp_rates_len
,
364 const struct ieee80211_ht_capabilities
*ht_capab
,
365 const struct ieee80211_vht_capabilities
*vht_capab
,
366 u32 flags
, u8 qosinfo
, u8 vht_opmode
, int supp_p2p_ps
,
369 struct hostapd_sta_add_params params
;
371 if (hapd
->driver
== NULL
)
373 if (hapd
->driver
->sta_add
== NULL
)
376 os_memset(¶ms
, 0, sizeof(params
));
379 params
.capability
= capability
;
380 params
.supp_rates
= supp_rates
;
381 params
.supp_rates_len
= supp_rates_len
;
382 params
.listen_interval
= listen_interval
;
383 params
.ht_capabilities
= ht_capab
;
384 params
.vht_capabilities
= vht_capab
;
385 params
.vht_opmode_enabled
= !!(flags
& WLAN_STA_VHT_OPMODE_ENABLED
);
386 params
.vht_opmode
= vht_opmode
;
387 params
.flags
= hostapd_sta_flags_to_drv(flags
);
388 params
.qosinfo
= qosinfo
;
389 params
.support_p2p_ps
= supp_p2p_ps
;
391 return hapd
->driver
->sta_add(hapd
->drv_priv
, ¶ms
);
395 int hostapd_add_tspec(struct hostapd_data
*hapd
, const u8
*addr
,
396 u8
*tspec_ie
, size_t tspec_ielen
)
398 if (hapd
->driver
== NULL
|| hapd
->driver
->add_tspec
== NULL
)
400 return hapd
->driver
->add_tspec(hapd
->drv_priv
, addr
, tspec_ie
,
405 int hostapd_set_privacy(struct hostapd_data
*hapd
, int enabled
)
407 if (hapd
->driver
== NULL
|| hapd
->driver
->set_privacy
== NULL
)
409 return hapd
->driver
->set_privacy(hapd
->drv_priv
, enabled
);
413 int hostapd_set_generic_elem(struct hostapd_data
*hapd
, const u8
*elem
,
416 if (hapd
->driver
== NULL
|| hapd
->driver
->set_generic_elem
== NULL
)
418 return hapd
->driver
->set_generic_elem(hapd
->drv_priv
, elem
, elem_len
);
422 int hostapd_get_ssid(struct hostapd_data
*hapd
, u8
*buf
, size_t len
)
424 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_get_ssid
== NULL
)
426 return hapd
->driver
->hapd_get_ssid(hapd
->drv_priv
, buf
, len
);
430 int hostapd_set_ssid(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
)
432 if (hapd
->driver
== NULL
|| hapd
->driver
->hapd_set_ssid
== NULL
)
434 return hapd
->driver
->hapd_set_ssid(hapd
->drv_priv
, buf
, len
);
438 int hostapd_if_add(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
439 const char *ifname
, const u8
*addr
, void *bss_ctx
,
440 void **drv_priv
, char *force_ifname
, u8
*if_addr
,
441 const char *bridge
, int use_existing
)
443 if (hapd
->driver
== NULL
|| hapd
->driver
->if_add
== NULL
)
445 return hapd
->driver
->if_add(hapd
->drv_priv
, type
, ifname
, addr
,
446 bss_ctx
, drv_priv
, force_ifname
, if_addr
,
447 bridge
, use_existing
, 1);
451 int hostapd_if_remove(struct hostapd_data
*hapd
, enum wpa_driver_if_type type
,
454 if (hapd
->driver
== NULL
|| hapd
->drv_priv
== NULL
||
455 hapd
->driver
->if_remove
== NULL
)
457 return hapd
->driver
->if_remove(hapd
->drv_priv
, type
, ifname
);
461 int hostapd_set_ieee8021x(struct hostapd_data
*hapd
,
462 struct wpa_bss_params
*params
)
464 if (hapd
->driver
== NULL
|| hapd
->driver
->set_ieee8021x
== NULL
)
466 return hapd
->driver
->set_ieee8021x(hapd
->drv_priv
, params
);
470 int hostapd_get_seqnum(const char *ifname
, struct hostapd_data
*hapd
,
471 const u8
*addr
, int idx
, u8
*seq
)
473 if (hapd
->driver
== NULL
|| hapd
->driver
->get_seqnum
== NULL
)
475 return hapd
->driver
->get_seqnum(ifname
, hapd
->drv_priv
, addr
, idx
,
480 int hostapd_flush(struct hostapd_data
*hapd
)
482 if (hapd
->driver
== NULL
|| hapd
->driver
->flush
== NULL
)
484 return hapd
->driver
->flush(hapd
->drv_priv
);
488 int hostapd_set_freq(struct hostapd_data
*hapd
, enum hostapd_hw_mode mode
,
489 int freq
, int channel
, int ht_enabled
, int vht_enabled
,
490 int sec_channel_offset
, int vht_oper_chwidth
,
491 int center_segment0
, int center_segment1
)
493 struct hostapd_freq_params data
;
495 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, ht_enabled
,
496 vht_enabled
, sec_channel_offset
,
498 center_segment0
, center_segment1
,
499 hapd
->iface
->current_mode
?
500 hapd
->iface
->current_mode
->vht_capab
: 0))
503 if (hapd
->driver
== NULL
)
505 if (hapd
->driver
->set_freq
== NULL
)
507 return hapd
->driver
->set_freq(hapd
->drv_priv
, &data
);
510 int hostapd_set_rts(struct hostapd_data
*hapd
, int rts
)
512 if (hapd
->driver
== NULL
|| hapd
->driver
->set_rts
== NULL
)
514 return hapd
->driver
->set_rts(hapd
->drv_priv
, rts
);
518 int hostapd_set_frag(struct hostapd_data
*hapd
, int frag
)
520 if (hapd
->driver
== NULL
|| hapd
->driver
->set_frag
== NULL
)
522 return hapd
->driver
->set_frag(hapd
->drv_priv
, frag
);
526 int hostapd_sta_set_flags(struct hostapd_data
*hapd
, u8
*addr
,
527 int total_flags
, int flags_or
, int flags_and
)
529 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_set_flags
== NULL
)
531 return hapd
->driver
->sta_set_flags(hapd
->drv_priv
, addr
, total_flags
,
532 flags_or
, flags_and
);
536 int hostapd_set_country(struct hostapd_data
*hapd
, const char *country
)
538 if (hapd
->driver
== NULL
||
539 hapd
->driver
->set_country
== NULL
)
541 return hapd
->driver
->set_country(hapd
->drv_priv
, country
);
545 int hostapd_set_tx_queue_params(struct hostapd_data
*hapd
, int queue
, int aifs
,
546 int cw_min
, int cw_max
, int burst_time
)
548 if (hapd
->driver
== NULL
|| hapd
->driver
->set_tx_queue_params
== NULL
)
550 return hapd
->driver
->set_tx_queue_params(hapd
->drv_priv
, queue
, aifs
,
551 cw_min
, cw_max
, burst_time
);
555 struct hostapd_hw_modes
*
556 hostapd_get_hw_feature_data(struct hostapd_data
*hapd
, u16
*num_modes
,
559 if (hapd
->driver
== NULL
||
560 hapd
->driver
->get_hw_feature_data
== NULL
)
562 return hapd
->driver
->get_hw_feature_data(hapd
->drv_priv
, num_modes
,
567 int hostapd_driver_commit(struct hostapd_data
*hapd
)
569 if (hapd
->driver
== NULL
|| hapd
->driver
->commit
== NULL
)
571 return hapd
->driver
->commit(hapd
->drv_priv
);
575 int hostapd_drv_none(struct hostapd_data
*hapd
)
577 return hapd
->driver
&& os_strcmp(hapd
->driver
->name
, "none") == 0;
581 int hostapd_driver_scan(struct hostapd_data
*hapd
,
582 struct wpa_driver_scan_params
*params
)
584 if (hapd
->driver
&& hapd
->driver
->scan2
)
585 return hapd
->driver
->scan2(hapd
->drv_priv
, params
);
590 struct wpa_scan_results
* hostapd_driver_get_scan_results(
591 struct hostapd_data
*hapd
)
593 if (hapd
->driver
&& hapd
->driver
->get_scan_results2
)
594 return hapd
->driver
->get_scan_results2(hapd
->drv_priv
);
599 int hostapd_driver_set_noa(struct hostapd_data
*hapd
, u8 count
, int start
,
602 if (hapd
->driver
&& hapd
->driver
->set_noa
)
603 return hapd
->driver
->set_noa(hapd
->drv_priv
, count
, start
,
609 int hostapd_drv_set_key(const char *ifname
, struct hostapd_data
*hapd
,
610 enum wpa_alg alg
, const u8
*addr
,
611 int key_idx
, int set_tx
,
612 const u8
*seq
, size_t seq_len
,
613 const u8
*key
, size_t key_len
)
615 if (hapd
->driver
== NULL
|| hapd
->driver
->set_key
== NULL
)
617 return hapd
->driver
->set_key(ifname
, hapd
->drv_priv
, alg
, addr
,
618 key_idx
, set_tx
, seq
, seq_len
, key
,
623 int hostapd_drv_send_mlme(struct hostapd_data
*hapd
,
624 const void *msg
, size_t len
, int noack
)
626 if (hapd
->driver
== NULL
|| hapd
->driver
->send_mlme
== NULL
)
628 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
633 int hostapd_drv_send_mlme_csa(struct hostapd_data
*hapd
,
634 const void *msg
, size_t len
, int noack
,
635 const u16
*csa_offs
, size_t csa_offs_len
)
637 if (hapd
->driver
== NULL
|| hapd
->driver
->send_mlme
== NULL
)
639 return hapd
->driver
->send_mlme(hapd
->drv_priv
, msg
, len
, noack
, 0,
640 csa_offs
, csa_offs_len
);
644 int hostapd_drv_sta_deauth(struct hostapd_data
*hapd
,
645 const u8
*addr
, int reason
)
647 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_deauth
== NULL
)
649 return hapd
->driver
->sta_deauth(hapd
->drv_priv
, hapd
->own_addr
, addr
,
654 int hostapd_drv_sta_disassoc(struct hostapd_data
*hapd
,
655 const u8
*addr
, int reason
)
657 if (hapd
->driver
== NULL
|| hapd
->driver
->sta_disassoc
== NULL
)
659 return hapd
->driver
->sta_disassoc(hapd
->drv_priv
, hapd
->own_addr
, addr
,
664 int hostapd_drv_wnm_oper(struct hostapd_data
*hapd
, enum wnm_oper oper
,
665 const u8
*peer
, u8
*buf
, u16
*buf_len
)
667 if (hapd
->driver
== NULL
|| hapd
->driver
->wnm_oper
== NULL
)
669 return hapd
->driver
->wnm_oper(hapd
->drv_priv
, oper
, peer
, buf
,
674 int hostapd_drv_send_action(struct hostapd_data
*hapd
, unsigned int freq
,
675 unsigned int wait
, const u8
*dst
, const u8
*data
,
679 const u8 wildcard_bssid
[ETH_ALEN
] = {
680 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
683 if (hapd
->driver
== NULL
|| hapd
->driver
->send_action
== NULL
)
685 bssid
= hapd
->own_addr
;
686 if (!is_multicast_ether_addr(dst
) &&
687 len
> 0 && data
[0] == WLAN_ACTION_PUBLIC
) {
688 struct sta_info
*sta
;
691 * Public Action frames to a STA that is not a member of the BSS
692 * shall use wildcard BSSID value.
694 sta
= ap_get_sta(hapd
, dst
);
695 if (!sta
|| !(sta
->flags
& WLAN_STA_ASSOC
))
696 bssid
= wildcard_bssid
;
698 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
699 hapd
->own_addr
, bssid
, data
, len
, 0);
703 int hostapd_drv_send_action_addr3_ap(struct hostapd_data
*hapd
,
705 unsigned int wait
, const u8
*dst
,
706 const u8
*data
, size_t len
)
708 if (hapd
->driver
== NULL
|| hapd
->driver
->send_action
== NULL
)
710 return hapd
->driver
->send_action(hapd
->drv_priv
, freq
, wait
, dst
,
711 hapd
->own_addr
, hapd
->own_addr
, data
,
716 int hostapd_start_dfs_cac(struct hostapd_iface
*iface
,
717 enum hostapd_hw_mode mode
, int freq
,
718 int channel
, int ht_enabled
, int vht_enabled
,
719 int sec_channel_offset
, int vht_oper_chwidth
,
720 int center_segment0
, int center_segment1
)
722 struct hostapd_data
*hapd
= iface
->bss
[0];
723 struct hostapd_freq_params data
;
726 if (!hapd
->driver
|| !hapd
->driver
->start_dfs_cac
)
729 if (!iface
->conf
->ieee80211h
) {
730 wpa_printf(MSG_ERROR
, "Can't start DFS CAC, DFS functionality "
735 if (hostapd_set_freq_params(&data
, mode
, freq
, channel
, ht_enabled
,
736 vht_enabled
, sec_channel_offset
,
737 vht_oper_chwidth
, center_segment0
,
739 iface
->current_mode
->vht_capab
)) {
740 wpa_printf(MSG_ERROR
, "Can't set freq params");
744 res
= hapd
->driver
->start_dfs_cac(hapd
->drv_priv
, &data
);
746 iface
->cac_started
= 1;
747 os_get_reltime(&iface
->dfs_cac_start
);
754 int hostapd_drv_set_qos_map(struct hostapd_data
*hapd
,
755 const u8
*qos_map_set
, u8 qos_map_set_len
)
757 if (hapd
->driver
== NULL
|| hapd
->driver
->set_qos_map
== NULL
)
759 return hapd
->driver
->set_qos_map(hapd
->drv_priv
, qos_map_set
,
764 static void hostapd_get_hw_mode_any_channels(struct hostapd_data
*hapd
,
765 struct hostapd_hw_modes
*mode
,
771 for (i
= 0; i
< mode
->num_channels
; i
++) {
772 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
774 if ((acs_ch_list_all
||
775 freq_range_list_includes(&hapd
->iface
->conf
->acs_ch_list
,
777 !(chan
->flag
& HOSTAPD_CHAN_DISABLED
))
778 int_array_add_unique(freq_list
, chan
->freq
);
783 void hostapd_get_ext_capa(struct hostapd_iface
*iface
)
785 struct hostapd_data
*hapd
= iface
->bss
[0];
787 if (!hapd
->driver
|| !hapd
->driver
->get_ext_capab
)
790 hapd
->driver
->get_ext_capab(hapd
->drv_priv
, WPA_IF_AP_BSS
,
791 &iface
->extended_capa
,
792 &iface
->extended_capa_mask
,
793 &iface
->extended_capa_len
);
797 int hostapd_drv_do_acs(struct hostapd_data
*hapd
)
799 struct drv_acs_params params
;
800 int ret
, i
, acs_ch_list_all
= 0;
802 unsigned int num_channels
= 0;
803 struct hostapd_hw_modes
*mode
;
804 int *freq_list
= NULL
;
806 if (hapd
->driver
== NULL
|| hapd
->driver
->do_acs
== NULL
)
809 os_memset(¶ms
, 0, sizeof(params
));
810 params
.hw_mode
= hapd
->iface
->conf
->hw_mode
;
813 * If no chanlist config parameter is provided, include all enabled
814 * channels of the selected hw_mode.
816 if (!hapd
->iface
->conf
->acs_ch_list
.num
)
819 mode
= hapd
->iface
->current_mode
;
821 channels
= os_malloc(mode
->num_channels
);
822 if (channels
== NULL
)
825 for (i
= 0; i
< mode
->num_channels
; i
++) {
826 struct hostapd_channel_data
*chan
= &mode
->channels
[i
];
827 if (!acs_ch_list_all
&&
828 !freq_range_list_includes(
829 &hapd
->iface
->conf
->acs_ch_list
,
832 if (!(chan
->flag
& HOSTAPD_CHAN_DISABLED
)) {
833 channels
[num_channels
++] = chan
->chan
;
834 int_array_add_unique(&freq_list
, chan
->freq
);
838 for (i
= 0; i
< hapd
->iface
->num_hw_features
; i
++) {
839 mode
= &hapd
->iface
->hw_features
[i
];
840 hostapd_get_hw_mode_any_channels(hapd
, mode
,
846 params
.ch_list
= channels
;
847 params
.ch_list_len
= num_channels
;
848 params
.freq_list
= freq_list
;
850 params
.ht_enabled
= !!(hapd
->iface
->conf
->ieee80211n
);
851 params
.ht40_enabled
= !!(hapd
->iface
->conf
->ht_capab
&
852 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
);
853 params
.vht_enabled
= !!(hapd
->iface
->conf
->ieee80211ac
);
854 params
.ch_width
= 20;
855 if (hapd
->iface
->conf
->ieee80211n
&& params
.ht40_enabled
)
856 params
.ch_width
= 40;
858 /* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
860 if (hapd
->iface
->conf
->ieee80211ac
&& params
.ht40_enabled
) {
861 if (hapd
->iface
->conf
->vht_oper_chwidth
== VHT_CHANWIDTH_80MHZ
)
862 params
.ch_width
= 80;
863 else if (hapd
->iface
->conf
->vht_oper_chwidth
==
864 VHT_CHANWIDTH_160MHZ
||
865 hapd
->iface
->conf
->vht_oper_chwidth
==
866 VHT_CHANWIDTH_80P80MHZ
)
867 params
.ch_width
= 160;
870 ret
= hapd
->driver
->do_acs(hapd
->drv_priv
, ¶ms
);