ap.c revision 21de214b4ba4271ca20843f3b8fba9f1501b2a89
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/*
28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * WPA Supplicant - Basic AP mode support routines
38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Atheros Communications
58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *
6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license.
7c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details.
88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */
98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h"
118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h"
138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h"
148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/uuid.h"
158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/wpa_ctrl.h"
17b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt#include "eapol_supp/eapol_supp_sm.h"
18cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#include "crypto/dh_group5.h"
198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/hostapd.h"
208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_config.h"
218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ap_drv_ops.h"
221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef NEED_AP_MLME
238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ieee802_11.h"
248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */
258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/beacon.h"
268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ieee802_1x.h"
278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/wps_hostapd.h"
288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/ctrl_iface_ap.h"
298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wps/wps.h"
308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common/ieee802_11_defs.h"
318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config_ssid.h"
328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "config.h"
338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "wpa_supplicant_i.h"
348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "driver_i.h"
358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "p2p_supplicant.h"
368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap.h"
378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ap/sta_info.h"
388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "notify.h"
398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt#ifdef CONFIG_IEEE80211N
4768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtstatic void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
4868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			     struct hostapd_config *conf,
4968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			     struct hostapd_hw_modes *mode)
5068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt{
5121de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt#ifdef CONFIG_P2P
5268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	u8 center_chan = 0;
5368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	u8 channel = conf->channel;
5468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
5568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (!conf->secondary_channel)
5668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		goto no_vht;
5768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
5868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
5968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	if (!center_chan)
6068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		goto no_vht;
6168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
6268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	/* Use 80 MHz channel */
6368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	conf->vht_oper_chwidth = 1;
6468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	conf->vht_oper_centr_freq_seg0_idx = center_chan;
6568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	return;
6668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
6768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidtno_vht:
6868d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt	conf->vht_oper_centr_freq_seg0_idx =
6968d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt		channel + conf->secondary_channel * 2;
7021de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt#else /* CONFIG_P2P */
7121de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt	conf->vht_oper_centr_freq_seg0_idx =
7221de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt		conf->channel + conf->secondary_channel * 2;
7321de214b4ba4271ca20843f3b8fba9f1501b2a89Dmitry Shmidt#endif /* CONFIG_P2P */
7468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt}
7568d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt#endif /* CONFIG_IEEE80211N */
7668d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
7768d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  struct wpa_ssid *ssid,
808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  struct hostapd_config *conf)
818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
82cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt	struct hostapd_bss_config *bss = conf->bss[0];
838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->driver = wpa_s->driver;
858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
88b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	conf->hw_mode = ieee80211_freq_to_chan(ssid->frequency,
89b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt					       &conf->channel);
90b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
91b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
92b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt			   ssid->frequency);
93b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		return -1;
948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
96c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	/* TODO: enable HT40 if driver supports it;
978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * drop to 11b if driver does not support 11g */
988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
99c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#ifdef CONFIG_IEEE80211N
100c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	/*
1011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
1021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * and a mask of allowed capabilities within conf->ht_capab.
103c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	 * Using default config settings for: conf->ht_op_mode_fixed,
1041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * conf->secondary_channel, conf->require_ht
105c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	 */
1061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->hw.modes) {
107c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		struct hostapd_hw_modes *mode = NULL;
10804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		int i, no_ht = 0;
1091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (i = 0; i < wpa_s->hw.num_modes; i++) {
1101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
1111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				mode = &wpa_s->hw.modes[i];
112c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt				break;
113c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			}
114c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt		}
11504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#ifdef CONFIG_HT_OVERRIDES
11704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (ssid->disable_ht) {
11804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			conf->ieee80211n = 0;
11904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			conf->ht_capab = 0;
12004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			no_ht = 1;
12104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		}
12204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt#endif /* CONFIG_HT_OVERRIDES */
12304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
12404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		if (!no_ht && mode && mode->ht_capab) {
125c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt			conf->ieee80211n = 1;
12661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#ifdef CONFIG_P2P
12761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
12861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    (mode->ht_capab &
12961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
13061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			    ssid->ht40)
13161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				conf->secondary_channel =
13261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					wpas_p2p_get_ht40_mode(wpa_s, mode,
13361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt							       conf->channel);
13461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt			if (conf->secondary_channel)
13561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt				conf->ht_capab |=
13661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt					HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
13761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt#endif /* CONFIG_P2P */
1381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			/*
1401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * white-list capabilities that won't cause issues
1411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * to connecting stations, while leaving the current
1421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 * capabilities intact (currently disabled SMPS).
1431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			 */
1441f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			conf->ht_capab |= mode->ht_capab &
1451f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				(HT_CAP_INFO_GREEN_FIELD |
1461f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 HT_CAP_INFO_SHORT_GI20MHZ |
1471f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 HT_CAP_INFO_SHORT_GI40MHZ |
1481f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 HT_CAP_INFO_RX_STBC_MASK |
1491f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 HT_CAP_INFO_MAX_AMSDU_SIZE);
15068d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt
15168d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			if (mode->vht_capab && ssid->vht) {
15268d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				conf->ieee80211ac = 1;
15368d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt				wpas_conf_ap_vht(wpa_s, conf, mode);
15468d0e3ed07847339aedfac8e02f50db68c702e52Dmitry Shmidt			}
1551f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
156c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt	}
157c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt#endif /* CONFIG_IEEE80211N */
158c55524ad84d13014e8019491c2b17e5dcf13545aDmitry Shmidt
1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
16034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
16134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	    (ssid->mode == WPAS_MODE_P2P_GO ||
16234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt	     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		/* Remove 802.11b rates from supported and basic rate sets */
1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		int *list = os_malloc(4 * sizeof(int));
1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (list) {
1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[0] = 60;
1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[1] = 120;
1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[2] = 240;
1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[3] = -1;
1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->basic_rates = list;
1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		list = os_malloc(9 * sizeof(int));
1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (list) {
1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[0] = 60;
1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[1] = 90;
1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[2] = 120;
1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[3] = 180;
1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[4] = 240;
1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[5] = 360;
1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[6] = 480;
1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[7] = 540;
1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			list[8] = -1;
1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->supported_rates = list;
1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
1871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
1881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	bss->isolate = !wpa_s->conf->p2p_intra_bss;
189391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
190cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
191cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (ssid->p2p_group) {
192cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(bss->ip_addr_go, wpa_s->parent->conf->ip_addr_go, 4);
193cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(bss->ip_addr_mask, wpa_s->parent->conf->ip_addr_mask,
194cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  4);
195cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(bss->ip_addr_start,
196cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  wpa_s->parent->conf->ip_addr_start, 4);
197cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		os_memcpy(bss->ip_addr_end, wpa_s->parent->conf->ip_addr_end,
198cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			  4);
199cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ssid_len == 0) {
2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->ssid.ssid_len = ssid->ssid_len;
2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->ssid.ssid_set = 1;
2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
21004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
21104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
2121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid->auth_alg)
2131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->auth_algs = ssid->auth_alg;
2141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->wpa = ssid->proto;
2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_key_mgmt = ssid->key_mgmt;
2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->wpa_pairwise = ssid->pairwise_cipher;
219d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	if (ssid->psk_set) {
2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_free(bss->ssid.wpa_psk);
2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (bss->ssid.wpa_psk == NULL)
2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.wpa_psk->group = 1;
226d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt	} else if (ssid->passphrase) {
227d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt		bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
2281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
2291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		   ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
2301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		struct hostapd_wep_keys *wep = &bss->ssid.wep;
2311f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		int i;
2321f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		for (i = 0; i < NUM_WEP_KEYS; i++) {
2331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (ssid->wep_key_len[i] == 0)
2341f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				continue;
2351f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wep->key[i] = os_malloc(ssid->wep_key_len[i]);
2361f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			if (wep->key[i] == NULL)
2371f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				return -1;
2381f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			os_memcpy(wep->key[i], ssid->wep_key[i],
2391f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				  ssid->wep_key_len[i]);
2401f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			wep->len[i] = ssid->wep_key_len[i];
2411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		}
2421f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wep->idx = ssid->wep_tx_keyidx;
2431f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		wep->keys_set = 1;
2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
24604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->ap_max_inactivity)
24704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->ap_max_inactivity = ssid->ap_max_inactivity;
24804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
24904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (ssid->dtim_period)
25004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->dtim_period = ssid->dtim_period;
2517a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	else if (wpa_s->conf->dtim_period)
2527a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		bss->dtim_period = wpa_s->conf->dtim_period;
2537a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt
2547a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	if (ssid->beacon_int)
2557a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		conf->beacon_int = ssid->beacon_int;
2567a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt	else if (wpa_s->conf->beacon_int)
2577a5e50a0554bee77a9da492ea3d86f46147f1671Dmitry Shmidt		conf->beacon_int = wpa_s->conf->beacon_int;
25804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
259a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
260a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt		bss->rsn_pairwise = bss->wpa_pairwise;
261a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
262a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt						    bss->rsn_pairwise);
2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (bss->wpa && bss->ieee802_1x)
2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.security_policy = SECURITY_WPA;
2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (bss->wpa)
2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.security_policy = SECURITY_WPA_PSK;
2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (bss->ieee802_1x) {
2691f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		int cipher = WPA_CIPHER_NONE;
2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.security_policy = SECURITY_IEEE_802_1X;
2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.wep.default_len = bss->default_wep_key_len;
2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (bss->default_wep_key_len)
2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			cipher = bss->default_wep_key_len >= 13 ?
2741f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
2751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_group = cipher;
2761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_pairwise = cipher;
2771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->rsn_pairwise = cipher;
2781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else if (bss->ssid.wep.keys_set) {
2791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		int cipher = WPA_CIPHER_WEP40;
2801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		if (bss->ssid.wep.len[0] >= 13)
2811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			cipher = WPA_CIPHER_WEP104;
2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.security_policy = SECURITY_STATIC_WEP;
2831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_group = cipher;
2841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_pairwise = cipher;
2851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->rsn_pairwise = cipher;
2861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	} else {
2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->ssid.security_policy = SECURITY_PLAINTEXT;
2881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_group = WPA_CIPHER_NONE;
2891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->wpa_pairwise = WPA_CIPHER_NONE;
2901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		bss->rsn_pairwise = WPA_CIPHER_NONE;
2911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
2938da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt	if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
2948da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt	    (bss->wpa_group == WPA_CIPHER_CCMP ||
295fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	     bss->wpa_group == WPA_CIPHER_GCMP ||
296fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	     bss->wpa_group == WPA_CIPHER_CCMP_256 ||
297fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	     bss->wpa_group == WPA_CIPHER_GCMP_256)) {
2988da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		/*
2998da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		 * Strong ciphers do not need frequent rekeying, so increase
3008da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		 * the default GTK rekeying period to 24 hours.
3018da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		 */
3028da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt		bss->wpa_group_rekey = 86400;
3038da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt	}
3048da800a193fb6f8832218715f82a7b4e2d2ad338Dmitry Shmidt
305b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt#ifdef CONFIG_IEEE80211W
306b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt	if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
307b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt		bss->ieee80211w = ssid->ieee80211w;
308b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt#endif /* CONFIG_IEEE80211W */
309b36ed7cd946148d829f311de8fe53ea3ffaaffe3Dmitry Shmidt
3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
3121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * Enable WPS by default for open and WPA/WPA2-Personal network, but
3131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * require user interaction to actually use it. Only the internal
3141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	 * Registrar is supported.
3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
3161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
3171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    bss->ssid.security_policy != SECURITY_PLAINTEXT)
3181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		goto no_wps;
3191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
320a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	    (!(bss->rsn_pairwise & WPA_CIPHER_CCMP) || !(bss->wpa & 2)))
3211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		goto no_wps; /* WPS2 does not allow WPA/TKIP-only
3221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			      * configuration */
3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->eap_server = 1;
32404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
32504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!ssid->ignore_broadcast_ssid)
32604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		bss->wps_state = 2;
32704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->ap_setup_locked = 2;
3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->config_methods)
3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->config_methods = os_strdup(wpa_s->conf->config_methods);
3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(bss->device_type, wpa_s->conf->device_type,
3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  WPS_DEV_TYPE_LEN);
3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->device_name) {
3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->device_name = os_strdup(wpa_s->conf->device_name);
3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->friendly_name = os_strdup(wpa_s->conf->device_name);
3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->manufacturer)
3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->model_name)
3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->model_name = os_strdup(wpa_s->conf->model_name);
3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->model_number)
3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->model_number = os_strdup(wpa_s->conf->model_number);
3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->conf->serial_number)
3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->serial_number = os_strdup(wpa_s->conf->serial_number);
3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (is_nil_uuid(wpa_s->conf->uuid))
3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
35004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
3511f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtno_wps:
3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->max_stations &&
3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->max_num_sta = wpa_s->max_stations;
3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		bss->max_num_sta = wpa_s->conf->max_num_sta;
3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3620ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	if (wpa_s->conf->ap_vendor_elements) {
3630ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt		bss->vendor_elements =
3640ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt			wpabuf_dup(wpa_s->conf->ap_vendor_elements);
3650ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt	}
3660ccb66edb8d2a0a397320ace3ec2a03fb0d00d5fDmitry Shmidt
3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct ieee80211_mgmt *mgmt;
3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t hdr_len;
3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	mgmt = (const struct ieee80211_mgmt *) buf;
3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hdr_len > len)
3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
3821846323989242844f0e857458a8939fa5836429cDmitry Shmidt	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
3831846323989242844f0e857458a8939fa5836429cDmitry Shmidt		return;
3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   mgmt->u.action.category,
3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   &mgmt->u.action.u.vs_public_action.action,
3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   len - hdr_len, freq);
3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ap_wps_event_cb(void *ctx, enum wps_event event,
3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    union wps_event_data *data)
3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
39875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen	if (event == WPS_EV_FAIL) {
3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		struct wps_event_fail *fail = &data->fail;
4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
40175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		if (wpa_s->parent && wpa_s->parent != wpa_s &&
40275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		    wpa_s == wpa_s->global->p2p_group_formation) {
40375ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			/*
40475ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * src/ap/wps_hostapd.c has already sent this on the
40575ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * main interface, so only send on the parent interface
40675ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 * here if needed.
40775ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			 */
40875ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen			wpa_msg(wpa_s->parent, MSG_INFO, WPS_EVENT_FAIL
40975ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				"msg=%d config_error=%d",
41075ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen				fail->msg, fail->config_error);
41175ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		}
41275ecf5267604f166b85a7ee2cf0d9cb682966680Jouni Malinen		wpas_p2p_wps_failed(wpa_s, fail);
4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
4191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt				 int authorized, const u8 *p2p_dev_addr)
4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
425391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#ifdef CONFIG_P2P
426391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidtstatic void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
427391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt			  const u8 *psk, size_t psk_len)
428391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt{
429391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
430391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
431391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
432391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		return;
433391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt	wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
434391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt}
435391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt#endif /* CONFIG_P2P */
436391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
437391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt
4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	const struct ieee80211_mgmt *mgmt;
4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t hdr_len;
4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	mgmt = (const struct ieee80211_mgmt *) buf;
4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hdr_len = (const u8 *) &mgmt->u.action.u.vs_public_action.action - buf;
4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hdr_len > len)
4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   mgmt->u.action.category,
4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   &mgmt->u.action.u.vs_public_action.action,
4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   len - hdr_len, freq);
4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4581f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtstatic int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
45904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   const u8 *bssid, const u8 *ie, size_t ie_len,
46004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt			   int ssi_signal)
4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
46404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
46504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				     ssi_signal);
4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#else /* CONFIG_P2P */
4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				  const u8 *uuid_e)
4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_wps_success(wpa_s, mac_addr, 1);
4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_ap_configured_cb(void *ctx)
4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_configured_cb)
4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					wpa_s->ap_configured_cb_data);
4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
4958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			     struct wpa_ssid *ssid)
4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_driver_associate_params params;
4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_iface *hapd_iface;
4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_config *conf;
5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	size_t i;
5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->ssid == NULL || ssid->ssid_len == 0) {
5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_supplicant_ap_deinit(wpa_s);
5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&params, 0, sizeof(params));
5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ssid = ssid->ssid;
5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.ssid_len = ssid->ssid_len;
5158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	switch (ssid->mode) {
5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPAS_MODE_AP:
5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPAS_MODE_P2P_GO:
5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	case WPAS_MODE_P2P_GROUP_FORMATION:
5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.mode = IEEE80211_MODE_AP;
5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		break;
5213c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt	default:
5223c4793790bf06f1fe08a2ddf604c9caa855151f1Dmitry Shmidt		return -1;
5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
524b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	if (ssid->frequency == 0)
525b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt		ssid->frequency = 2462; /* default channel 11 */
5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.freq = ssid->frequency;
5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	params.wpa_proto = ssid->proto;
5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
533fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params.key_mgmt_suite = wpa_s->key_mgmt;
5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
535a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
536a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt							  1);
537a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt	if (wpa_s->pairwise_cipher < 0) {
5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "cipher.");
5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
542fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	params.pairwise_suite = wpa_s->pairwise_cipher;
5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	params.group_suite = params.pairwise_suite;
5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO ||
5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.p2p = 1;
5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->parent->set_ap_uapsd)
5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = wpa_s->parent->ap_uapsd;
553ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt	else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
554ec58b164a608cbc1d99e71bb3d86ef4b263377dcDmitry Shmidt		params.uapsd = 1; /* mandatory for P2P GO */
5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		params.uapsd = -1;
5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_drv_associate(wpa_s, &params) < 0) {
5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_iface = hapd_iface = os_zalloc(sizeof(*wpa_s->ap_iface));
5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd_iface == NULL)
5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd_iface->owner = wpa_s;
5671f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hapd_iface->drv_flags = wpa_s->drv_flags;
5681f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
569444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	hapd_iface->extended_capa = wpa_s->extended_capa;
570444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
571444d567b27731d8572ef37697dd12fd1c37c2f24Dmitry Shmidt	hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf == NULL) {
5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_deinit(wpa_s);
5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
57961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
58061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		  wpa_s->conf->wmm_ac_params,
58161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt		  sizeof(wpa_s->conf->wmm_ac_params));
58261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt
5831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (params.uapsd > 0) {
584cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		conf->bss[0]->wmm_enabled = 1;
585cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		conf->bss[0]->wmm_uapsd = 1;
5861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	}
5871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
5888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
5898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to create AP configuration");
5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_deinit(wpa_s);
5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO)
596cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
598cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_GROUP_FORMATION;
6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd_iface->num_bss = conf->num_bss;
60361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt	hapd_iface->bss = os_calloc(conf->num_bss,
6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				    sizeof(struct hostapd_data *));
6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd_iface->bss == NULL) {
6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_deinit(wpa_s);
6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	for (i = 0; i < conf->num_bss; i++) {
6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i] =
6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			hostapd_alloc_bss_data(hapd_iface, conf,
613cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt					       conf->bss[i]);
6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		if (hapd_iface->bss[i] == NULL) {
6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			wpa_supplicant_ap_deinit(wpa_s);
6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			return -1;
6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		}
6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->msg_ctx = wpa_s;
620497c1d5e50162d6b3c1cce5dbd9c5fd9da69aaefDmitry Shmidt		hapd_iface->bss[i]->msg_ctx_parent = wpa_s->parent;
6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hostapd_register_probereq_cb(hapd_iface->bss[i],
6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					     ap_probe_req_rx, wpa_s);
6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
634391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
635391c59f0632df8db1c325da1d31d479b2eedce45Dmitry Shmidt		hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
63704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
63804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt								    ssid);
6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd_iface->bss[0]->driver = wpa_s->driver;
6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = ssid;
649b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
6518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = ssid->frequency;
6528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hostapd_setup_interface(wpa_s->ap_iface)) {
6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_supplicant_ap_deinit(wpa_s);
6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->current_ssid = NULL;
673b7b4d0ec07161a6d76c40ba7ef1306e82fbb7e15Dmitry Shmidt	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->assoc_freq = 0;
6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface->bss)
6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_s->ap_iface->bss[0]->p2p_group = NULL;
6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_p2p_group_deinit(wpa_s);
6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
680a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt	wpa_s->ap_iface->driver_ap_teardown =
681a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt		!!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
682a38abf9af7bec7e89dbfb39ac7bb77223fe47c72Dmitry Shmidt
6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_interface_deinit(wpa_s->ap_iface);
6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_interface_free(wpa_s->ap_iface);
6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_s->ap_iface = NULL;
6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_drv_deinit_ap(wpa_s);
6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ap_tx_status(void *ctx, const u8 *addr,
6918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		  const u8 *buf, size_t len, int ack)
6928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME
6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
6958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
6968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */
6978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
6988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
6998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ap_eapol_tx_status(void *ctx, const u8 *dst,
7011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt			const u8 *data, size_t len, int ack)
7028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME
7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
705fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt	if (!wpa_s->ap_iface)
706fb79edc9df1f20461e90e478363d207348213d35Dmitry Shmidt		return;
7071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
7081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* NEED_AP_MLME */
7091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
7101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ap_client_poll_ok(void *ctx, const u8 *addr)
7131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
7141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef NEED_AP_MLME
7151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
7161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (wpa_s->ap_iface)
7171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
7181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* NEED_AP_MLME */
7191f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt}
7201f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7211f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt
7221f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtvoid ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
7231f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{
7241f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef NEED_AP_MLME
7251f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
7261f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */
7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
7328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7331f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#ifdef NEED_AP_MLME
7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_frame_info fi;
7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memset(&fi, 0, sizeof(fi));
7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fi.datarate = rx_mgmt->datarate;
7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	fi.ssi_signal = rx_mgmt->ssi_signal;
7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			rx_mgmt->frame_len, &fi);
7411f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt#endif /* NEED_AP_MLME */
7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef NEED_AP_MLME
7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = ctx;
7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* NEED_AP_MLME */
7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				const u8 *src_addr, const u8 *buf, size_t len)
7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_WPS
7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			      const u8 *p2p_dev_addr)
7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					 p2p_dev_addr);
7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
7718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
7748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
7758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wps_registrar *reg;
7768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int reg_sel = 0, wps_sta = 0;
7778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
7798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reg = wpa_s->ap_iface->bss[0]->wps->registrar;
7828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	reg_sel = wps_registrar_wps_cancel(reg);
7838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
78404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				  ap_sta_wps_cancel, NULL);
7858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!reg_sel && !wps_sta) {
7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   "time");
7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * There are 2 cases to return wps cancel as success:
7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * 1. When wps cancel was initiated but no connection has been
7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 *    established with client yet.
7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * 2. Client is in the middle of exchanging WPS messages.
7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
804d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			      const char *pin, char *buf, size_t buflen,
805d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt			      int timeout)
8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret, ret_len = 0;
8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (pin == NULL) {
8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		unsigned int rpin = wps_generate_pin();
8141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		ret_len = os_snprintf(buf, buflen, "%08d", rpin);
8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		pin = buf;
8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	} else
8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		ret_len = os_snprintf(buf, buflen, "%s", pin);
8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
820d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt				  timeout);
8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret)
8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return ret_len;
8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_supplicant *wpa_s = eloop_data;
8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_ap_pin_disable(wpa_s);
8328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
8368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
8388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
8408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
8428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->ap_pin_failures = 0;
8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (timeout > 0)
8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		eloop_register_timeout(timeout, 0,
8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				       wpas_wps_ap_pin_timeout, wpa_s, NULL);
8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(hapd->conf->ap_pin);
8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->conf->ap_pin = NULL;
8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	unsigned int pin;
8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char pin_txt[9];
8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pin = wps_generate_pin();
8751f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(hapd->conf->ap_pin);
8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->conf->ap_pin = os_strdup(pin_txt);
8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->ap_pin == NULL)
8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_ap_pin_enable(wpa_s, timeout);
8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->conf->ap_pin;
8838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
8878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
8898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
8908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return NULL;
8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hapd->conf->ap_pin;
8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			int timeout)
8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char pin_txt[9];
9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= (int) sizeof(pin_txt))
9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(hapd->conf->ap_pin);
9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->conf->ap_pin = os_strdup(pin_txt);
9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->conf->ap_pin == NULL)
9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpas_wps_ap_pin_enable(wpa_s, timeout);
9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	/*
9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * Registrar failed to prove its knowledge of the AP PIN. Disable AP
9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 * PIN if this happens multiple times to slow down brute force attacks.
9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	 */
9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->ap_pin_failures++;
9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		   hapd->ap_pin_failures);
9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (hapd->ap_pin_failures < 3)
9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return;
9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->ap_pin_failures = 0;
9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(hapd->conf->ap_pin);
9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd->conf->ap_pin = NULL;
9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
943f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
944f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#ifdef CONFIG_WPS_NFC
945f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
946f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstruct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
947f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt					     int ndef)
948f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
949f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	struct hostapd_data *hapd;
950f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
951f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
952f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		return NULL;
953f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
954f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	return hostapd_wps_nfc_config_token(hapd, ndef);
955f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
956f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
957f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
958f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtstruct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
959f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt					     int ndef)
960f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{
961f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	struct hostapd_data *hapd;
962f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
963f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
964f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt		return NULL;
965f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
966f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt	return hostapd_wps_nfc_hs_cr(hapd, ndef);
967f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt}
968f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
969cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
970cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
971cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    const struct wpabuf *req,
972cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt				    const struct wpabuf *sel)
973cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
974cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct hostapd_data *hapd;
975cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
976cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->ap_iface == NULL)
977cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
978cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
979cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return hostapd_wps_nfc_report_handover(hapd, req, sel);
980cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
981cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
982f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt#endif /* CONFIG_WPS_NFC */
983f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt
9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_WPS */
9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE
9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			    char *buf, size_t buflen)
9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_ctrl_iface_sta_first(wpa_s->ap_iface->bss[0],
9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					    buf, buflen);
9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		      char *buf, size_t buflen)
10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_ctrl_iface_sta(wpa_s->ap_iface->bss[0], txtaddr,
10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      buf, buflen);
10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   char *buf, size_t buflen)
10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return hostapd_ctrl_iface_sta_next(wpa_s->ap_iface->bss[0], txtaddr,
10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   buf, buflen);
10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
101904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
102004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				   const char *txtaddr)
102104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
102204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->ap_iface == NULL)
102304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
102404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
102504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt					       txtaddr);
102604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
102704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
102804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
102904949598a23f501be6eec21697465fd46a28840aDmitry Shmidtint ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
103004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt				     const char *txtaddr)
103104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
103204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (wpa_s->ap_iface == NULL)
103304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return -1;
103404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
103504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt						 txtaddr);
103604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
103704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
103804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				 size_t buflen, int verbose)
10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	char *pos = buf, *end = buf + buflen;
10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	int ret;
10448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_bss_config *conf;
10458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (wpa_s->ap_iface == NULL)
10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = wpa_s->ap_iface->bss[0]->conf;
10508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->wpa == 0)
10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	ret = os_snprintf(pos, end - pos,
10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "pairwise_cipher=%s\n"
10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "group_cipher=%s\n"
10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  "key_mgmt=%s\n",
10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_cipher_txt(conf->rsn_pairwise),
10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_cipher_txt(conf->wpa_group),
10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			  wpa_key_mgmt_txt(conf->wpa_key_mgmt,
10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt					   conf->wpa));
10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ret < 0 || ret >= end - pos)
10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return pos - buf;
10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	pos += ret;
10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return pos - buf;
10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE */
10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_iface *iface = wpa_s->ap_iface;
10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct wpa_ssid *ssid = wpa_s->current_ssid;
10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10761f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (ssid == NULL || wpa_s->ap_iface == NULL ||
10771f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    ssid->mode == WPAS_MODE_INFRA ||
10781f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	    ssid->mode == WPAS_MODE_IBSS)
10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_P2P
10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (ssid->mode == WPAS_MODE_P2P_GO)
1083cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1085cce06667447b5aec83452adb0c15100ada531095Dmitry Shmidt		iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			P2P_GROUP_FORMATION;
10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_P2P */
10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = iface->bss[0];
10901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	if (hapd->drv_priv == NULL)
10911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt		return -1;
10921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt	ieee802_11_set_beacons(iface);
10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hostapd_set_ap_wps_ie(hapd);
10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
1099e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint ap_switch_channel(struct wpa_supplicant *wpa_s,
1100e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		      struct csa_settings *settings)
1101e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{
1102e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#ifdef NEED_AP_MLME
1103e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0])
1104e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		return -1;
1105e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1106e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return hostapd_switch_channel(wpa_s->ap_iface->bss[0], settings);
1107e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#else /* NEED_AP_MLME */
1108e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return -1;
1109e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt#endif /* NEED_AP_MLME */
1110e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt}
1111e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1112e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1113e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidtint ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1114e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt{
1115e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	struct csa_settings settings;
1116e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	int ret = hostapd_parse_csa_settings(pos, &settings);
1117e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1118e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	if (ret)
1119e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt		return ret;
1120e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1121e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt	return ap_switch_channel(wpa_s, &settings);
1122e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt}
1123e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
1124e0e48dc666fb14a7bb60264ca87463ba7bc1fe0bDmitry Shmidt
112504949598a23f501be6eec21697465fd46a28840aDmitry Shmidtvoid wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
112604f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt		       int offset, int width, int cf1, int cf2)
112704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt{
112804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	if (!wpa_s->ap_iface)
112904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt		return;
113004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
113104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt	wpa_s->assoc_freq = freq;
113204f534e89ed127da4077485376f24debc50d80d5Dmitry Shmidt	hostapd_event_ch_switch(wpa_s->ap_iface->bss[0], freq, ht, offset, width, cf1, cf1);
113304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt}
113404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
113504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt
11368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
11378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt				      const u8 *addr)
11388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{
11398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_data *hapd;
11408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	struct hostapd_bss_config *conf;
11418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (!wpa_s->ap_iface)
11438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr)
11468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR,
11478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt			   MAC2STR(addr));
11488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	else
11498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		wpa_printf(MSG_DEBUG, "AP: Clear MAC address filter");
11508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
11528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf = hapd->conf;
11538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->accept_mac);
11558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->accept_mac = NULL;
11568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->num_accept_mac = 0;
11578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_free(conf->deny_mac);
11588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->deny_mac = NULL;
11598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->num_deny_mac = 0;
11608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (addr == NULL) {
11628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
11638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return 0;
11648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	}
11658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
11678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
11688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	if (conf->accept_mac == NULL)
11698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt		return -1;
11708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
11718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	conf->num_accept_mac = 1;
11728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt
11738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt	return 0;
11748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}
1175cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1176cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1177cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#ifdef CONFIG_WPS_NFC
1178cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidtint wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
1179cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt			   const struct wpabuf *pw, const u8 *pubkey_hash)
1180cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt{
1181cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct hostapd_data *hapd;
1182cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	struct wps_context *wps;
1183cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1184cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (!wpa_s->ap_iface)
1185cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
1186cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	hapd = wpa_s->ap_iface->bss[0];
1187cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wps = hapd->wps;
1188cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1189cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wpa_s->parent->conf->wps_nfc_dh_pubkey == NULL ||
1190cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	    wpa_s->parent->conf->wps_nfc_dh_privkey == NULL) {
1191cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
1192cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
1193cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
1194cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1195cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	dh5_free(wps->dh_ctx);
1196cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wps->dh_pubkey);
1197cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wpabuf_free(wps->dh_privkey);
1198cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wps->dh_privkey = wpabuf_dup(
1199cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->parent->conf->wps_nfc_dh_privkey);
1200cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wps->dh_pubkey = wpabuf_dup(
1201cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpa_s->parent->conf->wps_nfc_dh_pubkey);
1202cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
1203cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wps->dh_ctx = NULL;
1204cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(wps->dh_pubkey);
1205cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wps->dh_pubkey = NULL;
1206cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wpabuf_free(wps->dh_privkey);
1207cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		wps->dh_privkey = NULL;
1208cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
1209cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	}
1210cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
1211cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	if (wps->dh_ctx == NULL)
1212cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt		return -1;
1213cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt
1214cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt	return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
1215cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					      pw_id,
1216cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					      pw ? wpabuf_head(pw) : NULL,
1217cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt					      pw ? wpabuf_len(pw) : 0, 1);
1218cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt}
1219cf32e60fa7e0d33fe1551a6dba8dcbbec47ea50eDmitry Shmidt#endif /* CONFIG_WPS_NFC */
1220