From c48414af8f1425726920d87c3544ad264f150dcd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 13 Jan 2014 21:39:06 +0200 Subject: [PATCH] P2P: Limit join-a-group scans based on SSID from invitation If we already know the SSID of the P2P group we are trying to join, use that SSID to limit scan responses and BSS selection since we do not really look for any other network in this case. In addition, this can fix cases where the peer has just changed its SSID (e.g., started a new group) and there may be multiple BSS entries for the same BSSID. Signed-hostap: Jouni Malinen --- wpa_supplicant/p2p_supplicant.c | 63 +++++++++++++++++++++++-------- wpa_supplicant/wpa_supplicant_i.h | 2 + 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index caf8a5ec0..7d5667c2f 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -104,11 +104,12 @@ static struct wpa_supplicant * wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, int go); static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s); -static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq); +static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, + const u8 *ssid, size_t ssid_len); static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx); static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, const u8 *dev_addr, enum p2p_wps_method wps_method, - int auto_join); + int auto_join, const u8 *ssid, size_t ssid_len); static int wpas_p2p_create_iface(struct wpa_supplicant *wpa_s); static void wpas_p2p_cross_connect_setup(struct wpa_supplicant *wpa_s); static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx); @@ -2868,7 +2869,8 @@ static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid, if (!persistent_group) { wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR - " to join an active group", MAC2STR(sa)); + " to join an active group (SSID: %s)", + MAC2STR(sa), wpa_ssid_txt(ssid, ssid_len)); if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) && (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN) == 0 || @@ -2991,8 +2993,8 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, if (status == P2P_SC_SUCCESS) { wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR - " was accepted; op_freq=%d MHz", - MAC2STR(sa), op_freq); + " was accepted; op_freq=%d MHz, SSID=%s", + MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len)); if (s) { int go = s->mode == WPAS_MODE_P2P_GO; wpas_p2p_group_add_persistent( @@ -3001,7 +3003,8 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, } else if (bssid) { wpa_s->user_initiated_pd = 0; wpas_p2p_join(wpa_s, bssid, go_dev_addr, - wpa_s->p2p_wps_method, 0); + wpa_s->p2p_wps_method, 0, + ssid, ssid_len); } return; } @@ -4031,7 +4034,7 @@ static int wpas_p2p_peer_go(struct wpa_supplicant *wpa_s, static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) { - struct wpa_bss *bss; + struct wpa_bss *bss = NULL; int freq; u8 iface_addr[ETH_ALEN]; @@ -4063,7 +4066,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, MAC2STR(wpa_s-> pending_join_dev_addr), freq); - wpas_p2p_join_scan_req(wpa_s, freq); + wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0); return; } } @@ -4136,7 +4139,22 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " "from P2P peer table: %d MHz", freq); } - bss = wpa_bss_get_bssid_latest(wpa_s, wpa_s->pending_join_iface_addr); + if (wpa_s->p2p_join_ssid_len) { + wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID " + MACSTR " and SSID %s", + MAC2STR(wpa_s->pending_join_iface_addr), + wpa_ssid_txt(wpa_s->p2p_join_ssid, + wpa_s->p2p_join_ssid_len)); + bss = wpa_bss_get(wpa_s, wpa_s->pending_join_iface_addr, + wpa_s->p2p_join_ssid, + wpa_s->p2p_join_ssid_len); + } + if (!bss) { + wpa_printf(MSG_DEBUG, "P2P: Trying to find target GO BSS entry based on BSSID " + MACSTR, MAC2STR(wpa_s->pending_join_iface_addr)); + bss = wpa_bss_get_bssid_latest(wpa_s, + wpa_s->pending_join_iface_addr); + } if (bss) { freq = bss->freq; wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " @@ -4213,7 +4231,8 @@ start: } -static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) +static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, + const u8 *ssid, size_t ssid_len) { int ret; struct wpa_driver_scan_params params; @@ -4225,8 +4244,16 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) /* P2P Wildcard SSID */ params.num_ssids = 1; - params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; - params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; + if (ssid && ssid_len) { + params.ssids[0].ssid = ssid; + params.ssids[0].ssid_len = ssid_len; + os_memcpy(wpa_s->p2p_join_ssid, ssid, ssid_len); + wpa_s->p2p_join_ssid_len = ssid_len; + } else { + params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; + params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN; + wpa_s->p2p_join_ssid_len = 0; + } wpa_s->wps->dev.p2p = 1; wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, @@ -4283,18 +4310,22 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq) static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; - wpas_p2p_join_scan_req(wpa_s, 0); + wpas_p2p_join_scan_req(wpa_s, 0, NULL, 0); } static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, const u8 *dev_addr, enum p2p_wps_method wps_method, - int auto_join) + int auto_join, const u8 *ssid, size_t ssid_len) { wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface " MACSTR " dev " MACSTR ")%s", MAC2STR(iface_addr), MAC2STR(dev_addr), auto_join ? " (auto_join)" : ""); + if (ssid && ssid_len) { + wpa_printf(MSG_DEBUG, "P2P: Group SSID specified: %s", + wpa_ssid_txt(ssid, ssid_len)); + } wpa_s->p2p_auto_pd = 0; wpa_s->p2p_auto_join = !!auto_join; @@ -4306,7 +4337,7 @@ static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr, wpas_p2p_stop_find(wpa_s); wpa_s->p2p_join_scan_count = 0; - wpas_p2p_join_scan(wpa_s, NULL); + wpas_p2p_join_scan_req(wpa_s, 0, ssid, ssid_len); return 0; } @@ -4561,7 +4592,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, } wpa_s->user_initiated_pd = 1; if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, - auto_join) < 0) + auto_join, NULL, 0) < 0) return -1; return ret; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 0130f8157..3a2853489 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -670,6 +670,8 @@ struct wpa_supplicant { u8 pending_join_iface_addr[ETH_ALEN]; u8 pending_join_dev_addr[ETH_ALEN]; int pending_join_wps_method; + u8 p2p_join_ssid[32]; + size_t p2p_join_ssid_len; int p2p_join_scan_count; int auto_pd_scan_retry; int force_long_sd;