From aa0f14b2230260f6590e596f92e40557c1d73c09 Mon Sep 17 00:00:00 2001 From: akshat Date: Tue, 13 May 2025 14:38:21 +0530 Subject: [PATCH 1/4] fix(wpa_supplicant): Fix for WPS-PBC overlap detection in dual band When WPS is running on dual band(e.g. a separate 2.4 GHz and 5 GHz band radios in an AP device), detect pbc overlap only if UUID differs. --- .../esp_supplicant/src/esp_wps.c | 39 ++++++++++++++++++- .../esp_supplicant/src/esp_wps_i.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 3921574d62..b47849bc7f 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -346,11 +346,32 @@ 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 false; + } + + if (os_memcmp(sel_uuid, sm->uuid, 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, 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; + sm->wps_pbc_overlap = false; if (!sm->is_wps_scan || !scan->bssid) { return false; @@ -386,6 +407,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 +428,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 +440,18 @@ 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 (scan_uuid) { + if (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; + } + os_memcpy(sm->uuid, 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 +460,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; @@ -1604,7 +1638,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); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index 220e6c9c19..74b0b090c9 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -81,6 +81,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; From f14586589666dc772630fac6b6861693a37c1a97 Mon Sep 17 00:00:00 2001 From: akshat Date: Wed, 2 Apr 2025 15:03:42 +0530 Subject: [PATCH 2/4] fix(wpa_supplicant): Ensure pbc_overlap event is posted correctly Preserves the pbc_overlap flag to allow proper event posting. This ensures that pbc overlap detection functions as expected. --- .../wpa_supplicant/esp_supplicant/src/esp_wps.c | 15 ++++++++++----- .../wpa_supplicant/esp_supplicant/src/esp_wps_i.h | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index b47849bc7f..0c27f7ac38 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -354,12 +354,12 @@ is_wps_pbc_overlap(struct wps_sm *sm, const u8 *sel_uuid) return false; } - if (os_memcmp(sel_uuid, sm->uuid, WPS_UUID_LEN) != 0) { + 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, WPS_UUID_LEN); + sm->uuid_r, WPS_UUID_LEN); return true; } @@ -371,7 +371,10 @@ wps_parse_scan_result(struct wps_scan_ie *scan) { struct wps_sm *sm = gWpsSm; wifi_mode_t op_mode = 0; - sm->wps_pbc_overlap = false; + + if(sm->wps_pbc_overlap) { + return false; + } if (!sm->is_wps_scan || !scan->bssid) { return false; @@ -445,11 +448,11 @@ wps_parse_scan_result(struct wps_scan_ie *scan) scan_uuid = wps_get_uuid_e(buf); if (scan_uuid) { - if (wps_get_type() == WPS_TYPE_PBC && is_wps_pbc_overlap(sm, scan_uuid) == true) { + 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; } - os_memcpy(sm->uuid, scan_uuid, WPS_UUID_LEN); + os_memcpy(sm->uuid_r, scan_uuid, WPS_UUID_LEN); } if (ap_supports_sae(scan)) { @@ -1746,6 +1749,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); diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h index 74b0b090c9..f2414a2091 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps_i.h @@ -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; From 393d54d40e03a7bc8feb7ad545930881f3a78649 Mon Sep 17 00:00:00 2001 From: akshat Date: Wed, 2 Apr 2025 15:10:00 +0530 Subject: [PATCH 3/4] fix(wpa_supplicant): Detect PBC overlap even when UUID is null --- .../wpa_supplicant/esp_supplicant/src/esp_wps.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index 0c27f7ac38..f505f33b18 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -351,7 +351,7 @@ is_wps_pbc_overlap(struct wps_sm *sm, const u8 *sel_uuid) { if (!sel_uuid) { wpa_printf(MSG_DEBUG, "WPS: null uuid field"); - return false; + return true; } if (os_memcmp(sel_uuid, sm->uuid_r, WPS_UUID_LEN) != 0) { @@ -372,7 +372,7 @@ 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) { + if (sm->wps_pbc_overlap) { return false; } @@ -447,11 +447,13 @@ wps_parse_scan_result(struct wps_scan_ie *scan) 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) { - 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; - } os_memcpy(sm->uuid_r, scan_uuid, WPS_UUID_LEN); } From bfb000b23cf11c64b415b0b7c70ae10c83991163 Mon Sep 17 00:00:00 2001 From: akshat Date: Wed, 16 Apr 2025 10:20:09 +0530 Subject: [PATCH 4/4] fix(wpa_supplicant): Disconnect from previous AP while initiating WPS --- components/wpa_supplicant/esp_supplicant/src/esp_wps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c index f505f33b18..e17d50adaa 100644 --- a/components/wpa_supplicant/esp_supplicant/src/esp_wps.c +++ b/components/wpa_supplicant/esp_supplicant/src/esp_wps.c @@ -1463,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);