[PATCH 2/4] wpa_supplicant: Change share_vif_oper_freq() to handle multiple freqs
Ilan Peer
ilan.peer
Tue Jul 16 23:32:24 PDT 2013
There are devices that can operate several channels concurrently.
Change shared_vif_oper_freq() to get_shared_radio_freqs() that can
return an array of frequencies currently used by all the virtual
interfaces that share the same radio.
In addition move it to wpa_supplicant.c, so it can be used by other
modules.
Signed-hostap: Ilan Peer <ilan.peer at intel.com>
Signed-hostap: David Spinadel <david.spinadel at intel.com>
---
wpa_supplicant/scan.c | 83 ++++++++++++-------------------------
wpa_supplicant/wpa_supplicant.c | 63 ++++++++++++++++++++++++++++
wpa_supplicant/wpa_supplicant_i.h | 3 ++
3 files changed, 92 insertions(+), 57 deletions(-)
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index bdd6815..dcd06cb 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -483,45 +483,6 @@ static int non_p2p_network_enabled(struct wpa_supplicant *wpa_s)
#endif /* CONFIG_P2P */
-/*
- * Find the operating frequency of any other virtual interface that is using
- * the same radio concurrently.
- */
-static int shared_vif_oper_freq(struct wpa_supplicant *wpa_s)
-{
- const char *rn, *rn2;
- struct wpa_supplicant *ifs;
- u8 bssid[ETH_ALEN];
-
- if (!wpa_s->driver->get_radio_name)
- return -1;
-
- rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
- if (rn == NULL || rn[0] == '\0')
- return -1;
-
- for (ifs = wpa_s->global->ifaces; ifs; ifs = ifs->next) {
- if (ifs == wpa_s || !ifs->driver->get_radio_name)
- continue;
-
- rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
- if (!rn2 || os_strcmp(rn, rn2) != 0)
- continue;
-
- if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
- continue;
-
- if (ifs->current_ssid->mode == WPAS_MODE_AP ||
- ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
- return ifs->current_ssid->frequency;
- if (wpa_drv_get_bssid(ifs, bssid) == 0)
- return ifs->assoc_freq;
- }
-
- return 0;
-}
-
-
static struct hostapd_hw_modes * get_mode(struct hostapd_hw_modes *modes,
u16 num_modes,
enum hostapd_hw_mode mode)
@@ -815,14 +776,19 @@ ssid_list_set:
/* Use current associated channel? */
if (wpa_s->conf->scan_cur_freq && !params.freqs) {
- int freq = shared_vif_oper_freq(wpa_s);
- if (freq > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the current "
- "operating channel (%d MHz) since "
- "scan_cur_freq is enabled", freq);
- params.freqs = os_zalloc(sizeof(int) * 2);
- if (params.freqs)
- params.freqs[0] = freq;
+ int num = wpa_s->num_multichan_concurrent;
+
+ params.freqs = os_zalloc(sizeof(int) * (num + 1));
+ if (params.freqs) {
+ num = get_shared_radio_freqs(wpa_s, params.freqs, num);
+ if (num > 0) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
+ "current operating channels since "
+ "scan_cur_freq is enabled");
+ } else {
+ os_free(params.freqs);
+ params.freqs = NULL;
+ }
}
}
@@ -860,18 +826,21 @@ scan:
if (wpa_s->scan_for_connection && scan_req == NORMAL_SCAN_REQ &&
!scan_params->freqs && !params.freqs &&
wpas_is_p2p_prioritized(wpa_s) &&
- !(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
wpa_s->p2p_group_interface == NOT_P2P_GROUP_INTERFACE &&
non_p2p_network_enabled(wpa_s)) {
- int freq = shared_vif_oper_freq(wpa_s);
- if (freq > 0) {
- wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Scan only the current "
- "operating channel (%d MHz) since driver does "
- "not support multi-channel concurrency", freq);
- params.freqs = os_zalloc(sizeof(int) * 2);
- if (params.freqs)
- params.freqs[0] = freq;
- scan_params->freqs = params.freqs;
+ int num = wpa_s->num_multichan_concurrent;
+
+ params.freqs = os_zalloc(sizeof(int) * (num + 1));
+ if (params.freqs) {
+ num = get_shared_radio_freqs(wpa_s, params.freqs, num);
+ if (num > 0 && num == wpa_s->num_multichan_concurrent) {
+ wpa_dbg(wpa_s, MSG_DEBUG, "Scan only the "
+ "current operating channels since "
+ "all channels are already used");
+ } else {
+ os_free(params.freqs);
+ params.freqs = NULL;
+ }
}
}
#endif /* CONFIG_P2P */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index e7a2d99..86c2831 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3941,3 +3941,66 @@ int wpas_wpa_is_in_progress(struct wpa_supplicant *wpa_s)
return 0;
}
+
+/*
+ * 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, int len)
+{
+ const char *rn, *rn2;
+ struct wpa_supplicant *ifs;
+ u8 bssid[ETH_ALEN];
+ int freq;
+ int idx = 0, i;
+
+ memset(freq_array, 0, sizeof(int) * 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;
+ else if (wpa_drv_get_bssid(wpa_s, bssid) == 0)
+ freq_array[idx++] = wpa_s->assoc_freq;
+ }
+
+ /* If get_radio_name is not supported, use only the local freq */
+ if (!wpa_s->driver->get_radio_name)
+ return idx;
+
+ rn = wpa_s->driver->get_radio_name(wpa_s->drv_priv);
+ if (rn == NULL || rn[0] == '\0')
+ return idx;
+
+ for (ifs = wpa_s->global->ifaces, idx = 0; ifs && idx < len;
+ ifs = ifs->next) {
+ if (wpa_s == ifs || !ifs->driver->get_radio_name)
+ continue;
+
+ rn2 = ifs->driver->get_radio_name(ifs->drv_priv);
+ if (!rn2 || os_strcmp(rn, rn2) != 0)
+ continue;
+
+ if (ifs->current_ssid == NULL || ifs->assoc_freq == 0)
+ continue;
+
+ if (ifs->current_ssid->mode == WPAS_MODE_AP ||
+ ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
+ freq = ifs->current_ssid->frequency;
+ else if (wpa_drv_get_bssid(ifs, bssid) == 0)
+ freq = ifs->assoc_freq;
+ else
+ continue;
+
+ /* Hold only distinct freqs */
+ for (i = 0; i < idx; i++)
+ if (freq_array[i] == freq)
+ break;
+
+ if (i == idx)
+ freq_array[idx++] = freq;
+ }
+ return idx;
+}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 7597908..bfb3a0c 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -862,4 +862,7 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
int wpas_init_ext_pw(struct wpa_supplicant *wpa_s);
+int get_shared_radio_freqs(struct wpa_supplicant *wpa_s,
+ int *freq_array, int len);
+
#endif /* WPA_SUPPLICANT_I_H */
--
1.7.10.4
More information about the Hostap
mailing list