3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-10 14:09:22 +01:00

scan: track scanned frequencies for entire request

The NEW_SCAN_RESULTS handling was written to only parse the frequency
list if there were no additional scan commands to send. This results in
the scan callback containing frequencies of only the last CMD_TRIGGER.

Until now this worked fine because a) the queue is only used for hidden
networks and b) frequencies were never defined by any callers scanning
for hidden networks (e.g. dbus/periodic scans).

Soon the scan command queue will be used to break up scan requests
meaning only the last scan request frequencies would be used in the
callback, breaking the logic in station.

Now the NEW_SCAN_RESULTS case will parse the frequencies for each scan
command rather than only the last.
This commit is contained in:
James Prestwood 2022-08-03 14:36:33 -07:00 committed by Denis Kenzior
parent f555e5dda2
commit 27d8cf4ccc

View File

@ -98,6 +98,12 @@ struct scan_request {
/* The time the current scan was started. Reported in TRIGGER_SCAN */ /* The time the current scan was started. Reported in TRIGGER_SCAN */
uint64_t start_time_tsf; uint64_t start_time_tsf;
struct wiphy_radio_work_item work; struct wiphy_radio_work_item work;
/*
* List of frequencies scanned so far. Since the NEW_SCAN_RESULTS event
* contains frequencies of only the last CMD_TRIGGER we need to parse
* and save these since there may be additional scan commands to run.
*/
struct scan_freq_set *freqs_scanned;
}; };
struct scan_context { struct scan_context {
@ -125,7 +131,6 @@ struct scan_context {
struct scan_results { struct scan_results {
struct scan_context *sc; struct scan_context *sc;
struct l_queue *bss_list; struct l_queue *bss_list;
struct scan_freq_set *freqs;
uint64_t time_stamp; uint64_t time_stamp;
struct scan_request *sr; struct scan_request *sr;
}; };
@ -159,6 +164,8 @@ static void scan_request_free(struct wiphy_radio_work_item *item)
l_queue_destroy(sr->cmds, (l_queue_destroy_func_t) l_genl_msg_unref); l_queue_destroy(sr->cmds, (l_queue_destroy_func_t) l_genl_msg_unref);
scan_freq_set_free(sr->freqs_scanned);
l_free(sr); l_free(sr);
} }
@ -609,6 +616,7 @@ static struct scan_request *scan_request_new(struct scan_context *sc,
sr->destroy = destroy; sr->destroy = destroy;
sr->passive = passive; sr->passive = passive;
sr->cmds = l_queue_new(); sr->cmds = l_queue_new();
sr->freqs_scanned = scan_freq_set_new();
return sr; return sr;
} }
@ -1525,14 +1533,11 @@ fail:
return NULL; return NULL;
} }
static struct scan_freq_set *scan_parse_attr_scan_frequencies( static void scan_parse_attr_scan_frequencies(struct l_genl_attr *attr,
struct l_genl_attr *attr) struct scan_freq_set *set)
{ {
uint16_t type, len; uint16_t type, len;
const void *data; const void *data;
struct scan_freq_set *set;
set = scan_freq_set_new();
while (l_genl_attr_next(attr, &type, &len, &data)) { while (l_genl_attr_next(attr, &type, &len, &data)) {
uint32_t freq; uint32_t freq;
@ -1543,8 +1548,6 @@ static struct scan_freq_set *scan_parse_attr_scan_frequencies(
freq = *((uint32_t *) data); freq = *((uint32_t *) data);
scan_freq_set_add(set, freq); scan_freq_set_add(set, freq);
} }
return set;
} }
static struct scan_bss *scan_parse_result(struct l_genl_msg *msg, static struct scan_bss *scan_parse_result(struct l_genl_msg *msg,
@ -1825,14 +1828,12 @@ static void get_scan_done(void *user)
if (!results->sr || !results->sr->canceled) if (!results->sr || !results->sr->canceled)
scan_finished(sc, 0, results->bss_list, scan_finished(sc, 0, results->bss_list,
results->freqs, results->sr); results->sr->freqs_scanned,
results->sr);
else else
l_queue_destroy(results->bss_list, l_queue_destroy(results->bss_list,
(l_queue_destroy_func_t) scan_bss_free); (l_queue_destroy_func_t) scan_bss_free);
if (results->freqs)
scan_freq_set_free(results->freqs);
l_free(results); l_free(results);
} }
@ -1852,8 +1853,8 @@ static bool scan_parse_flush_flag_from_msg(struct l_genl_msg *msg)
return false; return false;
} }
static void scan_parse_new_scan_results(struct l_genl_msg *msg, static void scan_parse_result_frequencies(struct l_genl_msg *msg,
struct scan_results *results) struct scan_freq_set *freqs)
{ {
struct l_genl_attr attr, nested; struct l_genl_attr attr, nested;
uint16_t type, len; uint16_t type, len;
@ -1870,8 +1871,7 @@ static void scan_parse_new_scan_results(struct l_genl_msg *msg,
break; break;
} }
results->freqs = scan_parse_attr_scan_frequencies(&nested, freqs);
scan_parse_attr_scan_frequencies(&nested);
break; break;
} }
} }
@ -1950,8 +1950,11 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data)
*/ */
if (l_queue_isempty(sr->cmds)) if (l_queue_isempty(sr->cmds))
get_results = true; get_results = true;
else else {
scan_parse_result_frequencies(msg,
sr->freqs_scanned);
send_next = true; send_next = true;
}
} else { } else {
if (sc->get_scan_cmd_id) if (sc->get_scan_cmd_id)
break; break;
@ -1996,7 +1999,7 @@ static void scan_notify(struct l_genl_msg *msg, void *user_data)
results->sr = sr; results->sr = sr;
results->bss_list = l_queue_new(); results->bss_list = l_queue_new();
scan_parse_new_scan_results(msg, results); scan_parse_result_frequencies(msg, sr->freqs_scanned);
scan_msg = l_genl_msg_new_sized(NL80211_CMD_GET_SCAN, 8); scan_msg = l_genl_msg_new_sized(NL80211_CMD_GET_SCAN, 8);
l_genl_msg_append_attr(scan_msg, NL80211_ATTR_WDEV, 8, l_genl_msg_append_attr(scan_msg, NL80211_ATTR_WDEV, 8,