1e5b75505Sopenharmony_ci/*
2e5b75505Sopenharmony_ci * WPA Supplicant - Basic AP mode support routines
3e5b75505Sopenharmony_ci * Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi>
4e5b75505Sopenharmony_ci * Copyright (c) 2009, Atheros Communications
5e5b75505Sopenharmony_ci *
6e5b75505Sopenharmony_ci * This software may be distributed under the terms of the BSD license.
7e5b75505Sopenharmony_ci * See README for more details.
8e5b75505Sopenharmony_ci */
9e5b75505Sopenharmony_ci
10e5b75505Sopenharmony_ci#include "utils/includes.h"
11e5b75505Sopenharmony_ci
12e5b75505Sopenharmony_ci#include "utils/common.h"
13e5b75505Sopenharmony_ci#include "utils/eloop.h"
14e5b75505Sopenharmony_ci#include "utils/uuid.h"
15e5b75505Sopenharmony_ci#include "common/ieee802_11_defs.h"
16e5b75505Sopenharmony_ci#include "common/wpa_ctrl.h"
17e5b75505Sopenharmony_ci#include "eapol_supp/eapol_supp_sm.h"
18e5b75505Sopenharmony_ci#include "crypto/dh_group5.h"
19e5b75505Sopenharmony_ci#include "ap/hostapd.h"
20e5b75505Sopenharmony_ci#include "ap/ap_config.h"
21e5b75505Sopenharmony_ci#include "ap/ap_drv_ops.h"
22e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
23e5b75505Sopenharmony_ci#include "ap/ieee802_11.h"
24e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
25e5b75505Sopenharmony_ci#include "ap/beacon.h"
26e5b75505Sopenharmony_ci#include "ap/ieee802_1x.h"
27e5b75505Sopenharmony_ci#include "ap/wps_hostapd.h"
28e5b75505Sopenharmony_ci#include "ap/ctrl_iface_ap.h"
29e5b75505Sopenharmony_ci#include "ap/dfs.h"
30e5b75505Sopenharmony_ci#include "wps/wps.h"
31e5b75505Sopenharmony_ci#include "common/ieee802_11_defs.h"
32e5b75505Sopenharmony_ci#include "config_ssid.h"
33e5b75505Sopenharmony_ci#include "config.h"
34e5b75505Sopenharmony_ci#include "wpa_supplicant_i.h"
35e5b75505Sopenharmony_ci#include "driver_i.h"
36e5b75505Sopenharmony_ci#include "p2p_supplicant.h"
37e5b75505Sopenharmony_ci#include "ap.h"
38e5b75505Sopenharmony_ci#include "ap/sta_info.h"
39e5b75505Sopenharmony_ci#include "notify.h"
40e5b75505Sopenharmony_ci#ifdef CONFIG_WIFI_RPT
41e5b75505Sopenharmony_ci#include "p2p/p2p_i.h"
42e5b75505Sopenharmony_ci#endif /* CONFIG_WIFI_RPT */
43e5b75505Sopenharmony_ci
44e5b75505Sopenharmony_ci#ifdef CONFIG_WPS
45e5b75505Sopenharmony_cistatic void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx);
46e5b75505Sopenharmony_ci#endif /* CONFIG_WPS */
47e5b75505Sopenharmony_ci
48e5b75505Sopenharmony_ci
49e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
50e5b75505Sopenharmony_cistatic bool is_chanwidth160_supported(struct hostapd_hw_modes *mode,
51e5b75505Sopenharmony_ci				      struct hostapd_config *conf)
52e5b75505Sopenharmony_ci{
53e5b75505Sopenharmony_ci#ifdef CONFIG_IEEE80211AX
54e5b75505Sopenharmony_ci	if (conf->ieee80211ax) {
55e5b75505Sopenharmony_ci		struct he_capabilities *he_cap;
56e5b75505Sopenharmony_ci
57e5b75505Sopenharmony_ci		he_cap = &mode->he_capab[IEEE80211_MODE_AP];
58e5b75505Sopenharmony_ci		if (he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
59e5b75505Sopenharmony_ci		    (HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G |
60e5b75505Sopenharmony_ci		     HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))
61e5b75505Sopenharmony_ci			return true;
62e5b75505Sopenharmony_ci	}
63e5b75505Sopenharmony_ci#endif /* CONFIG_IEEE80211AX */
64e5b75505Sopenharmony_ci	if (mode->vht_capab & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
65e5b75505Sopenharmony_ci			       VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
66e5b75505Sopenharmony_ci		return true;
67e5b75505Sopenharmony_ci	return false;
68e5b75505Sopenharmony_ci}
69e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
70e5b75505Sopenharmony_ci
71e5b75505Sopenharmony_ci
72e5b75505Sopenharmony_cistatic void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
73e5b75505Sopenharmony_ci			     struct wpa_ssid *ssid,
74e5b75505Sopenharmony_ci			     struct hostapd_config *conf,
75e5b75505Sopenharmony_ci			     struct hostapd_hw_modes *mode)
76e5b75505Sopenharmony_ci{
77e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
78e5b75505Sopenharmony_ci	u8 center_chan = 0;
79e5b75505Sopenharmony_ci	u8 channel = conf->channel;
80e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
81e5b75505Sopenharmony_ci	u8 freq_seg_idx;
82e5b75505Sopenharmony_ci
83e5b75505Sopenharmony_ci	if (!conf->secondary_channel)
84e5b75505Sopenharmony_ci		goto no_vht;
85e5b75505Sopenharmony_ci
86e5b75505Sopenharmony_ci	/* Use the maximum oper channel width if it's given. */
87e5b75505Sopenharmony_ci	if (ssid->max_oper_chwidth)
88e5b75505Sopenharmony_ci		hostapd_set_oper_chwidth(conf, ssid->max_oper_chwidth);
89e5b75505Sopenharmony_ci	if (hostapd_get_oper_chwidth(conf))
90e5b75505Sopenharmony_ci		ieee80211_freq_to_channel_ext(ssid->frequency, 0,
91e5b75505Sopenharmony_ci					      hostapd_get_oper_chwidth(conf),
92e5b75505Sopenharmony_ci					      &conf->op_class,
93e5b75505Sopenharmony_ci					      &conf->channel);
94e5b75505Sopenharmony_ci
95e5b75505Sopenharmony_ci	if (hostapd_get_oper_chwidth(conf) == CHANWIDTH_80P80MHZ) {
96e5b75505Sopenharmony_ci		ieee80211_freq_to_chan(ssid->vht_center_freq2,
97e5b75505Sopenharmony_ci				       &freq_seg_idx);
98e5b75505Sopenharmony_ci		hostapd_set_oper_centr_freq_seg1_idx(conf, freq_seg_idx);
99e5b75505Sopenharmony_ci	}
100e5b75505Sopenharmony_ci
101e5b75505Sopenharmony_ci	if (!ssid->p2p_group) {
102e5b75505Sopenharmony_ci		if (!ssid->vht_center_freq1)
103e5b75505Sopenharmony_ci			goto no_vht;
104e5b75505Sopenharmony_ci		ieee80211_freq_to_chan(ssid->vht_center_freq1,
105e5b75505Sopenharmony_ci				       &freq_seg_idx);
106e5b75505Sopenharmony_ci		hostapd_set_oper_centr_freq_seg0_idx(conf, freq_seg_idx);
107e5b75505Sopenharmony_ci
108e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
109e5b75505Sopenharmony_ci			   "VHT seg0 index %d and seg1 index %d for AP",
110e5b75505Sopenharmony_ci			   hostapd_get_oper_centr_freq_seg0_idx(conf),
111e5b75505Sopenharmony_ci			   hostapd_get_oper_centr_freq_seg1_idx(conf));
112e5b75505Sopenharmony_ci		return;
113e5b75505Sopenharmony_ci	}
114e5b75505Sopenharmony_ci
115e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
116e5b75505Sopenharmony_ci	switch (hostapd_get_oper_chwidth(conf)) {
117e5b75505Sopenharmony_ci	case CHANWIDTH_80MHZ:
118e5b75505Sopenharmony_ci	case CHANWIDTH_80P80MHZ:
119e5b75505Sopenharmony_ci		center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel,
120e5b75505Sopenharmony_ci							conf->op_class);
121e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
122e5b75505Sopenharmony_ci			   "VHT center channel %u for 80 or 80+80 MHz bandwidth",
123e5b75505Sopenharmony_ci			   center_chan);
124e5b75505Sopenharmony_ci		break;
125e5b75505Sopenharmony_ci	case CHANWIDTH_160MHZ:
126e5b75505Sopenharmony_ci		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
127e5b75505Sopenharmony_ci							 conf->op_class);
128e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
129e5b75505Sopenharmony_ci			   "VHT center channel %u for 160 MHz bandwidth",
130e5b75505Sopenharmony_ci			   center_chan);
131e5b75505Sopenharmony_ci		break;
132e5b75505Sopenharmony_ci	default:
133e5b75505Sopenharmony_ci		/*
134e5b75505Sopenharmony_ci		 * conf->vht_oper_chwidth might not be set for non-P2P GO cases,
135e5b75505Sopenharmony_ci		 * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
136e5b75505Sopenharmony_ci		 * not supported.
137e5b75505Sopenharmony_ci		 */
138e5b75505Sopenharmony_ci		hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
139e5b75505Sopenharmony_ci		ieee80211_freq_to_channel_ext(ssid->frequency, 0,
140e5b75505Sopenharmony_ci					      conf->vht_oper_chwidth,
141e5b75505Sopenharmony_ci					      &conf->op_class,
142e5b75505Sopenharmony_ci					      &conf->channel);
143e5b75505Sopenharmony_ci		center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel,
144e5b75505Sopenharmony_ci							 conf->op_class);
145e5b75505Sopenharmony_ci		if (center_chan && is_chanwidth160_supported(mode, conf)) {
146e5b75505Sopenharmony_ci			wpa_printf(MSG_DEBUG,
147e5b75505Sopenharmony_ci				   "VHT center channel %u for auto-selected 160 MHz bandwidth",
148e5b75505Sopenharmony_ci				   center_chan);
149e5b75505Sopenharmony_ci		} else {
150e5b75505Sopenharmony_ci			hostapd_set_oper_chwidth(conf, CHANWIDTH_80MHZ);
151e5b75505Sopenharmony_ci			ieee80211_freq_to_channel_ext(ssid->frequency, 0,
152e5b75505Sopenharmony_ci						      conf->vht_oper_chwidth,
153e5b75505Sopenharmony_ci						      &conf->op_class,
154e5b75505Sopenharmony_ci						      &conf->channel);
155e5b75505Sopenharmony_ci			center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
156e5b75505Sopenharmony_ci								channel,
157e5b75505Sopenharmony_ci								conf->op_class);
158e5b75505Sopenharmony_ci			wpa_printf(MSG_DEBUG,
159e5b75505Sopenharmony_ci				   "VHT center channel %u for auto-selected 80 MHz bandwidth",
160e5b75505Sopenharmony_ci				   center_chan);
161e5b75505Sopenharmony_ci		}
162e5b75505Sopenharmony_ci		break;
163e5b75505Sopenharmony_ci	}
164e5b75505Sopenharmony_ci	if (!center_chan)
165e5b75505Sopenharmony_ci		goto no_vht;
166e5b75505Sopenharmony_ci
167e5b75505Sopenharmony_ci	hostapd_set_oper_centr_freq_seg0_idx(conf, center_chan);
168e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "VHT seg0 index %d for P2P GO",
169e5b75505Sopenharmony_ci		   hostapd_get_oper_centr_freq_seg0_idx(conf));
170e5b75505Sopenharmony_ci	return;
171e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
172e5b75505Sopenharmony_ci
173e5b75505Sopenharmony_cino_vht:
174e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG,
175e5b75505Sopenharmony_ci		   "No VHT higher bandwidth support for the selected channel %d",
176e5b75505Sopenharmony_ci		   conf->channel);
177e5b75505Sopenharmony_ci	hostapd_set_oper_centr_freq_seg0_idx(
178e5b75505Sopenharmony_ci		conf, conf->channel + conf->secondary_channel * 2);
179e5b75505Sopenharmony_ci	hostapd_set_oper_chwidth(conf, CHANWIDTH_USE_HT);
180e5b75505Sopenharmony_ci}
181e5b75505Sopenharmony_ci
182e5b75505Sopenharmony_ci
183e5b75505Sopenharmony_cistatic struct hostapd_hw_modes *
184e5b75505Sopenharmony_ciwpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
185e5b75505Sopenharmony_ci			    enum hostapd_hw_mode hw_mode)
186e5b75505Sopenharmony_ci{
187e5b75505Sopenharmony_ci	struct hostapd_hw_modes *mode = NULL;
188e5b75505Sopenharmony_ci	int i;
189e5b75505Sopenharmony_ci
190e5b75505Sopenharmony_ci	for (i = 0; i < wpa_s->hw.num_modes; i++) {
191e5b75505Sopenharmony_ci		if (wpa_s->hw.modes[i].mode == hw_mode) {
192e5b75505Sopenharmony_ci			mode = &wpa_s->hw.modes[i];
193e5b75505Sopenharmony_ci			break;
194e5b75505Sopenharmony_ci		}
195e5b75505Sopenharmony_ci	}
196e5b75505Sopenharmony_ci
197e5b75505Sopenharmony_ci	return mode;
198e5b75505Sopenharmony_ci}
199e5b75505Sopenharmony_ci
200e5b75505Sopenharmony_ci
201e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
202e5b75505Sopenharmony_ci
203e5b75505Sopenharmony_cistatic int get_max_oper_chwidth_6ghz(int chwidth)
204e5b75505Sopenharmony_ci{
205e5b75505Sopenharmony_ci	switch (chwidth) {
206e5b75505Sopenharmony_ci	case CHANWIDTH_USE_HT:
207e5b75505Sopenharmony_ci		return 20;
208e5b75505Sopenharmony_ci	case CHANWIDTH_40MHZ_6GHZ:
209e5b75505Sopenharmony_ci		return 40;
210e5b75505Sopenharmony_ci	case CHANWIDTH_80MHZ:
211e5b75505Sopenharmony_ci		return 80;
212e5b75505Sopenharmony_ci	case CHANWIDTH_80P80MHZ:
213e5b75505Sopenharmony_ci	case CHANWIDTH_160MHZ:
214e5b75505Sopenharmony_ci		return 160;
215e5b75505Sopenharmony_ci	default:
216e5b75505Sopenharmony_ci		return 0;
217e5b75505Sopenharmony_ci	}
218e5b75505Sopenharmony_ci}
219e5b75505Sopenharmony_ci
220e5b75505Sopenharmony_ci
221e5b75505Sopenharmony_cistatic void wpas_conf_ap_he_6ghz(struct wpa_supplicant *wpa_s,
222e5b75505Sopenharmony_ci				 struct hostapd_hw_modes *mode,
223e5b75505Sopenharmony_ci				 struct wpa_ssid *ssid,
224e5b75505Sopenharmony_ci				 struct hostapd_config *conf)
225e5b75505Sopenharmony_ci{
226e5b75505Sopenharmony_ci	bool is_chanwidth_40_80, is_chanwidth_160;
227e5b75505Sopenharmony_ci	int he_chanwidth;
228e5b75505Sopenharmony_ci
229e5b75505Sopenharmony_ci	he_chanwidth =
230e5b75505Sopenharmony_ci		mode->he_capab[wpas_mode_to_ieee80211_mode(
231e5b75505Sopenharmony_ci			ssid->mode)].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
232e5b75505Sopenharmony_ci	is_chanwidth_40_80 = he_chanwidth &
233e5b75505Sopenharmony_ci		HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
234e5b75505Sopenharmony_ci	is_chanwidth_160 = he_chanwidth &
235e5b75505Sopenharmony_ci		HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
236e5b75505Sopenharmony_ci
237e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG,
238e5b75505Sopenharmony_ci		   "Enable HE support (p2p_group=%d he_chwidth_cap=%d)",
239e5b75505Sopenharmony_ci		   ssid->p2p_group, he_chanwidth);
240e5b75505Sopenharmony_ci
241e5b75505Sopenharmony_ci	if (mode->he_capab[wpas_mode_to_ieee80211_mode(
242e5b75505Sopenharmony_ci			    ssid->mode)].he_supported &&
243e5b75505Sopenharmony_ci	    ssid->he)
244e5b75505Sopenharmony_ci		conf->ieee80211ax = 1;
245e5b75505Sopenharmony_ci
246e5b75505Sopenharmony_ci	if (is_chanwidth_40_80 && ssid->p2p_group &&
247e5b75505Sopenharmony_ci	    get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 40) {
248e5b75505Sopenharmony_ci		conf->secondary_channel =
249e5b75505Sopenharmony_ci			wpas_p2p_get_sec_channel_offset_40mhz(
250e5b75505Sopenharmony_ci				wpa_s, mode, conf->channel);
251e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
252e5b75505Sopenharmony_ci			   "Secondary channel offset %d for P2P group",
253e5b75505Sopenharmony_ci			   conf->secondary_channel);
254e5b75505Sopenharmony_ci		if (ssid->max_oper_chwidth == CHANWIDTH_40MHZ_6GHZ)
255e5b75505Sopenharmony_ci			ssid->max_oper_chwidth = CHANWIDTH_USE_HT;
256e5b75505Sopenharmony_ci	}
257e5b75505Sopenharmony_ci
258e5b75505Sopenharmony_ci	if ((is_chanwidth_40_80 || is_chanwidth_160) && ssid->p2p_group &&
259e5b75505Sopenharmony_ci	    get_max_oper_chwidth_6ghz(ssid->max_oper_chwidth) >= 80)
260e5b75505Sopenharmony_ci		wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
261e5b75505Sopenharmony_ci}
262e5b75505Sopenharmony_ci
263e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
264e5b75505Sopenharmony_ci
265e5b75505Sopenharmony_ci
266e5b75505Sopenharmony_ciint wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
267e5b75505Sopenharmony_ci			      struct wpa_ssid *ssid,
268e5b75505Sopenharmony_ci			      struct hostapd_config *conf)
269e5b75505Sopenharmony_ci{
270e5b75505Sopenharmony_ci	conf->hw_mode = ieee80211_freq_to_channel_ext(ssid->frequency, 0,
271e5b75505Sopenharmony_ci						      CHANWIDTH_USE_HT,
272e5b75505Sopenharmony_ci						      &conf->op_class,
273e5b75505Sopenharmony_ci						      &conf->channel);
274e5b75505Sopenharmony_ci	if (conf->hw_mode == NUM_HOSTAPD_MODES) {
275e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "Unsupported AP mode frequency: %d MHz",
276e5b75505Sopenharmony_ci			   ssid->frequency);
277e5b75505Sopenharmony_ci		return -1;
278e5b75505Sopenharmony_ci	}
279e5b75505Sopenharmony_ci
280e5b75505Sopenharmony_ci	/*
281e5b75505Sopenharmony_ci	 * Enable HT20 if the driver supports it, by setting conf->ieee80211n
282e5b75505Sopenharmony_ci	 * and a mask of allowed capabilities within conf->ht_capab.
283e5b75505Sopenharmony_ci	 * Using default config settings for: conf->ht_op_mode_fixed,
284e5b75505Sopenharmony_ci	 * conf->secondary_channel, conf->require_ht
285e5b75505Sopenharmony_ci	 */
286e5b75505Sopenharmony_ci	if (wpa_s->hw.modes) {
287e5b75505Sopenharmony_ci		struct hostapd_hw_modes *mode = NULL;
288e5b75505Sopenharmony_ci		int no_ht = 0;
289e5b75505Sopenharmony_ci
290e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
291e5b75505Sopenharmony_ci			   "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
292e5b75505Sopenharmony_ci			   ssid->frequency, conf->channel);
293e5b75505Sopenharmony_ci
294e5b75505Sopenharmony_ci		mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
295e5b75505Sopenharmony_ci				conf->hw_mode, is_6ghz_freq(ssid->frequency));
296e5b75505Sopenharmony_ci
297e5b75505Sopenharmony_ci		/* May drop to IEEE 802.11b if the driver does not support IEEE
298e5b75505Sopenharmony_ci		 * 802.11g */
299e5b75505Sopenharmony_ci		if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
300e5b75505Sopenharmony_ci			conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
301e5b75505Sopenharmony_ci			wpa_printf(MSG_INFO,
302e5b75505Sopenharmony_ci				   "Try downgrade to IEEE 802.11b as 802.11g is not supported by the current hardware");
303e5b75505Sopenharmony_ci			mode = wpa_supplicant_find_hw_mode(wpa_s,
304e5b75505Sopenharmony_ci							   conf->hw_mode);
305e5b75505Sopenharmony_ci		}
306e5b75505Sopenharmony_ci
307e5b75505Sopenharmony_ci		if (!mode) {
308e5b75505Sopenharmony_ci			wpa_printf(MSG_ERROR,
309e5b75505Sopenharmony_ci				   "No match between requested and supported hw modes found");
310e5b75505Sopenharmony_ci			return -1;
311e5b75505Sopenharmony_ci		}
312e5b75505Sopenharmony_ci
313e5b75505Sopenharmony_ci#ifdef CONFIG_HT_OVERRIDES
314e5b75505Sopenharmony_ci		if (ssid->disable_ht)
315e5b75505Sopenharmony_ci			ssid->ht = 0;
316e5b75505Sopenharmony_ci#endif /* CONFIG_HT_OVERRIDES */
317e5b75505Sopenharmony_ci
318e5b75505Sopenharmony_ci		if (!ssid->ht) {
319e5b75505Sopenharmony_ci			wpa_printf(MSG_DEBUG,
320e5b75505Sopenharmony_ci				   "HT not enabled in network profile");
321e5b75505Sopenharmony_ci			conf->ieee80211n = 0;
322e5b75505Sopenharmony_ci			conf->ht_capab = 0;
323e5b75505Sopenharmony_ci			no_ht = 1;
324e5b75505Sopenharmony_ci		}
325e5b75505Sopenharmony_ci
326e5b75505Sopenharmony_ci		if (mode && is_6ghz_freq(ssid->frequency) &&
327e5b75505Sopenharmony_ci		    conf->hw_mode == HOSTAPD_MODE_IEEE80211A) {
328e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
329e5b75505Sopenharmony_ci			wpas_conf_ap_he_6ghz(wpa_s, mode, ssid, conf);
330e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
331e5b75505Sopenharmony_ci		} else if (!no_ht && mode && mode->ht_capab) {
332e5b75505Sopenharmony_ci			wpa_printf(MSG_DEBUG,
333e5b75505Sopenharmony_ci				   "Enable HT support (p2p_group=%d 11a=%d ht40_hw_capab=%d ssid->ht40=%d)",
334e5b75505Sopenharmony_ci				   ssid->p2p_group,
335e5b75505Sopenharmony_ci				   conf->hw_mode == HOSTAPD_MODE_IEEE80211A,
336e5b75505Sopenharmony_ci				   !!(mode->ht_capab &
337e5b75505Sopenharmony_ci				      HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
338e5b75505Sopenharmony_ci				   ssid->ht40);
339e5b75505Sopenharmony_ci			conf->ieee80211n = 1;
340e5b75505Sopenharmony_ci
341e5b75505Sopenharmony_ci			if (ssid->ht40 &&
342e5b75505Sopenharmony_ci			    (mode->ht_capab &
343e5b75505Sopenharmony_ci			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
344e5b75505Sopenharmony_ci				conf->secondary_channel = ssid->ht40;
345e5b75505Sopenharmony_ci			else
346e5b75505Sopenharmony_ci				conf->secondary_channel = 0;
347e5b75505Sopenharmony_ci
348e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
349e5b75505Sopenharmony_ci			if (ssid->p2p_group &&
350e5b75505Sopenharmony_ci			    conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
351e5b75505Sopenharmony_ci			    (mode->ht_capab &
352e5b75505Sopenharmony_ci			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
353e5b75505Sopenharmony_ci			    ssid->ht40) {
354e5b75505Sopenharmony_ci				conf->secondary_channel =
355e5b75505Sopenharmony_ci					wpas_p2p_get_sec_channel_offset_40mhz(
356e5b75505Sopenharmony_ci						wpa_s, mode, conf->channel);
357e5b75505Sopenharmony_ci				wpa_printf(MSG_DEBUG,
358e5b75505Sopenharmony_ci					   "HT secondary channel offset %d for P2P group",
359e5b75505Sopenharmony_ci					   conf->secondary_channel);
360e5b75505Sopenharmony_ci			} else if (ssid->p2p_group && conf->secondary_channel &&
361e5b75505Sopenharmony_ci				   conf->hw_mode != HOSTAPD_MODE_IEEE80211A) {
362e5b75505Sopenharmony_ci				/* This ended up trying to configure invalid
363e5b75505Sopenharmony_ci				 * 2.4 GHz channels (e.g., HT40+ on channel 11)
364e5b75505Sopenharmony_ci				 * in some cases, so clear the secondary channel
365e5b75505Sopenharmony_ci				 * configuration now to avoid such cases that
366e5b75505Sopenharmony_ci				 * would lead to group formation failures. */
367e5b75505Sopenharmony_ci				wpa_printf(MSG_DEBUG,
368e5b75505Sopenharmony_ci					   "Disable HT secondary channel for P2P group on 2.4 GHz");
369e5b75505Sopenharmony_ci				conf->secondary_channel = 0;
370e5b75505Sopenharmony_ci			}
371e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
372e5b75505Sopenharmony_ci
373e5b75505Sopenharmony_ci			if (!ssid->p2p_group &&
374e5b75505Sopenharmony_ci			    (mode->ht_capab &
375e5b75505Sopenharmony_ci			     HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET)) {
376e5b75505Sopenharmony_ci				conf->secondary_channel = ssid->ht40;
377e5b75505Sopenharmony_ci				wpa_printf(MSG_DEBUG,
378e5b75505Sopenharmony_ci					   "HT secondary channel offset %d for AP",
379e5b75505Sopenharmony_ci					   conf->secondary_channel);
380e5b75505Sopenharmony_ci			}
381e5b75505Sopenharmony_ci
382e5b75505Sopenharmony_ci			if (conf->secondary_channel)
383e5b75505Sopenharmony_ci				conf->ht_capab |=
384e5b75505Sopenharmony_ci					HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
385e5b75505Sopenharmony_ci
386e5b75505Sopenharmony_ci			/*
387e5b75505Sopenharmony_ci			 * white-list capabilities that won't cause issues
388e5b75505Sopenharmony_ci			 * to connecting stations, while leaving the current
389e5b75505Sopenharmony_ci			 * capabilities intact (currently disabled SMPS).
390e5b75505Sopenharmony_ci			 */
391e5b75505Sopenharmony_ci			conf->ht_capab |= mode->ht_capab &
392e5b75505Sopenharmony_ci				(HT_CAP_INFO_GREEN_FIELD |
393e5b75505Sopenharmony_ci				 HT_CAP_INFO_SHORT_GI20MHZ |
394e5b75505Sopenharmony_ci				 HT_CAP_INFO_SHORT_GI40MHZ |
395e5b75505Sopenharmony_ci				 HT_CAP_INFO_RX_STBC_MASK |
396e5b75505Sopenharmony_ci				 HT_CAP_INFO_TX_STBC |
397e5b75505Sopenharmony_ci				 HT_CAP_INFO_MAX_AMSDU_SIZE);
398e5b75505Sopenharmony_ci
399e5b75505Sopenharmony_ci			/* check this before VHT, because setting oper chan
400e5b75505Sopenharmony_ci			 * width and friends is the same call for HE and VHT
401e5b75505Sopenharmony_ci			 * and checks if conf->ieee8021ax == 1 */
402e5b75505Sopenharmony_ci			if (mode->he_capab[wpas_mode_to_ieee80211_mode(
403e5b75505Sopenharmony_ci					    ssid->mode)].he_supported &&
404e5b75505Sopenharmony_ci			    ssid->he)
405e5b75505Sopenharmony_ci				conf->ieee80211ax = 1;
406e5b75505Sopenharmony_ci
407e5b75505Sopenharmony_ci			if (mode->vht_capab && ssid->vht) {
408e5b75505Sopenharmony_ci				conf->ieee80211ac = 1;
409e5b75505Sopenharmony_ci				conf->vht_capab |= mode->vht_capab;
410e5b75505Sopenharmony_ci				wpas_conf_ap_vht(wpa_s, ssid, conf, mode);
411e5b75505Sopenharmony_ci			}
412e5b75505Sopenharmony_ci		}
413e5b75505Sopenharmony_ci	}
414e5b75505Sopenharmony_ci
415e5b75505Sopenharmony_ci	if (conf->secondary_channel) {
416e5b75505Sopenharmony_ci		struct wpa_supplicant *iface;
417e5b75505Sopenharmony_ci
418e5b75505Sopenharmony_ci		for (iface = wpa_s->global->ifaces; iface; iface = iface->next)
419e5b75505Sopenharmony_ci		{
420e5b75505Sopenharmony_ci			if (iface == wpa_s ||
421e5b75505Sopenharmony_ci			    iface->wpa_state < WPA_AUTHENTICATING ||
422e5b75505Sopenharmony_ci			    (int) iface->assoc_freq != ssid->frequency)
423e5b75505Sopenharmony_ci				continue;
424e5b75505Sopenharmony_ci
425e5b75505Sopenharmony_ci			/*
426e5b75505Sopenharmony_ci			 * Do not allow 40 MHz co-ex PRI/SEC switch to force us
427e5b75505Sopenharmony_ci			 * to change our PRI channel since we have an existing,
428e5b75505Sopenharmony_ci			 * concurrent connection on that channel and doing
429e5b75505Sopenharmony_ci			 * multi-channel concurrency is likely to cause more
430e5b75505Sopenharmony_ci			 * harm than using different PRI/SEC selection in
431e5b75505Sopenharmony_ci			 * environment with multiple BSSes on these two channels
432e5b75505Sopenharmony_ci			 * with mixed 20 MHz or PRI channel selection.
433e5b75505Sopenharmony_ci			 */
434e5b75505Sopenharmony_ci			conf->no_pri_sec_switch = 1;
435e5b75505Sopenharmony_ci		}
436e5b75505Sopenharmony_ci#ifdef CONFIG_OPEN_HARMONY_PATCH
437e5b75505Sopenharmony_ci		/*
438e5b75505Sopenharmony_ci		 * p2p GO may switch between primary and secondary channels
439e5b75505Sopenharmony_ci		 * when creating, causing the channel scanned by GC to be
440e5b75505Sopenharmony_ci		 * inconsistent with the final channel selected by GO and the
441e5b75505Sopenharmony_ci		 * connection time is too long. So turn off channel switching.
442e5b75505Sopenharmony_ci		 */
443e5b75505Sopenharmony_ci		if (ssid->p2p_group) {
444e5b75505Sopenharmony_ci                        conf->no_pri_sec_switch = 1;
445e5b75505Sopenharmony_ci		}
446e5b75505Sopenharmony_ci#endif
447e5b75505Sopenharmony_ci	}
448e5b75505Sopenharmony_ci
449e5b75505Sopenharmony_ci	return 0;
450e5b75505Sopenharmony_ci}
451e5b75505Sopenharmony_ci
452e5b75505Sopenharmony_ci
453e5b75505Sopenharmony_cistatic int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
454e5b75505Sopenharmony_ci				  struct wpa_ssid *ssid,
455e5b75505Sopenharmony_ci				  struct hostapd_config *conf)
456e5b75505Sopenharmony_ci{
457e5b75505Sopenharmony_ci	struct hostapd_bss_config *bss = conf->bss[0];
458e5b75505Sopenharmony_ci
459e5b75505Sopenharmony_ci	conf->driver = wpa_s->driver;
460e5b75505Sopenharmony_ci
461e5b75505Sopenharmony_ci	os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));
462e5b75505Sopenharmony_ci
463e5b75505Sopenharmony_ci	if (wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf))
464e5b75505Sopenharmony_ci		return -1;
465e5b75505Sopenharmony_ci
466e5b75505Sopenharmony_ci	if (ssid->pbss > 1) {
467e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "Invalid pbss value(%d) for AP mode",
468e5b75505Sopenharmony_ci			   ssid->pbss);
469e5b75505Sopenharmony_ci		return -1;
470e5b75505Sopenharmony_ci	}
471e5b75505Sopenharmony_ci	bss->pbss = ssid->pbss;
472e5b75505Sopenharmony_ci
473e5b75505Sopenharmony_ci#ifdef CONFIG_ACS
474e5b75505Sopenharmony_ci	if (ssid->acs) {
475e5b75505Sopenharmony_ci		/* Setting channel to 0 in order to enable ACS */
476e5b75505Sopenharmony_ci		conf->channel = 0;
477e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG, "Use automatic channel selection");
478e5b75505Sopenharmony_ci	}
479e5b75505Sopenharmony_ci#endif /* CONFIG_ACS */
480e5b75505Sopenharmony_ci
481e5b75505Sopenharmony_ci	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
482e5b75505Sopenharmony_ci			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
483e5b75505Sopenharmony_ci		conf->ieee80211h = 1;
484e5b75505Sopenharmony_ci		conf->ieee80211d = 1;
485e5b75505Sopenharmony_ci		conf->country[0] = wpa_s->conf->country[0];
486e5b75505Sopenharmony_ci		conf->country[1] = wpa_s->conf->country[1];
487e5b75505Sopenharmony_ci		conf->country[2] = ' ';
488e5b75505Sopenharmony_ci	}
489e5b75505Sopenharmony_ci
490e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
491e5b75505Sopenharmony_ci	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211G &&
492e5b75505Sopenharmony_ci	    (ssid->mode == WPAS_MODE_P2P_GO ||
493e5b75505Sopenharmony_ci	     ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)) {
494e5b75505Sopenharmony_ci		/* Remove 802.11b rates from supported and basic rate sets */
495e5b75505Sopenharmony_ci		int *list = os_malloc(4 * sizeof(int));
496e5b75505Sopenharmony_ci		if (list) {
497e5b75505Sopenharmony_ci			list[0] = 60;
498e5b75505Sopenharmony_ci			list[1] = 120;
499e5b75505Sopenharmony_ci			list[2] = 240;
500e5b75505Sopenharmony_ci			list[3] = -1;
501e5b75505Sopenharmony_ci		}
502e5b75505Sopenharmony_ci		conf->basic_rates = list;
503e5b75505Sopenharmony_ci
504e5b75505Sopenharmony_ci		list = os_malloc(9 * sizeof(int));
505e5b75505Sopenharmony_ci		if (list) {
506e5b75505Sopenharmony_ci			list[0] = 60;
507e5b75505Sopenharmony_ci			list[1] = 90;
508e5b75505Sopenharmony_ci			list[2] = 120;
509e5b75505Sopenharmony_ci			list[3] = 180;
510e5b75505Sopenharmony_ci			list[4] = 240;
511e5b75505Sopenharmony_ci			list[5] = 360;
512e5b75505Sopenharmony_ci			list[6] = 480;
513e5b75505Sopenharmony_ci			list[7] = 540;
514e5b75505Sopenharmony_ci			list[8] = -1;
515e5b75505Sopenharmony_ci		}
516e5b75505Sopenharmony_ci		conf->supported_rates = list;
517e5b75505Sopenharmony_ci	}
518e5b75505Sopenharmony_ci
519e5b75505Sopenharmony_ci#ifdef CONFIG_IEEE80211AX
520e5b75505Sopenharmony_ci	if (ssid->mode == WPAS_MODE_P2P_GO ||
521e5b75505Sopenharmony_ci	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
522e5b75505Sopenharmony_ci		conf->ieee80211ax = ssid->he;
523e5b75505Sopenharmony_ci#endif /* CONFIG_IEEE80211AX */
524e5b75505Sopenharmony_ci
525e5b75505Sopenharmony_ci	bss->isolate = !wpa_s->conf->p2p_intra_bss;
526e5b75505Sopenharmony_ci	bss->extended_key_id = wpa_s->conf->extended_key_id;
527e5b75505Sopenharmony_ci	bss->force_per_enrollee_psk = wpa_s->global->p2p_per_sta_psk;
528e5b75505Sopenharmony_ci	bss->wpa_deny_ptk0_rekey = ssid->wpa_deny_ptk0_rekey;
529e5b75505Sopenharmony_ci
530e5b75505Sopenharmony_ci	if (ssid->p2p_group) {
531e5b75505Sopenharmony_ci		os_memcpy(bss->ip_addr_go, wpa_s->p2pdev->conf->ip_addr_go, 4);
532e5b75505Sopenharmony_ci		os_memcpy(bss->ip_addr_mask, wpa_s->p2pdev->conf->ip_addr_mask,
533e5b75505Sopenharmony_ci			  4);
534e5b75505Sopenharmony_ci		os_memcpy(bss->ip_addr_start,
535e5b75505Sopenharmony_ci			  wpa_s->p2pdev->conf->ip_addr_start, 4);
536e5b75505Sopenharmony_ci		os_memcpy(bss->ip_addr_end, wpa_s->p2pdev->conf->ip_addr_end,
537e5b75505Sopenharmony_ci			  4);
538e5b75505Sopenharmony_ci	}
539e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
540e5b75505Sopenharmony_ci
541e5b75505Sopenharmony_ci	if (ssid->ssid_len == 0) {
542e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
543e5b75505Sopenharmony_ci		return -1;
544e5b75505Sopenharmony_ci	}
545e5b75505Sopenharmony_ci	os_memcpy(bss->ssid.ssid, ssid->ssid, ssid->ssid_len);
546e5b75505Sopenharmony_ci	bss->ssid.ssid_len = ssid->ssid_len;
547e5b75505Sopenharmony_ci	bss->ssid.ssid_set = 1;
548e5b75505Sopenharmony_ci
549e5b75505Sopenharmony_ci	bss->ignore_broadcast_ssid = ssid->ignore_broadcast_ssid;
550e5b75505Sopenharmony_ci
551e5b75505Sopenharmony_ci	if (ssid->auth_alg)
552e5b75505Sopenharmony_ci		bss->auth_algs = ssid->auth_alg;
553e5b75505Sopenharmony_ci
554e5b75505Sopenharmony_ci	if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt))
555e5b75505Sopenharmony_ci		bss->wpa = ssid->proto;
556e5b75505Sopenharmony_ci	if (ssid->key_mgmt == DEFAULT_KEY_MGMT)
557e5b75505Sopenharmony_ci		bss->wpa_key_mgmt = WPA_KEY_MGMT_PSK;
558e5b75505Sopenharmony_ci	else
559e5b75505Sopenharmony_ci		bss->wpa_key_mgmt = ssid->key_mgmt;
560e5b75505Sopenharmony_ci	bss->wpa_pairwise = ssid->pairwise_cipher;
561e5b75505Sopenharmony_ci	if (wpa_key_mgmt_sae(bss->wpa_key_mgmt) && ssid->passphrase) {
562e5b75505Sopenharmony_ci		bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
563e5b75505Sopenharmony_ci	} else if (ssid->psk_set) {
564e5b75505Sopenharmony_ci		bin_clear_free(bss->ssid.wpa_psk, sizeof(*bss->ssid.wpa_psk));
565e5b75505Sopenharmony_ci		bss->ssid.wpa_psk = os_zalloc(sizeof(struct hostapd_wpa_psk));
566e5b75505Sopenharmony_ci		if (bss->ssid.wpa_psk == NULL)
567e5b75505Sopenharmony_ci			return -1;
568e5b75505Sopenharmony_ci		os_memcpy(bss->ssid.wpa_psk->psk, ssid->psk, PMK_LEN);
569e5b75505Sopenharmony_ci		bss->ssid.wpa_psk->group = 1;
570e5b75505Sopenharmony_ci		bss->ssid.wpa_psk_set = 1;
571e5b75505Sopenharmony_ci	} else if (ssid->passphrase) {
572e5b75505Sopenharmony_ci		bss->ssid.wpa_passphrase = os_strdup(ssid->passphrase);
573e5b75505Sopenharmony_ci#ifdef CONFIG_WEP
574e5b75505Sopenharmony_ci	} else if (ssid->wep_key_len[0] || ssid->wep_key_len[1] ||
575e5b75505Sopenharmony_ci		   ssid->wep_key_len[2] || ssid->wep_key_len[3]) {
576e5b75505Sopenharmony_ci		struct hostapd_wep_keys *wep = &bss->ssid.wep;
577e5b75505Sopenharmony_ci		int i;
578e5b75505Sopenharmony_ci		for (i = 0; i < NUM_WEP_KEYS; i++) {
579e5b75505Sopenharmony_ci			if (ssid->wep_key_len[i] == 0)
580e5b75505Sopenharmony_ci				continue;
581e5b75505Sopenharmony_ci			wep->key[i] = os_memdup(ssid->wep_key[i],
582e5b75505Sopenharmony_ci						ssid->wep_key_len[i]);
583e5b75505Sopenharmony_ci			if (wep->key[i] == NULL)
584e5b75505Sopenharmony_ci				return -1;
585e5b75505Sopenharmony_ci			wep->len[i] = ssid->wep_key_len[i];
586e5b75505Sopenharmony_ci		}
587e5b75505Sopenharmony_ci		wep->idx = ssid->wep_tx_keyidx;
588e5b75505Sopenharmony_ci		wep->keys_set = 1;
589e5b75505Sopenharmony_ci#endif /* CONFIG_WEP */
590e5b75505Sopenharmony_ci	}
591e5b75505Sopenharmony_ci#ifdef CONFIG_SAE
592e5b75505Sopenharmony_ci	if (ssid->sae_password) {
593e5b75505Sopenharmony_ci		struct sae_password_entry *pw;
594e5b75505Sopenharmony_ci
595e5b75505Sopenharmony_ci		pw = os_zalloc(sizeof(*pw));
596e5b75505Sopenharmony_ci		if (!pw)
597e5b75505Sopenharmony_ci			return -1;
598e5b75505Sopenharmony_ci		os_memset(pw->peer_addr, 0xff, ETH_ALEN);
599e5b75505Sopenharmony_ci		pw->password = os_strdup(ssid->sae_password);
600e5b75505Sopenharmony_ci		if (!pw->password) {
601e5b75505Sopenharmony_ci			os_free(pw);
602e5b75505Sopenharmony_ci			return -1;
603e5b75505Sopenharmony_ci		}
604e5b75505Sopenharmony_ci		if (ssid->sae_password_id) {
605e5b75505Sopenharmony_ci			pw->identifier = os_strdup(ssid->sae_password_id);
606e5b75505Sopenharmony_ci			if (!pw->identifier) {
607e5b75505Sopenharmony_ci				str_clear_free(pw->password);
608e5b75505Sopenharmony_ci				os_free(pw);
609e5b75505Sopenharmony_ci				return -1;
610e5b75505Sopenharmony_ci			}
611e5b75505Sopenharmony_ci		}
612e5b75505Sopenharmony_ci
613e5b75505Sopenharmony_ci		pw->next = bss->sae_passwords;
614e5b75505Sopenharmony_ci		bss->sae_passwords = pw;
615e5b75505Sopenharmony_ci	}
616e5b75505Sopenharmony_ci
617e5b75505Sopenharmony_ci	if (ssid->sae_pwe != DEFAULT_SAE_PWE)
618e5b75505Sopenharmony_ci		bss->sae_pwe = ssid->sae_pwe;
619e5b75505Sopenharmony_ci	else
620e5b75505Sopenharmony_ci		bss->sae_pwe = wpa_s->conf->sae_pwe;
621e5b75505Sopenharmony_ci#endif /* CONFIG_SAE */
622e5b75505Sopenharmony_ci
623e5b75505Sopenharmony_ci	if (wpa_s->conf->go_interworking) {
624e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG,
625e5b75505Sopenharmony_ci			   "P2P: Enable Interworking with access_network_type: %d",
626e5b75505Sopenharmony_ci			   wpa_s->conf->go_access_network_type);
627e5b75505Sopenharmony_ci		bss->interworking = wpa_s->conf->go_interworking;
628e5b75505Sopenharmony_ci		bss->access_network_type = wpa_s->conf->go_access_network_type;
629e5b75505Sopenharmony_ci		bss->internet = wpa_s->conf->go_internet;
630e5b75505Sopenharmony_ci		if (wpa_s->conf->go_venue_group) {
631e5b75505Sopenharmony_ci			wpa_printf(MSG_DEBUG,
632e5b75505Sopenharmony_ci				   "P2P: Venue group: %d  Venue type: %d",
633e5b75505Sopenharmony_ci				   wpa_s->conf->go_venue_group,
634e5b75505Sopenharmony_ci				   wpa_s->conf->go_venue_type);
635e5b75505Sopenharmony_ci			bss->venue_group = wpa_s->conf->go_venue_group;
636e5b75505Sopenharmony_ci			bss->venue_type = wpa_s->conf->go_venue_type;
637e5b75505Sopenharmony_ci			bss->venue_info_set = 1;
638e5b75505Sopenharmony_ci		}
639e5b75505Sopenharmony_ci	}
640e5b75505Sopenharmony_ci
641e5b75505Sopenharmony_ci	if (ssid->ap_max_inactivity)
642e5b75505Sopenharmony_ci		bss->ap_max_inactivity = ssid->ap_max_inactivity;
643e5b75505Sopenharmony_ci
644e5b75505Sopenharmony_ci	if (ssid->dtim_period)
645e5b75505Sopenharmony_ci		bss->dtim_period = ssid->dtim_period;
646e5b75505Sopenharmony_ci	else if (wpa_s->conf->dtim_period)
647e5b75505Sopenharmony_ci		bss->dtim_period = wpa_s->conf->dtim_period;
648e5b75505Sopenharmony_ci
649e5b75505Sopenharmony_ci	if (ssid->beacon_int)
650e5b75505Sopenharmony_ci		conf->beacon_int = ssid->beacon_int;
651e5b75505Sopenharmony_ci	else if (wpa_s->conf->beacon_int)
652e5b75505Sopenharmony_ci		conf->beacon_int = wpa_s->conf->beacon_int;
653e5b75505Sopenharmony_ci
654e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
655e5b75505Sopenharmony_ci	if (ssid->mode == WPAS_MODE_P2P_GO ||
656e5b75505Sopenharmony_ci	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION) {
657e5b75505Sopenharmony_ci		if (wpa_s->conf->p2p_go_ctwindow > conf->beacon_int) {
658e5b75505Sopenharmony_ci			wpa_printf(MSG_INFO,
659e5b75505Sopenharmony_ci				   "CTWindow (%d) is bigger than beacon interval (%d) - avoid configuring it",
660e5b75505Sopenharmony_ci				   wpa_s->conf->p2p_go_ctwindow,
661e5b75505Sopenharmony_ci				   conf->beacon_int);
662e5b75505Sopenharmony_ci			conf->p2p_go_ctwindow = 0;
663e5b75505Sopenharmony_ci		} else {
664e5b75505Sopenharmony_ci			conf->p2p_go_ctwindow = wpa_s->conf->p2p_go_ctwindow;
665e5b75505Sopenharmony_ci		}
666e5b75505Sopenharmony_ci	}
667e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
668e5b75505Sopenharmony_ci
669e5b75505Sopenharmony_ci	if ((bss->wpa & 2) && bss->rsn_pairwise == 0)
670e5b75505Sopenharmony_ci		bss->rsn_pairwise = bss->wpa_pairwise;
671e5b75505Sopenharmony_ci	bss->wpa_group = wpa_select_ap_group_cipher(bss->wpa, bss->wpa_pairwise,
672e5b75505Sopenharmony_ci						    bss->rsn_pairwise);
673e5b75505Sopenharmony_ci
674e5b75505Sopenharmony_ci	if (bss->wpa && bss->ieee802_1x) {
675e5b75505Sopenharmony_ci		bss->ssid.security_policy = SECURITY_WPA;
676e5b75505Sopenharmony_ci	} else if (bss->wpa) {
677e5b75505Sopenharmony_ci		bss->ssid.security_policy = SECURITY_WPA_PSK;
678e5b75505Sopenharmony_ci#ifdef CONFIG_WEP
679e5b75505Sopenharmony_ci	} else if (bss->ieee802_1x) {
680e5b75505Sopenharmony_ci		int cipher = WPA_CIPHER_NONE;
681e5b75505Sopenharmony_ci		bss->ssid.security_policy = SECURITY_IEEE_802_1X;
682e5b75505Sopenharmony_ci		bss->ssid.wep.default_len = bss->default_wep_key_len;
683e5b75505Sopenharmony_ci		if (bss->default_wep_key_len)
684e5b75505Sopenharmony_ci			cipher = bss->default_wep_key_len >= 13 ?
685e5b75505Sopenharmony_ci				WPA_CIPHER_WEP104 : WPA_CIPHER_WEP40;
686e5b75505Sopenharmony_ci		bss->wpa_group = cipher;
687e5b75505Sopenharmony_ci		bss->wpa_pairwise = cipher;
688e5b75505Sopenharmony_ci		bss->rsn_pairwise = cipher;
689e5b75505Sopenharmony_ci	} else if (bss->ssid.wep.keys_set) {
690e5b75505Sopenharmony_ci		int cipher = WPA_CIPHER_WEP40;
691e5b75505Sopenharmony_ci		if (bss->ssid.wep.len[0] >= 13)
692e5b75505Sopenharmony_ci			cipher = WPA_CIPHER_WEP104;
693e5b75505Sopenharmony_ci		bss->ssid.security_policy = SECURITY_STATIC_WEP;
694e5b75505Sopenharmony_ci		bss->wpa_group = cipher;
695e5b75505Sopenharmony_ci		bss->wpa_pairwise = cipher;
696e5b75505Sopenharmony_ci		bss->rsn_pairwise = cipher;
697e5b75505Sopenharmony_ci#endif /* CONFIG_WEP */
698e5b75505Sopenharmony_ci	} else {
699e5b75505Sopenharmony_ci		bss->ssid.security_policy = SECURITY_PLAINTEXT;
700e5b75505Sopenharmony_ci		bss->wpa_group = WPA_CIPHER_NONE;
701e5b75505Sopenharmony_ci		bss->wpa_pairwise = WPA_CIPHER_NONE;
702e5b75505Sopenharmony_ci		bss->rsn_pairwise = WPA_CIPHER_NONE;
703e5b75505Sopenharmony_ci	}
704e5b75505Sopenharmony_ci
705e5b75505Sopenharmony_ci	if (bss->wpa_group_rekey < 86400 && (bss->wpa & 2) &&
706e5b75505Sopenharmony_ci	    (bss->wpa_group == WPA_CIPHER_CCMP ||
707e5b75505Sopenharmony_ci	     bss->wpa_group == WPA_CIPHER_GCMP ||
708e5b75505Sopenharmony_ci	     bss->wpa_group == WPA_CIPHER_CCMP_256 ||
709e5b75505Sopenharmony_ci	     bss->wpa_group == WPA_CIPHER_GCMP_256)) {
710e5b75505Sopenharmony_ci		/*
711e5b75505Sopenharmony_ci		 * Strong ciphers do not need frequent rekeying, so increase
712e5b75505Sopenharmony_ci		 * the default GTK rekeying period to 24 hours.
713e5b75505Sopenharmony_ci		 */
714e5b75505Sopenharmony_ci		bss->wpa_group_rekey = 86400;
715e5b75505Sopenharmony_ci	}
716e5b75505Sopenharmony_ci
717e5b75505Sopenharmony_ci	if (ssid->ieee80211w != MGMT_FRAME_PROTECTION_DEFAULT)
718e5b75505Sopenharmony_ci		bss->ieee80211w = ssid->ieee80211w;
719e5b75505Sopenharmony_ci
720e5b75505Sopenharmony_ci#ifdef CONFIG_OCV
721e5b75505Sopenharmony_ci	bss->ocv = ssid->ocv;
722e5b75505Sopenharmony_ci#endif /* CONFIG_OCV */
723e5b75505Sopenharmony_ci
724e5b75505Sopenharmony_ci#ifdef CONFIG_WPS
725e5b75505Sopenharmony_ci#ifdef CONFIG_WIFI_RPT
726e5b75505Sopenharmony_ci	if (wpa_s->global != NULL && wpa_s->global->p2p != NULL &&
727e5b75505Sopenharmony_ci		wpa_s->global->p2p->p2p_rpt == TRUE) {
728e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG, "wifi rpt mode not support wps");
729e5b75505Sopenharmony_ci		goto no_wps;
730e5b75505Sopenharmony_ci	}
731e5b75505Sopenharmony_ci#endif /* CONFIG_WIFI_RPT */
732e5b75505Sopenharmony_ci	/*
733e5b75505Sopenharmony_ci	 * Enable WPS by default for open and WPA/WPA2-Personal network, but
734e5b75505Sopenharmony_ci	 * require user interaction to actually use it. Only the internal
735e5b75505Sopenharmony_ci	 * Registrar is supported.
736e5b75505Sopenharmony_ci	 */
737e5b75505Sopenharmony_ci	if (bss->ssid.security_policy != SECURITY_WPA_PSK &&
738e5b75505Sopenharmony_ci	    bss->ssid.security_policy != SECURITY_PLAINTEXT)
739e5b75505Sopenharmony_ci		goto no_wps;
740e5b75505Sopenharmony_ci	if (bss->ssid.security_policy == SECURITY_WPA_PSK &&
741e5b75505Sopenharmony_ci	    (!(bss->rsn_pairwise & (WPA_CIPHER_CCMP | WPA_CIPHER_GCMP)) ||
742e5b75505Sopenharmony_ci	     !(bss->wpa & 2)))
743e5b75505Sopenharmony_ci		goto no_wps; /* WPS2 does not allow WPA/TKIP-only
744e5b75505Sopenharmony_ci			      * configuration */
745e5b75505Sopenharmony_ci	if (ssid->wps_disabled)
746e5b75505Sopenharmony_ci		goto no_wps;
747e5b75505Sopenharmony_ci	bss->eap_server = 1;
748e5b75505Sopenharmony_ci
749e5b75505Sopenharmony_ci	if (!ssid->ignore_broadcast_ssid)
750e5b75505Sopenharmony_ci		bss->wps_state = 2;
751e5b75505Sopenharmony_ci
752e5b75505Sopenharmony_ci	bss->ap_setup_locked = 2;
753e5b75505Sopenharmony_ci	if (wpa_s->conf->config_methods)
754e5b75505Sopenharmony_ci		bss->config_methods = os_strdup(wpa_s->conf->config_methods);
755e5b75505Sopenharmony_ci	os_memcpy(bss->device_type, wpa_s->conf->device_type,
756e5b75505Sopenharmony_ci		  WPS_DEV_TYPE_LEN);
757e5b75505Sopenharmony_ci	if (wpa_s->conf->device_name) {
758e5b75505Sopenharmony_ci		bss->device_name = os_strdup(wpa_s->conf->device_name);
759e5b75505Sopenharmony_ci		bss->friendly_name = os_strdup(wpa_s->conf->device_name);
760e5b75505Sopenharmony_ci	}
761e5b75505Sopenharmony_ci	if (wpa_s->conf->manufacturer)
762e5b75505Sopenharmony_ci		bss->manufacturer = os_strdup(wpa_s->conf->manufacturer);
763e5b75505Sopenharmony_ci	if (wpa_s->conf->model_name)
764e5b75505Sopenharmony_ci		bss->model_name = os_strdup(wpa_s->conf->model_name);
765e5b75505Sopenharmony_ci	if (wpa_s->conf->model_number)
766e5b75505Sopenharmony_ci		bss->model_number = os_strdup(wpa_s->conf->model_number);
767e5b75505Sopenharmony_ci	if (wpa_s->conf->serial_number)
768e5b75505Sopenharmony_ci		bss->serial_number = os_strdup(wpa_s->conf->serial_number);
769e5b75505Sopenharmony_ci	if (is_nil_uuid(wpa_s->conf->uuid))
770e5b75505Sopenharmony_ci		os_memcpy(bss->uuid, wpa_s->wps->uuid, WPS_UUID_LEN);
771e5b75505Sopenharmony_ci	else
772e5b75505Sopenharmony_ci		os_memcpy(bss->uuid, wpa_s->conf->uuid, WPS_UUID_LEN);
773e5b75505Sopenharmony_ci	os_memcpy(bss->os_version, wpa_s->conf->os_version, 4);
774e5b75505Sopenharmony_ci	bss->pbc_in_m1 = wpa_s->conf->pbc_in_m1;
775e5b75505Sopenharmony_ci	if (ssid->eap.fragment_size != DEFAULT_FRAGMENT_SIZE)
776e5b75505Sopenharmony_ci		bss->fragment_size = ssid->eap.fragment_size;
777e5b75505Sopenharmony_cino_wps:
778e5b75505Sopenharmony_ci#endif /* CONFIG_WPS */
779e5b75505Sopenharmony_ci
780e5b75505Sopenharmony_ci	if (wpa_s->max_stations &&
781e5b75505Sopenharmony_ci	    wpa_s->max_stations < wpa_s->conf->max_num_sta)
782e5b75505Sopenharmony_ci		bss->max_num_sta = wpa_s->max_stations;
783e5b75505Sopenharmony_ci	else
784e5b75505Sopenharmony_ci		bss->max_num_sta = wpa_s->conf->max_num_sta;
785e5b75505Sopenharmony_ci
786e5b75505Sopenharmony_ci	if (!bss->isolate)
787e5b75505Sopenharmony_ci		bss->isolate = wpa_s->conf->ap_isolate;
788e5b75505Sopenharmony_ci
789e5b75505Sopenharmony_ci	bss->disassoc_low_ack = wpa_s->conf->disassoc_low_ack;
790e5b75505Sopenharmony_ci
791e5b75505Sopenharmony_ci	if (wpa_s->conf->ap_vendor_elements) {
792e5b75505Sopenharmony_ci		bss->vendor_elements =
793e5b75505Sopenharmony_ci			wpabuf_dup(wpa_s->conf->ap_vendor_elements);
794e5b75505Sopenharmony_ci	}
795e5b75505Sopenharmony_ci	if (wpa_s->conf->ap_assocresp_elements) {
796e5b75505Sopenharmony_ci		bss->assocresp_elements =
797e5b75505Sopenharmony_ci			wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
798e5b75505Sopenharmony_ci	}
799e5b75505Sopenharmony_ci
800e5b75505Sopenharmony_ci	bss->ftm_responder = wpa_s->conf->ftm_responder;
801e5b75505Sopenharmony_ci	bss->ftm_initiator = wpa_s->conf->ftm_initiator;
802e5b75505Sopenharmony_ci
803e5b75505Sopenharmony_ci	bss->transition_disable = ssid->transition_disable;
804e5b75505Sopenharmony_ci
805e5b75505Sopenharmony_ci	return 0;
806e5b75505Sopenharmony_ci}
807e5b75505Sopenharmony_ci
808e5b75505Sopenharmony_ci
809e5b75505Sopenharmony_cistatic void ap_public_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
810e5b75505Sopenharmony_ci{
811e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
812e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
813e5b75505Sopenharmony_ci	const struct ieee80211_mgmt *mgmt;
814e5b75505Sopenharmony_ci
815e5b75505Sopenharmony_ci	mgmt = (const struct ieee80211_mgmt *) buf;
816e5b75505Sopenharmony_ci	if (len < IEEE80211_HDRLEN + 1)
817e5b75505Sopenharmony_ci		return;
818e5b75505Sopenharmony_ci	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
819e5b75505Sopenharmony_ci		return;
820e5b75505Sopenharmony_ci	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
821e5b75505Sopenharmony_ci			   mgmt->u.action.category,
822e5b75505Sopenharmony_ci			   buf + IEEE80211_HDRLEN + 1,
823e5b75505Sopenharmony_ci			   len - IEEE80211_HDRLEN - 1, freq);
824e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
825e5b75505Sopenharmony_ci}
826e5b75505Sopenharmony_ci
827e5b75505Sopenharmony_ci
828e5b75505Sopenharmony_cistatic void ap_wps_event_cb(void *ctx, enum wps_event event,
829e5b75505Sopenharmony_ci			    union wps_event_data *data)
830e5b75505Sopenharmony_ci{
831e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
832e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
833e5b75505Sopenharmony_ci
834e5b75505Sopenharmony_ci	if (event == WPS_EV_FAIL) {
835e5b75505Sopenharmony_ci		struct wps_event_fail *fail = &data->fail;
836e5b75505Sopenharmony_ci
837e5b75505Sopenharmony_ci		if (wpa_s->p2pdev && wpa_s->p2pdev != wpa_s &&
838e5b75505Sopenharmony_ci		    wpa_s == wpa_s->global->p2p_group_formation) {
839e5b75505Sopenharmony_ci			/*
840e5b75505Sopenharmony_ci			 * src/ap/wps_hostapd.c has already sent this on the
841e5b75505Sopenharmony_ci			 * main interface, so only send on the parent interface
842e5b75505Sopenharmony_ci			 * here if needed.
843e5b75505Sopenharmony_ci			 */
844e5b75505Sopenharmony_ci			wpa_msg(wpa_s->p2pdev, MSG_INFO, WPS_EVENT_FAIL
845e5b75505Sopenharmony_ci				"msg=%d config_error=%d",
846e5b75505Sopenharmony_ci				fail->msg, fail->config_error);
847e5b75505Sopenharmony_ci		}
848e5b75505Sopenharmony_ci		wpas_p2p_wps_failed(wpa_s, fail);
849e5b75505Sopenharmony_ci	}
850e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
851e5b75505Sopenharmony_ci}
852e5b75505Sopenharmony_ci
853e5b75505Sopenharmony_ci
854e5b75505Sopenharmony_cistatic void ap_sta_authorized_cb(void *ctx, const u8 *mac_addr,
855e5b75505Sopenharmony_ci				 int authorized, const u8 *p2p_dev_addr)
856e5b75505Sopenharmony_ci{
857e5b75505Sopenharmony_ci	wpas_notify_sta_authorized(ctx, mac_addr, authorized, p2p_dev_addr);
858e5b75505Sopenharmony_ci}
859e5b75505Sopenharmony_ci
860e5b75505Sopenharmony_ci
861e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
862e5b75505Sopenharmony_cistatic void ap_new_psk_cb(void *ctx, const u8 *mac_addr, const u8 *p2p_dev_addr,
863e5b75505Sopenharmony_ci			  const u8 *psk, size_t psk_len)
864e5b75505Sopenharmony_ci{
865e5b75505Sopenharmony_ci
866e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
867e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL || wpa_s->current_ssid == NULL)
868e5b75505Sopenharmony_ci		return;
869e5b75505Sopenharmony_ci	wpas_p2p_new_psk_cb(wpa_s, mac_addr, p2p_dev_addr, psk, psk_len);
870e5b75505Sopenharmony_ci}
871e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
872e5b75505Sopenharmony_ci
873e5b75505Sopenharmony_ci
874e5b75505Sopenharmony_cistatic int ap_vendor_action_rx(void *ctx, const u8 *buf, size_t len, int freq)
875e5b75505Sopenharmony_ci{
876e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
877e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
878e5b75505Sopenharmony_ci	const struct ieee80211_mgmt *mgmt;
879e5b75505Sopenharmony_ci
880e5b75505Sopenharmony_ci	mgmt = (const struct ieee80211_mgmt *) buf;
881e5b75505Sopenharmony_ci	if (len < IEEE80211_HDRLEN + 1)
882e5b75505Sopenharmony_ci		return -1;
883e5b75505Sopenharmony_ci	wpas_p2p_rx_action(wpa_s, mgmt->da, mgmt->sa, mgmt->bssid,
884e5b75505Sopenharmony_ci			   mgmt->u.action.category,
885e5b75505Sopenharmony_ci			   buf + IEEE80211_HDRLEN + 1,
886e5b75505Sopenharmony_ci			   len - IEEE80211_HDRLEN - 1, freq);
887e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
888e5b75505Sopenharmony_ci	return 0;
889e5b75505Sopenharmony_ci}
890e5b75505Sopenharmony_ci
891e5b75505Sopenharmony_ci
892e5b75505Sopenharmony_cistatic int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da,
893e5b75505Sopenharmony_ci			   const u8 *bssid, const u8 *ie, size_t ie_len,
894e5b75505Sopenharmony_ci			   int ssi_signal)
895e5b75505Sopenharmony_ci{
896e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
897e5b75505Sopenharmony_ci	unsigned int freq = 0;
898e5b75505Sopenharmony_ci
899e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
900e5b75505Sopenharmony_ci		freq = wpa_s->ap_iface->freq;
901e5b75505Sopenharmony_ci
902e5b75505Sopenharmony_ci	return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len,
903e5b75505Sopenharmony_ci				     freq, ssi_signal);
904e5b75505Sopenharmony_ci}
905e5b75505Sopenharmony_ci
906e5b75505Sopenharmony_ci
907e5b75505Sopenharmony_cistatic void ap_wps_reg_success_cb(void *ctx, const u8 *mac_addr,
908e5b75505Sopenharmony_ci				  const u8 *uuid_e)
909e5b75505Sopenharmony_ci{
910e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
911e5b75505Sopenharmony_ci	wpas_p2p_wps_success(wpa_s, mac_addr, 1);
912e5b75505Sopenharmony_ci}
913e5b75505Sopenharmony_ci
914e5b75505Sopenharmony_ci
915e5b75505Sopenharmony_cistatic void wpas_ap_configured_cb(void *ctx)
916e5b75505Sopenharmony_ci{
917e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
918e5b75505Sopenharmony_ci
919e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "AP interface setup completed - state %s",
920e5b75505Sopenharmony_ci		   hostapd_state_text(wpa_s->ap_iface->state));
921e5b75505Sopenharmony_ci	if (wpa_s->ap_iface->state == HAPD_IFACE_DISABLED) {
922e5b75505Sopenharmony_ci		wpa_supplicant_ap_deinit(wpa_s);
923e5b75505Sopenharmony_ci		return;
924e5b75505Sopenharmony_ci	}
925e5b75505Sopenharmony_ci
926e5b75505Sopenharmony_ci#ifdef CONFIG_ACS
927e5b75505Sopenharmony_ci	if (wpa_s->current_ssid && wpa_s->current_ssid->acs) {
928e5b75505Sopenharmony_ci		wpa_s->assoc_freq = wpa_s->ap_iface->freq;
929e5b75505Sopenharmony_ci		wpa_s->current_ssid->frequency = wpa_s->ap_iface->freq;
930e5b75505Sopenharmony_ci	}
931e5b75505Sopenharmony_ci#endif /* CONFIG_ACS */
932e5b75505Sopenharmony_ci
933e5b75505Sopenharmony_ci	wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
934e5b75505Sopenharmony_ci
935e5b75505Sopenharmony_ci	if (wpa_s->ap_configured_cb)
936e5b75505Sopenharmony_ci		wpa_s->ap_configured_cb(wpa_s->ap_configured_cb_ctx,
937e5b75505Sopenharmony_ci					wpa_s->ap_configured_cb_data);
938e5b75505Sopenharmony_ci}
939e5b75505Sopenharmony_ci
940e5b75505Sopenharmony_ci
941e5b75505Sopenharmony_ciint wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
942e5b75505Sopenharmony_ci			     struct wpa_ssid *ssid)
943e5b75505Sopenharmony_ci{
944e5b75505Sopenharmony_ci	struct wpa_driver_associate_params params;
945e5b75505Sopenharmony_ci	struct hostapd_iface *hapd_iface;
946e5b75505Sopenharmony_ci	struct hostapd_config *conf;
947e5b75505Sopenharmony_ci	size_t i;
948e5b75505Sopenharmony_ci
949e5b75505Sopenharmony_ci	if (ssid->ssid == NULL || ssid->ssid_len == 0) {
950e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "No SSID configured for AP mode");
951e5b75505Sopenharmony_ci		return -1;
952e5b75505Sopenharmony_ci	}
953e5b75505Sopenharmony_ci
954e5b75505Sopenharmony_ci	wpa_supplicant_ap_deinit(wpa_s);
955e5b75505Sopenharmony_ci
956e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "Setting up AP (SSID='%s')",
957e5b75505Sopenharmony_ci		   anonymize_ssid(wpa_ssid_txt(ssid->ssid, ssid->ssid_len)));
958e5b75505Sopenharmony_ci
959e5b75505Sopenharmony_ci	os_memset(&params, 0, sizeof(params));
960e5b75505Sopenharmony_ci	params.ssid = ssid->ssid;
961e5b75505Sopenharmony_ci	params.ssid_len = ssid->ssid_len;
962e5b75505Sopenharmony_ci	switch (ssid->mode) {
963e5b75505Sopenharmony_ci	case WPAS_MODE_AP:
964e5b75505Sopenharmony_ci	case WPAS_MODE_P2P_GO:
965e5b75505Sopenharmony_ci	case WPAS_MODE_P2P_GROUP_FORMATION:
966e5b75505Sopenharmony_ci		params.mode = IEEE80211_MODE_AP;
967e5b75505Sopenharmony_ci		break;
968e5b75505Sopenharmony_ci	default:
969e5b75505Sopenharmony_ci		return -1;
970e5b75505Sopenharmony_ci	}
971e5b75505Sopenharmony_ci	if (ssid->frequency == 0)
972e5b75505Sopenharmony_ci		ssid->frequency = 2462; /* default channel 11 */
973e5b75505Sopenharmony_ci	params.freq.freq = ssid->frequency;
974e5b75505Sopenharmony_ci
975e5b75505Sopenharmony_ci	if ((ssid->mode == WPAS_MODE_AP || ssid->mode == WPAS_MODE_P2P_GO) &&
976e5b75505Sopenharmony_ci	    ssid->enable_edmg) {
977e5b75505Sopenharmony_ci		u8 primary_channel;
978e5b75505Sopenharmony_ci
979e5b75505Sopenharmony_ci		if (ieee80211_freq_to_chan(ssid->frequency, &primary_channel) ==
980e5b75505Sopenharmony_ci		    NUM_HOSTAPD_MODES) {
981e5b75505Sopenharmony_ci			wpa_printf(MSG_WARNING,
982e5b75505Sopenharmony_ci				   "EDMG: Failed to get the primary channel");
983e5b75505Sopenharmony_ci			return -1;
984e5b75505Sopenharmony_ci		}
985e5b75505Sopenharmony_ci
986e5b75505Sopenharmony_ci		hostapd_encode_edmg_chan(ssid->enable_edmg, ssid->edmg_channel,
987e5b75505Sopenharmony_ci					 primary_channel, &params.freq.edmg);
988e5b75505Sopenharmony_ci	}
989e5b75505Sopenharmony_ci
990e5b75505Sopenharmony_ci	params.wpa_proto = ssid->proto;
991e5b75505Sopenharmony_ci	if (ssid->key_mgmt & WPA_KEY_MGMT_PSK)
992e5b75505Sopenharmony_ci		wpa_s->key_mgmt = WPA_KEY_MGMT_PSK;
993e5b75505Sopenharmony_ci	else if (ssid->key_mgmt & WPA_KEY_MGMT_SAE)
994e5b75505Sopenharmony_ci		wpa_s->key_mgmt = WPA_KEY_MGMT_SAE;
995e5b75505Sopenharmony_ci	else
996e5b75505Sopenharmony_ci		wpa_s->key_mgmt = WPA_KEY_MGMT_NONE;
997e5b75505Sopenharmony_ci	params.key_mgmt_suite = wpa_s->key_mgmt;
998e5b75505Sopenharmony_ci
999e5b75505Sopenharmony_ci	wpa_s->pairwise_cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher,
1000e5b75505Sopenharmony_ci							  1);
1001e5b75505Sopenharmony_ci	if (wpa_s->pairwise_cipher < 0) {
1002e5b75505Sopenharmony_ci		wpa_printf(MSG_WARNING, "WPA: Failed to select pairwise "
1003e5b75505Sopenharmony_ci			   "cipher.");
1004e5b75505Sopenharmony_ci		return -1;
1005e5b75505Sopenharmony_ci	}
1006e5b75505Sopenharmony_ci	params.pairwise_suite = wpa_s->pairwise_cipher;
1007e5b75505Sopenharmony_ci	params.group_suite = params.pairwise_suite;
1008e5b75505Sopenharmony_ci
1009e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
1010e5b75505Sopenharmony_ci	if (ssid->mode == WPAS_MODE_P2P_GO ||
1011e5b75505Sopenharmony_ci	    ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1012e5b75505Sopenharmony_ci		params.p2p = 1;
1013e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
1014e5b75505Sopenharmony_ci
1015e5b75505Sopenharmony_ci	if (wpa_s->p2pdev->set_ap_uapsd)
1016e5b75505Sopenharmony_ci		params.uapsd = wpa_s->p2pdev->ap_uapsd;
1017e5b75505Sopenharmony_ci	else if (params.p2p && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_UAPSD))
1018e5b75505Sopenharmony_ci		params.uapsd = 1; /* mandatory for P2P GO */
1019e5b75505Sopenharmony_ci	else
1020e5b75505Sopenharmony_ci		params.uapsd = -1;
1021e5b75505Sopenharmony_ci
1022e5b75505Sopenharmony_ci	if (ieee80211_is_dfs(params.freq.freq, wpa_s->hw.modes,
1023e5b75505Sopenharmony_ci			     wpa_s->hw.num_modes))
1024e5b75505Sopenharmony_ci		params.freq.freq = 0; /* set channel after CAC */
1025e5b75505Sopenharmony_ci
1026e5b75505Sopenharmony_ci	if (params.p2p)
1027e5b75505Sopenharmony_ci		wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_GO);
1028e5b75505Sopenharmony_ci	else
1029e5b75505Sopenharmony_ci		wpa_drv_get_ext_capa(wpa_s, WPA_IF_AP_BSS);
1030e5b75505Sopenharmony_ci
1031e5b75505Sopenharmony_ci	if (wpa_drv_associate(wpa_s, &params) < 0) {
1032e5b75505Sopenharmony_ci		wpa_msg(wpa_s, MSG_INFO, "Failed to start AP functionality");
1033e5b75505Sopenharmony_ci		return -1;
1034e5b75505Sopenharmony_ci	}
1035e5b75505Sopenharmony_ci
1036e5b75505Sopenharmony_ci	wpa_s->ap_iface = hapd_iface = hostapd_alloc_iface();
1037e5b75505Sopenharmony_ci	if (hapd_iface == NULL)
1038e5b75505Sopenharmony_ci		return -1;
1039e5b75505Sopenharmony_ci	hapd_iface->owner = wpa_s;
1040e5b75505Sopenharmony_ci	hapd_iface->drv_flags = wpa_s->drv_flags;
1041e5b75505Sopenharmony_ci	hapd_iface->probe_resp_offloads = wpa_s->probe_resp_offloads;
1042e5b75505Sopenharmony_ci	hapd_iface->extended_capa = wpa_s->extended_capa;
1043e5b75505Sopenharmony_ci	hapd_iface->extended_capa_mask = wpa_s->extended_capa_mask;
1044e5b75505Sopenharmony_ci	hapd_iface->extended_capa_len = wpa_s->extended_capa_len;
1045e5b75505Sopenharmony_ci
1046e5b75505Sopenharmony_ci	wpa_s->ap_iface->conf = conf = hostapd_config_defaults();
1047e5b75505Sopenharmony_ci	if (conf == NULL) {
1048e5b75505Sopenharmony_ci		wpa_supplicant_ap_deinit(wpa_s);
1049e5b75505Sopenharmony_ci		return -1;
1050e5b75505Sopenharmony_ci	}
1051e5b75505Sopenharmony_ci
1052e5b75505Sopenharmony_ci	os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
1053e5b75505Sopenharmony_ci		  wpa_s->conf->wmm_ac_params,
1054e5b75505Sopenharmony_ci		  sizeof(wpa_s->conf->wmm_ac_params));
1055e5b75505Sopenharmony_ci
1056e5b75505Sopenharmony_ci	os_memcpy(wpa_s->ap_iface->conf->tx_queue, wpa_s->conf->tx_queue,
1057e5b75505Sopenharmony_ci		  sizeof(wpa_s->conf->tx_queue));
1058e5b75505Sopenharmony_ci
1059e5b75505Sopenharmony_ci	if (params.uapsd > 0) {
1060e5b75505Sopenharmony_ci		conf->bss[0]->wmm_enabled = 1;
1061e5b75505Sopenharmony_ci		conf->bss[0]->wmm_uapsd = 1;
1062e5b75505Sopenharmony_ci	}
1063e5b75505Sopenharmony_ci
1064e5b75505Sopenharmony_ci	if (wpa_supplicant_conf_ap(wpa_s, ssid, conf)) {
1065e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "Failed to create AP configuration");
1066e5b75505Sopenharmony_ci		wpa_supplicant_ap_deinit(wpa_s);
1067e5b75505Sopenharmony_ci		return -1;
1068e5b75505Sopenharmony_ci	}
1069e5b75505Sopenharmony_ci
1070e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
1071e5b75505Sopenharmony_ci	if (ssid->mode == WPAS_MODE_P2P_GO)
1072e5b75505Sopenharmony_ci		conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
1073e5b75505Sopenharmony_ci	else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1074e5b75505Sopenharmony_ci		conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
1075e5b75505Sopenharmony_ci			P2P_GROUP_FORMATION;
1076e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
1077e5b75505Sopenharmony_ci
1078e5b75505Sopenharmony_ci	hapd_iface->num_bss = conf->num_bss;
1079e5b75505Sopenharmony_ci	hapd_iface->bss = os_calloc(conf->num_bss,
1080e5b75505Sopenharmony_ci				    sizeof(struct hostapd_data *));
1081e5b75505Sopenharmony_ci	if (hapd_iface->bss == NULL) {
1082e5b75505Sopenharmony_ci		wpa_supplicant_ap_deinit(wpa_s);
1083e5b75505Sopenharmony_ci		return -1;
1084e5b75505Sopenharmony_ci	}
1085e5b75505Sopenharmony_ci
1086e5b75505Sopenharmony_ci	for (i = 0; i < conf->num_bss; i++) {
1087e5b75505Sopenharmony_ci		hapd_iface->bss[i] =
1088e5b75505Sopenharmony_ci			hostapd_alloc_bss_data(hapd_iface, conf,
1089e5b75505Sopenharmony_ci					       conf->bss[i]);
1090e5b75505Sopenharmony_ci		if (hapd_iface->bss[i] == NULL) {
1091e5b75505Sopenharmony_ci			wpa_supplicant_ap_deinit(wpa_s);
1092e5b75505Sopenharmony_ci			return -1;
1093e5b75505Sopenharmony_ci		}
1094e5b75505Sopenharmony_ci
1095e5b75505Sopenharmony_ci		hapd_iface->bss[i]->msg_ctx = wpa_s;
1096e5b75505Sopenharmony_ci		hapd_iface->bss[i]->msg_ctx_parent = wpa_s->p2pdev;
1097e5b75505Sopenharmony_ci		hapd_iface->bss[i]->public_action_cb = ap_public_action_rx;
1098e5b75505Sopenharmony_ci		hapd_iface->bss[i]->public_action_cb_ctx = wpa_s;
1099e5b75505Sopenharmony_ci		hapd_iface->bss[i]->vendor_action_cb = ap_vendor_action_rx;
1100e5b75505Sopenharmony_ci		hapd_iface->bss[i]->vendor_action_cb_ctx = wpa_s;
1101e5b75505Sopenharmony_ci		hostapd_register_probereq_cb(hapd_iface->bss[i],
1102e5b75505Sopenharmony_ci					     ap_probe_req_rx, wpa_s);
1103e5b75505Sopenharmony_ci		hapd_iface->bss[i]->wps_reg_success_cb = ap_wps_reg_success_cb;
1104e5b75505Sopenharmony_ci		hapd_iface->bss[i]->wps_reg_success_cb_ctx = wpa_s;
1105e5b75505Sopenharmony_ci		hapd_iface->bss[i]->wps_event_cb = ap_wps_event_cb;
1106e5b75505Sopenharmony_ci		hapd_iface->bss[i]->wps_event_cb_ctx = wpa_s;
1107e5b75505Sopenharmony_ci		hapd_iface->bss[i]->sta_authorized_cb = ap_sta_authorized_cb;
1108e5b75505Sopenharmony_ci		hapd_iface->bss[i]->sta_authorized_cb_ctx = wpa_s;
1109e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
1110e5b75505Sopenharmony_ci		hapd_iface->bss[i]->new_psk_cb = ap_new_psk_cb;
1111e5b75505Sopenharmony_ci		hapd_iface->bss[i]->new_psk_cb_ctx = wpa_s;
1112e5b75505Sopenharmony_ci		hapd_iface->bss[i]->p2p = wpa_s->global->p2p;
1113e5b75505Sopenharmony_ci		hapd_iface->bss[i]->p2p_group = wpas_p2p_group_init(wpa_s,
1114e5b75505Sopenharmony_ci								    ssid);
1115e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
1116e5b75505Sopenharmony_ci		hapd_iface->bss[i]->setup_complete_cb = wpas_ap_configured_cb;
1117e5b75505Sopenharmony_ci		hapd_iface->bss[i]->setup_complete_cb_ctx = wpa_s;
1118e5b75505Sopenharmony_ci#ifdef CONFIG_TESTING_OPTIONS
1119e5b75505Sopenharmony_ci		hapd_iface->bss[i]->ext_eapol_frame_io =
1120e5b75505Sopenharmony_ci			wpa_s->ext_eapol_frame_io;
1121e5b75505Sopenharmony_ci#endif /* CONFIG_TESTING_OPTIONS */
1122e5b75505Sopenharmony_ci	}
1123e5b75505Sopenharmony_ci
1124e5b75505Sopenharmony_ci	os_memcpy(hapd_iface->bss[0]->own_addr, wpa_s->own_addr, ETH_ALEN);
1125e5b75505Sopenharmony_ci	hapd_iface->bss[0]->driver = wpa_s->driver;
1126e5b75505Sopenharmony_ci	hapd_iface->bss[0]->drv_priv = wpa_s->drv_priv;
1127e5b75505Sopenharmony_ci
1128e5b75505Sopenharmony_ci	wpa_s->current_ssid = ssid;
1129e5b75505Sopenharmony_ci	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1130e5b75505Sopenharmony_ci	os_memcpy(wpa_s->bssid, wpa_s->own_addr, ETH_ALEN);
1131e5b75505Sopenharmony_ci	wpa_s->assoc_freq = ssid->frequency;
1132e5b75505Sopenharmony_ci	wpa_s->ap_iface->conf->enable_edmg = ssid->enable_edmg;
1133e5b75505Sopenharmony_ci	wpa_s->ap_iface->conf->edmg_channel = ssid->edmg_channel;
1134e5b75505Sopenharmony_ci
1135e5b75505Sopenharmony_ci#if defined(CONFIG_P2P) && defined(CONFIG_ACS)
1136e5b75505Sopenharmony_ci	if (wpa_s->p2p_go_do_acs) {
1137e5b75505Sopenharmony_ci		wpa_s->ap_iface->conf->channel = 0;
1138e5b75505Sopenharmony_ci		wpa_s->ap_iface->conf->hw_mode = wpa_s->p2p_go_acs_band;
1139e5b75505Sopenharmony_ci		ssid->acs = 1;
1140e5b75505Sopenharmony_ci	}
1141e5b75505Sopenharmony_ci#endif /* CONFIG_P2P && CONFIG_ACS */
1142e5b75505Sopenharmony_ci
1143e5b75505Sopenharmony_ci	if (hostapd_setup_interface(wpa_s->ap_iface)) {
1144e5b75505Sopenharmony_ci		wpa_printf(MSG_ERROR, "Failed to initialize AP interface");
1145e5b75505Sopenharmony_ci		wpa_supplicant_ap_deinit(wpa_s);
1146e5b75505Sopenharmony_ci		return -1;
1147e5b75505Sopenharmony_ci	}
1148e5b75505Sopenharmony_ci
1149e5b75505Sopenharmony_ci	return 0;
1150e5b75505Sopenharmony_ci}
1151e5b75505Sopenharmony_ci
1152e5b75505Sopenharmony_ci
1153e5b75505Sopenharmony_civoid wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s)
1154e5b75505Sopenharmony_ci{
1155e5b75505Sopenharmony_ci#ifdef CONFIG_WPS
1156e5b75505Sopenharmony_ci	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
1157e5b75505Sopenharmony_ci#endif /* CONFIG_WPS */
1158e5b75505Sopenharmony_ci
1159e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1160e5b75505Sopenharmony_ci		return;
1161e5b75505Sopenharmony_ci
1162e5b75505Sopenharmony_ci	wpa_s->current_ssid = NULL;
1163e5b75505Sopenharmony_ci	eapol_sm_notify_config(wpa_s->eapol, NULL, NULL);
1164e5b75505Sopenharmony_ci	wpa_s->assoc_freq = 0;
1165e5b75505Sopenharmony_ci#ifdef CONFIG_WAPI
1166e5b75505Sopenharmony_ci	wpa_s->ap_wapi_ie_len = 0;
1167e5b75505Sopenharmony_ci#endif
1168e5b75505Sopenharmony_ci	wpas_p2p_ap_deinit(wpa_s);
1169e5b75505Sopenharmony_ci	wpa_s->ap_iface->driver_ap_teardown =
1170e5b75505Sopenharmony_ci		!!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_AP_TEARDOWN_SUPPORT);
1171e5b75505Sopenharmony_ci
1172e5b75505Sopenharmony_ci	hostapd_interface_deinit(wpa_s->ap_iface);
1173e5b75505Sopenharmony_ci	hostapd_interface_free(wpa_s->ap_iface);
1174e5b75505Sopenharmony_ci	wpa_s->ap_iface = NULL;
1175e5b75505Sopenharmony_ci	wpa_drv_deinit_ap(wpa_s);
1176e5b75505Sopenharmony_ci	wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid=" MACSTR
1177e5b75505Sopenharmony_ci		" reason=%d locally_generated=1",
1178e5b75505Sopenharmony_ci		MAC2STR(wpa_s->own_addr), WLAN_REASON_DEAUTH_LEAVING);
1179e5b75505Sopenharmony_ci}
1180e5b75505Sopenharmony_ci
1181e5b75505Sopenharmony_ci
1182e5b75505Sopenharmony_civoid ap_tx_status(void *ctx, const u8 *addr,
1183e5b75505Sopenharmony_ci		  const u8 *buf, size_t len, int ack)
1184e5b75505Sopenharmony_ci{
1185e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1186e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1187e5b75505Sopenharmony_ci	hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack);
1188e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1189e5b75505Sopenharmony_ci}
1190e5b75505Sopenharmony_ci
1191e5b75505Sopenharmony_ci
1192e5b75505Sopenharmony_civoid ap_eapol_tx_status(void *ctx, const u8 *dst,
1193e5b75505Sopenharmony_ci			const u8 *data, size_t len, int ack)
1194e5b75505Sopenharmony_ci{
1195e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1196e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1197e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1198e5b75505Sopenharmony_ci		return;
1199e5b75505Sopenharmony_ci	hostapd_tx_status(wpa_s->ap_iface->bss[0], dst, data, len, ack);
1200e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1201e5b75505Sopenharmony_ci}
1202e5b75505Sopenharmony_ci
1203e5b75505Sopenharmony_ci
1204e5b75505Sopenharmony_civoid ap_client_poll_ok(void *ctx, const u8 *addr)
1205e5b75505Sopenharmony_ci{
1206e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1207e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1208e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1209e5b75505Sopenharmony_ci		hostapd_client_poll_ok(wpa_s->ap_iface->bss[0], addr);
1210e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1211e5b75505Sopenharmony_ci}
1212e5b75505Sopenharmony_ci
1213e5b75505Sopenharmony_ci
1214e5b75505Sopenharmony_civoid ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds)
1215e5b75505Sopenharmony_ci{
1216e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1217e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1218e5b75505Sopenharmony_ci	ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds);
1219e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1220e5b75505Sopenharmony_ci}
1221e5b75505Sopenharmony_ci
1222e5b75505Sopenharmony_ci
1223e5b75505Sopenharmony_civoid ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt)
1224e5b75505Sopenharmony_ci{
1225e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1226e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1227e5b75505Sopenharmony_ci	struct hostapd_frame_info fi;
1228e5b75505Sopenharmony_ci	os_memset(&fi, 0, sizeof(fi));
1229e5b75505Sopenharmony_ci	fi.datarate = rx_mgmt->datarate;
1230e5b75505Sopenharmony_ci	fi.ssi_signal = rx_mgmt->ssi_signal;
1231e5b75505Sopenharmony_ci	ieee802_11_mgmt(wpa_s->ap_iface->bss[0], rx_mgmt->frame,
1232e5b75505Sopenharmony_ci			rx_mgmt->frame_len, &fi);
1233e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1234e5b75505Sopenharmony_ci}
1235e5b75505Sopenharmony_ci
1236e5b75505Sopenharmony_ci
1237e5b75505Sopenharmony_civoid ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok)
1238e5b75505Sopenharmony_ci{
1239e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1240e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = ctx;
1241e5b75505Sopenharmony_ci	ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok);
1242e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1243e5b75505Sopenharmony_ci}
1244e5b75505Sopenharmony_ci
1245e5b75505Sopenharmony_ci
1246e5b75505Sopenharmony_civoid wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s,
1247e5b75505Sopenharmony_ci				const u8 *src_addr, const u8 *buf, size_t len)
1248e5b75505Sopenharmony_ci{
1249e5b75505Sopenharmony_ci	ieee802_1x_receive(wpa_s->ap_iface->bss[0], src_addr, buf, len);
1250e5b75505Sopenharmony_ci}
1251e5b75505Sopenharmony_ci
1252e5b75505Sopenharmony_ci
1253e5b75505Sopenharmony_ci#ifdef CONFIG_WPS
1254e5b75505Sopenharmony_ci
1255e5b75505Sopenharmony_ciint wpa_supplicant_ap_wps_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
1256e5b75505Sopenharmony_ci			      const u8 *p2p_dev_addr)
1257e5b75505Sopenharmony_ci{
1258e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1259e5b75505Sopenharmony_ci		return -1;
1260e5b75505Sopenharmony_ci	return hostapd_wps_button_pushed(wpa_s->ap_iface->bss[0],
1261e5b75505Sopenharmony_ci					 p2p_dev_addr);
1262e5b75505Sopenharmony_ci}
1263e5b75505Sopenharmony_ci
1264e5b75505Sopenharmony_ci
1265e5b75505Sopenharmony_ciint wpa_supplicant_ap_wps_cancel(struct wpa_supplicant *wpa_s)
1266e5b75505Sopenharmony_ci{
1267e5b75505Sopenharmony_ci	struct wps_registrar *reg;
1268e5b75505Sopenharmony_ci	int reg_sel = 0, wps_sta = 0;
1269e5b75505Sopenharmony_ci
1270e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface || !wpa_s->ap_iface->bss[0]->wps)
1271e5b75505Sopenharmony_ci		return -1;
1272e5b75505Sopenharmony_ci
1273e5b75505Sopenharmony_ci	reg = wpa_s->ap_iface->bss[0]->wps->registrar;
1274e5b75505Sopenharmony_ci	reg_sel = wps_registrar_wps_cancel(reg);
1275e5b75505Sopenharmony_ci	wps_sta = ap_for_each_sta(wpa_s->ap_iface->bss[0],
1276e5b75505Sopenharmony_ci				  ap_sta_wps_cancel, NULL);
1277e5b75505Sopenharmony_ci
1278e5b75505Sopenharmony_ci	if (!reg_sel && !wps_sta) {
1279e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG, "No WPS operation in progress at this "
1280e5b75505Sopenharmony_ci			   "time");
1281e5b75505Sopenharmony_ci		return -1;
1282e5b75505Sopenharmony_ci	}
1283e5b75505Sopenharmony_ci
1284e5b75505Sopenharmony_ci	/*
1285e5b75505Sopenharmony_ci	 * There are 2 cases to return wps cancel as success:
1286e5b75505Sopenharmony_ci	 * 1. When wps cancel was initiated but no connection has been
1287e5b75505Sopenharmony_ci	 *    established with client yet.
1288e5b75505Sopenharmony_ci	 * 2. Client is in the middle of exchanging WPS messages.
1289e5b75505Sopenharmony_ci	 */
1290e5b75505Sopenharmony_ci
1291e5b75505Sopenharmony_ci	return 0;
1292e5b75505Sopenharmony_ci}
1293e5b75505Sopenharmony_ci
1294e5b75505Sopenharmony_ci
1295e5b75505Sopenharmony_ciint wpa_supplicant_ap_wps_pin(struct wpa_supplicant *wpa_s, const u8 *bssid,
1296e5b75505Sopenharmony_ci			      const char *pin, char *buf, size_t buflen,
1297e5b75505Sopenharmony_ci			      int timeout)
1298e5b75505Sopenharmony_ci{
1299e5b75505Sopenharmony_ci	int ret, ret_len = 0;
1300e5b75505Sopenharmony_ci
1301e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1302e5b75505Sopenharmony_ci		return -1;
1303e5b75505Sopenharmony_ci
1304e5b75505Sopenharmony_ci	if (pin == NULL) {
1305e5b75505Sopenharmony_ci		unsigned int rpin;
1306e5b75505Sopenharmony_ci
1307e5b75505Sopenharmony_ci		if (wps_generate_pin(&rpin) < 0)
1308e5b75505Sopenharmony_ci			return -1;
1309e5b75505Sopenharmony_ci		ret_len = os_snprintf(buf, buflen, "%08d", rpin);
1310e5b75505Sopenharmony_ci		if (os_snprintf_error(buflen, ret_len))
1311e5b75505Sopenharmony_ci			return -1;
1312e5b75505Sopenharmony_ci		pin = buf;
1313e5b75505Sopenharmony_ci	} else if (buf) {
1314e5b75505Sopenharmony_ci		ret_len = os_snprintf(buf, buflen, "%s", pin);
1315e5b75505Sopenharmony_ci		if (os_snprintf_error(buflen, ret_len))
1316e5b75505Sopenharmony_ci			return -1;
1317e5b75505Sopenharmony_ci	}
1318e5b75505Sopenharmony_ci
1319e5b75505Sopenharmony_ci	ret = hostapd_wps_add_pin(wpa_s->ap_iface->bss[0], bssid, "any", pin,
1320e5b75505Sopenharmony_ci				  timeout);
1321e5b75505Sopenharmony_ci	if (ret)
1322e5b75505Sopenharmony_ci		return -1;
1323e5b75505Sopenharmony_ci	return ret_len;
1324e5b75505Sopenharmony_ci}
1325e5b75505Sopenharmony_ci
1326e5b75505Sopenharmony_ci
1327e5b75505Sopenharmony_cistatic void wpas_wps_ap_pin_timeout(void *eloop_data, void *user_ctx)
1328e5b75505Sopenharmony_ci{
1329e5b75505Sopenharmony_ci	struct wpa_supplicant *wpa_s = eloop_data;
1330e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "WPS: AP PIN timed out");
1331e5b75505Sopenharmony_ci	wpas_wps_ap_pin_disable(wpa_s);
1332e5b75505Sopenharmony_ci}
1333e5b75505Sopenharmony_ci
1334e5b75505Sopenharmony_ci
1335e5b75505Sopenharmony_cistatic void wpas_wps_ap_pin_enable(struct wpa_supplicant *wpa_s, int timeout)
1336e5b75505Sopenharmony_ci{
1337e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1338e5b75505Sopenharmony_ci
1339e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1340e5b75505Sopenharmony_ci		return;
1341e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1342e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "WPS: Enabling AP PIN (timeout=%d)", timeout);
1343e5b75505Sopenharmony_ci	hapd->ap_pin_failures = 0;
1344e5b75505Sopenharmony_ci	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
1345e5b75505Sopenharmony_ci	if (timeout > 0)
1346e5b75505Sopenharmony_ci		eloop_register_timeout(timeout, 0,
1347e5b75505Sopenharmony_ci				       wpas_wps_ap_pin_timeout, wpa_s, NULL);
1348e5b75505Sopenharmony_ci}
1349e5b75505Sopenharmony_ci
1350e5b75505Sopenharmony_ci
1351e5b75505Sopenharmony_civoid wpas_wps_ap_pin_disable(struct wpa_supplicant *wpa_s)
1352e5b75505Sopenharmony_ci{
1353e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1354e5b75505Sopenharmony_ci
1355e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1356e5b75505Sopenharmony_ci		return;
1357e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "WPS: Disabling AP PIN");
1358e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1359e5b75505Sopenharmony_ci	os_free(hapd->conf->ap_pin);
1360e5b75505Sopenharmony_ci	hapd->conf->ap_pin = NULL;
1361e5b75505Sopenharmony_ci	eloop_cancel_timeout(wpas_wps_ap_pin_timeout, wpa_s, NULL);
1362e5b75505Sopenharmony_ci}
1363e5b75505Sopenharmony_ci
1364e5b75505Sopenharmony_ci
1365e5b75505Sopenharmony_ciconst char * wpas_wps_ap_pin_random(struct wpa_supplicant *wpa_s, int timeout)
1366e5b75505Sopenharmony_ci{
1367e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1368e5b75505Sopenharmony_ci	unsigned int pin;
1369e5b75505Sopenharmony_ci	char pin_txt[9];
1370e5b75505Sopenharmony_ci
1371e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1372e5b75505Sopenharmony_ci		return NULL;
1373e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1374e5b75505Sopenharmony_ci	if (wps_generate_pin(&pin) < 0)
1375e5b75505Sopenharmony_ci		return NULL;
1376e5b75505Sopenharmony_ci	os_snprintf(pin_txt, sizeof(pin_txt), "%08u", pin);
1377e5b75505Sopenharmony_ci	os_free(hapd->conf->ap_pin);
1378e5b75505Sopenharmony_ci	hapd->conf->ap_pin = os_strdup(pin_txt);
1379e5b75505Sopenharmony_ci	if (hapd->conf->ap_pin == NULL)
1380e5b75505Sopenharmony_ci		return NULL;
1381e5b75505Sopenharmony_ci	wpas_wps_ap_pin_enable(wpa_s, timeout);
1382e5b75505Sopenharmony_ci
1383e5b75505Sopenharmony_ci	return hapd->conf->ap_pin;
1384e5b75505Sopenharmony_ci}
1385e5b75505Sopenharmony_ci
1386e5b75505Sopenharmony_ci
1387e5b75505Sopenharmony_ciconst char * wpas_wps_ap_pin_get(struct wpa_supplicant *wpa_s)
1388e5b75505Sopenharmony_ci{
1389e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1390e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1391e5b75505Sopenharmony_ci		return NULL;
1392e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1393e5b75505Sopenharmony_ci	return hapd->conf->ap_pin;
1394e5b75505Sopenharmony_ci}
1395e5b75505Sopenharmony_ci
1396e5b75505Sopenharmony_ci
1397e5b75505Sopenharmony_ciint wpas_wps_ap_pin_set(struct wpa_supplicant *wpa_s, const char *pin,
1398e5b75505Sopenharmony_ci			int timeout)
1399e5b75505Sopenharmony_ci{
1400e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1401e5b75505Sopenharmony_ci	char pin_txt[9];
1402e5b75505Sopenharmony_ci	int ret;
1403e5b75505Sopenharmony_ci
1404e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1405e5b75505Sopenharmony_ci		return -1;
1406e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1407e5b75505Sopenharmony_ci	ret = os_snprintf(pin_txt, sizeof(pin_txt), "%s", pin);
1408e5b75505Sopenharmony_ci	if (os_snprintf_error(sizeof(pin_txt), ret))
1409e5b75505Sopenharmony_ci		return -1;
1410e5b75505Sopenharmony_ci	os_free(hapd->conf->ap_pin);
1411e5b75505Sopenharmony_ci	hapd->conf->ap_pin = os_strdup(pin_txt);
1412e5b75505Sopenharmony_ci	if (hapd->conf->ap_pin == NULL)
1413e5b75505Sopenharmony_ci		return -1;
1414e5b75505Sopenharmony_ci	wpas_wps_ap_pin_enable(wpa_s, timeout);
1415e5b75505Sopenharmony_ci
1416e5b75505Sopenharmony_ci	return 0;
1417e5b75505Sopenharmony_ci}
1418e5b75505Sopenharmony_ci
1419e5b75505Sopenharmony_ci
1420e5b75505Sopenharmony_civoid wpa_supplicant_ap_pwd_auth_fail(struct wpa_supplicant *wpa_s)
1421e5b75505Sopenharmony_ci{
1422e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1423e5b75505Sopenharmony_ci
1424e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1425e5b75505Sopenharmony_ci		return;
1426e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1427e5b75505Sopenharmony_ci
1428e5b75505Sopenharmony_ci	/*
1429e5b75505Sopenharmony_ci	 * Registrar failed to prove its knowledge of the AP PIN. Disable AP
1430e5b75505Sopenharmony_ci	 * PIN if this happens multiple times to slow down brute force attacks.
1431e5b75505Sopenharmony_ci	 */
1432e5b75505Sopenharmony_ci	hapd->ap_pin_failures++;
1433e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "WPS: AP PIN authentication failure number %u",
1434e5b75505Sopenharmony_ci		   hapd->ap_pin_failures);
1435e5b75505Sopenharmony_ci	if (hapd->ap_pin_failures < 3)
1436e5b75505Sopenharmony_ci		return;
1437e5b75505Sopenharmony_ci
1438e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "WPS: Disable AP PIN");
1439e5b75505Sopenharmony_ci	hapd->ap_pin_failures = 0;
1440e5b75505Sopenharmony_ci	os_free(hapd->conf->ap_pin);
1441e5b75505Sopenharmony_ci	hapd->conf->ap_pin = NULL;
1442e5b75505Sopenharmony_ci}
1443e5b75505Sopenharmony_ci
1444e5b75505Sopenharmony_ci
1445e5b75505Sopenharmony_ci#ifdef CONFIG_WPS_NFC
1446e5b75505Sopenharmony_ci
1447e5b75505Sopenharmony_cistruct wpabuf * wpas_ap_wps_nfc_config_token(struct wpa_supplicant *wpa_s,
1448e5b75505Sopenharmony_ci					     int ndef)
1449e5b75505Sopenharmony_ci{
1450e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1451e5b75505Sopenharmony_ci
1452e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1453e5b75505Sopenharmony_ci		return NULL;
1454e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1455e5b75505Sopenharmony_ci	return hostapd_wps_nfc_config_token(hapd, ndef);
1456e5b75505Sopenharmony_ci}
1457e5b75505Sopenharmony_ci
1458e5b75505Sopenharmony_ci
1459e5b75505Sopenharmony_cistruct wpabuf * wpas_ap_wps_nfc_handover_sel(struct wpa_supplicant *wpa_s,
1460e5b75505Sopenharmony_ci					     int ndef)
1461e5b75505Sopenharmony_ci{
1462e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1463e5b75505Sopenharmony_ci
1464e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1465e5b75505Sopenharmony_ci		return NULL;
1466e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1467e5b75505Sopenharmony_ci	return hostapd_wps_nfc_hs_cr(hapd, ndef);
1468e5b75505Sopenharmony_ci}
1469e5b75505Sopenharmony_ci
1470e5b75505Sopenharmony_ci
1471e5b75505Sopenharmony_ciint wpas_ap_wps_nfc_report_handover(struct wpa_supplicant *wpa_s,
1472e5b75505Sopenharmony_ci				    const struct wpabuf *req,
1473e5b75505Sopenharmony_ci				    const struct wpabuf *sel)
1474e5b75505Sopenharmony_ci{
1475e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1476e5b75505Sopenharmony_ci
1477e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1478e5b75505Sopenharmony_ci		return -1;
1479e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1480e5b75505Sopenharmony_ci	return hostapd_wps_nfc_report_handover(hapd, req, sel);
1481e5b75505Sopenharmony_ci}
1482e5b75505Sopenharmony_ci
1483e5b75505Sopenharmony_ci#endif /* CONFIG_WPS_NFC */
1484e5b75505Sopenharmony_ci
1485e5b75505Sopenharmony_ci#endif /* CONFIG_WPS */
1486e5b75505Sopenharmony_ci
1487e5b75505Sopenharmony_ci
1488e5b75505Sopenharmony_ci#ifdef CONFIG_CTRL_IFACE
1489e5b75505Sopenharmony_ci
1490e5b75505Sopenharmony_ciint ap_ctrl_iface_sta_first(struct wpa_supplicant *wpa_s,
1491e5b75505Sopenharmony_ci			    char *buf, size_t buflen)
1492e5b75505Sopenharmony_ci{
1493e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1494e5b75505Sopenharmony_ci
1495e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1496e5b75505Sopenharmony_ci		hapd = wpa_s->ap_iface->bss[0];
1497e5b75505Sopenharmony_ci	else if (wpa_s->ifmsh)
1498e5b75505Sopenharmony_ci		hapd = wpa_s->ifmsh->bss[0];
1499e5b75505Sopenharmony_ci	else
1500e5b75505Sopenharmony_ci		return -1;
1501e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_sta_first(hapd, buf, buflen);
1502e5b75505Sopenharmony_ci}
1503e5b75505Sopenharmony_ci
1504e5b75505Sopenharmony_ci
1505e5b75505Sopenharmony_ciint ap_ctrl_iface_sta(struct wpa_supplicant *wpa_s, const char *txtaddr,
1506e5b75505Sopenharmony_ci		      char *buf, size_t buflen)
1507e5b75505Sopenharmony_ci{
1508e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1509e5b75505Sopenharmony_ci
1510e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1511e5b75505Sopenharmony_ci		hapd = wpa_s->ap_iface->bss[0];
1512e5b75505Sopenharmony_ci	else if (wpa_s->ifmsh)
1513e5b75505Sopenharmony_ci		hapd = wpa_s->ifmsh->bss[0];
1514e5b75505Sopenharmony_ci	else
1515e5b75505Sopenharmony_ci		return -1;
1516e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_sta(hapd, txtaddr, buf, buflen);
1517e5b75505Sopenharmony_ci}
1518e5b75505Sopenharmony_ci
1519e5b75505Sopenharmony_ci
1520e5b75505Sopenharmony_ciint ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr,
1521e5b75505Sopenharmony_ci			   char *buf, size_t buflen)
1522e5b75505Sopenharmony_ci{
1523e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1524e5b75505Sopenharmony_ci
1525e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1526e5b75505Sopenharmony_ci		hapd = wpa_s->ap_iface->bss[0];
1527e5b75505Sopenharmony_ci	else if (wpa_s->ifmsh)
1528e5b75505Sopenharmony_ci		hapd = wpa_s->ifmsh->bss[0];
1529e5b75505Sopenharmony_ci	else
1530e5b75505Sopenharmony_ci		return -1;
1531e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_sta_next(hapd, txtaddr, buf, buflen);
1532e5b75505Sopenharmony_ci}
1533e5b75505Sopenharmony_ci
1534e5b75505Sopenharmony_ci
1535e5b75505Sopenharmony_ciint ap_ctrl_iface_sta_disassociate(struct wpa_supplicant *wpa_s,
1536e5b75505Sopenharmony_ci				   const char *txtaddr)
1537e5b75505Sopenharmony_ci{
1538e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1539e5b75505Sopenharmony_ci		return -1;
1540e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_disassociate(wpa_s->ap_iface->bss[0],
1541e5b75505Sopenharmony_ci					       txtaddr);
1542e5b75505Sopenharmony_ci}
1543e5b75505Sopenharmony_ci
1544e5b75505Sopenharmony_ci
1545e5b75505Sopenharmony_ciint ap_ctrl_iface_sta_deauthenticate(struct wpa_supplicant *wpa_s,
1546e5b75505Sopenharmony_ci				     const char *txtaddr)
1547e5b75505Sopenharmony_ci{
1548e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1549e5b75505Sopenharmony_ci		return -1;
1550e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_deauthenticate(wpa_s->ap_iface->bss[0],
1551e5b75505Sopenharmony_ci						 txtaddr);
1552e5b75505Sopenharmony_ci}
1553e5b75505Sopenharmony_ci
1554e5b75505Sopenharmony_ci
1555e5b75505Sopenharmony_ciint ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf,
1556e5b75505Sopenharmony_ci				 size_t buflen, int verbose)
1557e5b75505Sopenharmony_ci{
1558e5b75505Sopenharmony_ci	char *pos = buf, *end = buf + buflen;
1559e5b75505Sopenharmony_ci	int ret;
1560e5b75505Sopenharmony_ci	struct hostapd_bss_config *conf;
1561e5b75505Sopenharmony_ci
1562e5b75505Sopenharmony_ci	if (wpa_s->ap_iface == NULL)
1563e5b75505Sopenharmony_ci		return -1;
1564e5b75505Sopenharmony_ci
1565e5b75505Sopenharmony_ci	conf = wpa_s->ap_iface->bss[0]->conf;
1566e5b75505Sopenharmony_ci	if (conf->wpa == 0)
1567e5b75505Sopenharmony_ci		return 0;
1568e5b75505Sopenharmony_ci
1569e5b75505Sopenharmony_ci	ret = os_snprintf(pos, end - pos,
1570e5b75505Sopenharmony_ci			  "pairwise_cipher=%s\n"
1571e5b75505Sopenharmony_ci			  "group_cipher=%s\n"
1572e5b75505Sopenharmony_ci			  "key_mgmt=%s\n",
1573e5b75505Sopenharmony_ci			  wpa_cipher_txt(conf->rsn_pairwise),
1574e5b75505Sopenharmony_ci			  wpa_cipher_txt(conf->wpa_group),
1575e5b75505Sopenharmony_ci			  wpa_key_mgmt_txt(conf->wpa_key_mgmt,
1576e5b75505Sopenharmony_ci					   conf->wpa));
1577e5b75505Sopenharmony_ci	if (os_snprintf_error(end - pos, ret))
1578e5b75505Sopenharmony_ci		return pos - buf;
1579e5b75505Sopenharmony_ci	pos += ret;
1580e5b75505Sopenharmony_ci	return pos - buf;
1581e5b75505Sopenharmony_ci}
1582e5b75505Sopenharmony_ci
1583e5b75505Sopenharmony_ci#endif /* CONFIG_CTRL_IFACE */
1584e5b75505Sopenharmony_ci
1585e5b75505Sopenharmony_ci
1586e5b75505Sopenharmony_ciint wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s)
1587e5b75505Sopenharmony_ci{
1588e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1589e5b75505Sopenharmony_ci	struct wpa_ssid *ssid = wpa_s->current_ssid;
1590e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1591e5b75505Sopenharmony_ci
1592e5b75505Sopenharmony_ci	if (ssid == NULL || wpa_s->ap_iface == NULL ||
1593e5b75505Sopenharmony_ci	    ssid->mode == WPAS_MODE_INFRA ||
1594e5b75505Sopenharmony_ci	    ssid->mode == WPAS_MODE_IBSS)
1595e5b75505Sopenharmony_ci		return -1;
1596e5b75505Sopenharmony_ci
1597e5b75505Sopenharmony_ci#ifdef CONFIG_P2P
1598e5b75505Sopenharmony_ci	if (ssid->mode == WPAS_MODE_P2P_GO)
1599e5b75505Sopenharmony_ci		iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER;
1600e5b75505Sopenharmony_ci	else if (ssid->mode == WPAS_MODE_P2P_GROUP_FORMATION)
1601e5b75505Sopenharmony_ci		iface->conf->bss[0]->p2p = P2P_ENABLED | P2P_GROUP_OWNER |
1602e5b75505Sopenharmony_ci			P2P_GROUP_FORMATION;
1603e5b75505Sopenharmony_ci#endif /* CONFIG_P2P */
1604e5b75505Sopenharmony_ci
1605e5b75505Sopenharmony_ci	hapd = iface->bss[0];
1606e5b75505Sopenharmony_ci	if (hapd->drv_priv == NULL)
1607e5b75505Sopenharmony_ci		return -1;
1608e5b75505Sopenharmony_ci	ieee802_11_set_beacons(iface);
1609e5b75505Sopenharmony_ci	hostapd_set_ap_wps_ie(hapd);
1610e5b75505Sopenharmony_ci
1611e5b75505Sopenharmony_ci	return 0;
1612e5b75505Sopenharmony_ci}
1613e5b75505Sopenharmony_ci
1614e5b75505Sopenharmony_ci
1615e5b75505Sopenharmony_ciint ap_switch_channel(struct wpa_supplicant *wpa_s,
1616e5b75505Sopenharmony_ci		      struct csa_settings *settings)
1617e5b75505Sopenharmony_ci{
1618e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1619e5b75505Sopenharmony_ci	struct hostapd_iface *iface = NULL;
1620e5b75505Sopenharmony_ci
1621e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1622e5b75505Sopenharmony_ci		iface = wpa_s->ap_iface;
1623e5b75505Sopenharmony_ci	else if (wpa_s->ifmsh)
1624e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1625e5b75505Sopenharmony_ci
1626e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1627e5b75505Sopenharmony_ci		return -1;
1628e5b75505Sopenharmony_ci
1629e5b75505Sopenharmony_ci	return hostapd_switch_channel(iface->bss[0], settings);
1630e5b75505Sopenharmony_ci#else /* NEED_AP_MLME */
1631e5b75505Sopenharmony_ci	return -1;
1632e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1633e5b75505Sopenharmony_ci}
1634e5b75505Sopenharmony_ci
1635e5b75505Sopenharmony_ci
1636e5b75505Sopenharmony_ci#ifdef CONFIG_CTRL_IFACE
1637e5b75505Sopenharmony_ciint ap_ctrl_iface_chanswitch(struct wpa_supplicant *wpa_s, const char *pos)
1638e5b75505Sopenharmony_ci{
1639e5b75505Sopenharmony_ci	struct csa_settings settings;
1640e5b75505Sopenharmony_ci	int ret = hostapd_parse_csa_settings(pos, &settings);
1641e5b75505Sopenharmony_ci
1642e5b75505Sopenharmony_ci	if (ret)
1643e5b75505Sopenharmony_ci		return ret;
1644e5b75505Sopenharmony_ci
1645e5b75505Sopenharmony_ci	return ap_switch_channel(wpa_s, &settings);
1646e5b75505Sopenharmony_ci}
1647e5b75505Sopenharmony_ci#endif /* CONFIG_CTRL_IFACE */
1648e5b75505Sopenharmony_ci
1649e5b75505Sopenharmony_ci
1650e5b75505Sopenharmony_civoid wpas_ap_ch_switch(struct wpa_supplicant *wpa_s, int freq, int ht,
1651e5b75505Sopenharmony_ci		       int offset, int width, int cf1, int cf2, int finished)
1652e5b75505Sopenharmony_ci{
1653e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1654e5b75505Sopenharmony_ci
1655e5b75505Sopenharmony_ci	if (!iface)
1656e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1657e5b75505Sopenharmony_ci	if (!iface)
1658e5b75505Sopenharmony_ci		return;
1659e5b75505Sopenharmony_ci	wpa_s->assoc_freq = freq;
1660e5b75505Sopenharmony_ci	if (wpa_s->current_ssid)
1661e5b75505Sopenharmony_ci		wpa_s->current_ssid->frequency = freq;
1662e5b75505Sopenharmony_ci	hostapd_event_ch_switch(iface->bss[0], freq, ht,
1663e5b75505Sopenharmony_ci				offset, width, cf1, cf2, finished);
1664e5b75505Sopenharmony_ci}
1665e5b75505Sopenharmony_ci
1666e5b75505Sopenharmony_ci
1667e5b75505Sopenharmony_ciint wpa_supplicant_ap_mac_addr_filter(struct wpa_supplicant *wpa_s,
1668e5b75505Sopenharmony_ci				      const u8 *addr)
1669e5b75505Sopenharmony_ci{
1670e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1671e5b75505Sopenharmony_ci	struct hostapd_bss_config *conf;
1672e5b75505Sopenharmony_ci
1673e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1674e5b75505Sopenharmony_ci		return -1;
1675e5b75505Sopenharmony_ci
1676e5b75505Sopenharmony_ci	if (addr)
1677e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG, "AP: Set MAC address filter: " MACSTR_SEC,
1678e5b75505Sopenharmony_ci			   MAC2STR_SEC(addr));
1679e5b75505Sopenharmony_ci	else
1680e5b75505Sopenharmony_ci		wpa_printf(MSG_EXCESSIVE, "AP: Clear MAC address filter");
1681e5b75505Sopenharmony_ci
1682e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1683e5b75505Sopenharmony_ci	conf = hapd->conf;
1684e5b75505Sopenharmony_ci
1685e5b75505Sopenharmony_ci	os_free(conf->accept_mac);
1686e5b75505Sopenharmony_ci	conf->accept_mac = NULL;
1687e5b75505Sopenharmony_ci	conf->num_accept_mac = 0;
1688e5b75505Sopenharmony_ci	os_free(conf->deny_mac);
1689e5b75505Sopenharmony_ci	conf->deny_mac = NULL;
1690e5b75505Sopenharmony_ci	conf->num_deny_mac = 0;
1691e5b75505Sopenharmony_ci
1692e5b75505Sopenharmony_ci	if (addr == NULL) {
1693e5b75505Sopenharmony_ci		conf->macaddr_acl = ACCEPT_UNLESS_DENIED;
1694e5b75505Sopenharmony_ci		return 0;
1695e5b75505Sopenharmony_ci	}
1696e5b75505Sopenharmony_ci
1697e5b75505Sopenharmony_ci	conf->macaddr_acl = DENY_UNLESS_ACCEPTED;
1698e5b75505Sopenharmony_ci	conf->accept_mac = os_zalloc(sizeof(struct mac_acl_entry));
1699e5b75505Sopenharmony_ci	if (conf->accept_mac == NULL)
1700e5b75505Sopenharmony_ci		return -1;
1701e5b75505Sopenharmony_ci	os_memcpy(conf->accept_mac[0].addr, addr, ETH_ALEN);
1702e5b75505Sopenharmony_ci	conf->num_accept_mac = 1;
1703e5b75505Sopenharmony_ci
1704e5b75505Sopenharmony_ci	return 0;
1705e5b75505Sopenharmony_ci}
1706e5b75505Sopenharmony_ci
1707e5b75505Sopenharmony_ci
1708e5b75505Sopenharmony_ci#ifdef CONFIG_WPS_NFC
1709e5b75505Sopenharmony_ciint wpas_ap_wps_add_nfc_pw(struct wpa_supplicant *wpa_s, u16 pw_id,
1710e5b75505Sopenharmony_ci			   const struct wpabuf *pw, const u8 *pubkey_hash)
1711e5b75505Sopenharmony_ci{
1712e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1713e5b75505Sopenharmony_ci	struct wps_context *wps;
1714e5b75505Sopenharmony_ci
1715e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1716e5b75505Sopenharmony_ci		return -1;
1717e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1718e5b75505Sopenharmony_ci	wps = hapd->wps;
1719e5b75505Sopenharmony_ci
1720e5b75505Sopenharmony_ci	if (wpa_s->p2pdev->conf->wps_nfc_dh_pubkey == NULL ||
1721e5b75505Sopenharmony_ci	    wpa_s->p2pdev->conf->wps_nfc_dh_privkey == NULL) {
1722e5b75505Sopenharmony_ci		wpa_printf(MSG_DEBUG, "P2P: No NFC DH key known");
1723e5b75505Sopenharmony_ci		return -1;
1724e5b75505Sopenharmony_ci	}
1725e5b75505Sopenharmony_ci
1726e5b75505Sopenharmony_ci	dh5_free(wps->dh_ctx);
1727e5b75505Sopenharmony_ci	wpabuf_free(wps->dh_pubkey);
1728e5b75505Sopenharmony_ci	wpabuf_free(wps->dh_privkey);
1729e5b75505Sopenharmony_ci	wps->dh_privkey = wpabuf_dup(
1730e5b75505Sopenharmony_ci		wpa_s->p2pdev->conf->wps_nfc_dh_privkey);
1731e5b75505Sopenharmony_ci	wps->dh_pubkey = wpabuf_dup(
1732e5b75505Sopenharmony_ci		wpa_s->p2pdev->conf->wps_nfc_dh_pubkey);
1733e5b75505Sopenharmony_ci	if (wps->dh_privkey == NULL || wps->dh_pubkey == NULL) {
1734e5b75505Sopenharmony_ci		wps->dh_ctx = NULL;
1735e5b75505Sopenharmony_ci		wpabuf_free(wps->dh_pubkey);
1736e5b75505Sopenharmony_ci		wps->dh_pubkey = NULL;
1737e5b75505Sopenharmony_ci		wpabuf_free(wps->dh_privkey);
1738e5b75505Sopenharmony_ci		wps->dh_privkey = NULL;
1739e5b75505Sopenharmony_ci		return -1;
1740e5b75505Sopenharmony_ci	}
1741e5b75505Sopenharmony_ci	wps->dh_ctx = dh5_init_fixed(wps->dh_privkey, wps->dh_pubkey);
1742e5b75505Sopenharmony_ci	if (wps->dh_ctx == NULL)
1743e5b75505Sopenharmony_ci		return -1;
1744e5b75505Sopenharmony_ci
1745e5b75505Sopenharmony_ci	return wps_registrar_add_nfc_pw_token(hapd->wps->registrar, pubkey_hash,
1746e5b75505Sopenharmony_ci					      pw_id,
1747e5b75505Sopenharmony_ci					      pw ? wpabuf_head(pw) : NULL,
1748e5b75505Sopenharmony_ci					      pw ? wpabuf_len(pw) : 0, 1);
1749e5b75505Sopenharmony_ci}
1750e5b75505Sopenharmony_ci#endif /* CONFIG_WPS_NFC */
1751e5b75505Sopenharmony_ci
1752e5b75505Sopenharmony_ci
1753e5b75505Sopenharmony_ci#ifdef CONFIG_CTRL_IFACE
1754e5b75505Sopenharmony_ciint wpas_ap_stop_ap(struct wpa_supplicant *wpa_s)
1755e5b75505Sopenharmony_ci{
1756e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1757e5b75505Sopenharmony_ci
1758e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1759e5b75505Sopenharmony_ci		return -1;
1760e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1761e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_stop_ap(hapd);
1762e5b75505Sopenharmony_ci}
1763e5b75505Sopenharmony_ci
1764e5b75505Sopenharmony_ci
1765e5b75505Sopenharmony_ciint wpas_ap_pmksa_cache_list(struct wpa_supplicant *wpa_s, char *buf,
1766e5b75505Sopenharmony_ci			     size_t len)
1767e5b75505Sopenharmony_ci{
1768e5b75505Sopenharmony_ci	size_t reply_len = 0, i;
1769e5b75505Sopenharmony_ci	char ap_delimiter[] = "---- AP ----\n";
1770e5b75505Sopenharmony_ci	char mesh_delimiter[] = "---- mesh ----\n";
1771e5b75505Sopenharmony_ci	size_t dlen;
1772e5b75505Sopenharmony_ci
1773e5b75505Sopenharmony_ci	if (wpa_s->ap_iface) {
1774e5b75505Sopenharmony_ci		dlen = os_strlen(ap_delimiter);
1775e5b75505Sopenharmony_ci		if (dlen > len - reply_len)
1776e5b75505Sopenharmony_ci			return reply_len;
1777e5b75505Sopenharmony_ci		os_memcpy(&buf[reply_len], ap_delimiter, dlen);
1778e5b75505Sopenharmony_ci		reply_len += dlen;
1779e5b75505Sopenharmony_ci
1780e5b75505Sopenharmony_ci		for (i = 0; i < wpa_s->ap_iface->num_bss; i++) {
1781e5b75505Sopenharmony_ci			reply_len += hostapd_ctrl_iface_pmksa_list(
1782e5b75505Sopenharmony_ci				wpa_s->ap_iface->bss[i],
1783e5b75505Sopenharmony_ci				&buf[reply_len], len - reply_len);
1784e5b75505Sopenharmony_ci		}
1785e5b75505Sopenharmony_ci	}
1786e5b75505Sopenharmony_ci
1787e5b75505Sopenharmony_ci	if (wpa_s->ifmsh) {
1788e5b75505Sopenharmony_ci		dlen = os_strlen(mesh_delimiter);
1789e5b75505Sopenharmony_ci		if (dlen > len - reply_len)
1790e5b75505Sopenharmony_ci			return reply_len;
1791e5b75505Sopenharmony_ci		os_memcpy(&buf[reply_len], mesh_delimiter, dlen);
1792e5b75505Sopenharmony_ci		reply_len += dlen;
1793e5b75505Sopenharmony_ci
1794e5b75505Sopenharmony_ci		reply_len += hostapd_ctrl_iface_pmksa_list(
1795e5b75505Sopenharmony_ci			wpa_s->ifmsh->bss[0], &buf[reply_len],
1796e5b75505Sopenharmony_ci			len - reply_len);
1797e5b75505Sopenharmony_ci	}
1798e5b75505Sopenharmony_ci
1799e5b75505Sopenharmony_ci	return reply_len;
1800e5b75505Sopenharmony_ci}
1801e5b75505Sopenharmony_ci
1802e5b75505Sopenharmony_ci
1803e5b75505Sopenharmony_civoid wpas_ap_pmksa_cache_flush(struct wpa_supplicant *wpa_s)
1804e5b75505Sopenharmony_ci{
1805e5b75505Sopenharmony_ci	size_t i;
1806e5b75505Sopenharmony_ci
1807e5b75505Sopenharmony_ci	if (wpa_s->ap_iface) {
1808e5b75505Sopenharmony_ci		for (i = 0; i < wpa_s->ap_iface->num_bss; i++)
1809e5b75505Sopenharmony_ci			hostapd_ctrl_iface_pmksa_flush(wpa_s->ap_iface->bss[i]);
1810e5b75505Sopenharmony_ci	}
1811e5b75505Sopenharmony_ci
1812e5b75505Sopenharmony_ci	if (wpa_s->ifmsh)
1813e5b75505Sopenharmony_ci		hostapd_ctrl_iface_pmksa_flush(wpa_s->ifmsh->bss[0]);
1814e5b75505Sopenharmony_ci}
1815e5b75505Sopenharmony_ci
1816e5b75505Sopenharmony_ci
1817e5b75505Sopenharmony_ci#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
1818e5b75505Sopenharmony_ci#ifdef CONFIG_MESH
1819e5b75505Sopenharmony_ci
1820e5b75505Sopenharmony_ciint wpas_ap_pmksa_cache_list_mesh(struct wpa_supplicant *wpa_s, const u8 *addr,
1821e5b75505Sopenharmony_ci				  char *buf, size_t len)
1822e5b75505Sopenharmony_ci{
1823e5b75505Sopenharmony_ci	return hostapd_ctrl_iface_pmksa_list_mesh(wpa_s->ifmsh->bss[0], addr,
1824e5b75505Sopenharmony_ci						  &buf[0], len);
1825e5b75505Sopenharmony_ci}
1826e5b75505Sopenharmony_ci
1827e5b75505Sopenharmony_ci
1828e5b75505Sopenharmony_ciint wpas_ap_pmksa_cache_add_external(struct wpa_supplicant *wpa_s, char *cmd)
1829e5b75505Sopenharmony_ci{
1830e5b75505Sopenharmony_ci	struct external_pmksa_cache *entry;
1831e5b75505Sopenharmony_ci	void *pmksa_cache;
1832e5b75505Sopenharmony_ci
1833e5b75505Sopenharmony_ci	pmksa_cache = hostapd_ctrl_iface_pmksa_create_entry(wpa_s->own_addr,
1834e5b75505Sopenharmony_ci							    cmd);
1835e5b75505Sopenharmony_ci	if (!pmksa_cache)
1836e5b75505Sopenharmony_ci		return -1;
1837e5b75505Sopenharmony_ci
1838e5b75505Sopenharmony_ci	entry = os_zalloc(sizeof(struct external_pmksa_cache));
1839e5b75505Sopenharmony_ci	if (!entry)
1840e5b75505Sopenharmony_ci		return -1;
1841e5b75505Sopenharmony_ci
1842e5b75505Sopenharmony_ci	entry->pmksa_cache = pmksa_cache;
1843e5b75505Sopenharmony_ci
1844e5b75505Sopenharmony_ci	dl_list_add(&wpa_s->mesh_external_pmksa_cache, &entry->list);
1845e5b75505Sopenharmony_ci
1846e5b75505Sopenharmony_ci	return 0;
1847e5b75505Sopenharmony_ci}
1848e5b75505Sopenharmony_ci
1849e5b75505Sopenharmony_ci#endif /* CONFIG_MESH */
1850e5b75505Sopenharmony_ci#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
1851e5b75505Sopenharmony_ci
1852e5b75505Sopenharmony_ci
1853e5b75505Sopenharmony_ciint wpas_ap_update_beacon(struct wpa_supplicant *wpa_s)
1854e5b75505Sopenharmony_ci{
1855e5b75505Sopenharmony_ci	struct hostapd_data *hapd;
1856e5b75505Sopenharmony_ci
1857e5b75505Sopenharmony_ci	if (!wpa_s->ap_iface)
1858e5b75505Sopenharmony_ci		return -1;
1859e5b75505Sopenharmony_ci	hapd = wpa_s->ap_iface->bss[0];
1860e5b75505Sopenharmony_ci
1861e5b75505Sopenharmony_ci	wpabuf_free(hapd->conf->assocresp_elements);
1862e5b75505Sopenharmony_ci	hapd->conf->assocresp_elements = NULL;
1863e5b75505Sopenharmony_ci	if (wpa_s->conf->ap_assocresp_elements) {
1864e5b75505Sopenharmony_ci		hapd->conf->assocresp_elements =
1865e5b75505Sopenharmony_ci			wpabuf_dup(wpa_s->conf->ap_assocresp_elements);
1866e5b75505Sopenharmony_ci	}
1867e5b75505Sopenharmony_ci
1868e5b75505Sopenharmony_ci	wpabuf_free(hapd->conf->vendor_elements);
1869e5b75505Sopenharmony_ci	hapd->conf->vendor_elements = NULL;
1870e5b75505Sopenharmony_ci	if (wpa_s->conf->ap_vendor_elements) {
1871e5b75505Sopenharmony_ci		hapd->conf->vendor_elements =
1872e5b75505Sopenharmony_ci			wpabuf_dup(wpa_s->conf->ap_vendor_elements);
1873e5b75505Sopenharmony_ci	}
1874e5b75505Sopenharmony_ci
1875e5b75505Sopenharmony_ci	return ieee802_11_set_beacon(hapd);
1876e5b75505Sopenharmony_ci}
1877e5b75505Sopenharmony_ci
1878e5b75505Sopenharmony_ci#endif /* CONFIG_CTRL_IFACE */
1879e5b75505Sopenharmony_ci
1880e5b75505Sopenharmony_ci
1881e5b75505Sopenharmony_ci#ifdef NEED_AP_MLME
1882e5b75505Sopenharmony_civoid wpas_ap_event_dfs_radar_detected(struct wpa_supplicant *wpa_s,
1883e5b75505Sopenharmony_ci				      struct dfs_event *radar)
1884e5b75505Sopenharmony_ci{
1885e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1886e5b75505Sopenharmony_ci
1887e5b75505Sopenharmony_ci	if (!iface)
1888e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1889e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1890e5b75505Sopenharmony_ci		return;
1891e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "DFS radar detected on %d MHz", radar->freq);
1892e5b75505Sopenharmony_ci	hostapd_dfs_radar_detected(iface, radar->freq,
1893e5b75505Sopenharmony_ci				   radar->ht_enabled, radar->chan_offset,
1894e5b75505Sopenharmony_ci				   radar->chan_width,
1895e5b75505Sopenharmony_ci				   radar->cf1, radar->cf2);
1896e5b75505Sopenharmony_ci}
1897e5b75505Sopenharmony_ci
1898e5b75505Sopenharmony_ci
1899e5b75505Sopenharmony_civoid wpas_ap_event_dfs_cac_started(struct wpa_supplicant *wpa_s,
1900e5b75505Sopenharmony_ci				   struct dfs_event *radar)
1901e5b75505Sopenharmony_ci{
1902e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1903e5b75505Sopenharmony_ci
1904e5b75505Sopenharmony_ci	if (!iface)
1905e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1906e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1907e5b75505Sopenharmony_ci		return;
1908e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "DFS CAC started on %d MHz", radar->freq);
1909e5b75505Sopenharmony_ci	hostapd_dfs_start_cac(iface, radar->freq,
1910e5b75505Sopenharmony_ci			      radar->ht_enabled, radar->chan_offset,
1911e5b75505Sopenharmony_ci			      radar->chan_width, radar->cf1, radar->cf2);
1912e5b75505Sopenharmony_ci}
1913e5b75505Sopenharmony_ci
1914e5b75505Sopenharmony_ci
1915e5b75505Sopenharmony_civoid wpas_ap_event_dfs_cac_finished(struct wpa_supplicant *wpa_s,
1916e5b75505Sopenharmony_ci				    struct dfs_event *radar)
1917e5b75505Sopenharmony_ci{
1918e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1919e5b75505Sopenharmony_ci
1920e5b75505Sopenharmony_ci	if (!iface)
1921e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1922e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1923e5b75505Sopenharmony_ci		return;
1924e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "DFS CAC finished on %d MHz", radar->freq);
1925e5b75505Sopenharmony_ci	hostapd_dfs_complete_cac(iface, 1, radar->freq,
1926e5b75505Sopenharmony_ci				 radar->ht_enabled, radar->chan_offset,
1927e5b75505Sopenharmony_ci				 radar->chan_width, radar->cf1, radar->cf2);
1928e5b75505Sopenharmony_ci}
1929e5b75505Sopenharmony_ci
1930e5b75505Sopenharmony_ci
1931e5b75505Sopenharmony_civoid wpas_ap_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s,
1932e5b75505Sopenharmony_ci				   struct dfs_event *radar)
1933e5b75505Sopenharmony_ci{
1934e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1935e5b75505Sopenharmony_ci
1936e5b75505Sopenharmony_ci	if (!iface)
1937e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1938e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1939e5b75505Sopenharmony_ci		return;
1940e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "DFS CAC aborted on %d MHz", radar->freq);
1941e5b75505Sopenharmony_ci	hostapd_dfs_complete_cac(iface, 0, radar->freq,
1942e5b75505Sopenharmony_ci				 radar->ht_enabled, radar->chan_offset,
1943e5b75505Sopenharmony_ci				 radar->chan_width, radar->cf1, radar->cf2);
1944e5b75505Sopenharmony_ci}
1945e5b75505Sopenharmony_ci
1946e5b75505Sopenharmony_ci
1947e5b75505Sopenharmony_civoid wpas_ap_event_dfs_cac_nop_finished(struct wpa_supplicant *wpa_s,
1948e5b75505Sopenharmony_ci					struct dfs_event *radar)
1949e5b75505Sopenharmony_ci{
1950e5b75505Sopenharmony_ci	struct hostapd_iface *iface = wpa_s->ap_iface;
1951e5b75505Sopenharmony_ci
1952e5b75505Sopenharmony_ci	if (!iface)
1953e5b75505Sopenharmony_ci		iface = wpa_s->ifmsh;
1954e5b75505Sopenharmony_ci	if (!iface || !iface->bss[0])
1955e5b75505Sopenharmony_ci		return;
1956e5b75505Sopenharmony_ci	wpa_printf(MSG_DEBUG, "DFS NOP finished on %d MHz", radar->freq);
1957e5b75505Sopenharmony_ci	hostapd_dfs_nop_finished(iface, radar->freq,
1958e5b75505Sopenharmony_ci				 radar->ht_enabled, radar->chan_offset,
1959e5b75505Sopenharmony_ci				 radar->chan_width, radar->cf1, radar->cf2);
1960e5b75505Sopenharmony_ci}
1961e5b75505Sopenharmony_ci#endif /* NEED_AP_MLME */
1962e5b75505Sopenharmony_ci
1963e5b75505Sopenharmony_ci
1964e5b75505Sopenharmony_civoid ap_periodic(struct wpa_supplicant *wpa_s)
1965e5b75505Sopenharmony_ci{
1966e5b75505Sopenharmony_ci	if (wpa_s->ap_iface)
1967e5b75505Sopenharmony_ci		hostapd_periodic_iface(wpa_s->ap_iface);
1968e5b75505Sopenharmony_ci}
1969