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 <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-01-13 21:39:06 +02:00 committed by Jouni Malinen
parent 7559ad7af6
commit c48414af8f
2 changed files with 49 additions and 16 deletions

View file

@ -104,11 +104,12 @@ static struct wpa_supplicant *
wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
int go); int go);
static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s); 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 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, static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
const u8 *dev_addr, enum p2p_wps_method wps_method, 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 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_cross_connect_setup(struct wpa_supplicant *wpa_s);
static void wpas_p2p_group_idle_timeout(void *eloop_ctx, void *timeout_ctx); 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) { if (!persistent_group) {
wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR 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) && if (!is_zero_ether_addr(wpa_s->p2p_auth_invite) &&
(os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN) (os_memcmp(go_dev_addr, wpa_s->p2p_auth_invite, ETH_ALEN)
== 0 || == 0 ||
@ -2991,8 +2993,8 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
if (status == P2P_SC_SUCCESS) { if (status == P2P_SC_SUCCESS) {
wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR wpa_printf(MSG_DEBUG, "P2P: Invitation from peer " MACSTR
" was accepted; op_freq=%d MHz", " was accepted; op_freq=%d MHz, SSID=%s",
MAC2STR(sa), op_freq); MAC2STR(sa), op_freq, wpa_ssid_txt(ssid, ssid_len));
if (s) { if (s) {
int go = s->mode == WPAS_MODE_P2P_GO; int go = s->mode == WPAS_MODE_P2P_GO;
wpas_p2p_group_add_persistent( 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) { } else if (bssid) {
wpa_s->user_initiated_pd = 0; wpa_s->user_initiated_pd = 0;
wpas_p2p_join(wpa_s, bssid, go_dev_addr, 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; 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, static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res) struct wpa_scan_results *scan_res)
{ {
struct wpa_bss *bss; struct wpa_bss *bss = NULL;
int freq; int freq;
u8 iface_addr[ETH_ALEN]; u8 iface_addr[ETH_ALEN];
@ -4063,7 +4066,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
MAC2STR(wpa_s-> MAC2STR(wpa_s->
pending_join_dev_addr), pending_join_dev_addr),
freq); freq);
wpas_p2p_join_scan_req(wpa_s, freq); wpas_p2p_join_scan_req(wpa_s, freq, NULL, 0);
return; 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 " wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency "
"from P2P peer table: %d MHz", freq); "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) { if (bss) {
freq = bss->freq; freq = bss->freq;
wpa_printf(MSG_DEBUG, "P2P: Target GO operating frequency " 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; int ret;
struct wpa_driver_scan_params params; 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 */ /* P2P Wildcard SSID */
params.num_ssids = 1; params.num_ssids = 1;
params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID; if (ssid && ssid_len) {
params.ssids[0].ssid_len = P2P_WILDCARD_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; wpa_s->wps->dev.p2p = 1;
wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev, 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) static void wpas_p2p_join_scan(void *eloop_ctx, void *timeout_ctx)
{ {
struct wpa_supplicant *wpa_s = eloop_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, static int wpas_p2p_join(struct wpa_supplicant *wpa_s, const u8 *iface_addr,
const u8 *dev_addr, enum p2p_wps_method wps_method, 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 " wpa_printf(MSG_DEBUG, "P2P: Request to join existing group (iface "
MACSTR " dev " MACSTR ")%s", MACSTR " dev " MACSTR ")%s",
MAC2STR(iface_addr), MAC2STR(dev_addr), MAC2STR(iface_addr), MAC2STR(dev_addr),
auto_join ? " (auto_join)" : ""); 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_pd = 0;
wpa_s->p2p_auto_join = !!auto_join; 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); wpas_p2p_stop_find(wpa_s);
wpa_s->p2p_join_scan_count = 0; 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; 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; wpa_s->user_initiated_pd = 1;
if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method, if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
auto_join) < 0) auto_join, NULL, 0) < 0)
return -1; return -1;
return ret; return ret;
} }

View file

@ -670,6 +670,8 @@ struct wpa_supplicant {
u8 pending_join_iface_addr[ETH_ALEN]; u8 pending_join_iface_addr[ETH_ALEN];
u8 pending_join_dev_addr[ETH_ALEN]; u8 pending_join_dev_addr[ETH_ALEN];
int pending_join_wps_method; int pending_join_wps_method;
u8 p2p_join_ssid[32];
size_t p2p_join_ssid_len;
int p2p_join_scan_count; int p2p_join_scan_count;
int auto_pd_scan_retry; int auto_pd_scan_retry;
int force_long_sd; int force_long_sd;