From patchwork Tue Nov 29 16:36:26 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [PATCH/RFC] improve overlap detection and handling for P2P PBC Date: Tue, 29 Nov 2011 06:36:26 -0000 From: Vitaly Wool X-Patchwork-Id: 128302 Message-Id: To: hostap@lists.shmoo.com Hi, I've been struggling to get my prototype P2P device to work with Samsung Galaxy SII. The connection establishment kept failing with WPS_FAILURE and it turned out to be due to overlap detected: 01-03 01:27:26.140 E/wpa_supplicant( 2455): WPS: Requested UUID - hexdump(len=16): 22 21 02 03 04 05 06 07 08 09 1a 1b 1c 1d 1e 1f 01-03 01:27:26.140 D/wpa_supplicant( 2455): WPS: Consider PBC session with 06:46:65:d3:4a:54 01-03 01:27:26.140 E/wpa_supplicant( 2455): WPS: UUID-E - hexdump(len=16): 22 21 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 01-03 01:27:26.140 D/wpa_supplicant( 2455): WPS: New Enrollee 01-03 01:27:26.140 D/wpa_supplicant( 2455): WPS: 2 active PBC session(s) found 01-03 01:27:26.140 D/wpa_supplicant( 2455): WPS: PBC overlap - deny PBC negotiation So Galaxy changes UUID for PBC negotiation but the thing is, it could have been considered to be the same session because the MAC address is the same. There is a mechanism to do so for P2P connections in wpa_supplicant but it doesn't work because P2P MAC address is not passed over to wps_registrar_skip_overlap(). This patch adds that and also fixes the PBC session removal after the negotiation (the current version leaves the session in the list if it doesn't match UUID, I suggest that we remove all sessions for the given MAC). diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c index 4a49197..eed29e2 100644 --- a/src/wps/wps_registrar.c +++ b/src/wps/wps_registrar.c @@ -310,13 +310,16 @@ static void wps_registrar_add_pbc_session(struct wps_registrar *reg, static void wps_registrar_remove_pbc_session(struct wps_registrar *reg, - const u8 *uuid_e) + const u8 *uuid_e, + const u8 *p2p_dev_addr) { struct wps_pbc_session *pbc, *prev = NULL, *tmp; pbc = reg->pbc_sessions; while (pbc) { - if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0) { + if (os_memcmp(pbc->uuid_e, uuid_e, WPS_UUID_LEN) == 0 || + (!is_zero_ether_addr(reg->p2p_dev_addr) && + !os_memcmp(reg->p2p_dev_addr, p2p_dev_addr, ETH_ALEN))) { if (prev) prev->next = pbc->next; else @@ -3035,7 +3038,8 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps, if (wps->pbc) { wps_registrar_remove_pbc_session(wps->wps->registrar, - wps->uuid_e); + wps->uuid_e, + wps->p2p_dev_addr); wps_registrar_pbc_completed(wps->wps->registrar); } else { wps_registrar_pin_completed(wps->wps->registrar); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index c6484af..1700ace 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -689,7 +689,7 @@ static void p2p_go_configured(void *ctx, void *data) } if (params->wps_method == WPS_PBC) wpa_supplicant_ap_wps_pbc(wpa_s, params->peer_interface_addr, - NULL); + params->peer_device_addr); else if (wpa_s->p2p_pin[0]) wpa_supplicant_ap_wps_pin(wpa_s, params->peer_interface_addr, wpa_s->p2p_pin, NULL, 0);