]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Iterate through all peers in pending pre-find operation
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 23 Oct 2014 18:30:32 +0000 (21:30 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 23 Oct 2014 18:30:32 +0000 (21:30 +0300)
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 <jouni@qca.qualcomm.com>
src/p2p/p2p.c
src/p2p/p2p_i.h

index 5c82fd3d985bf872bf4c8cec11d20b3a4ccb8e25..b29b5060bf746c5926a63318a4af459c49ce1430 100644 (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;
+       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);
index 3b60582bb97c579f1197b6594385568c19b05b1c..75ae8dcd8d072ee75988f777df7994d9630f25fc 100644 (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;