From 1d30dac41b90317225c75500b45fae6f7cf39a6f Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 23 Oct 2014 21:30:32 +0300 Subject: 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). CRs-fixed: 746126 Git-commit: e706b8c8e5da0c6456e3b52f84585193232e79aa Git-repo : git://w1.fi/srv/git/hostap.git Signed-off-by: Jouni Malinen Change-Id: I61318abc3888d65c24d6cbca2528ab63cb3dd832 --- src/p2p/p2p.c | 62 +++++++++++++++++++++++++++++++++++++++++++++------------ src/p2p/p2p_i.h | 5 +++++ 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 9ee91476..e3d39e0a 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -2727,28 +2727,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; + int found; + 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->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 (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; } + } - if (p2p_start_sd(p2p, dev) == 0) + /* + * 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->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; } + 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 3b60582b..75ae8dcd 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; -- cgit v1.2.3