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