P2P: Iterate through all peers in pending pre-find operation

Commit 7139cf4a4f ('P2P: Decrement
sd_pending_bcast_queries when sd returns success') changed P2P SD
behavior in a way that the P2P search loop ended up in continuing with
the first peer entry until it acknowledged receipt of a pending
broadcast SD request while the previous design went through all peers
once. While it is reasonable to retry SD, getting stuck with the first
peer is not really desirable. Change the p2p_continue_find() loop to
continue from the next peer in each iteration to allow progress through
all peers that have pending operations if any other peer is not
acknowledging frames (e.g., due to not being on Listen channel).

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2014-10-23 21:30:32 +03:00 committed by Jouni Malinen
parent b41f26845a
commit e706b8c8e5
2 changed files with 58 additions and 17 deletions

View file

@ -2764,28 +2764,64 @@ int p2p_set_country(struct p2p_data *p2p, const char *country)
}
static int p2p_pre_find_operation(struct p2p_data *p2p, struct p2p_device *dev)
{
if (dev->sd_pending_bcast_queries == 0) {
/* Initialize with total number of registered broadcast
* SD queries. */
dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries;
}
if (p2p_start_sd(p2p, dev) == 0)
return 1;
if (dev->req_config_methods &&
!(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
p2p_dbg(p2p, "Send pending Provision Discovery Request to "
MACSTR " (config methods 0x%x)",
MAC2STR(dev->info.p2p_device_addr),
dev->req_config_methods);
if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0)
return 1;
}
return 0;
}
void p2p_continue_find(struct p2p_data *p2p)
{
struct p2p_device *dev;
p2p_set_state(p2p, P2P_SEARCH);
dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
if (dev->sd_pending_bcast_queries == 0) {
/* Initialize with total number of registered broadcast
* SD queries. */
dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries;
}
int found;
if (p2p_start_sd(p2p, dev) == 0)
return;
if (dev->req_config_methods &&
!(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
p2p_dbg(p2p, "Send pending Provision Discovery Request to "
MACSTR " (config methods 0x%x)",
MAC2STR(dev->info.p2p_device_addr),
dev->req_config_methods);
if (p2p_send_prov_disc_req(p2p, dev, 0, 0) == 0)
return;
p2p_set_state(p2p, P2P_SEARCH);
/* Continue from the device following the last iteration */
found = 0;
dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
if (dev == p2p->last_p2p_find_oper) {
found = 1;
continue;
}
if (!found)
continue;
if (p2p_pre_find_operation(p2p, dev) > 0) {
p2p->last_p2p_find_oper = dev;
return;
}
}
/*
* Wrap around to the beginning of the list and continue until the last
* iteration device.
*/
dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
if (p2p_pre_find_operation(p2p, dev) > 0) {
p2p->last_p2p_find_oper = dev;
return;
}
if (dev == p2p->last_p2p_find_oper)
break;
}
p2p_listen_in_find(p2p, 1);

View file

@ -260,6 +260,11 @@ struct p2p_data {
*/
struct p2p_device *invite_peer;
/**
* last_p2p_find_oper - Pointer to last pre-find operation peer
*/
struct p2p_device *last_p2p_find_oper;
const u8 *invite_go_dev_addr;
u8 invite_go_dev_addr_buf[ETH_ALEN];
int invite_dev_pw_id;