aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-02-05 18:52:24 (GMT)
committerJouni Malinen <j@w1.fi>2012-02-05 18:52:24 (GMT)
commitf63b8542156496ba88ef9f161e5931122d7319b9 (patch)
treecf548cc0a9cd2707d6942db0b05919d3d8ccc847 /wpa_supplicant
parentc19316354ed46e688704c1ebcf1c7efe816ddf31 (diff)
downloadhostap-f63b8542156496ba88ef9f161e5931122d7319b9.zip
hostap-f63b8542156496ba88ef9f161e5931122d7319b9.tar.gz
hostap-f63b8542156496ba88ef9f161e5931122d7319b9.tar.bz2
P2P: Wait for PD-before-join response
Even though the Provision Discovery Response frame from PD-before-join does not really provide any additional information, it can be better to wait for it before starting the join operation. This adds a minimal extra latency in the most common case and cleans up the sequence of driver operations and debug log by avoiding potential processing of the Provision Discovery Response while already running a scan for the actual connection. If transmission of Provision Discovery Request fails, join operation is started without the additional wait. In addition, a new timeout is used to start the join if Provision Discovery Response is lost for any reason. Signed-hostap: Jouni Malinen <j@w1.fi>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/p2p_supplicant.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index ffda3bb..5cfa972 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -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;