mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-27 02:32:52 +01:00
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.
This commit is contained in:
parent
45130ec5ee
commit
d63c8290a9
38
src/scan.c
38
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();
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user