config_add_string hwmode
config_add_int beacon_int chanbw frag rts
config_add_int rxantenna txantenna antenna_gain txpower distance
- config_add_boolean noscan
+ config_add_boolean noscan ht_coex
config_add_array ht_capab
+ config_add_array channels
config_add_boolean \
rxldpc \
short_gi_80 \
greenfield \
short_gi_20 \
short_gi_40 \
+ max_amsdu \
dsss_cck_40
}
config_add_boolean wds powersave
config_add_int maxassoc
config_add_int max_listen_int
- config_add_int dtim_interval
+ config_add_int dtim_period
+ config_add_int start_disabled
# mesh
config_add_string mesh_id
json_select config
[ "$auto_channel" -gt 0 ] && channel=acs_survey
+ [ "$auto_channel" -gt 0 ] && json_get_values channel_list channels
- json_get_vars noscan htmode
+ json_get_vars noscan ht_coex
json_get_values ht_capab_list ht_capab
ieee80211n=1
[ -n "$ieee80211n" ] && {
append base_cfg "ieee80211n=1" "$N"
+ set_default ht_coex 0
+ append base_cfg "ht_coex=$ht_coex" "$N"
+
json_get_vars \
ldpc:1 \
- greenfield:1 \
+ greenfield:0 \
short_gi_20:1 \
short_gi_40:1 \
tx_stbc:1 \
rx_stbc:3 \
+ max_amsdu:1 \
dsss_cck_40:1
ht_cap_mask=0
RX-STBC1:0x300:0x100:1 \
RX-STBC12:0x300:0x200:1 \
RX-STBC123:0x300:0x300:1 \
+ MAX-AMSDU-7935:0x800::$max_amsdu \
DSSS_CCK-40:0x1000::$dsss_cck_40
ht_capab="$ht_capab$ht_capab_flags"
vht_max_a_mpdu_len_exp:7 \
vht_max_mpdu:11454 \
rx_stbc:4 \
- tx_stbc:4 \
vht_link_adapt:3 \
vht160:2
cap_rx_stbc=$((($vht_cap >> 8) & 7))
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
- ht_cap_mask="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
+ vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
mac80211_add_capabilities vht_capab $vht_cap \
RXLDPC:0x10::$rxldpc \
SHORT-GI-80:0x20::$short_gi_80 \
SHORT-GI-160:0x40::$short_gi_160 \
- TX-STBC-2BY1:0x80::$tx_stbc \
+ TX-STBC-2BY1:0x80::$tx_stbc_2by1 \
SU-BEAMFORMER:0x800::$su_beamformer \
SU-BEAMFORMEE:0x1000::$su_beamformee \
MU-BEAMFORMER:0x80000::$mu_beamformer \
HTC-VHT:0x400000::$htc_vht \
RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \
TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \
- RX-STBC1:0x700:0x100:1 \
- RX-STBC12:0x700:0x200:1 \
- RX-STBC123:0x700:0x300:1 \
- RX-STBC1234:0x700:0x400:1 \
+ RX-STBC-1:0x700:0x100:1 \
+ RX-STBC-12:0x700:0x200:1 \
+ RX-STBC-123:0x700:0x300:1 \
+ RX-STBC-1234:0x700:0x400:1 \
# supported Channel widths
vht160_hw=0
vht_max_mpdu_hw=11454
[ "$vht_max_mpdu_hw" != 3895 ] && \
vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
-
+
# maximum A-MPDU length exponent
vht_max_a_mpdu_len_exp_hw=0
[ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \
hostapd_prepare_device_config "$hostapd_conf_file" nl80211
cat >> "$hostapd_conf_file" <<EOF
${channel:+channel=$channel}
+${channel_list:+chanlist=$channel_list}
${noscan:+noscan=$noscan}
$base_cfg
append hostapd_cfg "$type=$ifname" "$N"
hostapd_set_bss_options hostapd_cfg "$vif" || return 1
- json_get_vars wds dtim_period max_listen_int
+ json_get_vars wds dtim_period max_listen_int start_disabled
set_default wds 0
+ set_default start_disabled 0
[ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
- [ "$staidx" -gt 0 ] && append hostapd_cfg "start_disabled=1" "$N"
+ [ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
cat >> /var/run/hostapd-$phy.conf <<EOF
$hostapd_cfg
EOF
}
+mac80211_get_addr() {
+ local phy="$1"
+ local idx="$(($2 + 1))"
+
+ head -n $(($macidx + 1)) /sys/class/ieee80211/${phy}/addresses | tail -n1
+}
+
mac80211_generate_mac() {
local phy="$1"
local id="${macidx:-0}"
local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)"
local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)"
- [ "$mask" = "00:00:00:00:00:00" ] && mask="ff:ff:ff:ff:ff:ff";
+ [ "$mask" = "00:00:00:00:00:00" ] && {
+ mask="ff:ff:ff:ff:ff:ff";
+
+ [ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt 1 ] && {
+ addr="$(mac80211_get_addr "$phy" "$id")"
+ [ -n "$addr" ] && {
+ echo "$addr"
+ return
+ }
+ }
+ }
+
local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
local mask1=$1
find_phy() {
[ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0
- [ -n "$path" -a -d "/sys/devices/$path/ieee80211" ] && {
- phy="$(ls /sys/devices/$path/ieee80211 | grep -m 1 phy)"
- [ -n "$phy" ] && return 0
+ [ -n "$path" ] && {
+ for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
+ case "$(readlink -f /sys/class/ieee80211/$phy/device)" in
+ *$path) return 0;;
+ esac
+ done
}
[ -n "$macaddr" ] && {
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
has_ap=1
}
+mac80211_iw_interface_add() {
+ local phy="$1"
+ local ifname="$2"
+ local type="$3"
+ local wdsflag="$4"
+ local rc
+
+ iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
+ rc="$?"
+
+ [ "$rc" = 233 ] && {
+ # Device might have just been deleted, give the kernel some time to finish cleaning it up
+ sleep 1
+
+ iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
+ rc="$?"
+ }
+
+ [ "$rc" = 233 ] && {
+ # Device might not support virtual interfaces, so the interface never got deleted in the first place.
+ # Check if the interface already exists, and avoid failing in this case.
+ ip link show dev "$ifname" >/dev/null 2>/dev/null && rc=0
+ }
+
+ [ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
+ return $rc
+}
+
mac80211_prepare_vif() {
json_select config
# It is far easier to delete and create the desired interface
case "$mode" in
adhoc)
- iw phy "$phy" interface add "$ifname" type adhoc
+ mac80211_iw_interface_add "$phy" "$ifname" adhoc || return
;;
ap)
# Hostapd will handle recreating the interface and
mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
[ -n "$hostapd_ctrl" ] || {
- iw phy "$phy" interface add "$ifname" type managed
+ mac80211_iw_interface_add "$phy" "$ifname" __ap || return
hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
}
;;
mesh)
- json_get_vars key mesh_id
- if [ -n "$key" ]; then
- iw phy "$phy" interface add "$ifname" type mp
- else
- iw phy "$phy" interface add "$ifname" type mp mesh_id "$mesh_id"
- fi
+ mac80211_iw_interface_add "$phy" "$ifname" mp || return
;;
monitor)
- iw phy "$phy" interface add "$ifname" type monitor
+ mac80211_iw_interface_add "$phy" "$ifname" monitor || return
;;
sta)
local wdsflag=
staidx="$(($staidx + 1))"
[ "$wds" -gt 0 ] && wdsflag="4addr on"
- iw phy "$phy" interface add "$ifname" type managed $wdsflag
+ mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return
[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
iw "$ifname" set power_save "$powersave"
;;
# All interfaces must have unique mac addresses
# which can either be explicitly set in the device
# section, or automatically generated
- ifconfig "$ifname" hw ether "$macaddr"
+ ip link set dev "$ifname" address "$macaddr"
fi
json_select ..
wpa_supplicant_run "$ifname" ${hostapd_ctrl:+-H $hostapd_ctrl}
}
+mac80211_setup_adhoc_htmode() {
+ case "$htmode" in
+ VHT20|HT20) ibss_htmode=HT20;;
+ HT40*|VHT40|VHT160)
+ case "$hwmode" in
+ a)
+ case "$(( ($channel / 4) % 2 ))" in
+ 1) ibss_htmode="HT40+" ;;
+ 0) ibss_htmode="HT40-";;
+ esac
+ ;;
+ *)
+ case "$htmode" in
+ HT40+) ibss_htmode="HT40+";;
+ HT40-) ibss_htmode="HT40-";;
+ *)
+ if [ "$channel" -lt 7 ]; then
+ ibss_htmode="HT40+"
+ else
+ ibss_htmode="HT40-"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ [ "$auto_channel" -gt 0 ] && ibss_htmode="HT40+"
+ ;;
+ VHT80)
+ ibss_htmode="80MHZ"
+ ;;
+ NONE|NOHT)
+ ibss_htmode="NOHT"
+ ;;
+ *) ibss_htmode="" ;;
+ esac
+
+}
+
mac80211_setup_adhoc() {
json_get_vars bssid ssid key mcast_rate
keyspec=
- [ "$auth_type" == "wep" ] && {
+ [ "$auth_type" = "wep" ] && {
set_default key 1
case "$key" in
[1234])
brstr=
for br in $basic_rate_list; do
- hostapd_add_rate brstr "$br"
+ wpa_supplicant_add_rate brstr "$br"
done
mcval=
- [ -n "$mcast_rate" ] && hostapd_add_rate mcval "$mcast_rate"
+ [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
- iw dev "$ifname" ibss join "$ssid" $freq $htmode fixed-freq $bssid \
- ${beacon_int:+beacon-interval $beacon_int} \
+ iw dev "$ifname" ibss join "$ssid" $freq $ibss_htmode fixed-freq $bssid \
+ beacon-interval $beacon_int \
${brstr:+basic-rates $brstr} \
${mcval:+mcast-rate $mcval} \
${keyspec:+keys $keyspec}
json_get_vars mode
json_get_var vif_txpower txpower
- ifconfig "$ifname" up || {
+ ip link set dev "$ifname" up || {
wireless_setup_vif_failed IFUP_ERROR
json_select ..
return
case "$mode" in
mesh)
- for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do
- json_get_var mp_val "$var"
- [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val"
- done
-
- # authsae
+ # authsae or wpa_supplicant
json_get_vars key
if [ -n "$key" ]; then
if [ -e "/lib/wifi/authsae.sh" ]; then
. /lib/wifi/authsae.sh
authsae_start_interface || failed=1
else
- wireless_setup_vif_failed AUTHSAE_NOT_INSTALLED
- json_select ..
- return
+ wireless_vif_parse_encryption
+ mac80211_setup_supplicant || failed=1
fi
+ else
+ json_get_vars mesh_id mcast_rate
+
+ mcval=
+ [ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
+
+ case "$htmode" in
+ VHT20|HT20) mesh_htmode=HT20;;
+ HT40*|VHT40)
+ case "$hwmode" in
+ a)
+ case "$(( ($channel / 4) % 2 ))" in
+ 1) mesh_htmode="HT40+" ;;
+ 0) mesh_htmode="HT40-";;
+ esac
+ ;;
+ *)
+ case "$htmode" in
+ HT40+) mesh_htmode="HT40+";;
+ HT40-) mesh_htmode="HT40-";;
+ *)
+ if [ "$channel" -lt 7 ]; then
+ mesh_htmode="HT40+"
+ else
+ mesh_htmode="HT40-"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ VHT80)
+ mesh_htmode="80Mhz"
+ ;;
+ VHT160)
+ mesh_htmode="160Mhz"
+ ;;
+ *) mesh_htmode="NOHT" ;;
+ esac
+
+ freq="$(get_freq "$phy" "$channel")"
+ iw dev "$ifname" mesh join "$mesh_id" freq $freq $mesh_htmode \
+ ${mcval:+mcast-rate $mcval} \
+ beacon-interval $beacon_int
fi
+
+ for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do
+ json_get_var mp_val "$var"
+ [ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val"
+ done
;;
adhoc)
wireless_vif_parse_encryption
+ mac80211_setup_adhoc_htmode
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then
mac80211_setup_supplicant || failed=1
else
local phy="$1"
for wdev in $(list_phy_interfaces "$phy"); do
- ifconfig "$wdev" down 2>/dev/null
+ ip link set dev "$wdev" down 2>/dev/null
iw dev "$wdev" del
done
}
country chanbw distance \
txpower antenna_gain \
rxantenna txantenna \
- frag rts beacon_int
+ frag rts beacon_int:100 htmode
json_get_values basic_rate_list basic_rate
json_select ..
for_each_interface "ap" mac80211_prepare_vif
[ -n "$hostapd_ctrl" ] && {
- /usr/sbin/hostapd -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file"
+ /usr/sbin/hostapd -s -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file"
ret="$?"
wireless_add_process "$(cat /var/run/wifi-$phy.pid)" "/usr/sbin/hostapd" 1
[ "$ret" != 0 ] && {