Make frequency range list routines more general
This allows the frequency range list implementation to be shared for other purposes. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
941dae0a2e
commit
af8a827b90
6 changed files with 120 additions and 55 deletions
|
@ -624,3 +624,99 @@ char * dup_binstr(const void *src, size_t len)
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
|
||||||
|
{
|
||||||
|
struct wpa_freq_range *freq = NULL, *n;
|
||||||
|
unsigned int count = 0;
|
||||||
|
const char *pos, *pos2, *pos3;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Comma separated list of frequency ranges.
|
||||||
|
* For example: 2412-2432,2462,5000-6000
|
||||||
|
*/
|
||||||
|
pos = value;
|
||||||
|
while (pos && pos[0]) {
|
||||||
|
n = os_realloc_array(freq, count + 1,
|
||||||
|
sizeof(struct wpa_freq_range));
|
||||||
|
if (n == NULL) {
|
||||||
|
os_free(freq);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
freq = n;
|
||||||
|
freq[count].min = atoi(pos);
|
||||||
|
pos2 = os_strchr(pos, '-');
|
||||||
|
pos3 = os_strchr(pos, ',');
|
||||||
|
if (pos2 && (!pos3 || pos2 < pos3)) {
|
||||||
|
pos2++;
|
||||||
|
freq[count].max = atoi(pos2);
|
||||||
|
} else
|
||||||
|
freq[count].max = freq[count].min;
|
||||||
|
pos = pos3;
|
||||||
|
if (pos)
|
||||||
|
pos++;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_free(res->range);
|
||||||
|
res->range = freq;
|
||||||
|
res->num = count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int freq_range_list_includes(const struct wpa_freq_range_list *list,
|
||||||
|
unsigned int freq)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (list == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i < list->num; i++) {
|
||||||
|
if (freq >= list->range[i].min && freq <= list->range[i].max)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char * freq_range_list_str(const struct wpa_freq_range_list *list)
|
||||||
|
{
|
||||||
|
char *buf, *pos, *end;
|
||||||
|
size_t maxlen;
|
||||||
|
unsigned int i;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (list->num == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
maxlen = list->num * 30;
|
||||||
|
buf = os_malloc(maxlen);
|
||||||
|
if (buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
pos = buf;
|
||||||
|
end = buf + maxlen;
|
||||||
|
|
||||||
|
for (i = 0; i < list->num; i++) {
|
||||||
|
struct wpa_freq_range *range = &list->range[i];
|
||||||
|
|
||||||
|
if (range->min == range->max)
|
||||||
|
res = os_snprintf(pos, end - pos, "%s%u",
|
||||||
|
i == 0 ? "" : ",", range->min);
|
||||||
|
else
|
||||||
|
res = os_snprintf(pos, end - pos, "%s%u-%u",
|
||||||
|
i == 0 ? "" : ",",
|
||||||
|
range->min, range->max);
|
||||||
|
if (res < 0 || res > end - pos) {
|
||||||
|
os_free(buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pos += res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
|
@ -505,6 +505,20 @@ static inline int is_broadcast_ether_addr(const u8 *a)
|
||||||
#include "wpa_debug.h"
|
#include "wpa_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct wpa_freq_range_list {
|
||||||
|
struct wpa_freq_range {
|
||||||
|
unsigned int min;
|
||||||
|
unsigned int max;
|
||||||
|
} *range;
|
||||||
|
unsigned int num;
|
||||||
|
};
|
||||||
|
|
||||||
|
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value);
|
||||||
|
int freq_range_list_includes(const struct wpa_freq_range_list *list,
|
||||||
|
unsigned int freq);
|
||||||
|
char * freq_range_list_str(const struct wpa_freq_range_list *list);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
|
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
|
||||||
* networking socket uses that do not really result in a real problem and
|
* networking socket uses that do not really result in a real problem and
|
||||||
|
|
|
@ -4351,48 +4351,21 @@ static int p2p_ctrl_peer(struct wpa_supplicant *wpa_s, char *cmd,
|
||||||
static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
|
static int p2p_ctrl_disallow_freq(struct wpa_supplicant *wpa_s,
|
||||||
const char *param)
|
const char *param)
|
||||||
{
|
{
|
||||||
struct wpa_freq_range *freq = NULL, *n;
|
unsigned int i;
|
||||||
unsigned int count = 0, i;
|
|
||||||
const char *pos, *pos2, *pos3;
|
|
||||||
|
|
||||||
if (wpa_s->global->p2p == NULL)
|
if (wpa_s->global->p2p == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/*
|
if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0)
|
||||||
* param includes comma separated frequency range.
|
return -1;
|
||||||
* For example: 2412-2432,2462,5000-6000
|
|
||||||
*/
|
|
||||||
pos = param;
|
|
||||||
while (pos && pos[0]) {
|
|
||||||
n = os_realloc_array(freq, count + 1,
|
|
||||||
sizeof(struct wpa_freq_range));
|
|
||||||
if (n == NULL) {
|
|
||||||
os_free(freq);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
freq = n;
|
|
||||||
freq[count].min = atoi(pos);
|
|
||||||
pos2 = os_strchr(pos, '-');
|
|
||||||
pos3 = os_strchr(pos, ',');
|
|
||||||
if (pos2 && (!pos3 || pos2 < pos3)) {
|
|
||||||
pos2++;
|
|
||||||
freq[count].max = atoi(pos2);
|
|
||||||
} else
|
|
||||||
freq[count].max = freq[count].min;
|
|
||||||
pos = pos3;
|
|
||||||
if (pos)
|
|
||||||
pos++;
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < wpa_s->global->p2p_disallow_freq.num; i++) {
|
||||||
|
struct wpa_freq_range *freq;
|
||||||
|
freq = &wpa_s->global->p2p_disallow_freq.range[i];
|
||||||
wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
|
wpa_printf(MSG_DEBUG, "P2P: Disallowed frequency range %u-%u",
|
||||||
freq[i].min, freq[i].max);
|
freq->min, freq->max);
|
||||||
}
|
}
|
||||||
|
|
||||||
os_free(wpa_s->global->p2p_disallow_freq);
|
|
||||||
wpa_s->global->p2p_disallow_freq = freq;
|
|
||||||
wpa_s->global->num_p2p_disallow_freq = count;
|
|
||||||
wpas_p2p_update_channel_list(wpa_s);
|
wpas_p2p_update_channel_list(wpa_s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2908,18 +2908,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
|
||||||
static int wpas_p2p_disallowed_freq(struct wpa_global *global,
|
static int wpas_p2p_disallowed_freq(struct wpa_global *global,
|
||||||
unsigned int freq)
|
unsigned int freq)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
return freq_range_list_includes(&global->p2p_disallow_freq, freq);
|
||||||
|
|
||||||
if (global->p2p_disallow_freq == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
for (i = 0; i < global->num_p2p_disallow_freq; i++) {
|
|
||||||
if (freq >= global->p2p_disallow_freq[i].min &&
|
|
||||||
freq <= global->p2p_disallow_freq[i].max)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3500,7 +3500,7 @@ void wpa_supplicant_deinit(struct wpa_global *global)
|
||||||
os_free(global->params.override_driver);
|
os_free(global->params.override_driver);
|
||||||
os_free(global->params.override_ctrl_interface);
|
os_free(global->params.override_ctrl_interface);
|
||||||
|
|
||||||
os_free(global->p2p_disallow_freq);
|
os_free(global->p2p_disallow_freq.range);
|
||||||
os_free(global->add_psk);
|
os_free(global->add_psk);
|
||||||
|
|
||||||
os_free(global);
|
os_free(global);
|
||||||
|
|
|
@ -227,12 +227,6 @@ struct p2p_srv_upnp {
|
||||||
char *service;
|
char *service;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wpa_freq_range {
|
|
||||||
unsigned int min;
|
|
||||||
unsigned int max;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct wpa_global - Internal, global data for all %wpa_supplicant interfaces
|
* struct wpa_global - Internal, global data for all %wpa_supplicant interfaces
|
||||||
*
|
*
|
||||||
|
@ -257,8 +251,7 @@ struct wpa_global {
|
||||||
struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
|
struct dl_list p2p_srv_upnp; /* struct p2p_srv_upnp */
|
||||||
int p2p_disabled;
|
int p2p_disabled;
|
||||||
int cross_connection;
|
int cross_connection;
|
||||||
struct wpa_freq_range *p2p_disallow_freq;
|
struct wpa_freq_range_list p2p_disallow_freq;
|
||||||
unsigned int num_p2p_disallow_freq;
|
|
||||||
enum wpa_conc_pref {
|
enum wpa_conc_pref {
|
||||||
WPA_CONC_PREF_NOT_SET,
|
WPA_CONC_PREF_NOT_SET,
|
||||||
WPA_CONC_PREF_STA,
|
WPA_CONC_PREF_STA,
|
||||||
|
|
Loading…
Reference in a new issue