[PATCH 1/5] wpa_supplicant: Collect and use extended data on used frequencies

Ilan Peer ilan.peer at intel.com
Mon May 19 03:05:35 EDT 2014


When the number of frequencies supported by the kernel is bigger
than one, and there is a need to pick a frequency for a new flow
such as P2P GON or P2P invitation, the flow should be able to
pick the best frequency among all the frequencies currently used
by the device.

In order to prioritize between the currently used frequencies, add
the ability to collect additional data about each used frequency
(if the frequency is used by a station interface or P2P Client)
and when needed select the best frequency, where:

1. Infrastructure interfaces have highest priority
2. P2P Client interfaces have higher priority over AP/GO
   interfaces.

The rational is that the frequency of an AP/GO can change while
that of a station interface cannot.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 wpa_supplicant/p2p_supplicant.c   |  262 ++++++++++++++++++++++---------------
 wpa_supplicant/wpa_supplicant.c   |   92 +++++++++++--
 wpa_supplicant/wpa_supplicant_i.h |   15 +++
 3 files changed, 255 insertions(+), 114 deletions(-)

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index a814028..7b3224e 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -155,29 +155,31 @@ static int wpas_p2p_num_unused_channels(struct wpa_supplicant *wpa_s)
  * Get the frequencies that are currently in use by one or more of the virtual
  * interfaces, and that are also valid for P2P operation.
  */
-static int wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
-				     int *p2p_freqs, unsigned int len)
+static unsigned int wpas_p2p_valid_oper_freqs(struct wpa_supplicant *wpa_s,
+					      struct wpa_used_freq_data *p2p_freqs,
+					      unsigned int len)
 {
-	int *freqs;
+	struct wpa_used_freq_data *freqs_data;
 	unsigned int num, i, j;
 
-	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
-	if (!freqs)
-		return -1;
+	freqs_data = os_calloc(wpa_s->num_multichan_concurrent,
+			       sizeof(struct wpa_used_freq_data));
+	if (!freqs_data)
+		return 0;
 
-	num = get_shared_radio_freqs(wpa_s, freqs,
-				     wpa_s->num_multichan_concurrent);
+	num = get_shared_radio_freqs_data(wpa_s, freqs_data,
+					  wpa_s->num_multichan_concurrent);
 
-	os_memset(p2p_freqs, 0, sizeof(int) * len);
+	os_memset(p2p_freqs, 0, sizeof(struct wpa_used_freq_data) * len);
 
 	for (i = 0, j = 0; i < num && j < len; i++) {
-		if (p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
-			p2p_freqs[j++] = freqs[i];
+		if (p2p_supported_freq(wpa_s->global->p2p, freqs_data[i].freq))
+			p2p_freqs[j++] = freqs_data[i];
 	}
 
-	os_free(freqs);
+	os_free(freqs_data);
 
-	dump_freq_array(wpa_s, "valid for P2P", p2p_freqs, j);
+	dump_freq_data(wpa_s, "valid for P2P", p2p_freqs, j);
 
 	return j;
 }
@@ -2910,6 +2912,33 @@ static int freq_included(const struct p2p_channels *channels, unsigned int freq)
 
 }
 
+/**
+ * Pick the best frequency to use from all the currently used frequencies.
+ * The function assumes that all the freqs in freqs_data are valid P2P
+ * frequencies.
+ */
+static int wpas_p2p_pick_best_used_freq(struct wpa_supplicant *wpa_s,
+					struct wpa_used_freq_data *freqs_data,
+					unsigned int num)
+{
+	unsigned int i, c = 0;
+
+	if (num == 0)
+		return 0;
+
+	for (i = 1; i < num; i++) {
+		/* 1. BSS interfaces have higher preference.
+		 * 2. P2P Clients have higher preference.
+		 * 3. All others.
+		 */
+		if (freqs_data[i].flags & WPA_FREQ_USED_BY_BSS)
+			c = i;
+		else if ((freqs_data[i].flags & WPA_FREQ_USED_BY_P2P_CLIENT) &&
+			 !(freqs_data[c].flags & WPA_FREQ_USED_BY_BSS))
+			c = i;
+	}
+	return freqs_data[c].freq;
+}
 
 static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
 				  const u8 *go_dev_addr, const u8 *ssid,
@@ -2920,8 +2949,9 @@ static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
 {
 	struct wpa_supplicant *wpa_s = ctx;
 	struct wpa_ssid *s;
-	int res;
+	struct wpa_used_freq_data *freqs_data;
 	struct wpa_supplicant *grp;
+	int best_freq;
 
 	if (!persistent_group) {
 		wpa_printf(MSG_DEBUG, "P2P: Invitation from " MACSTR
@@ -3012,19 +3042,26 @@ static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
 accept_inv:
 	wpas_p2p_set_own_freq_preference(wpa_s, 0);
 
+	best_freq = 0;
+	freqs_data = os_calloc(wpa_s->num_multichan_concurrent,
+			       sizeof(struct wpa_used_freq_data));
+
+	if (freqs_data) {
+		int num_channels = wpa_s->num_multichan_concurrent;
+		int num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
+						    num_channels);
+		best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs_data,
+							 num);
+		os_free(freqs_data);
+	}
+
 	/* Get one of the frequencies currently in use */
-	if (wpas_p2p_valid_oper_freqs(wpa_s, &res, 1) > 0) {
-		wpa_printf(MSG_DEBUG, "P2P: Trying to prefer a channel already used by one of the interfaces");
-		wpas_p2p_set_own_freq_preference(wpa_s, res);
-
-		if (wpa_s->num_multichan_concurrent < 2 ||
-		    wpas_p2p_num_unused_channels(wpa_s) < 1) {
-			wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
-			*force_freq = res;
-		}
+	if (best_freq > 0) {
+		wpa_printf(MSG_DEBUG, "P2P: Trying to force channel to match a channel already used by one of the interfaces");
+		wpas_p2p_set_own_freq_preference(wpa_s, best_freq);
 	}
 
-	if (*force_freq > 0 && wpa_s->num_multichan_concurrent > 1 &&
+	if (wpa_s->num_multichan_concurrent > 1 &&
 	    wpas_p2p_num_unused_channels(wpa_s) > 0) {
 		if (*go == 0) {
 			/* We are the client */
@@ -3041,8 +3078,10 @@ accept_inv:
 				   *force_freq);
 			*force_freq = 0;
 		}
+	} else {
+		wpa_printf(MSG_DEBUG, "P2P: No extra channels available - trying to force channel to match a channel already used by one of the interfaces");
+		*force_freq = best_freq;
 	}
-
 	return P2P_SC_SUCCESS;
 }
 
@@ -4091,26 +4130,24 @@ static void wpas_p2p_check_join_scan_limit(struct wpa_supplicant *wpa_s)
 
 static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
 {
-	int *freqs, res, num, i;
+	unsigned int res, num, i;
+	struct wpa_used_freq_data *freqs_data;
 
 	if (wpas_p2p_num_unused_channels(wpa_s) > 0) {
 		/* Multiple channels are supported and not all are in use */
 		return 0;
 	}
 
-	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
-	if (!freqs)
+	freqs_data = os_calloc(wpa_s->num_multichan_concurrent,
+			       sizeof(struct wpa_used_freq_data));
+	if (!freqs_data)
 		return 1;
 
-	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
+	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
 					wpa_s->num_multichan_concurrent);
-	if (num < 0) {
-		res = 1;
-		goto exit_free;
-	}
 
 	for (i = 0; i < num; i++) {
-		if (freqs[i] == freq) {
+		if (freqs_data[i].freq == freq) {
 			wpa_printf(MSG_DEBUG, "P2P: Frequency %d MHz in use by another virtual interface and can be used",
 				   freq);
 			res = 0;
@@ -4118,10 +4155,11 @@ static int wpas_check_freq_conflict(struct wpa_supplicant *wpa_s, int freq)
 		}
 	}
 
+	wpa_printf(MSG_DEBUG, "P2P: No valid operating frequencies");
 	res = 1;
 
 exit_free:
-	os_free(freqs);
+	os_free(freqs_data);
 	return res;
 }
 
@@ -4551,15 +4589,24 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
 static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
 				int *force_freq, int *pref_freq, int go)
 {
-	int *freqs, res;
-	unsigned int freq_in_use = 0, num, i;
+	int res;
+	struct wpa_used_freq_data *freqs_data;
+	unsigned int freq_in_use = 0, num, num_unused, i;
+	int best_freq;
 
-	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
-	if (!freqs)
+	freqs_data = os_calloc(wpa_s->num_multichan_concurrent,
+			       sizeof(struct wpa_used_freq_data));
+	if (!freqs_data)
 		return -1;
 
-	num = get_shared_radio_freqs(wpa_s, freqs,
-				     wpa_s->num_multichan_concurrent);
+	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
+					wpa_s->num_multichan_concurrent);
+
+	/* It is possible that the total number of used frequencies is bigger
+	 * than the number of frequencies used for P2P, so get the system wide
+	 * number of unused freqs */
+	num_unused = wpas_p2p_num_unused_channels(wpa_s);
+
 	wpa_printf(MSG_DEBUG,
 		   "P2P: Setup freqs: freq=%d num_MCC=%d shared_freqs=%u",
 		   freq, wpa_s->num_multichan_concurrent, num);
@@ -4579,12 +4626,13 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
 		}
 
 		for (i = 0; i < num; i++) {
-			if (freqs[i] == freq)
+			if (freqs_data[i].freq == freq)
 				freq_in_use = 1;
 		}
 
-		if (num == wpa_s->num_multichan_concurrent && !freq_in_use) {
-			wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group on %u MHz as there are no available channels",
+		if (num_unused <= 0 && !freq_in_use) {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Cannot start P2P group on %u MHz as there are no available channels",
 				   freq);
 			res = -2;
 			goto exit_free;
@@ -4595,40 +4643,38 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
 		goto exit_ok;
 	}
 
-	for (i = 0; i < num; i++) {
-		if (!p2p_supported_freq(wpa_s->global->p2p, freqs[i]))
-			continue;
+	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs_data, num);
 
-		if (*pref_freq == 0 && num < wpa_s->num_multichan_concurrent) {
-			wpa_printf(MSG_DEBUG, "P2P: Try to prefer a frequency (%u MHz) we are already using",
-				   freqs[i]);
-			*pref_freq = freqs[i];
-		} else {
-			wpa_printf(MSG_DEBUG, "P2P: Try to force us to use frequency (%u MHz) which is already in use",
-				   freqs[i]);
-			*force_freq = freqs[i];
-		}
-		break;
-	}
+	/* We have a candidate frequency to use */
+	if (best_freq > 0) {
+		if (*pref_freq == 0 && num_unused > 0) {
+			*pref_freq = best_freq;
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Try to prefer a frequency (%u MHz) which we are already using",
+				   *pref_freq);
 
-	if (i == num) {
-		if (num < wpa_s->num_multichan_concurrent && num > 0) {
-			wpa_printf(MSG_DEBUG, "P2P: Current operating channels are not available for P2P. Try to use another channel");
-			*force_freq = 0;
-		} else if (num < wpa_s->num_multichan_concurrent) {
-			wpa_printf(MSG_DEBUG, "P2P: No current operating channels - try to use a new channel");
-			*force_freq = 0;
 		} else {
-			wpa_printf(MSG_DEBUG, "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
-			res = -2;
-			goto exit_free;
+			*force_freq = best_freq;
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Try to force a frequency (%u MHz) which we are already in using",
+				   *force_freq);
 		}
+
+	} else if (num_unused > 0) {
+		wpa_printf(MSG_DEBUG,
+			   "P2P: Current operating channels are not available for P2P. Try to use another channel");
+		*force_freq = 0;
+	} else {
+		wpa_printf(MSG_DEBUG,
+			   "P2P: All channels are in use and none of them are P2P enabled. Cannot start P2P group");
+		res = -2;
+		goto exit_free;
 	}
 
 exit_ok:
 	res = 0;
 exit_free:
-	os_free(freqs);
+	os_free(freqs_data);
 	return res;
 }
 
@@ -4958,9 +5004,9 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 				   int freq, int ht40, int vht,
 				   const struct p2p_channels *channels)
 {
-	int res, *freqs;
-	unsigned int pref_freq;
-	unsigned int num, i;
+	struct wpa_used_freq_data *freqs_data;
+	unsigned int pref_freq, cand_freq;
+	unsigned int i, num;
 
 	os_memset(params, 0, sizeof(*params));
 	params->role_go = 1;
@@ -5041,45 +5087,57 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
 			   "known)", params->freq);
 	}
 
-	freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(int));
-	if (!freqs)
+	freqs_data = os_calloc(wpa_s->num_multichan_concurrent,
+			       sizeof(struct wpa_used_freq_data));
+	if (!freqs_data)
 		return -1;
 
-	res = wpas_p2p_valid_oper_freqs(wpa_s, freqs,
+	num = wpas_p2p_valid_oper_freqs(wpa_s, freqs_data,
 					wpa_s->num_multichan_concurrent);
-	if (res < 0) {
-		os_free(freqs);
-		return -1;
-	}
-	num = res;
 
-	for (i = 0; i < num; i++) {
-		if (freq && freqs[i] == freq)
-			break;
-		if (!freq && freq_included(channels, freqs[i])) {
-			wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
-				   freqs[i]);
-			params->freq = freqs[i];
-			break;
+	cand_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs_data, num);
+
+	/* First try the best used frequency if possible */
+	if (!freq && cand_freq > 0 && freq_included(channels, cand_freq)) {
+			params->freq = cand_freq;
+	} else if (!freq) {
+		/* Try any of the used frequencies */
+		for (i = 0; i < num; i++) {
+			if (freq_included(channels, freqs_data[i].freq)) {
+				wpa_printf(MSG_DEBUG, "P2P: Force GO on a channel we are already using (%u MHz)",
+					   freqs_data[i].freq);
+				params->freq = freqs_data[i].freq;
+				break;
+			}
 		}
-	}
 
-	if (i == num) {
-		if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
-			if (freq)
-				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
-			else
+		if (i == num) {
+			if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
 				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using");
-			os_free(freqs);
-			return -1;
-		} else if (num == 0) {
-			wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
-		} else {
-			wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
+				os_free(freqs_data);
+				return -1;
+			} else {
+				wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on any of the channels we are already using. Use one of the free channels");
+			}
+		}
+	} else {
+		for (i = 0; i < num; i++) {
+			if (freqs_data[i].freq == freq)
+				break;
 		}
-	}
 
-	os_free(freqs);
+		if (i == num) {
+			if (wpas_p2p_num_unused_channels(wpa_s) <= 0) {
+				if (freq)
+					wpa_printf(MSG_DEBUG, "P2P: Cannot force GO on freq (%u MHz) as all the channels are in use", freq);
+				os_free(freqs_data);
+				return -1;
+			} else {
+				wpa_printf(MSG_DEBUG, "P2P: Use one of the free channels");
+			}
+		}
+	}
+	os_free(freqs_data);
 	return 0;
 }
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7843808..ec347be 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -4645,13 +4645,30 @@ void dump_freq_array(struct wpa_supplicant *wpa_s, const char *title,
 		wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d", i, freq_array[i]);
 }
 
+void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
+		    struct wpa_used_freq_data *freqs_data,
+		    unsigned int len)
+{
+	unsigned int i;
+
+	wpa_dbg(wpa_s, MSG_DEBUG, "Shared frequencies (len=%u): %s",
+		len, title);
+	for (i = 0; i < len; i++) {
+		struct wpa_used_freq_data *cur = &freqs_data[i];
+		wpa_dbg(wpa_s, MSG_DEBUG, "freq[%u]: %d, flags=0x%X",
+			i, cur->freq, cur->flags);
+	}
+}
+
 
 /*
  * Find the operating frequencies of any of the virtual interfaces that
- * are using the same radio as the current interface.
+ * are using the same radio as the current interface, and in addition, get
+ * information about the interface types that are using the frequency.
  */
-int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
-			   int *freq_array, unsigned int len)
+int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
+				struct wpa_used_freq_data *freqs_data,
+				unsigned int len)
 {
 	struct wpa_supplicant *ifs;
 	u8 bssid[ETH_ALEN];
@@ -4660,29 +4677,45 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
 
 	wpa_dbg(wpa_s, MSG_DEBUG,
 		"Determining shared radio frequencies (max len %u)", len);
-	os_memset(freq_array, 0, sizeof(int) * len);
+	os_memset(freqs_data, 0, sizeof(struct wpa_used_freq_data) * len);
 
 	/* First add the frequency of the local interface */
 	if (wpa_s->current_ssid != NULL && wpa_s->assoc_freq != 0) {
 		if (wpa_s->current_ssid->mode == WPAS_MODE_AP ||
 		    wpa_s->current_ssid->mode == WPAS_MODE_P2P_GO)
-			freq_array[idx++] = wpa_s->current_ssid->frequency;
+			freqs_data[idx++].freq = wpa_s->current_ssid->frequency;
 		else if (wpa_drv_get_bssid(wpa_s, bssid) == 0)
-			freq_array[idx++] = wpa_s->assoc_freq;
+			freqs_data[idx++].freq = wpa_s->assoc_freq;
+
+		if (idx) {
+			if (wpa_s->current_ssid->mode == WPAS_MODE_INFRA) {
+				if (wpa_s->p2p_group_interface ==
+				    P2P_GROUP_INTERFACE_CLIENT)
+					freqs_data[0].flags =
+						WPA_FREQ_USED_BY_P2P_CLIENT;
+				else
+					freqs_data[0].flags =
+						WPA_FREQ_USED_BY_BSS;
+			}
+		}
 	}
 
 	/* If get_radio_name is not supported, use only the local freq */
 	if (!wpa_driver_get_radio_name(wpa_s)) {
 		freq = wpa_drv_shared_freq(wpa_s);
 		if (freq > 0 && idx < len &&
-		    (idx == 0 || freq_array[0] != freq))
-			freq_array[idx++] = freq;
-		dump_freq_array(wpa_s, "No get_radio_name", freq_array, idx);
+		    (idx == 0 || freqs_data[0].freq != freq)) {
+			freqs_data[idx++].freq = freq;
+		}
+		dump_freq_data(wpa_s, "No get_radio_name", freqs_data, idx);
 		return idx;
 	}
 
 	dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
 			 radio_list) {
+		if (idx == len)
+			break;
+
 		if (wpa_s == ifs)
 			continue;
 
@@ -4699,13 +4732,48 @@ int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
 
 		/* Hold only distinct freqs */
 		for (i = 0; i < idx; i++)
-			if (freq_array[i] == freq)
+			if (freqs_data[i].freq == freq)
 				break;
 
 		if (i == idx)
-			freq_array[idx++] = freq;
+			freqs_data[idx++].freq = freq;
+
+		if (ifs->current_ssid->mode == WPAS_MODE_INFRA) {
+			if (ifs->p2p_group_interface ==
+			    P2P_GROUP_INTERFACE_CLIENT)
+				freqs_data[i].flags |=
+					WPA_FREQ_USED_BY_P2P_CLIENT;
+			else
+				freqs_data[i].flags |=
+					WPA_FREQ_USED_BY_BSS;
+		}
 	}
 
-	dump_freq_array(wpa_s, "completed iteration", freq_array, idx);
+	dump_freq_data(wpa_s, "completed iteration", freqs_data, idx);
 	return idx;
 }
+
+/*
+ * Find the operating frequencies of any of the virtual interfaces that
+ * are using the same radio as the current interface.
+ */
+int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
+			   int *freq_array, unsigned int len)
+{
+	struct wpa_used_freq_data *freqs_data;
+	int num, i;
+
+	os_memset(freq_array, 0, sizeof(int) * len);
+
+	freqs_data = os_calloc(len, sizeof(struct wpa_used_freq_data));
+	if (!freqs_data)
+		return -1;
+
+	num = get_shared_radio_freqs_data(wpa_s, freqs_data, len);
+	for (i = 0; i < num; i++)
+		freq_array[i] = freqs_data[i].freq;
+
+	os_free(freqs_data);
+	return num;
+}
+
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index a57f962..aab4c62 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -365,6 +365,14 @@ struct wpa_ssid_value {
 	size_t ssid_len;
 };
 
+#define WPA_FREQ_USED_BY_BSS BIT(0)
+#define WPA_FREQ_USED_BY_P2P_CLIENT BIT(1)
+
+struct wpa_used_freq_data {
+	int freq;
+	unsigned int flags;
+};
+
 /**
  * struct wpa_supplicant - Internal data for wpa_supplicant interface
  *
@@ -988,6 +996,13 @@ int wpas_init_ext_pw(struct wpa_supplicant *wpa_s);
 
 void dump_freq_array(struct wpa_supplicant *wpa_s, const char *title,
 		     int *freq_array, unsigned int len);
+void dump_freq_data(struct wpa_supplicant *wpa_s, const char *title,
+		    struct wpa_used_freq_data *freqs_data,
+		    unsigned int len);
+
+int get_shared_radio_freqs_data(struct wpa_supplicant *wpa_s,
+				struct wpa_used_freq_data *freqs_data,
+				unsigned int len);
 int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
 			   int *freq_array, unsigned int len);
 
-- 
1.7.10.4



More information about the HostAP mailing list