]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow persistent group join retry limit to be configured via D-Bus
authorMatthew Wang <matthewmwang@google.com>
Fri, 16 Dec 2022 19:10:00 +0000 (11:10 -0800)
committerJouni Malinen <j@w1.fi>
Sun, 18 Dec 2022 15:37:08 +0000 (17:37 +0200)
Android and ChromeOS use this to limit retries for auto GO join
operation.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
doc/dbus.doxygen
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant_i.h

index 7950c9b2efddf860b29dde00c1e8435e9b0c5a6b..f75917c2ab905c57797b4985c5788ac1550a290a 100644 (file)
@@ -1592,6 +1592,7 @@ Interface for performing P2P (Wi-Fi Peer-to-Peer) P2P Device operations.
        <tr><td>persistent</td><td>b</td><td>Whether to form a persistent group.</td><td>no</td></tr>
        <tr><td>persistent_group_object</td><td>o</td><td></td><td>no</td></tr>
        <tr><td>frequency</td><td>i</td><td>Operating frequency in MHz</td><td>no</td></tr>
+       <tr><td>retry_limit</td><td>i</td><td>Optional limit on the number of scan attempts to join a group</td><td>no</td></tr>
        </table>
       </dd>
     </dl>
index e0b6e11bb931bd96282433bb83038cfa7e62a917..6588fd47b4a9099a23781d4cfa40ed24dff854fa 100644 (file)
@@ -7128,7 +7128,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
        return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
                                             vht_center_freq2, 0, ht40, vht,
                                             vht_chwidth, he, edmg,
-                                            NULL, 0, 0, allow_6ghz);
+                                            NULL, 0, 0, allow_6ghz, 0);
 }
 
 
index de79178f465533c6d28479d97548b5d90ceffc5f..370aee278cfefcdf5eabd9d4f66090658cd6c5f7 100644 (file)
@@ -355,6 +355,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
        char *pg_object_path = NULL;
        int persistent_group = 0;
        int freq = 0;
+       int retry_limit = 0;
        char *iface = NULL;
        unsigned int group_id = 0;
        struct wpa_ssid *ssid;
@@ -376,6 +377,11 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
                        freq = entry.int32_value;
                        if (freq <= 0)
                                goto inv_args_clear;
+               } else if (os_strcmp(entry.key, "retry_limit") == 0 &&
+                          entry.type == DBUS_TYPE_INT32) {
+                       retry_limit = entry.int32_value;
+                       if (retry_limit <= 0)
+                               goto inv_args_clear;
                } else if (os_strcmp(entry.key, "persistent_group_object") ==
                           0 &&
                           entry.type == DBUS_TYPE_OBJECT_PATH)
@@ -426,7 +432,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
 
                if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
                                                  0, 0, 0, 0, NULL, 0, 0,
-                                                 false)) {
+                                                 false, retry_limit)) {
                        reply = wpas_dbus_error_unknown_error(
                                message,
                                "Failed to reinvoke a persistent group");
index a0b8bcfb32ac5c51506385de321227684b65efb0..64b2bcd1daf1382cef3f352a0f3aef443090f24b 100644 (file)
@@ -2435,6 +2435,9 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s,
                        if (res == 1)
                                return 0;
 
+                       if (wpas_p2p_retry_limit_exceeded(wpa_s))
+                               return 0;
+
                        if (wpa_s->p2p_in_provisioning ||
                            wpa_s->show_group_started ||
                            wpa_s->p2p_in_invitation) {
index 4ef354b690883e2b5244a6b9cd688f95ec2d83d7..ec3f9b2f043fe8d0b29d74220b3131f5db8a23cb 100644 (file)
@@ -1013,6 +1013,7 @@ static int wpas_p2p_group_delete(struct wpa_supplicant *wpa_s,
        }
 
        wpa_s->p2p_in_invitation = 0;
+       wpa_s->p2p_retry_limit = 0;
        eloop_cancel_timeout(wpas_p2p_move_go, wpa_s, NULL);
        eloop_cancel_timeout(wpas_p2p_reconsider_moving_go, wpa_s, NULL);
 
@@ -1407,6 +1408,7 @@ static void wpas_group_formation_completed(struct wpa_supplicant *wpa_s,
                wpa_s->p2p_in_provisioning = 0;
        }
        wpa_s->p2p_in_invitation = 0;
+       wpa_s->p2p_retry_limit = 0;
        wpa_s->group_formation_reported = 1;
 
        if (!success) {
@@ -2423,6 +2425,21 @@ void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
 }
 
 
+bool wpas_p2p_retry_limit_exceeded(struct wpa_supplicant *wpa_s)
+{
+       if (!wpa_s->p2p_in_invitation || !wpa_s->p2p_retry_limit ||
+           wpa_s->p2p_in_invitation <= wpa_s->p2p_retry_limit)
+               return false;
+
+       wpa_printf(MSG_DEBUG, "P2P: Group join retry limit exceeded");
+       eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
+                            wpa_s->p2pdev, NULL);
+       eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
+                              wpa_s->p2pdev, NULL);
+       return true;
+}
+
+
 static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
 {
        struct wpa_supplicant *wpa_s = ctx;
@@ -3282,7 +3299,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
                                wpa_s->conf->p2p_go_he,
                                wpa_s->conf->p2p_go_edmg, NULL,
                                go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
-                               1, is_p2p_allow_6ghz(wpa_s->global->p2p));
+                               1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
                } else if (bssid) {
                        wpa_s->user_initiated_pd = 0;
                        wpa_msg_global(wpa_s, MSG_INFO,
@@ -3512,7 +3529,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
                                      ssid->mode == WPAS_MODE_P2P_GO ?
                                      P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
                                      0, 1,
-                                     is_p2p_allow_6ghz(wpa_s->global->p2p));
+                                     is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
 }
 
 
@@ -4598,7 +4615,7 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
                                        persistent_go->mode ==
                                        WPAS_MODE_P2P_GO ?
                                        P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
-                                       0, 0, false);
+                                       0, 0, false, 0);
                        } else if (response_done) {
                                wpas_p2p_group_add(wpa_s, 1, freq,
                                                   0, 0, 0, 0, 0, 0, false);
@@ -4721,7 +4738,7 @@ static int wpas_prov_disc_resp_cb(void *ctx)
                        NULL,
                        persistent_go->mode == WPAS_MODE_P2P_GO ?
                        P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0,
-                       is_p2p_allow_6ghz(wpa_s->global->p2p));
+                       is_p2p_allow_6ghz(wpa_s->global->p2p), 0);
        } else {
                wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
                                   is_p2p_allow_6ghz(wpa_s->global->p2p));
@@ -6894,7 +6911,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
 
 static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
                                 struct wpa_ssid *params, int addr_allocated,
-                                int freq, int force_scan)
+                                int freq, int force_scan, int retry_limit)
 {
        struct wpa_ssid *ssid;
        int other_iface_found = 0;
@@ -6939,6 +6956,7 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
 
        wpa_s->show_group_started = 1;
        wpa_s->p2p_in_invitation = 1;
+       wpa_s->p2p_retry_limit = retry_limit;
        wpa_s->p2p_invite_go_freq = freq;
        wpa_s->p2p_go_group_formation_completed = 0;
        wpa_s->global->p2p_group_formation = wpa_s;
@@ -6982,7 +7000,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                                  int edmg,
                                  const struct p2p_channels *channels,
                                  int connection_timeout, int force_scan,
-                                 bool allow_6ghz)
+                                 bool allow_6ghz, int retry_limit)
 {
        struct p2p_go_neg_results params;
        int go = 0, freq;
@@ -7050,7 +7068,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                }
 
                return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq,
-                                            force_scan);
+                                            force_scan, retry_limit);
        } else {
                return -1;
        }
@@ -7806,6 +7824,7 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
                wpa_s->global->p2p_group_formation = NULL;
                wpa_s->p2p_in_provisioning = 0;
                wpa_s->p2p_in_invitation = 0;
+               wpa_s->p2p_retry_limit = 0;
        }
 
        os_memset(go_dev_addr, 0, ETH_ALEN);
@@ -8639,6 +8658,7 @@ void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
                wpa_s->global->p2p_group_formation = NULL;
                wpa_s->p2p_in_provisioning = 0;
                wpa_s->p2p_in_invitation = 0;
+               wpa_s->p2p_retry_limit = 0;
        }
        wpa_s->global->p2p_go_wait_client.sec = 0;
        if (addr == NULL)
index 70f59dcfd35fc2ded6b0201c0e73291fde2cf3ca..11cc9c390eabd46436ddd846588742feb61d3dcc 100644 (file)
@@ -52,7 +52,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                                  int max_oper_chwidth, int he, int edmg,
                                  const struct p2p_channels *channels,
                                  int connection_timeout, int force_scan,
-                                 bool allow_6ghz);
+                                 bool allow_6ghz, int retry_limit);
 struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
                                       struct wpa_ssid *ssid);
 enum wpas_p2p_prov_disc_use {
@@ -209,6 +209,7 @@ void wpas_p2p_notif_disconnected(struct wpa_supplicant *wpa_s);
 int wpas_p2p_notif_pbc_overlap(struct wpa_supplicant *wpa_s);
 int wpas_p2p_4way_hs_failed(struct wpa_supplicant *wpa_s);
 void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s);
+bool wpas_p2p_retry_limit_exceeded(struct wpa_supplicant *wpa_s);
 void wpas_p2p_indicate_state_change(struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit_iface(struct wpa_supplicant *wpa_s);
 void wpas_p2p_ap_deinit(struct wpa_supplicant *wpa_s);
index 9689067335abbdf0e38cd3378fb2ce12464c07fb..fc37c6b9a4204381900e37c63d8805a221d28299 100644 (file)
@@ -467,6 +467,7 @@ static void wpa_supplicant_optimize_freqs(
                         */
                        wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Clear p2p_in_invitation");
                        wpa_s->p2p_in_invitation = 0;
+                       wpa_s->p2p_retry_limit = 0;
                }
        }
 #endif /* CONFIG_P2P */
index 2c1330653777f72c18c9b6c05a81a4fe4071f8b4..da8152560f8411c76f8161f9d308363c5712e890 100644 (file)
@@ -1051,6 +1051,7 @@ struct wpa_supplicant {
        int p2p_sd_over_ctrl_iface;
        int p2p_in_provisioning;
        int p2p_in_invitation;
+       int p2p_retry_limit;
        int p2p_invite_go_freq;
        int pending_invite_ssid_id;
        int show_group_started;