From d63c8290a992267c2c5fc42effcb5f633b7a0135 Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Wed, 26 Jun 2019 10:42:48 -0700 Subject: [PATCH] scan: add suspend/resume scan APIs In order to do ANQP efficiently IWD needs the ability to suspend scanning temporarily. This is because both scanning and ANQP go offchannel and must remain off channel for some amount of time. This cannot be done simultaneously and if e.g. ANQP is requested after a scan is already pending, the kernel will wait till that scan finishes before sending out the frame. --- src/scan.c | 38 +++++++++++++++++++++++++++++++++++--- src/scan.h | 3 +++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/scan.c b/src/scan.c index 759f01a1..e42cec99 100644 --- a/src/scan.c +++ b/src/scan.c @@ -100,6 +100,7 @@ struct scan_context { bool triggered:1; /* Whether any commands from current request's queue have started */ bool started:1; + bool suspended:1; struct wiphy *wiphy; }; @@ -711,6 +712,9 @@ static bool start_next_scan_request(struct scan_context *sc) { struct scan_request *sr = l_queue_peek_head(sc->requests); + if (sc->suspended) + return true; + if (sc->state != SCAN_STATE_NOT_RUNNING) return true; @@ -1226,6 +1230,9 @@ static void scan_finished(struct scan_context *sc, uint32_t wiphy, l_queue_remove(sc->requests, sr); sc->started = false; + if (sr->callback) + new_owner = sr->callback(err, bss_list, sr->userdata); + /* * Can start a new scan now that we've removed this one from * the queue. If this were an external scan request (sr NULL) @@ -1235,9 +1242,6 @@ static void scan_finished(struct scan_context *sc, uint32_t wiphy, */ start_next_scan_request(sc); - if (sr->callback) - new_owner = sr->callback(err, bss_list, sr->userdata); - scan_request_free(sr); } else if (sc->sp.callback) new_owner = sc->sp.callback(err, bss_list, sc->sp.userdata); @@ -1874,6 +1878,34 @@ bool scan_ifindex_remove(uint32_t ifindex) return true; } +bool scan_suspend(uint32_t ifindex) +{ + struct scan_context *sc; + + sc = l_queue_find(scan_contexts, scan_context_match, + L_UINT_TO_PTR(ifindex)); + if (!sc) + return false; + + sc->suspended = true; + + return true; +} + +void scan_resume(uint32_t ifindex) +{ + struct scan_context *sc; + + sc = l_queue_find(scan_contexts, scan_context_match, + L_UINT_TO_PTR(ifindex)); + if (!sc) + return; + + sc->suspended = false; + + start_next_scan_request(sc); +} + static int scan_init(void) { const struct l_settings *config = iwd_get_config(); diff --git a/src/scan.h b/src/scan.h index 5577b204..57f5a92e 100644 --- a/src/scan.h +++ b/src/scan.h @@ -135,3 +135,6 @@ void scan_freq_set_constrain(struct scan_freq_set *set, bool scan_ifindex_add(uint32_t ifindex); bool scan_ifindex_remove(uint32_t ifindex); + +bool scan_suspend(uint32_t ifindex); +void scan_resume(uint32_t ifindex);