|
@@ -62,6 +62,8 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s);
|
|
|
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);
|
|
|
+static void wpas_p2p_pd_before_join_timeout(void *eloop_ctx,
|
|
|
+ void *timeout_ctx);
|
|
|
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);
|
|
@@ -638,12 +640,14 @@ static void wpas_p2p_send_action_tx_status(struct wpa_supplicant *wpa_s,
|
|
|
|
|
|
p2p_send_action_cb(wpa_s->global->p2p, freq, dst, src, bssid, res);
|
|
|
|
|
|
- if (wpa_s->pending_pd_before_join &&
|
|
|
+ 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)) {
|
|
|
wpa_s->pending_pd_before_join = 0;
|
|
|
wpa_printf(MSG_DEBUG, "P2P: Starting pending "
|
|
|
- "join-existing-group operation");
|
|
|
+ "join-existing-group operation (no ACK for PD "
|
|
|
+ "Req)");
|
|
|
wpas_p2p_join_start(wpa_s);
|
|
|
}
|
|
|
}
|
|
@@ -2408,6 +2412,7 @@ void wpas_p2p_deinit(struct wpa_supplicant *wpa_s)
|
|
|
wpa_s->go_params = NULL;
|
|
|
eloop_cancel_timeout(wpas_p2p_group_formation_timeout, wpa_s, NULL);
|
|
|
eloop_cancel_timeout(wpas_p2p_join_scan, wpa_s, NULL);
|
|
|
+ eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s, NULL);
|
|
|
wpa_s->p2p_long_listen = 0;
|
|
|
eloop_cancel_timeout(wpas_p2p_long_listen_timeout, wpa_s, NULL);
|
|
|
eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
|
|
@@ -2542,6 +2547,21 @@ static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
|
|
|
}
|
|
|
|
|
|
|
|
|
+static void wpas_p2p_pd_before_join_timeout(void *eloop_ctx, void *timeout_ctx)
|
|
|
+{
|
|
|
+ struct wpa_supplicant *wpa_s = eloop_ctx;
|
|
|
+ if (!wpa_s->pending_pd_before_join)
|
|
|
+ return;
|
|
|
+
|
|
|
+ * Provision Discovery Response may have been lost - try to connect
|
|
|
+ * anyway since we do not need any information from this PD.
|
|
|
+ */
|
|
|
+ wpa_printf(MSG_DEBUG, "P2P: PD timeout for join-existing-group - "
|
|
|
+ "try to connect anyway");
|
|
|
+ wpas_p2p_join_start(wpa_s);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
|
|
|
struct wpa_scan_results *scan_res)
|
|
|
{
|
|
@@ -2640,8 +2660,15 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
|
|
|
|
|
|
|
|
|
* Actual join operation will be started from the Action frame
|
|
|
- * TX status callback.
|
|
|
+ * TX status callback (if no ACK is received) or when the
|
|
|
+ * Provision Discovery Response is received. Use a short
|
|
|
+ * timeout as a backup mechanism should the Provision Discovery
|
|
|
+ * Response be lost for any reason.
|
|
|
*/
|
|
|
+ eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s,
|
|
|
+ NULL);
|
|
|
+ eloop_register_timeout(2, 0, wpas_p2p_pd_before_join_timeout,
|
|
|
+ wpa_s, NULL);
|
|
|
return;
|
|
|
}
|
|
|
|
|
@@ -2740,6 +2767,7 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s)
|
|
|
struct wpa_supplicant *group;
|
|
|
struct p2p_go_neg_results res;
|
|
|
|
|
|
+ eloop_cancel_timeout(wpas_p2p_pd_before_join_timeout, wpa_s, NULL);
|
|
|
group = wpas_p2p_get_group_iface(wpa_s, 0, 0);
|
|
|
if (group == NULL)
|
|
|
return -1;
|