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"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h"
1461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "p2p/p2p.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "hostapd.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11.h"
178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "sta_info.h"
188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_config.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_hostapd.h"
2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#include "hs20.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap_drv_ops.h"
228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu32 hostapd_sta_flags_to_drv(u32 flags)
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int res = 0;
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_AUTHORIZED)
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_AUTHORIZED;
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_WMM)
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_WMM;
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_SHORT_PREAMBLE)
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_SHORT_PREAMBLE;
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (flags & WLAN_STA_MFP)
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		res |= WPA_STA_MFP;
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return res;
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_build_ap_extra_ies(struct hostapd_data *hapd,
401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **beacon_ret,
411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **proberesp_ret,
421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf **assocresp_ret)
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpabuf *beacon = NULL, *proberesp = NULL, *assocresp = NULL;
451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	u8 buf[200], *pos;
468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*beacon_ret = *proberesp_ret = *assocresp_ret = NULL;
481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = buf;
501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_time_adv(hapd, pos);
511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
561f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_time_zone(hapd, pos);
571f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
601f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
611f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
621f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
631f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = buf;
641f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_ext_capab(hapd, pos);
651f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
661f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&assocresp, pos - buf) != 0)
671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(assocresp, buf, pos - buf);
691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_interworking(hapd, pos);
711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_adv_proto(hapd, pos);
721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	pos = hostapd_eid_roaming_consortium(hapd, pos);
731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (pos != buf) {
741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->wps_beacon_ie) {
841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, wpabuf_len(hapd->wps_beacon_ie)) <
851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    0)
861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(beacon, hapd->wps_beacon_ie);
881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->wps_probe_resp_ie) {
911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp,
921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  wpabuf_len(hapd->wps_probe_resp_ie)) < 0)
931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(proberesp, hapd->wps_probe_resp_ie);
951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->p2p_beacon_ie) {
991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, wpabuf_len(hapd->p2p_beacon_ie)) <
1001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    0)
1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(beacon, hapd->p2p_beacon_ie);
1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->p2p_probe_resp_ie) {
1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp,
1071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  wpabuf_len(hapd->p2p_probe_resp_ie)) < 0)
1081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			goto fail;
1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_put_buf(proberesp, hapd->p2p_probe_resp_ie);
1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER
1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->p2p & P2P_MANAGE) {
1151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&beacon, 100) == 0) {
1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(beacon, 0);
1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(beacon, p - start);
1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&proberesp, 100) == 0) {
1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(proberesp, 0);
1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(proberesp, p - start);
1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */
1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
13115907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt#ifdef CONFIG_WPS
1321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->conf->wps_state) {
1331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		struct wpabuf *a = wps_build_assoc_resp_ie();
1341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
1351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put_buf(assocresp, a);
1361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wpabuf_free(a);
1371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
13815907098d1f67c24bb000e593e279af173cf57d7Dmitry Shmidt#endif /* CONFIG_WPS */
1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P_MANAGER
1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->p2p & P2P_MANAGE) {
1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (wpabuf_resize(&assocresp, 100) == 0) {
1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			u8 *start, *p;
1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			start = wpabuf_put(assocresp, 0);
1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			p = hostapd_eid_p2p_manage(hapd, start);
1461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wpabuf_put(assocresp, p - start);
1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P_MANAGER */
1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
15161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_WIFI_DISPLAY
15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hapd->p2p_group) {
15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		struct wpabuf *a;
15461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		a = p2p_group_assoc_resp_ie(hapd->p2p_group, P2P_SC_SUCCESS);
15561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (a && wpabuf_resize(&assocresp, wpabuf_len(a)) == 0)
15661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			wpabuf_put_buf(assocresp, a);
15761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_free(a);
15861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
15961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_WIFI_DISPLAY */
16061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
16161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_HS20
16261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = buf;
16361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	pos = hostapd_eid_hs20_indication(hapd, pos);
16461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (pos != buf) {
16561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
16661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
16761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
16861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
16961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
17061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			goto fail;
17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
17261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	}
173f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
174f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	pos = hostapd_eid_osen(hapd, buf);
175f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	if (pos != buf) {
176f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (wpabuf_resize(&beacon, pos - buf) != 0)
177f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			goto fail;
178f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpabuf_put_data(beacon, buf, pos - buf);
179f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt
180f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		if (wpabuf_resize(&proberesp, pos - buf) != 0)
181f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt			goto fail;
182f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt		wpabuf_put_data(proberesp, buf, pos - buf);
183f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt	}
18461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_HS20 */
18561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
1860ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	if (hapd->conf->vendor_elements) {
1870ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		size_t add = wpabuf_len(hapd->conf->vendor_elements);
1880ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&beacon, add) == 0)
1890ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(beacon, hapd->conf->vendor_elements);
1900ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		if (wpabuf_resize(&proberesp, add) == 0)
1910ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_put_buf(proberesp, hapd->conf->vendor_elements);
1920ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	}
1930ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
1941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*beacon_ret = beacon;
1951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*proberesp_ret = proberesp;
1961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	*assocresp_ret = assocresp;
1971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return 0;
1991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtfail:
2011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
2021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
2031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
2041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return -1;
2051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
2061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid hostapd_free_ap_extra_ies(struct hostapd_data *hapd,
2091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *beacon,
2101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *proberesp,
2111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			       struct wpabuf *assocresp)
2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(beacon);
2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(proberesp);
2151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpabuf_free(assocresp);
2161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
2171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_set_ap_wps_ie(struct hostapd_data *hapd)
2201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
2211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpabuf *beacon, *proberesp, *assocresp;
2221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	int ret;
2231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ap_wps_ie == NULL)
2251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
2261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hostapd_build_ap_extra_ies(hapd, &beacon, &proberesp, &assocresp) <
2281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    0)
2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = hapd->driver->set_ap_wps_ie(hapd->drv_priv, beacon, proberesp,
2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  assocresp);
2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hostapd_free_ap_extra_ies(hapd, beacon, proberesp, assocresp);
2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret;
2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_authorized(struct hostapd_data *hapd,
2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   struct sta_info *sta, int authorized)
2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (authorized) {
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hostapd_sta_set_flags(hapd, sta->addr,
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     hostapd_sta_flags_to_drv(
2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						     sta->flags),
2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     WPA_STA_AUTHORIZED, ~0);
2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr,
2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     hostapd_sta_flags_to_drv(sta->flags),
2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     0, ~WPA_STA_AUTHORIZED);
2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_sta_flags(struct hostapd_data *hapd, struct sta_info *sta)
2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int set_flags, total_flags, flags_and, flags_or;
2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	total_flags = hostapd_sta_flags_to_drv(sta->flags);
2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	set_flags = WPA_STA_SHORT_PREAMBLE | WPA_STA_WMM | WPA_STA_MFP;
2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (((!hapd->conf->ieee802_1x && !hapd->conf->wpa) ||
2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	     sta->auth_alg == WLAN_AUTH_FT) &&
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    sta->flags & WLAN_STA_AUTHORIZED)
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		set_flags |= WPA_STA_AUTHORIZED;
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_or = total_flags & set_flags;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	flags_and = total_flags | ~set_flags;
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_sta_set_flags(hapd, sta->addr, total_flags,
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     flags_or, flags_and);
2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_drv_ieee8021x(struct hostapd_data *hapd, const char *ifname,
2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      int enabled)
2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_bss_params params;
2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ifname = ifname;
2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.enabled = enabled;
2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (enabled) {
2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa = hapd->conf->wpa;
2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee802_1x = hapd->conf->ieee802_1x;
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_group = hapd->conf->wpa_group;
283b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt		params.wpa_pairwise = hapd->conf->wpa_pairwise |
284b5d893b5dec601a58c3ce0fc9e5d6da3816ce97aDmitry Shmidt			hapd->conf->rsn_pairwise;
2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.wpa_key_mgmt = hapd->conf->wpa_key_mgmt;
2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.rsn_preauth = hapd->conf->rsn_preauth;
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_IEEE80211W
2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.ieee80211w = hapd->conf->ieee80211w;
2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_set_ieee8021x(hapd, &params);
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char force_ifname[IFNAMSIZ];
2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	u8 if_addr[ETH_ALEN];
2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, hapd->own_addr,
300cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt			      NULL, NULL, force_ifname, if_addr, NULL, 0);
3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_vlan_if_remove(struct hostapd_data *hapd, const char *ifname)
3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_if_remove(hapd, WPA_IF_AP_VLAN, ifname);
3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
310c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidtint hostapd_set_wds_sta(struct hostapd_data *hapd, char *ifname_wds,
311c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt			const u8 *addr, int aid, int val)
3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const char *bridge = NULL;
3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_wds_sta == NULL)
316c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt		return -1;
3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->wds_bridge[0])
3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->wds_bridge;
3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (hapd->conf->bridge[0])
3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bridge = hapd->conf->bridge;
3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_wds_sta(hapd->drv_priv, addr, aid, val,
322c2ebb4b85d69b65f552fee71ac68f44e8d87b39eDmitry Shmidt					 bridge, ifname_wds);
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_sta_node(struct hostapd_data *hapd, const u8 *addr,
3271f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 u16 auth_alg)
3281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_sta_node == NULL)
3301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_sta_node(hapd->drv_priv, addr, auth_alg);
3321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_auth(struct hostapd_data *hapd, const u8 *addr,
3361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		     u16 seq, u16 status, const u8 *ie, size_t len)
3371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_auth == NULL)
3391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_auth(hapd->drv_priv, hapd->own_addr, addr,
3411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				      seq, status, ie, len);
3421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_sta_assoc(struct hostapd_data *hapd, const u8 *addr,
3461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      int reassoc, u16 status, const u8 *ie, size_t len)
3471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_assoc == NULL)
3491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3501f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->sta_assoc(hapd->drv_priv, hapd->own_addr, addr,
3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       reassoc, status, ie, len);
3521f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3531f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3541f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_add(struct hostapd_data *hapd,
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *addr, u16 aid, u16 capability,
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    const u8 *supp_rates, size_t supp_rates_len,
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		    u16 listen_interval,
3591f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		    const struct ieee80211_ht_capabilities *ht_capab,
360a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    const struct ieee80211_vht_capabilities *vht_capab,
361bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt		    u32 flags, u8 qosinfo, u8 vht_opmode)
3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_sta_add_params params;
3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL)
3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver->sta_add == NULL)
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.addr = addr;
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.aid = aid;
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.capability = capability;
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates = supp_rates;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.supp_rates_len = supp_rates_len;
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.listen_interval = listen_interval;
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ht_capabilities = ht_capab;
378a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	params.vht_capabilities = vht_capab;
379bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt	params.vht_opmode_enabled = !!(flags & WLAN_STA_VHT_OPMODE_ENABLED);
380bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt	params.vht_opmode = vht_opmode;
3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.flags = hostapd_sta_flags_to_drv(flags);
3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.qosinfo = qosinfo;
3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_add(hapd->drv_priv, &params);
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtint hostapd_add_tspec(struct hostapd_data *hapd, const u8 *addr,
3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		      u8 *tspec_ie, size_t tspec_ielen)
3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->add_tspec == NULL)
3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return 0;
3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->add_tspec(hapd->drv_priv, addr, tspec_ie,
3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				       tspec_ielen);
3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_privacy(struct hostapd_data *hapd, int enabled)
3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_privacy == NULL)
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_privacy(hapd->drv_priv, enabled);
4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_generic_elem(struct hostapd_data *hapd, const u8 *elem,
4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     size_t elem_len)
4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_generic_elem == NULL)
4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_generic_elem(hapd->drv_priv, elem, elem_len);
4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len)
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_get_ssid == NULL)
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_get_ssid(hapd->drv_priv, buf, len);
4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->hapd_set_ssid == NULL)
4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->hapd_set_ssid(hapd->drv_priv, buf, len);
4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   const char *ifname, const u8 *addr, void *bss_ctx,
4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   void **drv_priv, char *force_ifname, u8 *if_addr,
433cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		   const char *bridge, int use_existing)
4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->if_add == NULL)
4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_add(hapd->drv_priv, type, ifname, addr,
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    bss_ctx, drv_priv, force_ifname, if_addr,
439cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt				    bridge, use_existing);
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      const char *ifname)
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
446cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (hapd->driver == NULL || hapd->drv_priv == NULL ||
447cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	    hapd->driver->if_remove == NULL)
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->if_remove(hapd->drv_priv, type, ifname);
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_ieee8021x(struct hostapd_data *hapd,
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  struct wpa_bss_params *params)
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_ieee8021x == NULL)
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_ieee8021x(hapd->drv_priv, params);
4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_get_seqnum(const char *ifname, struct hostapd_data *hapd,
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		       const u8 *addr, int idx, u8 *seq)
4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->get_seqnum == NULL)
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_seqnum(ifname, hapd->drv_priv, addr, idx,
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					seq);
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_flush(struct hostapd_data *hapd)
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->flush == NULL)
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->flush(hapd->drv_priv);
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
48004f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidtint hostapd_set_freq_params(struct hostapd_freq_params *data, int mode,
48104f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			    int freq, int channel, int ht_enabled,
48204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			    int vht_enabled, int sec_channel_offset,
48304f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			    int vht_oper_chwidth, int center_segment0,
48404f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt			    int center_segment1, u32 vht_caps)
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
486a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	int tmp;
487a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
488051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	os_memset(data, 0, sizeof(*data));
489051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->mode = mode;
490051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->freq = freq;
491051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->channel = channel;
492051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->ht_enabled = ht_enabled;
493051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->vht_enabled = vht_enabled;
494051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->sec_channel_offset = sec_channel_offset;
495051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->center_freq1 = freq + sec_channel_offset * 10;
496051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->center_freq2 = 0;
497051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	data->bandwidth = sec_channel_offset ? 40 : 20;
498a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt
499a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	/*
500a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * This validation code is probably misplaced, maybe it should be
501a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 * in src/ap/hw_features.c and check the hardware support as well.
502a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	 */
503051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (data->vht_enabled) switch (vht_oper_chwidth) {
504a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_USE_HT:
505a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1)
506a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
507b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		if (center_segment0 != 0 &&
508b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		    5000 + center_segment0 * 5 != data->center_freq1 &&
509cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		    2407 + center_segment0 * 5 != data->center_freq1)
510a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
511a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
512a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_80P80MHZ:
51368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(vht_caps & VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)) {
51468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_printf(MSG_ERROR,
51568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   "80+80 channel width is not supported!");
51668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return -1;
51768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
518a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1 == center_segment0 + 4 ||
519a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		    center_segment1 == center_segment0 - 4)
520a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
521051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq2 = 5000 + center_segment1 * 5;
522a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* fall through */
523a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_80MHZ:
524051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->bandwidth = 80;
525a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (vht_oper_chwidth == 1 && center_segment1)
526a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
527a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (vht_oper_chwidth == 3 && !center_segment1)
528a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
529a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (!sec_channel_offset)
530a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
531a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* primary 40 part must match the HT configuration */
532a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp = (30 + freq - 5000 - center_segment0 * 5)/20;
533a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp /= 2;
534051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		if (data->center_freq1 != 5000 +
535a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					 center_segment0 * 5 - 20 + 40 * tmp)
536a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
537051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq1 = 5000 + center_segment0 * 5;
538a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
539a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	case VHT_CHANWIDTH_160MHZ:
540051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->bandwidth = 160;
54168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		if (!(vht_caps & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
54268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				  VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))) {
54368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			wpa_printf(MSG_ERROR,
54468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				   "160MHZ channel width is not supported!");
54568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			return -1;
54668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		}
547a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (center_segment1)
548a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
549a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		if (!sec_channel_offset)
550a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
551a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		/* primary 40 part must match the HT configuration */
552a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp = (70 + freq - 5000 - center_segment0 * 5)/20;
553a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		tmp /= 2;
554051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		if (data->center_freq1 != 5000 +
555a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt					 center_segment0 * 5 - 60 + 40 * tmp)
556a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt			return -1;
557051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		data->center_freq1 = 5000 + center_segment0 * 5;
558a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		break;
559a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	}
560051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
561051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return 0;
562051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
563051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
564051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
565051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_set_freq(struct hostapd_data *hapd, int mode, int freq,
566051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int channel, int ht_enabled, int vht_enabled,
567051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int sec_channel_offset, int vht_oper_chwidth,
568051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		     int center_segment0, int center_segment1)
569051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
570051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
571051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
572051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
573051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
574051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth,
57568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment0, center_segment1,
57668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    hapd->iface->current_mode->vht_capab))
577051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
578051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
579a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver == NULL)
580a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
581a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (hapd->driver->set_freq == NULL)
582a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		return 0;
5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_freq(hapd->drv_priv, &data);
5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_rts(struct hostapd_data *hapd, int rts)
5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_rts == NULL)
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_rts(hapd->drv_priv, rts);
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_frag(struct hostapd_data *hapd, int frag)
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_frag == NULL)
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_frag(hapd->drv_priv, frag);
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_sta_set_flags(struct hostapd_data *hapd, u8 *addr,
6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  int total_flags, int flags_or, int flags_and)
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_set_flags == NULL)
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_set_flags(hapd->drv_priv, addr, total_flags,
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   flags_or, flags_and);
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_country(struct hostapd_data *hapd, const char *country)
6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->set_country == NULL)
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_country(hapd->drv_priv, country);
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_set_tx_queue_params(struct hostapd_data *hapd, int queue, int aifs,
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				int cw_min, int cw_max, int burst_time)
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_tx_queue_params == NULL)
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_tx_queue_params(hapd->drv_priv, queue, aifs,
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 cw_min, cw_max, burst_time);
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct hostapd_hw_modes *
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidthostapd_get_hw_feature_data(struct hostapd_data *hapd, u16 *num_modes,
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    u16 *flags)
6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL ||
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    hapd->driver->get_hw_feature_data == NULL)
6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt						 flags);
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_commit(struct hostapd_data *hapd)
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->commit == NULL)
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->commit(hapd->drv_priv);
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_none(struct hostapd_data *hapd)
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver && os_strcmp(hapd->driver->name, "none") == 0;
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_scan(struct hostapd_data *hapd,
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			struct wpa_driver_scan_params *params)
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->scan2)
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->scan2(hapd->drv_priv, params);
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpa_scan_results * hostapd_driver_get_scan_results(
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd)
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->get_scan_results2)
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->get_scan_results2(hapd->drv_priv);
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return NULL;
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_driver_set_noa(struct hostapd_data *hapd, u8 count, int start,
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   int duration)
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver && hapd->driver->set_noa)
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return hapd->driver->set_noa(hapd->drv_priv, count, start,
6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     duration);
6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return -1;
6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_set_key(const char *ifname, struct hostapd_data *hapd,
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			enum wpa_alg alg, const u8 *addr,
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int key_idx, int set_tx,
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *seq, size_t seq_len,
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			const u8 *key, size_t key_len)
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_key == NULL)
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->set_key(ifname, hapd->drv_priv, alg, addr,
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_idx, set_tx, seq, seq_len, key,
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				     key_len);
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_send_mlme(struct hostapd_data *hapd,
7001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			  const void *msg, size_t len, int noack)
7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_mlme == NULL)
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	return hapd->driver->send_mlme(hapd->drv_priv, msg, len, noack);
7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_deauth(struct hostapd_data *hapd,
7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   const u8 *addr, int reason)
7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_deauth == NULL)
7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_deauth(hapd->drv_priv, hapd->own_addr, addr,
7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					reason);
7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint hostapd_drv_sta_disassoc(struct hostapd_data *hapd,
7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     const u8 *addr, int reason)
7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->sta_disassoc == NULL)
7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->driver->sta_disassoc(hapd->drv_priv, hapd->own_addr, addr,
7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					  reason);
7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
72604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
72704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
72861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_drv_wnm_oper(struct hostapd_data *hapd, enum wnm_oper oper,
72961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			 const u8 *peer, u8 *buf, u16 *buf_len)
73061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{
73161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->wnm_oper == NULL)
732fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return -1;
73361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	return hapd->driver->wnm_oper(hapd->drv_priv, oper, peer, buf,
73461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				      buf_len);
73561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt}
73661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
73761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
73804949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint hostapd_drv_send_action(struct hostapd_data *hapd, unsigned int freq,
73904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    unsigned int wait, const u8 *dst, const u8 *data,
74004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			    size_t len)
74104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
74204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (hapd->driver == NULL || hapd->driver->send_action == NULL)
74304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return 0;
74404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hapd->driver->send_action(hapd->drv_priv, freq, wait, dst,
74504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 hapd->own_addr, hapd->own_addr, data,
74604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					 len, 0);
74704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
748051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
749cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt
750cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidtint hostapd_start_dfs_cac(struct hostapd_iface *iface, int mode, int freq,
751051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int channel, int ht_enabled, int vht_enabled,
752051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int sec_channel_offset, int vht_oper_chwidth,
753051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			  int center_segment0, int center_segment1)
754051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
755cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	struct hostapd_data *hapd = iface->bss[0];
756051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	struct hostapd_freq_params data;
75768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	int res;
758051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
759051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (!hapd->driver || !hapd->driver->start_dfs_cac)
760051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
761051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
762cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	if (!iface->conf->ieee80211h) {
763051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		wpa_printf(MSG_ERROR, "Can't start DFS CAC, DFS functionality "
764051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			   "is not enabled");
765051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
766051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	}
767051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
768051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hostapd_set_freq_params(&data, mode, freq, channel, ht_enabled,
769051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_enabled, sec_channel_offset,
770051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt				    vht_oper_chwidth, center_segment0,
77168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				    center_segment1,
772a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt				    iface->current_mode->vht_capab)) {
773a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt		wpa_printf(MSG_ERROR, "Can't set freq params");
774051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return -1;
775a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt	}
776051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
77768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	res = hapd->driver->start_dfs_cac(hapd->drv_priv, &data);
778df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	if (!res) {
779cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		iface->cac_started = 1;
780df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt		os_get_reltime(&iface->dfs_cac_start);
781df5a7e4c5c64890c2425bb47d665bbce4992b676Dmitry Shmidt	}
78268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
78368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return res;
784051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
785051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
786051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt
787051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidtint hostapd_drv_set_qos_map(struct hostapd_data *hapd,
788051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt			    const u8 *qos_map_set, u8 qos_map_set_len)
789051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt{
790051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	if (hapd->driver == NULL || hapd->driver->set_qos_map == NULL)
791051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt		return 0;
792051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt	return hapd->driver->set_qos_map(hapd->drv_priv, qos_map_set,
793051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt					 qos_map_set_len);
794051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt}
795