]> git.ipfire.org Git - people/ms/network.git/blobdiff - src/functions/functions.wireless
wireless-ap: Allow setting the wireless environment (indoor/outdoor)
[people/ms/network.git] / src / functions / functions.wireless
index 7ddb59cb23b545f4174f70fcccc602eb3b74bda8..12204c07879b6794c99f94e9d13b0442674cb4ce 100644 (file)
@@ -27,7 +27,18 @@ WIRELESS_REGULATORY_DOMAIN_DATABASE="/usr/lib/crda/regulatory.bin"
 
 WIRELESS_DEFAULT_ENCRYPTION_MODE="NONE"
 WIRELESS_VALID_ENCRYPTION_MODES="WPA2-PSK-SHA256 WPA2-PSK \
-       WPA-PSK-SHA256 WPA-PSK WEP NONE"
+       WPA-PSK-SHA256 WPA-PSK NONE"
+
+declare -A WIRELESS_CHANNEL_BANDWIDTHS=(
+       ["802.11ac"]="20 40 80 160 80+80"
+       ["802.11a/n"]="20 40"
+       ["802.11a"]="20 40"
+       ["802.11g/n"]="20 40"
+       ["802.11g"]="20 40"
+)
+
+WIRELESS_ENVIRONMENTS=( "indoor+outdoor" "indoor" "outdoor" )
+WIRELESS_DEFAULT_ENVIRONMENT="${WIRELESS_ENVIRONMENTS[0]}"
 
 cli_wireless() {
        local action=${1}
@@ -111,7 +122,7 @@ wireless_create() {
 
        # Set the channel
        if isset channel; then
-               wireless_set_channel "${device}" "${channel}" || return $?
+               wireless_set_channel "${device}" "${channel}" "auto" || return $?
        fi
 
        return ${ret}
@@ -309,9 +320,46 @@ wireless_channel_is_valid() {
        return ${EXIT_FALSE}
 }
 
+wireless_channel_bandwidth_is_valid() {
+       local mode="${1}"
+       assert isset mode
+
+       local bandwidth="${2}"
+       assert isset bandwidth
+
+       local bandwidths="${WIRELESS_CHANNEL_BANDWIDTHS["${mode}"]}"
+
+       list_match "${bandwidth}" ${bandwidths}
+}
+
+wireless_channel_is_ht40_plus() {
+       local channel="${1}"
+       assert isinteger channel
+
+       # 2.4 GHz
+       if [ ${channel} -le 6 ]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
+wireless_channel_is_ht40_minus() {
+       local channel="${1}"
+       assert isinteger channel
+
+       # 2.4 GHz
+       if [ ${channel} -ge 6 ]; then
+               return ${EXIT_TRUE}
+       fi
+
+       return ${EXIT_FALSE}
+}
+
 wireless_set_channel() {
-       local device=${1}
-       local channel=${2}
+       local device="${1}"
+       local channel="${2}"
+       local bandwidth="${3}"
 
        # Check if the device exists
        if ! device_exists "${device}"; then
@@ -325,8 +373,54 @@ wireless_set_channel() {
                return ${EXIT_ERROR}
        fi
 
+       local ht_flag
+       if [ "${bandwidth}" = "auto" ]; then
+               local phy="$(device_get_phy "${device}")"
+
+               # Offset of a 40 MHz channel
+               local ht_offset=5
+
+               if wireless_channel_is_ht40_plus "${channel}" \
+                               && phy_supports_ht_capability "${phy}" "HT40+" \
+                               && phy_supports_channel "${phy}" $(( channel + ht_offset )); then
+                       ht_flag="HT40+"
+
+               elif wireless_channel_is_ht40_minus "${channel}" \
+                               && phy_supports_ht_capability "${phy}" "HT40-" \
+                               && phy_supports_channel "${phy}" $(( channel - ht_offset )); then
+                       ht_flags="HT40-"
+               fi
+       fi
+
        log DEBUG "Setting wireless channel on device '${device}' to channel '${channel}'"
-       cmd iw dev "${device}" set channel "${channel}"
+       cmd iw dev "${device}" set channel "${channel}" "${ht_flag}"
+}
+
+wireless_pre_shared_key_is_valid() {
+       local encryption_mode="${1}"
+       local psk="${2}"
+
+       # Length of the PSK
+       local l="${#psk}"
+
+       case "${encryption_mode}" in
+               # For WPA*, the key must be between 8 and 63 chars
+               WPA2-PSK|WPA2-PSK-SHA256|WPA-PSK|WPA-PSK-SHA256)
+                       if [ ${l} -ge 8 ] && [ ${l} -le 63 ]; then
+                               return ${EXIT_TRUE}
+                       fi
+
+                       return ${EXIT_FALSE}
+                       ;;
+       esac
+
+       return ${EXIT_ERROR}
+}
+
+wireless_client_is_connected() {
+       local device="${1}"
+
+       device_has_carrier "${device}"
 }
 
 wireless_ibss_join() {
@@ -418,3 +512,61 @@ wireless_monitor() {
 
        return ${EXIT_OK}
 }
+
+wireless_get_ht_caps() {
+       local device="${1}"
+       assert isset device
+
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
+               return ${EXIT_ERROR}
+       fi
+
+       network-phy-list-ht-caps "${phy}"
+}
+
+wireless_get_vht_caps() {
+       local device="${1}"
+       assert isset device
+
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
+               return ${EXIT_ERROR}
+       fi
+
+       network-phy-list-vht-caps "${phy}"
+}
+
+wireless_supports_acs() {
+       local device="${1}"
+       assert isset device
+
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
+               return ${EXIT_ERROR}
+       fi
+
+       phy_supports_acs "${phy}"
+}
+
+wireless_supports_dfs() {
+       local device="${1}"
+       assert isset device
+
+       local phy="$(device_get_phy "${device}")"
+       if ! isset phy; then
+               log ERROR "Could not determine PHY for ${device}"
+               return ${EXIT_ERROR}
+       fi
+
+       phy_supports_dfs "${phy}"
+}
+
+wireless_environment_is_valid() {
+       local environment="${1}"
+
+       list_match "${environment}" "${WIRELESS_ENVIRONMENTS[@]}"
+}