mac80211/hostapd: add support for HT capa in case of IBSS/RSN
authorJohn Crispin <john@openwrt.org>
Tue, 24 Jul 2012 23:07:25 +0000 (23:07 +0000)
committerJohn Crispin <john@openwrt.org>
Tue, 24 Jul 2012 23:07:25 +0000 (23:07 +0000)
Signed-off-by: Antonio Quartulli <ordex@autistici.org>
SVN-Revision: 32830

package/hostapd/files/wpa_supplicant.sh
package/hostapd/patches/604-wpa_s-support-htmode-param.patch [new file with mode: 0644]
package/mac80211/files/lib/wifi/mac80211.sh

index 6f89c646aab12212f78f7267ba572f025f93845f..babacd79689e77055494864bd31e77ffb36deb7c 100644 (file)
@@ -4,6 +4,7 @@ wpa_supplicant_setup_vif() {
        local key="$key"
        local options="$3"
        local freq=""
+       local ht="$5"
        local ap_scan=""
        local scan_ssid="1"
        [ -n "$4" ] && freq="frequency=$4"
@@ -149,6 +150,9 @@ wpa_supplicant_setup_vif() {
                mrate=${mcast_rate:+"mcast_rate=$mcval"}
        }
 
+       local ht_str
+       [ -n "$ht" ] && ht_str="htmode=$ht"
+
        rm -rf /var/run/wpa_supplicant-$ifname
        cat > /var/run/wpa_supplicant-$ifname.conf <<EOF
 ctrl_interface=/var/run/wpa_supplicant-$ifname
@@ -165,6 +169,7 @@ network={
        $beacon_interval
        $brates
        $mrate
+       $ht_str
        $ieee80211w
        $passphrase
        $pairwise
diff --git a/package/hostapd/patches/604-wpa_s-support-htmode-param.patch b/package/hostapd/patches/604-wpa_s-support-htmode-param.patch
new file mode 100644 (file)
index 0000000..7e1a7a0
--- /dev/null
@@ -0,0 +1,169 @@
+From b9329c5dfeed7d5c55d2117d8dfe326fc40c8fb1 Mon Sep 17 00:00:00 2001
+From: Antonio Quartulli <ordex@autistici.org>
+Date: Tue, 3 Jul 2012 00:36:24 +0200
+Subject: [PATCH] wpa_s: support htmode param
+
+possible values are HT20, HT40-, HT40+ and NOHT
+
+Signed-off-by: Antonio Quartulli <ordex@autistici.org>
+---
+ src/drivers/driver.h            |    2 ++
+ src/drivers/driver_nl80211.c    |   16 ++++++++++
+ wpa_supplicant/config.c         |   66 +++++++++++++++++++++++++++++++++++++++
+ wpa_supplicant/config_ssid.h    |    2 ++
+ wpa_supplicant/wpa_supplicant.c |    2 ++
+ 5 files changed, 88 insertions(+)
+
+diff --git a/src/drivers/driver.h b/src/drivers/driver.h
+index dda2fbc..28bd181 100644
+--- a/src/drivers/driver.h
++++ b/src/drivers/driver.h
+@@ -337,6 +337,8 @@ struct wpa_driver_associate_params {
+       int fixed_freq;
+       unsigned char rates[NL80211_MAX_SUPP_RATES];
+       int mcast_rate;
++      int ht_set;
++      unsigned int htmode;
+       /**
+        * bg_scan_period - Background scan period in seconds, 0 to disable
+diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
+index 9783c96..d1257a7 100644
+--- a/src/drivers/driver_nl80211.c
++++ b/src/drivers/driver_nl80211.c
+@@ -6493,6 +6493,22 @@ retry:
+               NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, params->mcast_rate);
+       }
++      if (params->ht_set) {
++              switch(params->htmode) {
++                      case NL80211_CHAN_HT20:
++                              wpa_printf(MSG_DEBUG, "  * ht=HT20");
++                              break;
++                      case NL80211_CHAN_HT40PLUS:
++                              wpa_printf(MSG_DEBUG, "  * ht=HT40+");
++                              break;
++                      case NL80211_CHAN_HT40MINUS:
++                              wpa_printf(MSG_DEBUG, "  * ht=HT40-");
++                              break;
++              }
++              NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE,
++                          params->htmode);
++      }
++
+       ret = nl80211_set_conn_keys(params, msg);
+       if (ret)
+               goto nla_put_failure;
+diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
+index 3d6c0e6..d96b2ea 100644
+--- a/wpa_supplicant/config.c
++++ b/wpa_supplicant/config.c
+@@ -1468,6 +1468,71 @@ static char * wpa_config_write_mcast_rate(const struct parse_data *data,
+ }
+ #endif /* NO_CONFIG_WRITE */
++static int wpa_config_parse_htmode(const struct parse_data *data,
++                                 struct wpa_ssid *ssid, int line,
++                                 const char *value)
++{
++      int i;
++      static const struct {
++              const char *name;
++              unsigned int val;
++      } htmap[] = {
++              { .name = "HT20", .val = NL80211_CHAN_HT20, },
++              { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, },
++              { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, },
++              { .name = "NOHT", .val = NL80211_CHAN_NO_HT, },
++      };
++      ssid->ht_set = 0;;
++      for (i = 0; i < 4; i++) {
++              if (strcasecmp(htmap[i].name, value) == 0) {
++                      ssid->htmode = htmap[i].val;
++                      ssid->ht_set = 1;
++                      break;
++              }
++      }
++
++      return 0;
++}
++
++#ifndef NO_CONFIG_WRITE
++static char * wpa_config_write_htmode(const struct parse_data *data,
++                                    struct wpa_ssid *ssid)
++{
++      char *value;
++      int res;
++
++      value = os_malloc(6); /* longest: HT40+ */
++      if (value == NULL)
++              return NULL;
++
++      switch(ssid->htmode) {
++              case NL80211_CHAN_HT20:
++                      res = os_snprintf(value, 4, "HT20");
++                      break;
++              case NL80211_CHAN_HT40PLUS:
++                      res = os_snprintf(value, 5, "HT40+");
++                      break;
++              case NL80211_CHAN_HT40MINUS:
++                      res = os_snprintf(value, 5, "HT40-");
++                      break;
++              case NL80211_CHAN_NO_HT:
++                      res = os_snprintf(value, 4, "NOHT");
++                      break;
++              default:
++                      os_free(value);
++                      return NULL;
++      }
++
++      if (res < 0) {
++              os_free(value);
++              return NULL;
++      }
++
++      return value;
++}
++#endif /* NO_CONFIG_WRITE */
++
++
+ static int wpa_config_parse_rates(const struct parse_data *data,
+                                 struct wpa_ssid *ssid, int line,
+                                 const char *value)
+@@ -1706,6 +1771,7 @@ static const struct parse_data ssid_fields[] = {
+       { INT_RANGE(beacon_interval, 0, 1000) },
+       { FUNC(rates) },
+       { FUNC(mcast_rate) },
++      { FUNC(htmode) },
+ };
+ #undef OFFSET
+diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
+index 8d152a4..7143277 100644
+--- a/wpa_supplicant/config_ssid.h
++++ b/wpa_supplicant/config_ssid.h
+@@ -505,6 +505,8 @@ struct wpa_ssid {
+       int beacon_interval;
+       unsigned char rates[NL80211_MAX_SUPP_RATES];
+       double mcast_rate;
++      int ht_set;
++      unsigned int htmode;
+ };
+ #endif /* CONFIG_SSID_H */
+diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
+index 59efa16..fc8762f 100644
+--- a/wpa_supplicant/wpa_supplicant.c
++++ b/wpa_supplicant/wpa_supplicant.c
+@@ -1379,6 +1379,8 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s,
+                       i++;
+               }
+               params.mcast_rate = ssid->mcast_rate;
++              params.ht_set = ssid->ht_set;
++              params.htmode = ssid->htmode;
+       }
+       params.wpa_ie = wpa_ie;
+-- 
+1.7.9.4
+
index 97fd0507445e3fe7b5cc67e0017262bb701b5083..6dfe2a2caf1be51210a0ce01c1d46cbd8d8c1ad4 100644 (file)
@@ -445,11 +445,17 @@ enable_mac80211() {
                                config_get encryption "$vif" encryption
                                config_get key "$vif" key 1
                                config_get mcast_rate "$vif" mcast_rate
+                               config_get htmode "$device" htmode
+                               case "$htmode" in
+                                       HT20|HT40+|HT40-) ;;
+                                       *) htmode= ;;
+                               esac
+
 
                                local keyspec=""
                                [ "$encryption" == "psk" -o "$encryption" == "psk2" ] && {
                                        if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
-                                               wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" $freq || {
+                                               wpa_supplicant_setup_vif "$vif" nl80211 "${hostapd_ctrl:+-H $hostapd_ctrl}" $freq $htmode || {
                                                        echo "enable_mac80211($device): Failed to set up wpa_supplicant for interface $ifname" >&2
                                                        # make sure this wifi interface won't accidentally stay open without encryption
                                                        ifconfig "$ifname" down
@@ -496,12 +502,6 @@ enable_mac80211() {
                                        [ "$mcsub" -gt 0 ] && mcval="$mcval.$mcsub"
                                }
 
-                               config_get htmode "$device" htmode
-                               case "$htmode" in
-                                       HT20|HT40+|HT40-|NOHT) ;;
-                                       *) htmode= ;;
-                               esac
-
                                iw dev "$ifname" ibss join "$ssid" $freq $htmode \
                                        ${fixed:+fixed-freq} $bssid \
                                        ${beacon_int:+beacon-interval $beacon_int} \