scan: move scan_freq_set* into util

This will allow scan_freq_set utilities to be used in any
modules requiring unit testing
This commit is contained in:
James Prestwood 2021-11-30 10:24:11 -08:00 committed by Denis Kenzior
parent 24494e978c
commit 9c732cb32d
4 changed files with 176 additions and 174 deletions

View File

@ -2017,166 +2017,6 @@ bool scan_get_firmware_scan(uint64_t wdev_id, scan_notify_func_t notify,
return true;
}
struct scan_freq_set {
uint16_t channels_2ghz;
struct l_uintset *channels_5ghz;
};
struct scan_freq_set *scan_freq_set_new(void)
{
struct scan_freq_set *ret = l_new(struct scan_freq_set, 1);
/* 802.11-2012, 8.4.2.10 hints that 200 is the largest channel number */
ret->channels_5ghz = l_uintset_new_from_range(1, 200);
return ret;
}
void scan_freq_set_free(struct scan_freq_set *freqs)
{
l_uintset_free(freqs->channels_5ghz);
l_free(freqs);
}
bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq)
{
enum band_freq band;
uint8_t channel;
channel = band_freq_to_channel(freq, &band);
if (!channel)
return false;
switch (band) {
case BAND_FREQ_2_4_GHZ:
freqs->channels_2ghz |= 1 << (channel - 1);
return true;
case BAND_FREQ_5_GHZ:
return l_uintset_put(freqs->channels_5ghz, channel);
}
return false;
}
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq)
{
enum band_freq band;
uint8_t channel;
channel = band_freq_to_channel(freq, &band);
if (!channel)
return false;
switch (band) {
case BAND_FREQ_2_4_GHZ:
return freqs->channels_2ghz & (1 << (channel - 1));
case BAND_FREQ_5_GHZ:
return l_uintset_contains(freqs->channels_5ghz, channel);
}
return false;
}
uint32_t scan_freq_set_get_bands(struct scan_freq_set *freqs)
{
uint32_t bands = 0;
uint32_t max;
if (freqs->channels_2ghz)
bands |= BAND_FREQ_2_4_GHZ;
max = l_uintset_get_max(freqs->channels_5ghz);
if (l_uintset_find_min(freqs->channels_5ghz) <= max)
bands |= BAND_FREQ_5_GHZ;
return bands;
}
static void scan_channels_5ghz_add(uint32_t channel, void *user_data)
{
struct l_uintset *to = user_data;
l_uintset_put(to, channel);
}
void scan_freq_set_merge(struct scan_freq_set *to,
const struct scan_freq_set *from)
{
to->channels_2ghz |= from->channels_2ghz;
l_uintset_foreach(from->channels_5ghz, scan_channels_5ghz_add,
to->channels_5ghz);
}
bool scan_freq_set_isempty(const struct scan_freq_set *set)
{
if (set->channels_2ghz == 0 && l_uintset_isempty(set->channels_5ghz))
return true;
return false;
}
struct channels_5ghz_foreach_data {
scan_freq_set_func_t func;
void *user_data;
};
static void scan_channels_5ghz_frequency(uint32_t channel, void *user_data)
{
const struct channels_5ghz_foreach_data *channels_5ghz_data = user_data;
uint32_t freq;
freq = band_channel_to_freq(channel, BAND_FREQ_5_GHZ);
channels_5ghz_data->func(freq, channels_5ghz_data->user_data);
}
void scan_freq_set_foreach(const struct scan_freq_set *freqs,
scan_freq_set_func_t func, void *user_data)
{
struct channels_5ghz_foreach_data data = { };
uint8_t channel;
uint32_t freq;
if (unlikely(!freqs || !func))
return;
data.func = func;
data.user_data = user_data;
l_uintset_foreach(freqs->channels_5ghz, scan_channels_5ghz_frequency,
&data);
if (!freqs->channels_2ghz)
return;
for (channel = 1; channel <= 14; channel++) {
if (freqs->channels_2ghz & (1 << (channel - 1))) {
freq = band_channel_to_freq(channel, BAND_FREQ_2_4_GHZ);
func(freq, user_data);
}
}
}
void scan_freq_set_constrain(struct scan_freq_set *set,
const struct scan_freq_set *constraint)
{
struct l_uintset *intersection;
intersection = l_uintset_intersect(constraint->channels_5ghz,
set->channels_5ghz);
if (!intersection)
/* This shouldn't ever be the case. */
return;
l_uintset_free(set->channels_5ghz);
set->channels_5ghz = intersection;
set->channels_2ghz &= constraint->channels_2ghz;
}
bool scan_wdev_add(uint64_t wdev_id)
{
struct scan_context *sc;

View File

@ -108,7 +108,6 @@ typedef bool (*scan_notify_func_t)(int err, struct l_queue *bss_list,
const struct scan_freq_set *freqs,
void *userdata);
typedef void (*scan_destroy_func_t)(void *userdata);
typedef void (*scan_freq_set_func_t)(uint32_t freq, void *userdata);
static inline int scan_bss_addr_cmp(const struct scan_bss *a1,
const struct scan_bss *a2)
@ -168,18 +167,5 @@ struct scan_bss *scan_bss_new_from_probe_req(const struct mmpdu_header *mpdu,
size_t body_len,
uint32_t frequency, int rssi);
struct scan_freq_set *scan_freq_set_new(void);
void scan_freq_set_free(struct scan_freq_set *freqs);
bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq);
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq);
uint32_t scan_freq_set_get_bands(struct scan_freq_set *freqs);
void scan_freq_set_foreach(const struct scan_freq_set *freqs,
scan_freq_set_func_t func, void *user_data);
void scan_freq_set_merge(struct scan_freq_set *to,
const struct scan_freq_set *from);
void scan_freq_set_constrain(struct scan_freq_set *set,
const struct scan_freq_set *constraint);
bool scan_freq_set_isempty(const struct scan_freq_set *set);
bool scan_wdev_add(uint64_t wdev_id);
bool scan_wdev_remove(uint64_t wdev_id);

View File

@ -35,6 +35,7 @@
#include "ell/useful.h"
#include "src/util.h"
#include "src/band.h"
const char *util_ssid_to_utf8(size_t len, const uint8_t *ssid)
{
@ -309,3 +310,163 @@ bool util_ip_prefix_tohl(const char *ip, uint8_t *prefix_out,
return true;
}
struct scan_freq_set {
uint16_t channels_2ghz;
struct l_uintset *channels_5ghz;
};
struct scan_freq_set *scan_freq_set_new(void)
{
struct scan_freq_set *ret = l_new(struct scan_freq_set, 1);
/* 802.11-2012, 8.4.2.10 hints that 200 is the largest channel number */
ret->channels_5ghz = l_uintset_new_from_range(1, 200);
return ret;
}
void scan_freq_set_free(struct scan_freq_set *freqs)
{
l_uintset_free(freqs->channels_5ghz);
l_free(freqs);
}
bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq)
{
enum band_freq band;
uint8_t channel;
channel = band_freq_to_channel(freq, &band);
if (!channel)
return false;
switch (band) {
case BAND_FREQ_2_4_GHZ:
freqs->channels_2ghz |= 1 << (channel - 1);
return true;
case BAND_FREQ_5_GHZ:
return l_uintset_put(freqs->channels_5ghz, channel);
}
return false;
}
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq)
{
enum band_freq band;
uint8_t channel;
channel = band_freq_to_channel(freq, &band);
if (!channel)
return false;
switch (band) {
case BAND_FREQ_2_4_GHZ:
return freqs->channels_2ghz & (1 << (channel - 1));
case BAND_FREQ_5_GHZ:
return l_uintset_contains(freqs->channels_5ghz, channel);
}
return false;
}
uint32_t scan_freq_set_get_bands(struct scan_freq_set *freqs)
{
uint32_t bands = 0;
uint32_t max;
if (freqs->channels_2ghz)
bands |= BAND_FREQ_2_4_GHZ;
max = l_uintset_get_max(freqs->channels_5ghz);
if (l_uintset_find_min(freqs->channels_5ghz) <= max)
bands |= BAND_FREQ_5_GHZ;
return bands;
}
static void scan_channels_5ghz_add(uint32_t channel, void *user_data)
{
struct l_uintset *to = user_data;
l_uintset_put(to, channel);
}
void scan_freq_set_merge(struct scan_freq_set *to,
const struct scan_freq_set *from)
{
to->channels_2ghz |= from->channels_2ghz;
l_uintset_foreach(from->channels_5ghz, scan_channels_5ghz_add,
to->channels_5ghz);
}
bool scan_freq_set_isempty(const struct scan_freq_set *set)
{
if (set->channels_2ghz == 0 && l_uintset_isempty(set->channels_5ghz))
return true;
return false;
}
struct channels_5ghz_foreach_data {
scan_freq_set_func_t func;
void *user_data;
};
static void scan_channels_5ghz_frequency(uint32_t channel, void *user_data)
{
const struct channels_5ghz_foreach_data *channels_5ghz_data = user_data;
uint32_t freq;
freq = band_channel_to_freq(channel, BAND_FREQ_5_GHZ);
channels_5ghz_data->func(freq, channels_5ghz_data->user_data);
}
void scan_freq_set_foreach(const struct scan_freq_set *freqs,
scan_freq_set_func_t func, void *user_data)
{
struct channels_5ghz_foreach_data data = { };
uint8_t channel;
uint32_t freq;
if (unlikely(!freqs || !func))
return;
data.func = func;
data.user_data = user_data;
l_uintset_foreach(freqs->channels_5ghz, scan_channels_5ghz_frequency,
&data);
if (!freqs->channels_2ghz)
return;
for (channel = 1; channel <= 14; channel++) {
if (freqs->channels_2ghz & (1 << (channel - 1))) {
freq = band_channel_to_freq(channel, BAND_FREQ_2_4_GHZ);
func(freq, user_data);
}
}
}
void scan_freq_set_constrain(struct scan_freq_set *set,
const struct scan_freq_set *constraint)
{
struct l_uintset *intersection;
intersection = l_uintset_intersect(constraint->channels_5ghz,
set->channels_5ghz);
if (!intersection)
/* This shouldn't ever be the case. */
return;
l_uintset_free(set->channels_5ghz);
set->channels_5ghz = intersection;
set->channels_2ghz &= constraint->channels_2ghz;
}

View File

@ -101,4 +101,19 @@ static inline bool util_ip_subnet_match(uint8_t prefix_len,
~((1u << (8 - (prefix_len % 8))) - 1));
}
typedef void (*scan_freq_set_func_t)(uint32_t freq, void *userdata);
struct scan_freq_set *scan_freq_set_new(void);
void scan_freq_set_free(struct scan_freq_set *freqs);
bool scan_freq_set_add(struct scan_freq_set *freqs, uint32_t freq);
bool scan_freq_set_contains(const struct scan_freq_set *freqs, uint32_t freq);
uint32_t scan_freq_set_get_bands(struct scan_freq_set *freqs);
void scan_freq_set_foreach(const struct scan_freq_set *freqs,
scan_freq_set_func_t func, void *user_data);
void scan_freq_set_merge(struct scan_freq_set *to,
const struct scan_freq_set *from);
void scan_freq_set_constrain(struct scan_freq_set *set,
const struct scan_freq_set *constraint);
bool scan_freq_set_isempty(const struct scan_freq_set *set);
#endif /* __UTIL_H */