]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Fix remain-on-channel use with PD/Invitation Request while in Listen
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 27 Feb 2012 15:23:41 +0000 (17:23 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 27 Feb 2012 15:23:41 +0000 (17:23 +0200)
If Listen state was in progress on another channel when a request to
send an Action frame (e.g., Provision Discovery Request or Invitation
Request to a peer on the peer's Listen channel that is different from
our Listenc hannel) is issued, wpa_supplicant tried to use concurrent
remain-on-channel operations. While some drivers can handle this
cleanly, there are drivers that don't and wpa_supplicant is not expected
to request concurrent remain-on-channel operations.

Fix this by cancelling the ongoing remain-on-channel with stop_listen
prior to sending the Action frame on another channel. If a P2P search
was in progress, it will be continued after the timeout on the new
operation.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/p2p/p2p.c
src/p2p/p2p_i.h
src/p2p/p2p_invitation.c
src/p2p/p2p_pd.c

index 2b003aee85bcb475c68de482f5c6f516ee24a82f..b196e6fddd680e63716e982394f68d942153a72c 100644 (file)
@@ -1024,11 +1024,21 @@ void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
        p2p->go_neg_peer = NULL;
        p2p->sd_peer = NULL;
        p2p->invite_peer = NULL;
+       p2p_stop_listen_for_freq(p2p, freq);
+}
+
+
+void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq)
+{
        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;
        }
+       if (p2p->in_listen) {
+               p2p->in_listen = 0;
+               p2p_clear_timeout(p2p);
+       }
        if (p2p->drv_in_listen) {
                /*
                 * The driver may not deliver callback to p2p_listen_end()
index 8f9449eab05d5b4fcd6d201638e9242fe81e7137..eecef5488643018d7af69e6798fff61999851095 100644 (file)
@@ -667,5 +667,6 @@ void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len);
 int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
                    const u8 *src, const u8 *bssid, const u8 *buf,
                    size_t len, unsigned int wait_time);
+void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq);
 
 #endif /* P2P_I_H */
index 417f1e7ea7b1a0cf40f930e27a5e80226deab4c8..1e6ed7d715188c953e8217c6a8fc8a466098802d 100644 (file)
@@ -344,6 +344,8 @@ int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev,
        req = p2p_build_invitation_req(p2p, dev, go_dev_addr);
        if (req == NULL)
                return -1;
+       if (p2p->state != P2P_IDLE)
+               p2p_stop_listen_for_freq(p2p, freq);
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                "P2P: Sending Invitation Request");
        p2p_set_state(p2p, P2P_INVITE);
index 55a3b908e1c4812e3e1f0974356ffb5ace04631f..ca248aed642e36892f4caf6a90ab669ecdeb598b 100644 (file)
@@ -316,6 +316,8 @@ int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
        if (req == NULL)
                return -1;
 
+       if (p2p->state != P2P_IDLE)
+               p2p_stop_listen_for_freq(p2p, freq);
        p2p->pending_action_state = P2P_PENDING_PD;
        if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
                            p2p->cfg->dev_addr, dev->info.p2p_device_addr,