An earlier patch fixed a problem where a queued quick scan would
be triggered and fail once already connected, resulting in a state
transition from connected --> autoconnect_full. This fixed the
Connect() path but this could also happen via autoconnect. Starting
from a connected state, the sequence goes:
- DBus scan is triggered
- AP disconnects IWD
- State transition from disconnected --> autoconnect_quick
- Queue quick scan
- DBus scan results come in and used to autoconnect
- A connect work item is inserted ahead of all others, transition
from autoconnect_quick --> connecting.
- Connect completes, transition from connecting --> connected
- Quick scan can finally get triggered, which the kernel fails to
do since IWD is connected, transition from connected -->
autoconnect_full.
By moving the scan cancellation from station_connect_network into
__station_connect_network we handle both the explicit Connect()
path as well as autoconnect.
---
src/station.c | 38 +++++++++++++++++++-------------------
1 file changed, 19 insertions(+), 19 deletions(-)
v2:
* Clarifed the exact sequence of events in description
diff --git a/src/station.c b/src/station.c
index 8288916f..1f59e270 100644
--- a/src/station.c
+++ b/src/station.c
@@ -2497,6 +2497,25 @@ int __station_connect_network(struct station *station, struct
network *network,
struct handshake_state *hs;
int r;
+ /*
+ * If a hidden scan is not completed, station_is_busy would not
+ * indicate anything is going on so we need to cancel the scan and
+ * fail the connection now.
+ */
+ if (station->hidden_network_scan_id) {
+ scan_cancel(netdev_get_wdev_id(station->netdev),
+ station->hidden_network_scan_id);
+
+ dbus_pending_reply(&station->hidden_pending,
+ dbus_error_failed(station->hidden_pending));
+ }
+
+ if (station->quick_scan_id) {
+ scan_cancel(netdev_get_wdev_id(station->netdev),
+ station->quick_scan_id);
+ station->quick_scan_id = 0;
+ }
+
hs = station_handshake_setup(station, network, bss);
if (!hs)
return -ENOTSUP;
@@ -2576,25 +2595,6 @@ void station_connect_network(struct station *station, struct
network *network,
struct l_dbus *dbus = dbus_get_bus();
int err;
- /*
- * If a hidden scan is not completed, station_is_busy would not
- * indicate anything is going on so we need to cancel the scan and
- * fail the connection now.
- */
- if (station->hidden_network_scan_id) {
- scan_cancel(netdev_get_wdev_id(station->netdev),
- station->hidden_network_scan_id);
-
- dbus_pending_reply(&station->hidden_pending,
- dbus_error_failed(station->hidden_pending));
- }
-
- if (station->quick_scan_id) {
- scan_cancel(netdev_get_wdev_id(station->netdev),
- station->quick_scan_id);
- station->quick_scan_id = 0;
- }
-
if (station_is_busy(station)) {
station_disconnect_onconnect(station, network, bss, message);
--
2.26.2
Show replies by date
After recent changes fixing wait_for_object_condition it was accidentally
made to only work with classes, not other types of objects. Instead
create a minimal class to hold _wait_timed_out so it doesnt rely on
'obj' holding the boolean.
---
autotests/util/iwd.py | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/autotests/util/iwd.py b/autotests/util/iwd.py
index 4fa26517..6b153ea7 100755
--- a/autotests/util/iwd.py
+++ b/autotests/util/iwd.py
@@ -1009,23 +1009,26 @@ class IWD(AsyncOpAbstract):
@staticmethod
def _wait_for_object_condition(obj, condition_str, max_wait = 50):
- obj._wait_timed_out = False
+ class TimeoutData:
+ _wait_timed_out = False
- def wait_timeout_cb():
- obj._wait_timed_out = True
+ data = TimeoutData()
+
+ def wait_timeout_cb(data):
+ data._wait_timed_out = True
return False
try:
- timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb)
+ timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb, data)
context = ctx.mainloop.get_context()
while not eval(condition_str):
context.iteration(may_block=True)
- if obj._wait_timed_out and ctx.args.gdb == None:
+ if data._wait_timed_out and ctx.args.gdb == None:
raise TimeoutError('[' + condition_str + ']'\
' condition was not met in '\
+ str(max_wait) + ' sec')
finally:
- if not obj._wait_timed_out:
+ if not data._wait_timed_out:
GLib.source_remove(timeout)
def wait_for_object_condition(self, *args, **kwargs):
--
2.26.2