]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Do not stop Listen state if it is on correct channel
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 20 Oct 2010 16:37:47 +0000 (19:37 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 20 Oct 2010 16:44:16 +0000 (19:44 +0300)
This is needed to optimize response to GO Negotiation Request frames.
The extra remain-on-channel cancel followed by new remain-on-channel for
the same channel takes too much time with some driver/firmware
designs for the response to go out quickly enough to avoid peer
timing out while waiting for our response.

src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_go_neg.c

index 7e93d9ae8ce8e0f38673a71eb61ebd58db059835..1db44f55da23ef55e770d893db5e154a9503c528 100644 (file)
@@ -783,7 +783,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
 }
 
 
-void p2p_stop_find(struct p2p_data *p2p)
+void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
 {
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Stopping find");
        eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
@@ -793,10 +793,21 @@ void p2p_stop_find(struct p2p_data *p2p)
        p2p->go_neg_peer = NULL;
        p2p->sd_peer = NULL;
        p2p->invite_peer = NULL;
+       if (freq > 0 && p2p->drv_in_listen == freq && p2p->in_listen) {
+               wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip stop_listen "
+                       "since we are on correct channel for response");
+               return;
+       }
        p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
 }
 
 
+void p2p_stop_find(struct p2p_data *p2p)
+{
+       p2p_stop_find_for_freq(p2p, 0);
+}
+
+
 static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq)
 {
        if (force_freq) {
@@ -2193,7 +2204,7 @@ void p2p_listen_cb(struct p2p_data *p2p, unsigned int freq,
                p2p->pending_listen_sec, p2p->pending_listen_usec,
                p2p->pending_listen_freq);
        p2p->in_listen = 1;
-       p2p->drv_in_listen = 1;
+       p2p->drv_in_listen = freq;
        if (p2p->pending_listen_sec || p2p->pending_listen_usec) {
                /*
                 * Add 20 msec extra wait to avoid race condition with driver
index 108af5d4b78531637b4d6895109707a83ea11cff..ffe02a2a89c9bfb98c0141bdcd240d917ba2a519 100644 (file)
@@ -669,6 +669,16 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout,
  */
 void p2p_stop_find(struct p2p_data *p2p);
 
+/**
+ * p2p_stop_find_for_freq - Stop P2P Find for next oper on specific freq
+ * @p2p: P2P module context from p2p_init()
+ * @freq: Frequency in MHz for next operation
+ *
+ * This is like p2p_stop_find(), but Listen state is not stopped if we are
+ * already on the same frequency.
+ */
+void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq);
+
 /**
  * p2p_listen - Start P2P Listen state for specified duration
  * @p2p: P2P module context from p2p_init()
index 434d2094f84ca754764caf40957d564fa79b9b09..55c576dcab4504a184401e071a2b19897bd2af01 100644 (file)
@@ -579,7 +579,7 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: GO Negotiation with " MACSTR, MAC2STR(sa));
                if (p2p->state != P2P_IDLE)
-                       p2p_stop_find(p2p);
+                       p2p_stop_find_for_freq(p2p, rx_freq);
                p2p_set_state(p2p, P2P_GO_NEG);
                p2p_clear_timeout(p2p);
                dev->dialog_token = msg.dialog_token;