From 17e20912790a2cca616ddd2856e60e871a377726 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 9 Sep 2014 17:20:23 +0300 Subject: [PATCH] P2P: Fix radio work issue with wait-for-peer GO Negotiation If a TX status event and RX event for a GO Negotiation frame gets delayed long enough to miss the initial wait, it was possible for reception of a GO Negotiation Response frame with status 1 to try to initiate a new p2p-listen work item to wait for the peer to become ready while a previous p2p-listen was already in progress due to that earlier timeout while waiting for peer. This would result in the new start_listen request getting rejected ("P2P: Reject start_listen since p2p_listen_work already exists") and the negotiation not proceeding. Work around this by using P2P_WAIT_PEER_CONNECT state instead of P2P_WAIT_PEER_IDLE if P2P_CONNECT_LISTEN state has already been entered when processing this special GO Negotiation Response status=1 case. This can avoid double-scheduling of p2p-listen and as such, completion of the GO negotiation even if the driver event or peer response are not received in time (the response is supposed to be there within 100 ms per spec, but there are number of deployed devices that do not really meet this requirement). Signed-off-by: Jouni Malinen --- src/p2p/p2p_go_neg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index bd7a2cf51..21fae3f20 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -958,7 +958,10 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, p2p_dbg(p2p, "Wait for the peer to become ready for GO Negotiation"); dev->flags |= P2P_DEV_NOT_YET_READY; os_get_reltime(&dev->go_neg_wait_started); - p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); + if (p2p->state == P2P_CONNECT_LISTEN) + p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); + else + p2p_set_state(p2p, P2P_WAIT_PEER_IDLE); p2p_set_timeout(p2p, 0, 0); } else { p2p_dbg(p2p, "Stop GO Negotiation attempt");