From e706b8c8e5da0c6456e3b52f84585193232e79aa Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 23 Oct 2014 21:30:32 +0300 Subject: [PATCH] P2P: Iterate through all peers in pending pre-find operation Commit 7139cf4a4f1fecfd03d0daff9bb33adb80cc3530 ('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 --- src/p2p/p2p.c | 70 +++++++++++++++++++++++++++++++++++++------------ src/p2p/p2p_i.h | 5 ++++ 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 5c82fd3d9..b29b5060b 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -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); diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 3b60582bb..75ae8dcd8 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -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;