}
} else {
wpa_dbg(wpa_s, MSG_DEBUG, "External program started a scan");
- wpa_s->radio->external_scan_running = 1;
+ wpa_s->radio->external_scan_req_interface = wpa_s;
wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_SCAN_STARTED);
}
break;
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
wpa_s->scan_res_handler = NULL;
wpa_s->own_scan_running = 0;
- wpa_s->radio->external_scan_running = 0;
+ wpa_s->radio->external_scan_req_interface = NULL;
wpa_s->last_scan_req = NORMAL_SCAN_REQ;
break;
}
if (!(data && data->scan_info.external_scan))
wpa_s->own_scan_running = 0;
if (data && data->scan_info.nl_scan_event)
- wpa_s->radio->external_scan_running = 0;
+ wpa_s->radio->external_scan_req_interface = NULL;
radio_work_check_next(wpa_s);
break;
#endif /* CONFIG_NO_SCAN_PROCESSING */
unsigned int delay = wpas_p2p_search_delay(wpa_s);
/* In case of concurrent P2P and external scans, delay P2P search. */
- if (wpa_s->radio->external_scan_running) {
+ if (external_scan_running(wpa_s->radio)) {
delay = wpa_s->conf->p2p_search_delay;
wpa_printf(MSG_DEBUG,
"P2P: Delay next P2P search by %d ms to let externally triggered scan complete",
dl_list_for_each(tmp, &radio->work, struct wpa_radio_work,
list) {
if (os_strcmp(tmp->type, "scan") == 0 &&
- radio->external_scan_running &&
+ external_scan_running(radio) &&
(((struct wpa_driver_scan_params *)
tmp->ctx)->only_new_results ||
tmp->wpa_s->clear_driver_scan_cache))
* rejected by kernel.
*/
if (os_strcmp(tmp->type, "scan") == 0 &&
- radio->external_scan_running &&
+ external_scan_running(radio) &&
(((struct wpa_driver_scan_params *)
tmp->ctx)->only_new_results ||
tmp->wpa_s->clear_driver_scan_cache))
if (work->started)
return; /* already started and still in progress */
- if (wpa_s && wpa_s->radio->external_scan_running) {
+ if (wpa_s && external_scan_running(wpa_s->radio)) {
wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
return;
}
wpa_s->ifname, radio->name);
dl_list_del(&wpa_s->radio_list);
radio_remove_works(wpa_s, NULL, 0);
+ /* If the interface that triggered the external scan was removed, the
+ * external scan is no longer running. */
+ if (wpa_s == radio->external_scan_req_interface)
+ radio->external_scan_req_interface = NULL;
wpa_s->radio = NULL;
if (!dl_list_empty(&radio->ifaces))
return; /* Interfaces remain for this radio */
struct wpa_radio {
char name[16]; /* from driver_ops get_radio_name() or empty if not
* available */
- unsigned int external_scan_running:1;
+ /** NULL if no external scan running. */
+ struct wpa_supplicant *external_scan_req_interface;
unsigned int num_active_works;
struct dl_list ifaces; /* struct wpa_supplicant::radio_list entries */
struct dl_list work; /* struct wpa_radio_work::list entries */
};
+/**
+ * Checks whether an external scan is running on a given radio.
+ * @radio: Pointer to radio struct
+ * Returns: true if an external scan is running, false otherwise.
+ */
+static inline bool external_scan_running(struct wpa_radio *radio)
+{
+ return radio && radio->external_scan_req_interface;
+}
+
#define MAX_ACTIVE_WORKS 2