From a3a48da542d8060e3c789a482c26452ac5ca2916 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Wed, 28 Aug 2019 09:14:31 -0700 Subject: [PATCH] station: allow autoconnect to hotspot networks Since hotspot networks may require ANQP the autoconnect loop needed to be delayed until after the ANQP results came back and the network objects were updated. If there are hotspot networks in range ANQP will be performed and once complete autoconnect will begin for all networks including hotspots. If no hotspots are in range autoconnect will proceed as it always has. Note: Assuming hotspots are in range this will introduce some delay in autoconnecting to any network since ANQP must come back. The full plan is to intellegently decide when and when not to do ANQP in order to minimize delays but since ANQP is disabled by default the behavior introduced with this patch is acceptable. --- src/station.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/src/station.c b/src/station.c index 0c8e783b..27ad773b 100644 --- a/src/station.c +++ b/src/station.c @@ -418,6 +418,17 @@ static bool match_nai_realms(const struct network_info *info, void *user_data) return true; } +static void network_add_foreach(struct network *network, void *user_data) +{ + struct station *station = user_data; + struct scan_bss *bss = network_bss_select(network, false); + + if (!bss) + return; + + station_add_autoconnect_bss(station, network, bss); +} + static void station_anqp_response_cb(enum anqp_result result, const void *anqp, size_t anqp_len, void *user_data) @@ -472,8 +483,18 @@ request_done: l_queue_remove(station->anqp_pending, entry); /* If no more requests, resume scanning */ - if (l_queue_isempty(station->anqp_pending)) - scan_resume(netdev_get_wdev_id(station->netdev)); + if (!l_queue_isempty(station->anqp_pending)) + return; + + l_queue_destroy(station->autoconnect_list, l_free); + station->autoconnect_list = l_queue_new(); + + if (station_is_autoconnecting(station)) { + station_network_foreach(station, network_add_foreach, station); + station_autoconnect_next(station); + } + + scan_resume(netdev_get_wdev_id(station->netdev)); } static bool station_start_anqp(struct station *station, struct network *network, @@ -600,11 +621,6 @@ void station_set_scan_results(struct station *station, if (station_start_anqp(station, network, bss)) wait_for_anqp = true; - - if (!add_to_autoconnect) - continue; - - station_add_autoconnect_bss(station, network, bss); } station->bss_list = new_bss_list; @@ -623,6 +639,10 @@ void station_set_scan_results(struct station *station, */ if (wait_for_anqp) scan_suspend(netdev_get_wdev_id(station->netdev)); + else if (add_to_autoconnect) { + station_network_foreach(station, network_add_foreach, station); + station_autoconnect_next(station); + } } static void station_reconnect(struct station *station); @@ -948,9 +968,6 @@ static bool new_scan_results(int err, struct l_queue *bss_list, void *userdata) autoconnect = station_is_autoconnecting(station); station_set_scan_results(station, bss_list, autoconnect); - if (autoconnect) - station_autoconnect_next(station); - return true; } @@ -1021,9 +1038,6 @@ static bool station_quick_scan_results(int err, struct l_queue *bss_list, autoconnect = station_is_autoconnecting(station); station_set_scan_results(station, bss_list, autoconnect); - if (autoconnect) - station_autoconnect_next(station); - if (station->state == STATION_STATE_AUTOCONNECT_QUICK) /* * If we're still in AUTOCONNECT_QUICK state, then autoconnect