P2P: Skip Listen phase when peer is expected to be waiting
In case we have replied to a peer's GO Negotiation Request frame with a GO Negotiation Response frame using status code info-currently-unavailable (1), the peer is likely going to wait for us to initiate GO Negotiation on its Listen channel. We were previously using alternativing send-GO-Neg-Req and Listen phase when providing that response after the user had authorized the connection. However, the Listen phase here is unnecessary in this case and will make the connection take longer time to go through. Skip the Listen phase and make the wait-for-GO-Neg-Resp timeout random between 100 and 200 ms to avoid getting in sync with the peer. In practice, this will make us retry GO Negotiation Request frames more frequently and remain on the peer's Listen channel for most of the time when initiating GO Negotiation after status=1 response. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
8e4839cefa
commit
fb8984fd6f
1 changed files with 31 additions and 2 deletions
|
@ -198,8 +198,10 @@ void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
|
|||
struct p2p_go_neg_results res;
|
||||
p2p_clear_timeout(p2p);
|
||||
p2p_set_state(p2p, P2P_IDLE);
|
||||
if (p2p->go_neg_peer)
|
||||
if (p2p->go_neg_peer) {
|
||||
p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE;
|
||||
p2p->go_neg_peer->wps_method = WPS_NOT_READY;
|
||||
}
|
||||
p2p->go_neg_peer = NULL;
|
||||
|
||||
os_memset(&res, 0, sizeof(res));
|
||||
|
@ -1128,6 +1130,10 @@ void p2p_stop_find_for_freq(struct p2p_data *p2p, int freq)
|
|||
p2p_set_state(p2p, P2P_IDLE);
|
||||
p2p_free_req_dev_types(p2p);
|
||||
p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
|
||||
if (p2p->go_neg_peer) {
|
||||
p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE;
|
||||
p2p->go_neg_peer->wps_method = WPS_NOT_READY;
|
||||
}
|
||||
p2p->go_neg_peer = NULL;
|
||||
p2p->sd_peer = NULL;
|
||||
p2p->invite_peer = NULL;
|
||||
|
@ -2907,6 +2913,7 @@ int p2p_ie_text(struct wpabuf *p2p_ie, char *buf, char *end)
|
|||
static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
|
||||
{
|
||||
struct p2p_device *dev = p2p->go_neg_peer;
|
||||
int timeout;
|
||||
|
||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
|
||||
"P2P: GO Negotiation Request TX callback: success=%d",
|
||||
|
@ -2945,7 +2952,20 @@ static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
|
|||
* channel.
|
||||
*/
|
||||
p2p_set_state(p2p, P2P_CONNECT);
|
||||
p2p_set_timeout(p2p, 0, success ? 500000 : 100000);
|
||||
timeout = success ? 500000 : 100000;
|
||||
if (!success && p2p->go_neg_peer &&
|
||||
(p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE)) {
|
||||
unsigned int r;
|
||||
/*
|
||||
* Peer is expected to wait our response and we will skip the
|
||||
* listen phase. Add some randomness to the wait time here to
|
||||
* make it less likely to hit cases where we could end up in
|
||||
* sync with peer not listening.
|
||||
*/
|
||||
os_get_random((u8 *) &r, sizeof(r));
|
||||
timeout += r % 100000;
|
||||
}
|
||||
p2p_set_timeout(p2p, 0, timeout);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3183,6 +3203,15 @@ static void p2p_timeout_connect(struct p2p_data *p2p)
|
|||
p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
|
||||
return;
|
||||
}
|
||||
if (p2p->go_neg_peer &&
|
||||
(p2p->go_neg_peer->flags & P2P_DEV_PEER_WAITING_RESPONSE) &&
|
||||
p2p->go_neg_peer->connect_reqs < 120) {
|
||||
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Peer expected to "
|
||||
"wait our response - skip listen");
|
||||
p2p_connect_send(p2p, p2p->go_neg_peer);
|
||||
return;
|
||||
}
|
||||
|
||||
p2p_set_state(p2p, P2P_CONNECT_LISTEN);
|
||||
p2p_listen_in_find(p2p, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue