WIRELESS_REGULATORY_DOMAIN_DATABASE="/usr/lib/crda/regulatory.bin"
-WIRELESS_NETWORK_CONFIG_SETTINGS="\
- SSID \
- ENCRYPTION_MODE \
- KEY \
- PRIORITY"
+WIRELESS_DEFAULT_ENCRYPTION_MODE="NONE"
+WIRELESS_VALID_ENCRYPTION_MODES="WPA2-PSK-SHA256 WPA2-PSK \
+ WPA-PSK-SHA256 WPA-PSK NONE"
-WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES="WPA2-PSK"
+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}
+ shift 1
+
+ case "${action}" in
+ network)
+ cli_wireless_network "$@"
+ ;;
+ *)
+ error "Unrecognized argument: ${action}"
+ exit ${EXIT_ERROR}
+ ;;
+ esac
+}
wireless_create() {
local device=${1}
# Set the channel
if isset channel; then
- wireless_set_channel "${device}" "${channel}" || return $?
+ wireless_set_channel "${device}" "${channel}" "auto" || return $?
fi
return ${ret}
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
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 psk="${1}"
+
+ # Length of the PSK
+ local l="${#psk}"
+
+ # For WPA*, the key must be between 8 and 63 chars
+ if [ ${l} -lt 8 ] || [ ${l} -gt 63 ]; then
+ return ${EXIT_FALSE}
+ fi
+
+ # Can only contain ASCII chararcters
+ if contains_non_ascii_characters "${psk}"; then
+ return ${EXIT_FALSE}
+ fi
+
+ # Seems OK
+ return ${EXIT_TRUE}
+}
+
+wireless_client_is_connected() {
+ local device="${1}"
+
+ device_has_carrier "${device}"
}
wireless_ibss_join() {
return ${EXIT_OK}
}
-cli_wireless() {
- local action=${1}
- shift 1
-
- case "${action}" in
- network)
- cli_wireless_network "$@"
- ;;
- *)
- error "Unrecognized argument: ${action}"
- exit ${EXIT_ERROR}
- ;;
- esac
-}
-
-cli_wireless_network() {
- if wireless_network_exists "${1}"; then
- local ssid="${1}"
- local key="${2}"
- key=${key//-/_}
- shift 2
-
- case "${key}" in
- encryption_mode|key|priority)
- wireless_network_${key} "${ssid}" "$@"
- ;;
- show)
- wireless_network_show "${ssid}"
- exit $?
- ;;
- *)
- error "Unrecognized argument: ${key}"
- exit ${EXIT_ERROR}
- ;;
- esac
- else
- local action=${1}
- shift
-
- case "${action}" in
- new)
- wireless_network_new "$@"
- ;;
- destroy)
- wireless_network_destroy "$@"
- ;;
- ""|*)
- if [ -n "${action}" ]; then
- error "Unrecognized argument: '${action}'"
- fi
- exit ${EXIT_ERROR}
- ;;
- esac
- fi
-}
-
-# This function writes all values to a via ${ssid} specificated wireless network configuration file
-wireless_network_write_config() {
- assert [ $# -ge 1 ]
-
- local ssid="${1}"
-
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
-
- if ! wireless_network_exists "${ssid}"; then
- log ERROR "No such wireless network: '${ssid}'"
- return ${EXIT_ERROR}
- fi
-
- local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
- if ! settings_write "${path}" ${WIRELESS_NETWORK_CONFIG_SETTINGS}; then
- log ERROR "Could not write configuration settings for wireless network ${ssid}"
- return ${EXIT_ERROR}
- fi
-
- # When we get here the writing of the config file was successful
- return ${EXIT_OK}
-}
-
-# This funtion writes the value for one key to a via ${ssid} specificated
-# wireless network configuration file
-wireless_network_write_config_key() {
- assert [ $# -ge 3 ]
-
- local ssid="${1}"
- local key="${2}"
- shift 2
-
- local value="$@"
-
- if ! wireless_network_exists "${ssid}"; then
- log ERROR "No such wireless network: ${ssid}"
- return ${EXIT_ERROR}
- fi
-
- log DEBUG "Set '${key}' to new value '${value}' in wireless network '${ssid}'"
-
- local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
-
- # Read the config settings
- if ! wireless_network_read_config "${ssid}"; then
- return ${EXIT_ERROR}
- fi
-
- # Set the key to a new value
- assign "${key}" "${value}"
+wireless_get_ht_caps() {
+ local device="${1}"
+ assert isset device
- if ! wireless_network_write_config "${ssid}"; then
+ local phy="$(device_get_phy "${device}")"
+ if ! isset phy; then
+ log ERROR "Could not determine PHY for ${device}"
return ${EXIT_ERROR}
fi
- return ${EXIT_OK}
+ network-phy-list-ht-caps "${phy}"
}
-# Reads one or more keys out of a settings file or all if no key is provided.
-wireless_network_read_config() {
- assert [ $# -ge 1 ]
-
- local ssid="${1}"
- shift 1
-
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
-
- if ! wireless_network_exists "${ssid}"; then
- log ERROR "No such wireless network : ${ssid}"
- return ${EXIT_ERROR}
- fi
-
- local args
- if [ $# -eq 0 ] && [ -n "${WIRELESS_NETWORK_CONFIG_SETTINGS}" ]; then
- list_append args ${WIRELESS_NETWORK_CONFIG_SETTINGS}
- else
- list_append args "$@"
- fi
-
- local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
+wireless_get_vht_caps() {
+ local device="${1}"
+ assert isset device
- if ! settings_read "${path}" ${args}; then
- log ERROR "Could not read settings for wireless network ${ssid}"
+ local phy="$(device_get_phy "${device}")"
+ if ! isset phy; then
+ log ERROR "Could not determine PHY for ${device}"
return ${EXIT_ERROR}
fi
-}
-
-# This function checks if a wireless network exists
-# Returns True when yes and false when not
-wireless_network_exists() {
- assert [ $# -eq 1 ]
-
- local ssid="${1}"
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
-
- local path="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"
-
- # We cannot use wireless_network_read_config here beacuse we would end in a loop
- local SSID
-
- local path_settings="${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
- if ! settings_read "${path_settings}" SSID; then
- return ${EXIT_FALSE}
- fi
- assert isset SSID
-
- if [ -d "${path}" ] && [[ "${ssid}" = "${SSID}" ]]; then
- return ${EXIT_TRUE}
- else
- return ${EXIT_FALSE}
- fi
+ network-phy-list-vht-caps "${phy}"
}
-wireless_network_hash() {
- assert [ $# -eq 1 ]
-
- local string="${1}"
-
- local hash=$(echo -n "${string}" | md5sum )
- hash=${hash%% -}
-
- local path="${NETWORK_WIRELESS_NETWORKS_DIR}/*${hash}"
-
- if [ -d "${path}" ]; then
- basename "${path}"
- else
- local normalized=$(normalize "${string}")
- normalized=${normalized%-}
- echo "${normalized}-${hash}"
- fi
-}
-
-wireless_network_new() {
- if [ $# -gt 1 ]; then
- error "Too many arguments"
- return ${EXIT_ERROR}
- fi
-
- local ssid="${1}"
- if ! isset ssid; then
- error "Please provide a SSID"
- return ${EXIT_ERROR}
- fi
-
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
-
- # Check for duplicates
- if wireless_network_exists "${ssid}"; then
- error "The wireless network ${ssid} already exists"
- return ${EXIT_ERROR}
- fi
-
- log DEBUG "Creating wireless network '${ssid}'"
-
- if ! mkdir -p "${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"; then
- log ERROR "Could not create config directory for wireless network ${ssid}"
- return ${EXIT_ERROR}
- fi
-
- # When the ssid is not set in the settings file we cannot write it because wireless_network_exists fails
- echo "SSID=\"${ssid}\"" >>"${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}/settings"
-
- local ${WIRELESS_NETWORK_CONFIG_SETTINGS}
- SSID="${ssid}"
- PRIORITY=500
+wireless_supports_acs() {
+ local device="${1}"
+ assert isset device
- if ! wireless_network_write_config "${ssid}"; then
- log ERROR "Could not write new config file"
+ local phy="$(device_get_phy "${device}")"
+ if ! isset phy; then
+ log ERROR "Could not determine PHY for ${device}"
return ${EXIT_ERROR}
fi
-}
-
-# Function that deletes based on the passed parameters
-# one ore more wireless networks
-wireless_network_destroy() {
- local ssid
- for ssid in "$@"; do
- local ssid_hash="$(wireless_network_hash "${ssid}")"
- assert isset ssid_hash
-
- if ! wireless_network_exists "${ssid}"; then
- log ERROR "The wireless network ${ssid} does not exist."
- continue
- fi
- log DEBUG "Deleting wireless network ${ssid}"
-
- if ! rm -rf "${NETWORK_WIRELESS_NETWORKS_DIR}/${ssid_hash}"; then
- log ERROR "Deleting the wireless network ${ssid} was not sucessful"
- return ${EXIT_ERROR}
- fi
- done
+ phy_supports_acs "${phy}"
}
-wireless_network_encryption_mode() {
- if [ ! $# -eq 2 ]; then
- log ERROR "Not enough arguments"
- return ${EXIT_ERROR}
- fi
- local ssid="${1}"
- local mode="${2}"
-
- if ! isoneof mode ${WIRELESS_NETWORKS_VALID_ENCRYPTION_MODES}; then
- log ERROR "Encryption mode '${mode}' is invalid"
- return ${EXIT_ERROR}
- fi
-
- if ! wireless_network_write_config_key "${ssid}" "ENCRYPTION_MODE" ${mode^^}; then
- log ERROR "Could not write configuration settings"
- return ${EXIT_ERROR}
- fi
-}
+wireless_supports_dfs() {
+ local device="${1}"
+ assert isset device
-wireless_network_key() {
- if [ ! $# -eq 2 ]; then
- log ERROR "Not enough arguments"
+ local phy="$(device_get_phy "${device}")"
+ if ! isset phy; then
+ log ERROR "Could not determine PHY for ${device}"
return ${EXIT_ERROR}
fi
- local ssid="${1}"
- local key="${2}"
- if ! wireless_network_write_config_key "${ssid}" "KEY" "${key}"; then
- log ERROR "Could not write configuration settings"
- return ${EXIT_ERROR}
- fi
+ phy_supports_dfs "${phy}"
}
-wireless_network_priority() {
- if [ ! $# -eq 2 ]; then
- log ERROR "Not enough arguments"
- return ${EXIT_ERROR}
- fi
- local ssid="${1}"
- local priority=${2}
-
- if ! isinteger priority && [ ! ${priority} -ge 0 ]; then
- log ERROR "The priority must be an integer greater or eqal zero"
- return ${EXIT_ERROR}
- fi
+wireless_environment_is_valid() {
+ local environment="${1}"
- if ! wireless_network_write_config_key "${ssid}" "PRIORITY" "${priority}"; then
- log ERROR "Could not write configuration settings"
- return ${EXIT_ERROR}
- fi
+ list_match "${environment}" "${WIRELESS_ENVIRONMENTS[@]}"
}