mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-25 17:59:25 +01:00
dpp: scan to pick up extra frequencies when enrolling
The DPP-PKEX spec provides a very limited list of frequencies used to discover configurators, only 3 on 2.4 and 5GHz bands. Since configurators (at least in IWD's implementation) are only allowed on the current operating frequency its very unlikely an enrollee will find a configurator on these frequencies out of the entire spectrum. The spec does mention that the 3 default frequencies should be used "In lieu of specific channel information obtained in a manner outside the scope of this specification, ...". This allows the implementation some flexibility in using a broader range of frequencies. To increase the chances of finding a configurator shared code enrollees will first issue a scan to determine what access points are around, then iterate these frequencies. This is especially helpful when the configurators are IWD-based since we know that they'll be on the same channels as the APs in the area.
This commit is contained in:
parent
c8a86edffe
commit
3c02f387cb
98
src/dpp.c
98
src/dpp.c
@ -183,6 +183,7 @@ struct dpp_sm {
|
||||
size_t z_len;
|
||||
uint8_t u[L_ECC_SCALAR_MAX_BYTES];
|
||||
size_t u_len;
|
||||
uint32_t pkex_scan_id;
|
||||
|
||||
bool mcast_support : 1;
|
||||
bool roc_started : 1;
|
||||
@ -508,6 +509,11 @@ static void dpp_reset(struct dpp_sm *dpp)
|
||||
dpp->retry_timeout = NULL;
|
||||
}
|
||||
|
||||
if (dpp->pkex_scan_id) {
|
||||
scan_cancel(dpp->wdev_id, dpp->pkex_scan_id);
|
||||
dpp->pkex_scan_id = 0;
|
||||
}
|
||||
|
||||
dpp->state = DPP_STATE_NOTHING;
|
||||
dpp->new_freq = 0;
|
||||
dpp->frame_retry = 0;
|
||||
@ -4073,6 +4079,14 @@ static struct l_dbus_message *dpp_dbus_stop(struct l_dbus *dbus,
|
||||
return l_dbus_message_new_method_return(message);
|
||||
}
|
||||
|
||||
static void dpp_pkex_scan_trigger(int err, void *user_data)
|
||||
{
|
||||
struct dpp_sm *dpp = user_data;
|
||||
|
||||
if (err < 0)
|
||||
dpp_reset(dpp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Section 5.6.1
|
||||
* In lieu of specific channel information obtained in a manner outside
|
||||
@ -4111,6 +4125,62 @@ static uint32_t *dpp_default_freqs(struct dpp_sm *dpp, size_t *out_len)
|
||||
return freqs_out;
|
||||
}
|
||||
|
||||
static bool dpp_pkex_scan_notify(int err, struct l_queue *bss_list,
|
||||
const struct scan_freq_set *freqs,
|
||||
void *user_data)
|
||||
{
|
||||
struct dpp_sm *dpp = user_data;
|
||||
const struct l_queue_entry *e;
|
||||
_auto_(scan_freq_set_free) struct scan_freq_set *freq_set = NULL;
|
||||
|
||||
if (err < 0)
|
||||
goto failed;
|
||||
|
||||
freq_set = scan_freq_set_new();
|
||||
|
||||
if (!bss_list || l_queue_isempty(bss_list)) {
|
||||
dpp->freqs = dpp_default_freqs(dpp, &dpp->freqs_len);
|
||||
if (!dpp->freqs)
|
||||
goto failed;
|
||||
|
||||
l_debug("No BSS's seen, using default frequency list");
|
||||
goto start;
|
||||
}
|
||||
|
||||
for (e = l_queue_get_entries(bss_list); e; e = e->next) {
|
||||
const struct scan_bss *bss = e->data;
|
||||
|
||||
scan_freq_set_add(freq_set, bss->frequency);
|
||||
}
|
||||
|
||||
l_debug("Found %u frequencies to search for configurator",
|
||||
l_queue_length(bss_list));
|
||||
|
||||
dpp->freqs = scan_freq_set_to_fixed_array(freq_set, &dpp->freqs_len);
|
||||
|
||||
start:
|
||||
dpp->current_freq = dpp->freqs[0];
|
||||
|
||||
dpp_reset_protocol_timer(dpp, DPP_PKEX_PROTO_TIMEOUT);
|
||||
|
||||
l_debug("PKEX start enrollee (id=%s)", dpp->pkex_id ?: "unset");
|
||||
|
||||
dpp_start_offchannel(dpp, dpp->current_freq);
|
||||
|
||||
return false;
|
||||
|
||||
failed:
|
||||
dpp_reset(dpp);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dpp_pkex_scan_destroy(void *user_data)
|
||||
{
|
||||
struct dpp_sm *dpp = user_data;
|
||||
|
||||
dpp->pkex_scan_id = 0;
|
||||
}
|
||||
|
||||
static bool dpp_start_pkex_enrollee(struct dpp_sm *dpp, const char *key,
|
||||
const char *identifier)
|
||||
{
|
||||
@ -4156,18 +4226,26 @@ static bool dpp_start_pkex_enrollee(struct dpp_sm *dpp, const char *key,
|
||||
|
||||
dpp_property_changed_notify(dpp);
|
||||
|
||||
dpp->freqs = dpp_default_freqs(dpp, &dpp->freqs_len);
|
||||
if (!dpp->freqs)
|
||||
/*
|
||||
* The 'dpp_default_freqs' function returns the default frequencies
|
||||
* outlined in section 5.6.1. For 2.4/5GHz this is only 3 frequencies
|
||||
* which is unlikely to result in discovery of a configurator. The spec
|
||||
* does allow frequencies to be "obtained in a manner outside the scope
|
||||
* of this specification" which is what is being done here.
|
||||
*
|
||||
* This is mainly geared towards IWD-based configurators; banking on the
|
||||
* fact that they are currently connected to nearby APs. Scanning lets
|
||||
* us see nearby BSS's which should be the same frequencies as our
|
||||
* target configurator.
|
||||
*/
|
||||
l_debug("Performing scan for frequencies to start PKEX");
|
||||
|
||||
dpp->pkex_scan_id = scan_active(dpp->wdev_id, NULL, 0,
|
||||
dpp_pkex_scan_trigger, dpp_pkex_scan_notify,
|
||||
dpp, dpp_pkex_scan_destroy);
|
||||
if (!dpp->pkex_scan_id)
|
||||
goto failed;
|
||||
|
||||
dpp->current_freq = dpp->freqs[dpp->freqs_idx];
|
||||
|
||||
dpp_reset_protocol_timer(dpp, DPP_PKEX_PROTO_TIMEOUT);
|
||||
|
||||
l_debug("PKEX start enrollee (id=%s)", dpp->pkex_id ?: "unset");
|
||||
|
||||
dpp_start_offchannel(dpp, dpp->current_freq);
|
||||
|
||||
return true;
|
||||
|
||||
failed:
|
||||
|
Loading…
Reference in New Issue
Block a user