diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index af2d24afd..22760d91e 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -2650,8 +2650,7 @@ static void p2p_retry_pd(struct p2p_data *p2p) /* * Retry the prov disc req attempt only for the peer that the user had - * requested for and provided a join has not been initiated on it - * in the meantime. + * requested. */ dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { @@ -2660,15 +2659,14 @@ static void p2p_retry_pd(struct p2p_data *p2p) continue; if (!dev->req_config_methods) continue; - if (dev->flags & P2P_DEV_PD_FOR_JOIN) - continue; wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send " "pending Provision Discovery Request to " MACSTR " (config methods 0x%x)", MAC2STR(dev->info.p2p_device_addr), dev->req_config_methods); - p2p_send_prov_disc_req(p2p, dev, 0, 0); + p2p_send_prov_disc_req(p2p, dev, + dev->flags & P2P_DEV_PD_FOR_JOIN, 0); return; } } @@ -3183,9 +3181,23 @@ static void p2p_timeout_prov_disc_req(struct p2p_data *p2p) p2p->pd_retries--; p2p_retry_pd(p2p); } else { + struct p2p_device *dev; + int for_join = 0; + + dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) { + if (os_memcmp(p2p->pending_pd_devaddr, + dev->info.p2p_device_addr, ETH_ALEN) != 0) + continue; + if (dev->req_config_methods && + (dev->flags & P2P_DEV_PD_FOR_JOIN)) + for_join = 1; + } + if (p2p->cfg->prov_disc_fail) p2p->cfg->prov_disc_fail(p2p->cfg->cb_ctx, p2p->pending_pd_devaddr, + for_join ? + P2P_PROV_DISC_TIMEOUT_JOIN : P2P_PROV_DISC_TIMEOUT); p2p_reset_pending_pd(p2p); } diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 5eeb65385..8b2aab2d1 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -232,6 +232,7 @@ enum p2p_prov_disc_status { P2P_PROV_DISC_SUCCESS, P2P_PROV_DISC_TIMEOUT, P2P_PROV_DISC_REJECTED, + P2P_PROV_DISC_TIMEOUT_JOIN, }; struct p2p_channel { diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index d3e63b73f..9b6a88e7f 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -723,19 +723,13 @@ static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s, if (result != OFFCHANNEL_SEND_ACTION_SUCCESS && wpa_s->pending_pd_before_join && (os_memcmp(dst, wpa_s->pending_join_dev_addr, ETH_ALEN) == 0 || - os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0)) { + os_memcmp(dst, wpa_s->pending_join_iface_addr, ETH_ALEN) == 0) && + wpa_s->p2p_fallback_to_go_neg) { wpa_s->pending_pd_before_join = 0; - if (wpa_s->p2p_fallback_to_go_neg) { - wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req " - "during p2p_connect-auto"); - wpas_p2p_fallback_to_go_neg(wpa_s, 0); - return; - } - - wpa_printf(MSG_DEBUG, "P2P: Starting pending " - "join-existing-group operation (no ACK for PD " - "Req)"); - wpas_p2p_join_start(wpa_s); + wpa_dbg(wpa_s, MSG_DEBUG, "P2P: No ACK for PD Req " + "during p2p_connect-auto"); + wpas_p2p_fallback_to_go_neg(wpa_s, 0); + return; } } @@ -2290,6 +2284,15 @@ static void wpas_prov_disc_fail(void *ctx, const u8 *peer, return; } + if (status == P2P_PROV_DISC_TIMEOUT_JOIN) { + wpa_s->pending_pd_before_join = 0; + wpa_printf(MSG_DEBUG, "P2P: Starting pending " + "join-existing-group operation (no ACK for PD " + "Req attempts)"); + wpas_p2p_join_start(wpa_s); + return; + } + wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_PROV_DISC_FAILURE " p2p_dev_addr=" MACSTR " status=%d", MAC2STR(peer), status);