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 "common/ieee802_11_defs.h"
137f65602d49069f96a7bb44da8bd79ffe8d4c6a98Dmitry Shmidt#include "common/hw_features_common.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
13215907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt#ifdef CONFIG_WPS
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	}
13915907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt#endif /* CONFIG_WPS */
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	}
174f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
175f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	pos = hostapd_eid_osen(hapd, buf);
176f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (pos != buf) {
177f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
178f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			goto fail;
179f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
180f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
181f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
182f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			goto fail;
183f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
184f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	}
18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
18661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1870ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	if (hapd->conf->vendor_elements) {
1880ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		size_t add = wpabuf_len(hapd->conf->vendor_elements);
1890ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&beacon, add) == 0)
1900ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
1910ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&proberesp, add) == 0)
1920ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
1930ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	}
1940ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*beacon_ret = beacon;
1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*proberesp_ret = proberesp;
1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*assocresp_ret = assocresp;
1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtfail:
2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return -1;
2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *beacon,
2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *proberesp,
2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *assocresp)
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
220dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidtint hostapd_reset_ap_wps_ie(struct hostapd_data *hapd)
221dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt{
222dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
223dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return 0;
224dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
225dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	return hapd->driver->set_ap_wps_ie(hapd->drv_priv, NULL, NULL, NULL);
226dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt}
227dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
228dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpabuf *beacon, *proberesp, *assocresp;
2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    0)
2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  assocresp);
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_authorized(struct hostapd_data *hapd,
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   struct sta_info *sta, int authorized)
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (authorized) {
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hostapd_sta_set_flags(hapd, sta->addr,
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     hostapd_sta_flags_to_drv(
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     sta->flags),
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     WPA_STA_AUTHORIZED, ~0);
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr,
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     hostapd_sta_flags_to_drv(sta->flags),
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     0, ~WPA_STA_AUTHORIZED);
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int set_flags, total_flags, flags_and, flags_or;
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	total_flags = hostapd_sta_flags_to_drv(sta->flags);
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     sta->auth_alg == WLAN_AUTH_FT) &&
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    sta->flags & WLAN_STA_AUTHORIZED)
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		set_flags |= WPA_STA_AUTHORIZED;
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_or = total_flags & set_flags;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_and = total_flags | ~set_flags;
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     flags_or, flags_and);
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      int enabled)
2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss_params params;
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ifname = ifname;
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.enabled = enabled;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (enabled) {
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa = hapd->conf->wpa;
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee802_1x = hapd->conf->ieee802_1x;
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_group = hapd->conf->wpa_group;
2937a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		if ((hapd->conf->wpa & (WPA_PROTO_WPA | WPA_PROTO_RSN)) ==
2947a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		    (WPA_PROTO_WPA | WPA_PROTO_RSN))
2957a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt			params.wpa_pairwise = hapd->conf->wpa_pairwise |
2967a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt				hapd->conf->rsn_pairwise;
2977a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		else if (hapd->conf->wpa & WPA_PROTO_RSN)
2987a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt			params.wpa_pairwise = hapd->conf->rsn_pairwise;
2997a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt		else if (hapd->conf->wpa & WPA_PROTO_WPA)
3007a53dbb56693ee9f55c0cab1a8297436511e8613Dmitry Shmidt			params.wpa_pairwise = hapd->conf->wpa_pairwise;
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.rsn_preauth = hapd->conf->rsn_preauth;
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee80211w = hapd->conf->ieee80211w;
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_set_ieee8021x(hapd, &params);
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char force_ifname[IFNAMSIZ];
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 if_addr[ETH_ALEN];
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
316cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			      NULL, NULL, force_ifname, if_addr, NULL, 0);
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
326c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtint hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
327c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			const u8 *addr, int aid, int val)
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *bridge = NULL;
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
332c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->wds_bridge[0])
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->wds_bridge;
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hapd->conf->bridge[0])
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->bridge;
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
338c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					 bridge, ifname_wds);
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 u16 auth_alg)
3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
3461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		     u16 seq, u16 status, const u8 *ie, size_t len)
3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
3551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
3571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      seq, status, ie, len);
3581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
3621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      int reassoc, u16 status, const u8 *ie, size_t len)
3631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
3651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
3671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       reassoc, status, ie, len);
3681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_add(struct hostapd_data *hapd,
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *addr, u16 aid, u16 capability,
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *supp_rates, size_t supp_rates_len,
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    u16 listen_interval,
3751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    const struct ieee80211_ht_capabilities *ht_capab,
376a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    const struct ieee80211_vht_capabilities *vht_capab,
377bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		    u32 flags, u8 qosinfo, u8 vht_opmode)
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_sta_add_params params;
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL)
3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver->sta_add == NULL)
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.addr = addr;
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.aid = aid;
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.capability = capability;
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates = supp_rates;
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates_len = supp_rates_len;
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.listen_interval = listen_interval;
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ht_capabilities = ht_capab;
394a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	params.vht_capabilities = vht_capab;
395bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt	params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
396bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt	params.vht_opmode = vht_opmode;
3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.flags = hostapd_sta_flags_to_drv(flags);
3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.qosinfo = qosinfo;
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_add(hapd->drv_priv, &params);
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      u8 *tspec_ie, size_t tspec_ielen)
4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       tspec_ielen);
4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     size_t elem_len)
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const char *ifname, const u8 *addr, void *bss_ctx,
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   void **drv_priv, char *force_ifname, u8 *if_addr,
449cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		   const char *bridge, int use_existing)
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    bss_ctx, drv_priv, force_ifname, if_addr,
455cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				    bridge, use_existing);
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      const char *ifname)
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
462cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
463cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	    hapd->driver->if_remove == NULL)
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ieee8021x(struct hostapd_data *hapd,
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  struct wpa_bss_params *params)
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       const u8 *addr, int idx, u8 *seq)
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					seq);
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_flush(struct hostapd_data *hapd)
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->flush == NULL)
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->flush(hapd->drv_priv);
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4966c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint hostapd_set_freq(struct hostapd_data *hapd, enum hostapd_hw_mode mode,
4976c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		     int freq, int channel, int ht_enabled, int vht_enabled,
498051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int sec_channel_offset, int vht_oper_chwidth,
499051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int center_segment0, int center_segment1)
500051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
501051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
502051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
503051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
504051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
505051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth,
50668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment0, center_segment1,
5076c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    hapd->iface->current_mode ?
5086c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				    hapd->iface->current_mode->vht_capab : 0))
509051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
510051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver == NULL)
512a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
513a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver->set_freq == NULL)
514a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_freq(hapd->drv_priv, &data);
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_rts(struct hostapd_data *hapd, int rts)
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
5218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_rts(hapd->drv_priv, rts);
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_frag(struct hostapd_data *hapd, int frag)
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_frag(hapd->drv_priv, frag);
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  int total_flags, int flags_or, int flags_and)
5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   flags_or, flags_and);
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_country(struct hostapd_data *hapd, const char *country)
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->set_country == NULL)
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_country(hapd->drv_priv, country);
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int cw_min, int cw_max, int burst_time)
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 cw_min, cw_max, burst_time);
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_hw_modes *
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    u16 *flags)
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->get_hw_feature_data == NULL)
5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 flags);
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_commit(struct hostapd_data *hapd)
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->commit == NULL)
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->commit(hapd->drv_priv);
5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_none(struct hostapd_data *hapd)
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_scan(struct hostapd_data *hapd,
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct wpa_driver_scan_params *params)
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->scan2)
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->scan2(hapd->drv_priv, params);
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_scan_results * hostapd_driver_get_scan_results(
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd)
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->get_scan_results2)
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->get_scan_results2(hapd->drv_priv);
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   int duration)
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->set_noa)
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->set_noa(hapd->drv_priv, count, start,
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     duration);
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			enum wpa_alg alg, const u8 *addr,
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int key_idx, int set_tx,
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *seq, size_t seq_len,
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *key, size_t key_len)
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_idx, set_tx, seq, seq_len, key,
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_len);
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_send_mlme(struct hostapd_data *hapd,
6321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  const void *msg, size_t len, int noack)
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
636a3dc30964aa24aea2b518246f6812663a1103490Dmitry Shmidt	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack, 0);
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_deauth(struct hostapd_data *hapd,
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   const u8 *addr, int reason)
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					reason);
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *addr, int reason)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  reason);
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
65804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
65904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
66061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
66161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 const u8 *peer, u8 *buf, u16 *buf_len)
66261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
66361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
664fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
66561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
66661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				      buf_len);
66761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
66861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
66961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
67004949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
67104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    unsigned int wait, const u8 *dst, const u8 *data,
67204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    size_t len)
67304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
67404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
67504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
67604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
67704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 hapd->own_addr, hapd->own_addr, data,
67804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 len, 0);
67904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
680051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
681cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
6826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint hostapd_start_dfs_cac(struct hostapd_iface *iface,
6836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt			  enum hostapd_hw_mode mode, int freq,
684051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int channel, int ht_enabled, int vht_enabled,
685051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int sec_channel_offset, int vht_oper_chwidth,
686051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int center_segment0, int center_segment1)
687051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
688cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	struct hostapd_data *hapd = iface->bss[0];
689051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
69068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int res;
691051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
692051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (!hapd->driver || !hapd->driver->start_dfs_cac)
693051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
694051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
695cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (!iface->conf->ieee80211h) {
696051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
697051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			   "is not enabled");
698051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
699051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
700051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
701051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
702051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
703051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth, center_segment0,
70468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment1,
705a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt				    iface->current_mode->vht_capab)) {
706a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt		wpa_printf(MSG_ERROR, "Can't set freq params");
707051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
708a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt	}
709051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
71068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
711df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if (!res) {
712cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		iface->cac_started = 1;
713df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		os_get_reltime(&iface->dfs_cac_start);
714df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	}
71568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
71668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return res;
717051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
718051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
719051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
720051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_drv_set_qos_map(struct hostapd_data *hapd,
721051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			    const u8 *qos_map_set, u8 qos_map_set_len)
722051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
723051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
724051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
725051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
726051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt					 qos_map_set_len);
727051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
7286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
7296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
7306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtint hostapd_drv_do_acs(struct hostapd_data *hapd)
7316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{
7326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	struct drv_acs_params params;
733dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	int ret, i, acs_ch_list_all = 0;
734dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	u8 *channels = NULL;
735dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	unsigned int num_channels = 0;
736dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	struct hostapd_hw_modes *mode;
7376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt
7386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->do_acs == NULL)
7396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt		return 0;
740dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
7416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	os_memset(&params, 0, sizeof(params));
7426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	params.hw_mode = hapd->iface->conf->hw_mode;
743dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
744dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	/*
745dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	 * If no chanlist config parameter is provided, include all enabled
746dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	 * channels of the selected hw_mode.
747dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	 */
748dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (!hapd->iface->conf->acs_ch_list.num)
749dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		acs_ch_list_all = 1;
750dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
751dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	mode = hapd->iface->current_mode;
752dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (mode == NULL)
753dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return -1;
754dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	channels = os_malloc(mode->num_channels);
755dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (channels == NULL)
756dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		return -1;
757dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
758dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	for (i = 0; i < mode->num_channels; i++) {
759dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		struct hostapd_channel_data *chan = &mode->channels[i];
760dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (!acs_ch_list_all &&
761dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		    !freq_range_list_includes(&hapd->iface->conf->acs_ch_list,
762dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt					      chan->chan))
763dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			continue;
764dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (!(chan->flag & HOSTAPD_CHAN_DISABLED))
765dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			channels[num_channels++] = chan->chan;
766dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
767dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
768dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	params.ch_list = channels;
769dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	params.ch_list_len = num_channels;
770dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
7716c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	params.ht_enabled = !!(hapd->iface->conf->ieee80211n);
7726c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt	params.ht40_enabled = !!(hapd->iface->conf->ht_capab &
7736c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt				 HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET);
774dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	params.vht_enabled = !!(hapd->iface->conf->ieee80211ac);
775dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	params.ch_width = 20;
776dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (hapd->iface->conf->ieee80211n && params.ht40_enabled)
777dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		params.ch_width = 40;
778dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
779dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	/* Note: VHT20 is defined by combination of ht_capab & vht_oper_chwidth
780dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	 */
781dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	if (hapd->iface->conf->ieee80211ac && params.ht40_enabled) {
782dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		if (hapd->iface->conf->vht_oper_chwidth == VHT_CHANWIDTH_80MHZ)
783dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			params.ch_width = 80;
784dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt		else if (hapd->iface->conf->vht_oper_chwidth ==
785dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			 VHT_CHANWIDTH_160MHZ ||
786dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			 hapd->iface->conf->vht_oper_chwidth ==
787dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			 VHT_CHANWIDTH_80P80MHZ)
788dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt			params.ch_width = 160;
789dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	}
790dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
791dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	ret = hapd->driver->do_acs(hapd->drv_priv, &params);
792dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	os_free(channels);
793dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt
794dda10c2afb8378747491ea5d329a1de635d6d58eDmitry Shmidt	return ret;
7956c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt}
796