Merge branch 'bugfix/wps_pbc_overlap_uuid_v5.1' into 'release/v5.1'

fix(wpa_supplicant): Ensure pbc_overlap event is posted correctly (Backport v5.1)

See merge request espressif/esp-idf!39083
This commit is contained in:
Jiang Jiang Jian
2025-07-09 18:26:22 +08:00
2 changed files with 48 additions and 4 deletions

View File

@@ -346,12 +346,36 @@ static bool ap_supports_sae(struct wps_scan_ie *scan)
return false;
}
static bool
is_wps_pbc_overlap(struct wps_sm *sm, const u8 *sel_uuid)
{
if (!sel_uuid) {
wpa_printf(MSG_DEBUG, "WPS: null uuid field");
return true;
}
if (os_memcmp(sel_uuid, sm->uuid_r, WPS_UUID_LEN) != 0) {
wpa_printf(MSG_DEBUG, "uuid is not same");
wpa_hexdump(MSG_DEBUG, "WPS: UUID of scanned BSS is",
sel_uuid, WPS_UUID_LEN);
wpa_hexdump(MSG_DEBUG, "WPS: UUID of sm BSS is",
sm->uuid_r, WPS_UUID_LEN);
return true;
}
return false;
}
static bool
wps_parse_scan_result(struct wps_scan_ie *scan)
{
struct wps_sm *sm = gWpsSm;
wifi_mode_t op_mode = 0;
if (sm->wps_pbc_overlap) {
return false;
}
if (!sm->is_wps_scan || !scan->bssid) {
return false;
}
@@ -386,6 +410,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
bool ap_found = false;
struct wpabuf *buf = wpabuf_alloc_copy(scan->wps + 6, scan->wps[1] - 4);
int count;
const u8 *scan_uuid;
if ((wps_get_type() == WPS_TYPE_PBC && wps_is_selected_pbc_registrar(buf)) ||
(wps_get_type() == WPS_TYPE_PIN && wps_is_addr_authorized(buf, sm->ownaddr, 1))) {
@@ -406,8 +431,8 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
}
if (ap_found || sm->ignore_sel_reg) {
wpabuf_free(buf);
if (scan->ssid[1] > SSID_MAX_LEN) {
wpabuf_free(buf);
return false;
}
esp_wifi_enable_sta_privacy_internal();
@@ -418,7 +443,20 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
wpa_printf(MSG_INFO, "sm BSSid: "MACSTR " scan BSSID " MACSTR,
MAC2STR(sm->bssid), MAC2STR(scan->bssid));
sm->discover_ssid_cnt++;
wpa_printf(MSG_INFO, "discoverd cnt is %d and chan is %d ", sm->discover_ssid_cnt, scan->chan);
os_memcpy(sm->bssid, scan->bssid, ETH_ALEN);
scan_uuid = wps_get_uuid_e(buf);
if (sm->discover_ssid_cnt > 1 && wps_get_type() == WPS_TYPE_PBC && is_wps_pbc_overlap(sm, scan_uuid) == true) {
wpa_printf(MSG_INFO, "pbc_overlap flag is true");
sm->wps_pbc_overlap = true;
wpabuf_free(buf);
return false;
}
if (scan_uuid) {
os_memcpy(sm->uuid_r, scan_uuid, WPS_UUID_LEN);
}
if (ap_supports_sae(scan)) {
wpa_printf(MSG_INFO, "AP supports SAE, get password in passphrase");
sm->dev->config_methods |= WPS_CONFIG_DISPLAY | WPS_CONFIG_VIRT_DISPLAY;
@@ -427,6 +465,7 @@ wps_parse_scan_result(struct wps_scan_ie *scan)
wps_build_ic_appie_wps_ar();
}
}
wpabuf_free(buf);
wpa_printf(MSG_DEBUG, "wps discover [%s]", (char *)sm->creds[0].ssid);
sm->channel = scan->chan;
@@ -1424,7 +1463,7 @@ static int wifi_station_wps_init(const esp_wps_config_t *config)
}
sm = gWpsSm;
esp_wifi_disconnect();
esp_wifi_get_macaddr_internal(WIFI_IF_STA, sm->ownaddr);
os_memcpy(gWpaSm.own_addr, sm->ownaddr, ETH_ALEN);
@@ -1604,7 +1643,8 @@ wifi_wps_scan_done(void *arg, ETS_STATUS status)
} else if (sm->discover_ssid_cnt == 0) {
wps_set_status(WPS_STATUS_SCANNING);
} else {
if (wps_get_type() == WPS_TYPE_PBC) {
if (sm->wps_pbc_overlap) {
sm->wps_pbc_overlap = false;
wpa_printf(MSG_INFO, "PBC session overlap!");
wps_set_status(WPS_STATUS_DISABLE);
esp_event_post(WIFI_EVENT, WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP, 0, 0, OS_BLOCK);
@@ -1711,6 +1751,8 @@ int wifi_station_wps_start(void)
default:
break;
}
os_memset(sm->uuid_r, 0, sizeof(sm->uuid_r));
sm->wps_pbc_overlap = false;
sm->discard_ap_cnt = 0;
os_memset(&sm->dis_ap_list, 0, WPS_MAX_DIS_AP_NUM * sizeof(struct discard_ap_list_t));
esp_wifi_set_wps_start_flag_internal(true);

View File

@@ -71,7 +71,8 @@ struct wps_sm {
struct wps_credential creds[MAX_CRED_COUNT];
u8 ap_cred_cnt;
struct wps_device_data *dev;
u8 uuid[16];
u8 uuid[WPS_UUID_LEN];
u8 uuid_r[WPS_UUID_LEN];
u8 current_identifier;
bool is_wps_scan;
u8 channel;
@@ -81,6 +82,7 @@ struct wps_sm {
#endif
u8 discover_ssid_cnt;
bool ignore_sel_reg;
bool wps_pbc_overlap;
struct discard_ap_list_t dis_ap_list[WPS_MAX_DIS_AP_NUM];
u8 discard_ap_cnt;
bool intermediate_disconnect;