[PATCH 2/2] Change channel before IBSS associations
Christopher Wiley
wiley
Thu Jun 26 13:13:07 PDT 2014
Fix a bug where changing the mode of the interface to IBSS
fails because the interface is sitting on a channel where IBSS is
disallowed because of a previous association.
Signed-off-by: Christopher Wiley <wiley at chromium.org>
---
src/drivers/driver_nl80211.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 0f4b37c..ed4522f 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -348,6 +348,8 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx,
void *timeout_ctx);
static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
enum nl80211_iftype nlmode);
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq);
+
static int
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
const u8 *set_addr, int first);
@@ -414,6 +416,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv);
static int wpa_driver_nl80211_authenticate_retry(
struct wpa_driver_nl80211_data *drv);
+static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
static int i802_set_iface_flags(struct i802_bss *bss, int up);
@@ -8594,8 +8597,7 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
- if (wpa_driver_nl80211_set_mode(drv->first_bss,
- NL80211_IFTYPE_ADHOC)) {
+ if (wpa_driver_nl80211_set_mode_ibss(drv->first_bss, params->freq)) {
wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
"IBSS mode");
return -1;
@@ -9035,8 +9037,10 @@ nla_put_failure:
}
-static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
- enum nl80211_iftype nlmode)
+static int wpa_driver_nl80211_set_mode_impl(
+ struct i802_bss *bss,
+ enum nl80211_iftype nlmode,
+ struct hostapd_freq_params *desired_freq_params)
{
struct wpa_driver_nl80211_data *drv = bss->drv;
int ret = -1;
@@ -9081,6 +9085,16 @@ static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
"interface down");
continue;
}
+ /* Setting the mode will fail for some drivers if the phy is
+ * on a frequency that the mode is disallowed in.
+ */
+ if (desired_freq_params) {
+ res = i802_set_freq(bss, desired_freq_params);
+ if (res) {
+ wpa_printf(MSG_DEBUG, "nl80211: Failed to set "
+ "frequency on interface.");
+ }
+ }
/* Try to set the mode again while the interface is down */
mode_switch_res = nl80211_set_mode(drv, drv->ifindex, nlmode);
if (mode_switch_res == -EBUSY) {
@@ -9169,6 +9183,23 @@ static int dfs_info_handler(struct nl_msg *msg, void *arg)
}
+static int wpa_driver_nl80211_set_mode(struct i802_bss *bss,
+ enum nl80211_iftype nlmode)
+{
+ return wpa_driver_nl80211_set_mode_impl(bss, nlmode, NULL);
+}
+
+
+static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss, int freq)
+{
+ struct hostapd_freq_params freq_params;
+ os_memset(&freq_params, 0, sizeof(freq_params));
+ freq_params.freq = freq;
+ return wpa_driver_nl80211_set_mode_impl(bss, NL80211_IFTYPE_ADHOC,
+ &freq_params);
+}
+
+
static int wpa_driver_nl80211_get_capa(void *priv,
struct wpa_driver_capa *capa)
{
--
2.0.0.526.g5318336
More information about the Hostap
mailing list