diff --git a/src/utils/common.c b/src/utils/common.c index 207d4778c..5734de711 100644 --- a/src/utils/common.c +++ b/src/utils/common.c @@ -624,3 +624,99 @@ char * dup_binstr(const void *src, size_t len) 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; +} diff --git a/src/utils/common.h b/src/utils/common.h index 29f0b9535..399ab7963 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -505,6 +505,20 @@ static inline int is_broadcast_ether_addr(const u8 *a) #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 * networking socket uses that do not really result in a real problem and diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index b2d7882c3..d0c0a01e1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -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, const char *param) { - struct wpa_freq_range *freq = NULL, *n; - unsigned int count = 0, i; - const char *pos, *pos2, *pos3; + unsigned int i; if (wpa_s->global->p2p == NULL) return -1; - /* - * param includes comma separated frequency range. - * 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++; - } + if (freq_range_list_parse(&wpa_s->global->p2p_disallow_freq, param) < 0) + return -1; - 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", - 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); return 0; } diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 95ebdfd6f..5f5145b44 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -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, unsigned int freq) { - unsigned int i; - - 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; + return freq_range_list_includes(&global->p2p_disallow_freq, freq); } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index bd0773fd1..d9c6c10b4 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3500,7 +3500,7 @@ void wpa_supplicant_deinit(struct wpa_global *global) os_free(global->params.override_driver); 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); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d44f0a28e..eea7be9ab 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -227,12 +227,6 @@ struct p2p_srv_upnp { char *service; }; -struct wpa_freq_range { - unsigned int min; - unsigned int max; -}; - - /** * 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 */ int p2p_disabled; int cross_connection; - struct wpa_freq_range *p2p_disallow_freq; - unsigned int num_p2p_disallow_freq; + struct wpa_freq_range_list p2p_disallow_freq; enum wpa_conc_pref { WPA_CONC_PREF_NOT_SET, WPA_CONC_PREF_STA,