P2P: Fix a race condition in some P2P command sequencies
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 22 Sep 2011 19:43:03 +0000 (22:43 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 22 Sep 2011 19:49:21 +0000 (22:49 +0300)
The p2p->drv_in_listen variable is used to track Listen state operations
in the driver. This is cleared when the driver reports that the Listen
state has ended (p2p_listen_end() gets called). However, it is possible
that the driver does not indicate that if the Listen state is canceled.
This can apparently happen in some cases where p2p_connect command is
issues while the Listen state is in progress.

Work around this issue by clearing p2p->drv_in_listen when Listen state
is stopped as part of p2p_stop operation. This allows the P2P module to
process CONNECT_LISTEN timeout in p2p_timeout_connect_listen() to move
to CONNECT state, e.g., when starting GO Negotiation after Device
Discoverability mechanism.

src/p2p/p2p.c

index cd71a24..ed9f81a 100644 (file)
@@ -929,6 +929,16 @@ void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
                        "since we are on correct channel for response");
                return;
        }
+       if (p2p->drv_in_listen) {
+               /*
+                * The driver may not deliver callback to p2p_listen_end()
+                * when the operation gets canceled, so clear the internal
+                * variable that is tracking driver state.
+                */
+               wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Clear "
+                       "drv_in_listen (%d)", p2p->drv_in_listen);
+               p2p->drv_in_listen = 0;
+       }
        p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
 }