The roam D-Bus and wpa_cli commands flip the reassociate bit before calling wpa_supplicant_connect. wpa_supplicant connect eventually aborts ongoing scans, which causes scan results to be reported. Since the reassociate bit is set, this will trigger a connection attempt based on the aborted scan's scan results and cancel the initial connetion request. This often causes wpa_supplicant to reassociate to the same AP it is currently associated to. Add a roam_in_progress flag to indicate that we're currently attempting to roam via D-Bus so that we don't initate another connection attempt. Signed-off-by: Matthew Wang <matthewmwang@xxxxxxxxxxxx> Series-to: hostap@xxxxxxxxxxxxxxxxxxx Series-cc: j@xxxxx, matthewmwang@xxxxxxxxxxxx --- wpa_supplicant/ctrl_iface.c | 11 +++++++++++ wpa_supplicant/dbus/dbus_new_handlers.c | 11 +++++++++++ wpa_supplicant/sme.c | 7 +++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 4 files changed, 30 insertions(+) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 0d4c2bc8f0b..93cfa9dd18f 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -5656,6 +5656,7 @@ static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, u8 bssid[ETH_ALEN]; struct wpa_bss *bss; struct wpa_ssid *ssid = wpa_s->current_ssid; + struct wpa_radio_work *already_connecting; if (hwaddr_aton(addr, bssid)) { wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid " @@ -5683,9 +5684,19 @@ static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s, * allow roaming to other networks */ + already_connecting = radio_work_pending(wpa_s, "sme-connect"); wpa_s->reassociate = 1; wpa_supplicant_connect(wpa_s, bss, ssid); + /* + * Indicate that an explicitly requested roam is in progress so scan + * results that come in before the 'sme-connect' radio work gets + * executed do not override the original connection attempt. + */ + if (!already_connecting && radio_work_pending(wpa_s, "sme-connect")) { + wpa_s->roam_in_progress = true; + } + return 0; #endif /* CONFIG_NO_SCAN_PROCESSING */ } diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 7d20f2123a8..6c3646979c1 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -1979,6 +1979,7 @@ DBusMessage * wpas_dbus_handler_roam(DBusMessage *message, struct wpa_bss *bss; struct wpa_ssid *ssid = wpa_s->current_ssid; char *addr; + struct wpa_radio_work *already_connecting; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &addr, DBUS_TYPE_INVALID)) @@ -2002,9 +2003,19 @@ DBusMessage * wpas_dbus_handler_roam(DBusMessage *message, message, "Target BSS not found"); } + already_connecting = radio_work_pending(wpa_s, "sme-connect"); wpa_s->reassociate = 1; wpa_supplicant_connect(wpa_s, bss, ssid); + /* + * Indicate that an explicitly requested roam is in progress so scan + * results that come in before the 'sme-connect' radio work gets + * executed do not override the original connection attempt. + */ + if (!already_connecting && radio_work_pending(wpa_s, "sme-connect")) { + wpa_s->roam_in_progress = true; + } + return NULL; #endif /* CONFIG_NO_SCAN_PROCESSING */ } diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 522c8297f7e..dde80863a98 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -941,6 +941,8 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit) struct wpa_connect_work *cwork = work->ctx; struct wpa_supplicant *wpa_s = work->wpa_s; + wpa_s->roam_in_progress = false; + if (deinit) { if (work->started) wpa_s->connect_work = NULL; @@ -981,6 +983,11 @@ void sme_authenticate(struct wpa_supplicant *wpa_s, return; } + if (wpa_s->roam_in_progress) { + wpa_dbg(wpa_s, MSG_DEBUG, + "SME: Reject sme_authenticate() in favor of explicit roam request"); + return; + } if (radio_work_pending(wpa_s, "sme-connect")) { /* * The previous sme-connect work might no longer be valid due to diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 7d14b627d89..b6c339ab711 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -621,6 +621,7 @@ struct wpa_supplicant { u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this * field contains the target BSSID. */ int reassociate; /* reassociation requested */ + bool roam_in_progress; /* roam in progress */ unsigned int reassoc_same_bss:1; /* reassociating to the same BSS */ unsigned int reassoc_same_ess:1; /* reassociating to the same ESS */ int disconnected; /* all connections disabled; i.e., do no reassociate -- 2.29.2 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap