Make frequency range list routines more general
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 22 Oct 2013 16:10:56 +0000 (19:10 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 22 Oct 2013 21:44:07 +0000 (00:44 +0300)
This allows the frequency range list implementation to be shared for
other purposes.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/utils/common.c
src/utils/common.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 207d477..5734de7 100644 (file)
@@ -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;
+}
index 29f0b95..399ab79 100644 (file)
@@ -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
index b2d7882..d0c0a01 100644 (file)
@@ -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;
 }
index 95ebdfd..5f5145b 100644 (file)
@@ -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);
 }
 
 
index bd0773f..d9c6c10 100644 (file)
@@ -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);
index d44f0a2..eea7be9 100644 (file)
@@ -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,