]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - build-utilities/hostap.git/commitdiff
P2P: Wait for PD-before-join response
authorJouni Malinen <j@w1.fi>
Sun, 5 Feb 2012 18:52:24 +0000 (20:52 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 5 Feb 2012 18:52:24 +0000 (20:52 +0200)
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>

wpa_supplicant/p2p_supplicant.c

index ffda3bb6f37de601ba7ba4b7e787b891e61ab528..5cfa9720d609b354e55a9a1ddbd6337a2e37b188 100644 (file)
@@ -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;