diff options
| author | Jouni Malinen <jouni@qca.qualcomm.com> | 2014-10-23 21:30:32 +0300 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2014-11-04 08:24:46 -0700 |
| commit | 1d30dac41b90317225c75500b45fae6f7cf39a6f (patch) | |
| tree | f7b5983aa19af409d690b00f29f4ea5b34241f0e | |
| parent | dad4d8aec0303abfe19d63baf9a318886ac8c4f7 (diff) | |
| download | android_external_wpa_supplicant_8-1d30dac41b90317225c75500b45fae6f7cf39a6f.tar.gz android_external_wpa_supplicant_8-1d30dac41b90317225c75500b45fae6f7cf39a6f.tar.bz2 android_external_wpa_supplicant_8-1d30dac41b90317225c75500b45fae6f7cf39a6f.zip | |
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 <jouni@qca.qualcomm.com>
Change-Id: I61318abc3888d65c24d6cbca2528ab63cb3dd832
| -rw-r--r-- | src/p2p/p2p.c | 62 | ||||
| -rw-r--r-- | 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; |
