P2P: Use timer to fail GO Negotation while waiting for peer

The timeout check while waiting for the peer to accept the GO
Negotiation depended on the WAIT_PEER_IDLE or WAIT_PEER_CONNECT states
being in use. Any P2P command to alter such states would have resulted
in the failure to time out GO Negotiation and thus ended up in not
indicating GO Negotiation failure or left the selected peer available
for new GO negotiation after the expected two minute timeout.

Fix this by using a separate timer to time out GO Negotiation
irrespective of the P2P state.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Rashmi Ramanna 2014-10-28 16:56:43 +05:30 committed by Jouni Malinen
parent 4fb26cee95
commit 0c6eee8b75
3 changed files with 27 additions and 11 deletions

View file

@ -216,6 +216,7 @@ void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
{
struct p2p_go_neg_results res;
p2p_clear_timeout(p2p);
eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL);
p2p_set_state(p2p, P2P_IDLE);
if (p2p->go_neg_peer) {
p2p->go_neg_peer->flags &= ~P2P_DEV_PEER_WAITING_RESPONSE;
@ -2551,6 +2552,7 @@ void p2p_deinit(struct p2p_data *p2p)
eloop_cancel_timeout(p2p_ext_listen_timeout, p2p, NULL);
eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL);
eloop_cancel_timeout(p2p_go_neg_start, p2p, NULL);
eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL);
p2p_flush(p2p);
p2p_free_req_dev_types(p2p);
os_free(p2p->cfg->dev_name);
@ -2593,8 +2595,10 @@ int p2p_unauthorize(struct p2p_data *p2p, const u8 *addr)
p2p_dbg(p2p, "Unauthorizing " MACSTR, MAC2STR(addr));
if (p2p->go_neg_peer == dev)
if (p2p->go_neg_peer == dev) {
eloop_cancel_timeout(p2p_go_neg_wait_timeout, p2p, NULL);
p2p->go_neg_peer = NULL;
}
dev->wps_method = WPS_NOT_READY;
dev->oob_pw_id = 0;
@ -3404,20 +3408,12 @@ static void p2p_timeout_wait_peer_connect(struct p2p_data *p2p)
static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
{
struct p2p_device *dev = p2p->go_neg_peer;
struct os_reltime now;
if (dev == NULL) {
p2p_dbg(p2p, "Unknown GO Neg peer - stop GO Neg wait");
return;
}
os_get_reltime(&now);
if (os_reltime_expired(&now, &dev->go_neg_wait_started, 120)) {
p2p_dbg(p2p, "Timeout on waiting peer to become ready for GO Negotiation");
p2p_go_neg_failed(p2p, dev, -1);
return;
}
p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation");
p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
p2p_listen_in_find(p2p, 0);
@ -4902,3 +4898,14 @@ void p2p_set_vendor_elems(struct p2p_data *p2p, struct wpabuf **vendor_elem)
{
p2p->vendor_elem = vendor_elem;
}
void p2p_go_neg_wait_timeout(void *eloop_ctx, void *timeout_ctx)
{
struct p2p_data *p2p = eloop_ctx;
p2p_dbg(p2p,
"Timeout on waiting peer to become ready for GO Negotiation");
if (p2p->go_neg_peer)
p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
}