ap_drv_ops.c revision 68d0e3ed07847339aedfac8e02f50db68c702e52
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * hostapd - Driver operations
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009-2010, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "drivers/driver.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h"
1561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "p2p/p2p.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h"
2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "hs20.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h"
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu32 hostapd_sta_flags_to_drv(u32 flags)
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res = 0;
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_AUTHORIZED)
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_AUTHORIZED;
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_WMM)
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_WMM;
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_SHORT_PREAMBLE)
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_SHORT_PREAMBLE;
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_MFP)
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_MFP;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return res;
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **beacon_ret,
421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **proberesp_ret,
431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **assocresp_ret)
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 buf[200], *pos;
478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = buf;
511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_time_adv(hapd, pos);
521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_time_zone(hapd, pos);
581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = buf;
651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_ext_capab(hapd, pos);
661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&assocresp, pos - buf) != 0)
681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(assocresp, buf, pos - buf);
701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_interworking(hapd, pos);
721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_adv_proto(hapd, pos);
731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_roaming_consortium(hapd, pos);
741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->wps_beacon_ie) {
851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    0)
871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->wps_probe_resp_ie) {
921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp,
931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->p2p_beacon_ie) {
1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    0)
1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
1031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->p2p_probe_resp_ie) {
1071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp,
1081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
1101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER
1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->p2p & P2P_MANAGE) {
1161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, 100) == 0) {
1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(beacon, 0);
1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(beacon, p - start);
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, 100) == 0) {
1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(proberesp, 0);
1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(proberesp, p - start);
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */
1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS2
1331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->conf->wps_state) {
1341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		struct wpabuf *a = wps_build_assoc_resp_ie();
1351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
1361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put_buf(assocresp, a);
1371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_free(a);
1381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS2 */
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER
1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->p2p & P2P_MANAGE) {
1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&assocresp, 100) == 0) {
1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(assocresp, 0);
1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(assocresp, p - start);
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */
1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hapd->p2p_group) {
15461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		struct wpabuf *a;
15561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
15761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpabuf_put_buf(assocresp, a);
15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_free(a);
15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = hostapd_eid_hs20_indication(hapd, pos);
16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos != buf) {
16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
17361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
17461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
17561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1760ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	if (hapd->conf->vendor_elements) {
1770ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		size_t add = wpabuf_len(hapd->conf->vendor_elements);
1780ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&beacon, add) == 0)
1790ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
1800ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&proberesp, add) == 0)
1810ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
1820ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	}
1830ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
1841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*beacon_ret = beacon;
1851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*proberesp_ret = proberesp;
1861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*assocresp_ret = assocresp;
1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
1891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtfail:
1911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
1921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
1931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return -1;
1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *beacon,
2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *proberesp,
2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *assocresp)
2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpabuf *beacon, *proberesp, *assocresp;
2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    0)
2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  assocresp);
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_authorized(struct hostapd_data *hapd,
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   struct sta_info *sta, int authorized)
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (authorized) {
2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hostapd_sta_set_flags(hapd, sta->addr,
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     hostapd_sta_flags_to_drv(
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     sta->flags),
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     WPA_STA_AUTHORIZED, ~0);
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr,
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     hostapd_sta_flags_to_drv(sta->flags),
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     0, ~WPA_STA_AUTHORIZED);
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int set_flags, total_flags, flags_and, flags_or;
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	total_flags = hostapd_sta_flags_to_drv(sta->flags);
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     sta->auth_alg == WLAN_AUTH_FT) &&
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    sta->flags & WLAN_STA_AUTHORIZED)
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		set_flags |= WPA_STA_AUTHORIZED;
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_or = total_flags & set_flags;
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_and = total_flags | ~set_flags;
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     flags_or, flags_and);
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      int enabled)
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss_params params;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ifname = ifname;
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.enabled = enabled;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (enabled) {
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa = hapd->conf->wpa;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee802_1x = hapd->conf->ieee802_1x;
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_group = hapd->conf->wpa_group;
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_pairwise = hapd->conf->wpa_pairwise;
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.rsn_preauth = hapd->conf->rsn_preauth;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee80211w = hapd->conf->ieee80211w;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_set_ieee8021x(hapd, &params);
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char force_ifname[IFNAMSIZ];
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 if_addr[ETH_ALEN];
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      NULL, NULL, force_ifname, if_addr, NULL);
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
299c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtint hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
300c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			const u8 *addr, int aid, int val)
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *bridge = NULL;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
305c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->wds_bridge[0])
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->wds_bridge;
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hapd->conf->bridge[0])
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->bridge;
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
311c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					 bridge, ifname_wds);
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
3161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 u16 auth_alg)
3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
3251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		     u16 seq, u16 status, const u8 *ie, size_t len)
3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
3281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
3301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      seq, status, ie, len);
3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      int reassoc, u16 status, const u8 *ie, size_t len)
3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       reassoc, status, ie, len);
3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_add(struct hostapd_data *hapd,
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *addr, u16 aid, u16 capability,
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *supp_rates, size_t supp_rates_len,
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    u16 listen_interval,
3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    const struct ieee80211_ht_capabilities *ht_capab,
349a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    const struct ieee80211_vht_capabilities *vht_capab,
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    u32 flags, u8 qosinfo)
3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_sta_add_params params;
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL)
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver->sta_add == NULL)
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.addr = addr;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.aid = aid;
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.capability = capability;
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates = supp_rates;
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates_len = supp_rates_len;
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.listen_interval = listen_interval;
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ht_capabilities = ht_capab;
367a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	params.vht_capabilities = vht_capab;
3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.flags = hostapd_sta_flags_to_drv(flags);
3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.qosinfo = qosinfo;
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_add(hapd->drv_priv, &params);
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      u8 *tspec_ie, size_t tspec_ielen)
3761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
3781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
3801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       tspec_ielen);
3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     size_t elem_len)
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const char *ifname, const u8 *addr, void *bss_ctx,
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   void **drv_priv, char *force_ifname, u8 *if_addr,
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const char *bridge)
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    bss_ctx, drv_priv, force_ifname, if_addr,
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    bridge);
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      const char *ifname)
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->if_remove == NULL)
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ieee8021x(struct hostapd_data *hapd,
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  struct wpa_bss_params *params)
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       const u8 *addr, int idx, u8 *seq)
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					seq);
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_flush(struct hostapd_data *hapd)
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->flush == NULL)
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->flush(hapd->drv_priv);
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
466051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtstatic int hostapd_set_freq_params(struct hostapd_freq_params *data, int mode,
467051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				   int freq, int channel, int ht_enabled,
468051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				   int vht_enabled, int sec_channel_offset,
469051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				   int vht_oper_chwidth, int center_segment0,
47068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   int center_segment1, u32 vht_caps)
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
472a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	int tmp;
473a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
474051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	os_memset(data, 0, sizeof(*data));
475051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->mode = mode;
476051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->freq = freq;
477051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->channel = channel;
478051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->ht_enabled = ht_enabled;
479051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->vht_enabled = vht_enabled;
480051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->sec_channel_offset = sec_channel_offset;
481051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->center_freq1 = freq + sec_channel_offset * 10;
482051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->center_freq2 = 0;
483051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->bandwidth = sec_channel_offset ? 40 : 20;
484a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
485a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	/*
486a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * This validation code is probably misplaced, maybe it should be
487a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * in src/ap/hw_features.c and check the hardware support as well.
488a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 */
489051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (data->vht_enabled) switch (vht_oper_chwidth) {
490a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_USE_HT:
491a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1)
492a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
493051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		if (5000 + center_segment0 * 5 != data->center_freq1)
494a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
495a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
496a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_80P80MHZ:
49768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(vht_caps & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
49868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_printf(MSG_ERROR,
49968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   "80+80 channel width is not supported!");
50068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return -1;
50168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
502a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1 == center_segment0 + 4 ||
503a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    center_segment1 == center_segment0 - 4)
504a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
505051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq2 = 5000 + center_segment1 * 5;
506a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* fall through */
507a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_80MHZ:
508051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->bandwidth = 80;
509a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (vht_oper_chwidth == 1 && center_segment1)
510a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (vht_oper_chwidth == 3 && !center_segment1)
512a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
513a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (!sec_channel_offset)
514a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
515a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* primary 40 part must match the HT configuration */
516a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp = (30 + freq - 5000 - center_segment0 * 5)/20;
517a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp /= 2;
518051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		if (data->center_freq1 != 5000 +
519a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					 center_segment0 * 5 - 20 + 40 * tmp)
520a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
521051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq1 = 5000 + center_segment0 * 5;
522a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
523a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_160MHZ:
524051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->bandwidth = 160;
52568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
52668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				  VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
52768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_printf(MSG_ERROR,
52868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   "160MHZ channel width is not supported!");
52968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return -1;
53068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
531a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1)
532a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
533a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (!sec_channel_offset)
534a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
535a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* primary 40 part must match the HT configuration */
536a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp = (70 + freq - 5000 - center_segment0 * 5)/20;
537a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp /= 2;
538051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		if (data->center_freq1 != 5000 +
539a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					 center_segment0 * 5 - 60 + 40 * tmp)
540a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
541051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq1 = 5000 + center_segment0 * 5;
542a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
543a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
544051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
545051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return 0;
546051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
547051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
548051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
549051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
550051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int channel, int ht_enabled, int vht_enabled,
551051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int sec_channel_offset, int vht_oper_chwidth,
552051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int center_segment0, int center_segment1)
553051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
554051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
555051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
556051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
557051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
558051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth,
55968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment0, center_segment1,
56068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    hapd->iface->current_mode->vht_capab))
561051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
562051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
563a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver == NULL)
564a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
565a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver->set_freq == NULL)
566a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_freq(hapd->drv_priv, &data);
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_rts(struct hostapd_data *hapd, int rts)
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_rts(hapd->drv_priv, rts);
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_frag(struct hostapd_data *hapd, int frag)
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_frag(hapd->drv_priv, frag);
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  int total_flags, int flags_or, int flags_and)
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   flags_or, flags_and);
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_country(struct hostapd_data *hapd, const char *country)
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->set_country == NULL)
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_country(hapd->drv_priv, country);
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int cw_min, int cw_max, int burst_time)
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 cw_min, cw_max, burst_time);
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_hw_modes *
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    u16 *flags)
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->get_hw_feature_data == NULL)
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 flags);
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_commit(struct hostapd_data *hapd)
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->commit == NULL)
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->commit(hapd->drv_priv);
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_none(struct hostapd_data *hapd)
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_scan(struct hostapd_data *hapd,
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct wpa_driver_scan_params *params)
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->scan2)
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->scan2(hapd->drv_priv, params);
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_scan_results * hostapd_driver_get_scan_results(
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->get_scan_results2)
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->get_scan_results2(hapd->drv_priv);
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   int duration)
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->set_noa)
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->set_noa(hapd->drv_priv, count, start,
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     duration);
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			enum wpa_alg alg, const u8 *addr,
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int key_idx, int set_tx,
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *seq, size_t seq_len,
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *key, size_t key_len)
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_idx, set_tx, seq, seq_len, key,
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_len);
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_send_mlme(struct hostapd_data *hapd,
6841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  const void *msg, size_t len, int noack)
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_deauth(struct hostapd_data *hapd,
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   const u8 *addr, int reason)
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					reason);
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *addr, int reason)
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  reason);
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
71004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
71261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
71361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 const u8 *peer, u8 *buf, u16 *buf_len)
71461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
71561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
71661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		return 0;
71761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
71861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				      buf_len);
71961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
72061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
72161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
72204949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
72304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    unsigned int wait, const u8 *dst, const u8 *data,
72404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    size_t len)
72504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
72604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
72704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
72804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
72904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 hapd->own_addr, hapd->own_addr, data,
73004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 len, 0);
73104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
732051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
733051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_start_dfs_cac(struct hostapd_data *hapd, int mode, int freq,
734051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int channel, int ht_enabled, int vht_enabled,
735051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int sec_channel_offset, int vht_oper_chwidth,
736051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int center_segment0, int center_segment1)
737051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
738051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
73968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int res;
740051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
741051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (!hapd->driver || !hapd->driver->start_dfs_cac)
742051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
743051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
744051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (!hapd->iface->conf->ieee80211h) {
745051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
746051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			   "is not enabled");
747051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
748051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
749051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
750051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
751051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
752051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth, center_segment0,
75368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment1,
75468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    hapd->iface->current_mode->vht_capab))
755051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
756051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
75768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
75868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (!res)
75968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		hapd->cac_started = 1;
76068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
76168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return res;
762051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
763051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
764051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
765051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_drv_set_qos_map(struct hostapd_data *hapd,
766051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			    const u8 *qos_map_set, u8 qos_map_set_len)
767051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
768051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
769051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
770051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
771051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt					 qos_map_set_len);
772051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
773