RetroPie-Setup/scriptmodules/supplementary/wifi.sh
cmitu 4d60904810 wifi: update search locations for 'wifikeyfile'
Since RaspiOS Bookworm, the `bootfs` (1st) partition is mounted under `/boot/fimware` instead of `/boot`, so look for the WiFi file under that location also.
2023-10-17 18:26:34 +01:00

327 lines
9.9 KiB
Bash

#!/usr/bin/env bash
# This file is part of The RetroPie Project
#
# The RetroPie Project is the legal property of its developers, whose names are
# too numerous to list here. Please refer to the COPYRIGHT.md file distributed with this source.
#
# See the LICENSE.md file at the top-level directory of this distribution and
# at https://raw.githubusercontent.com/RetroPie/RetroPie-Setup/master/LICENSE.md
#
rp_module_id="wifi"
rp_module_desc="Configure WiFi"
rp_module_section="config"
rp_module_flags="!x11"
function _get_interface_wifi() {
local iface
# look for the first wireless interface present
for iface in /sys/class/net/*; do
if [[ -d "$iface/wireless" ]]; then
echo "$(basename $iface)"
return 0
fi
done
return 1
}
function _get_mgmt_tool_wifi() {
# get the WiFi connection manager
if systemctl -q is-active NetworkManager.service; then
echo "nm"
else
echo "wpasupplicant"
fi
}
function _set_interface_wifi() {
local iface="$1"
local state="$2"
if [[ "$state" == "up" ]]; then
if ! ifup $iface; then
ip link set $iface up
fi
elif [[ "$state" == "down" ]]; then
if ! ifdown $iface; then
ip link set $iface down
fi
fi
}
function remove_nm_wifi() {
local iface="$1"
# delete the NM connection named RetroPie-WiFi
nmcli connection delete RetroPie-WiFi
_set_interface_wifi $iface down 2>/dev/null
}
function remove_wpasupplicant_wifi() {
local iface="$1"
sed -i '/RETROPIE CONFIG START/,/RETROPIE CONFIG END/d' "/etc/wpa_supplicant/wpa_supplicant.conf"
_set_interface_wifi $iface down 2>/dev/null
}
function list_wifi() {
local line
local essid
local type
local iface="$1"
while read line; do
[[ "$line" =~ ^Cell && -n "$essid" ]] && echo -e "$essid\n$type"
[[ "$line" =~ ^ESSID ]] && essid=$(echo "$line" | cut -d\" -f2)
[[ "$line" == "Encryption key:off" ]] && type="open"
[[ "$line" == "Encryption key:on" ]] && type="wep"
[[ "$line" =~ ^IE:.*WPA ]] && type="wpa"
done < <(iwlist $iface scan | grep -o "Cell .*\|ESSID:\".*\"\|IE: .*WPA\|Encryption key:.*")
echo -e "$essid\n$type"
}
function connect_wifi() {
local iface
local mgmt_tool="wpasupplicant"
iface="$(_get_interface_wifi)"
if [[ -z "$iface" ]]; then
printMsgs "dialog" "No wireless interfaces detected"
return 1
fi
mgmt_tool="$(_get_mgmt_tool_wifi)"
local essids=()
local essid
local types=()
local type
local options=()
i=0
_set_interface_wifi $iface up 2>/dev/null
dialog --infobox "\nScanning for WiFi networks..." 5 40 > /dev/tty
sleep 1
while read essid; read type; do
essids+=("$essid")
types+=("$type")
options+=("$i" "$essid")
((i++))
done < <(list_wifi $iface)
options+=("H" "Hidden ESSID")
local cmd=(dialog --backtitle "$__backtitle" --menu "Please choose the WiFi network you would like to connect to" 22 76 16)
choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
[[ -z "$choice" ]] && return
local hidden=0
if [[ "$choice" == "H" ]]; then
essid=$(inputBox "ESSID" "" 4)
[[ -z "$essid" ]] && return
cmd=(dialog --backtitle "$__backtitle" --nocancel --menu "Please choose the WiFi type" 12 40 6)
options=(
wpa "WPA/WPA2"
wep "WEP"
open "Open"
)
type=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
hidden=1
else
essid=${essids[choice]}
type=${types[choice]}
fi
if [[ "$type" == "wpa" || "$type" == "wep" ]]; then
local key=""
local key_min
if [[ "$type" == "wpa" ]]; then
key_min=8
else
key_min=5
fi
cmd=(inputBox "WiFi key/password" "" $key_min)
local key_ok=0
while [[ $key_ok -eq 0 ]]; do
key=$("${cmd[@]}") || return
key_ok=1
done
fi
create_${mgmt_tool}_config_wifi "$type" "$essid" "$key" "$iface"
gui_connect_wifi "$iface"
}
function create_nm_config_wifi() {
local type="$1"
local essid="$2"
local key="$3"
local dev="$4"
local con="RetroPie-WiFi"
remove_nm_wifi
nmcli connection add type wifi ifname "$dev" ssid "$essid" con-name "$con" autoconnect yes
# configure security for the connection
case $type in
wpa)
nmcli connection modify "$con" \
wifi-sec.key-mgmt wpa-psk \
wifi-sec.psk-flags 0 \
wifi-sec.psk "$key"
;;
wep)
nmcli connection modify "$con" \
wifi-sec.key-mgmt none \
wifi-sec.wep-key-flags 0 \
wifi-sec.wep-key-type 2 \
wifi-sec.wep-key0 "$key"
;;
open)
;;
esac
[[ $hidden -eq 1 ]] && nmcli connection modify "$con" wifi.hidden yes
}
function create_wpasupplicant_config_wifi() {
local type="$1"
local essid="$2"
local key="$3"
local dev="$4"
local wpa_config
wpa_config+="\tssid=\"$essid\"\n"
case $type in
wpa)
wpa_config+="\tpsk=\"$key\"\n"
;;
wep)
wpa_config+="\tkey_mgmt=NONE\n"
wpa_config+="\twep_tx_keyidx=0\n"
wpa_config+="\twep_key0=$key\n"
;;
open)
wpa_config+="\tkey_mgmt=NONE\n"
;;
esac
[[ $hidden -eq 1 ]] && wpa_config+="\tscan_ssid=1\n"
remove_wpasupplicant_wifi
wpa_config=$(echo -e "$wpa_config")
cat >> "/etc/wpa_supplicant/wpa_supplicant.conf" <<_EOF_
# RETROPIE CONFIG START
network={
$wpa_config
}
# RETROPIE CONFIG END
_EOF_
}
function gui_connect_wifi() {
local iface="$1"
local mgmt_tool
mgmt_tool="$(_get_mgmt_tool_wifi)"
_set_interface_wifi $iface down 2>/dev/null
_set_interface_wifi $iface up 2>/dev/null
if [[ "$mgmt_tool" == "wpasupplicant" ]]; then
# BEGIN workaround for dhcpcd trigger failure on Raspbian stretch
systemctl restart dhcpcd &>/dev/null
# END workaround
fi
if [[ "$mgmt_tool" == "nm" ]]; then
nmcli -w 0 connection up RetroPie-WiFi
fi
dialog --backtitle "$__backtitle" --infobox "\nConnecting ..." 5 40 >/dev/tty
local id=""
i=0
while [[ -z "$id" && $i -lt 30 ]]; do
sleep 1
id=$(iwgetid -r)
((i++))
done
if [[ -z "$id" ]]; then
printMsgs "dialog" "Unable to connect to network $essid"
_set_interface_wifi $iface down 2>/dev/null
fi
}
function _check_country_wifi() {
local country
country="$(raspi-config nonint get_wifi_country)"
if [[ -z "$country" ]]; then
if dialog --defaultno --yesno "You don't currently have your WiFi country set.\n\nOn a Raspberry Pi 3B+ and later your WiFi will be disabled until the country is set. You can do this via raspi-config which is available from the RetroPie menu in Emulation Station. Once in raspi-config you can set your country via menu 5 (Localisation Options)\n\nDo you want me to launch raspi-config for you now ?" 22 76 2>&1 >/dev/tty; then
raspi-config
fi
fi
}
function gui_wifi() {
isPlatform "rpi" && _check_country_wifi
local default
local iface
local mgmt_tool
iface="$(_get_interface_wifi)"
mgmt_tool="$(_get_mgmt_tool_wifi)"
while true; do
local ip_current="$(getIPAddress)"
local ip_wlan="$(getIPAddress $iface)"
local cmd=(dialog --backtitle "$__backtitle" --colors --cancel-label "Exit" --item-help --help-button --default-item "$default" --title "Configure WiFi" --menu "Current IP: \Zb${ip_current:-(unknown)}\ZB\nWireless IP: \Zb${ip_wlan:-(unknown)}\ZB\nWireless ESSID: \Zb$(iwgetid -r || echo "none")\ZB" 22 76 16)
local options=(
1 "Connect to WiFi network"
"1 Connect to your WiFi network"
2 "Disconnect/Remove WiFi config"
"2 Disconnect and remove any WiFi configuration"
3 "Import WiFi credentials from wifikeyfile.txt"
"3 Will import the SSID (network name) and PSK (password) from the 'wifikeyfile.txt' file on the boot partition
The file should contain two lines as follows\n\nssid = \"YOUR WIFI SSID\"\npsk = \"YOUR PASSWORD\""
)
local choice=$("${cmd[@]}" "${options[@]}" 2>&1 >/dev/tty)
if [[ "${choice[@]:0:4}" == "HELP" ]]; then
choice="${choice[@]:5}"
default="${choice/%\ */}"
choice="${choice#* }"
printMsgs "dialog" "$choice"
continue
fi
default="$choice"
if [[ -n "$choice" ]]; then
case "$choice" in
1)
connect_wifi $iface
;;
2)
dialog --defaultno --yesno "This will remove the WiFi configuration and stop the WiFi.\n\nAre you sure you want to continue ?" 12 60 2>&1 >/dev/tty
[[ $? -ne 0 ]] && continue
remove_${mgmt_tool}_wifi $iface
;;
3)
# check in `/boot/` (pre-bookworm) and `/boot/firmware` (bookworm and later) for the file
local file="/boot/wifikeyfile.txt"
[[ ! -f "$file" ]] && file="/boot/firmware/wifikeyfile.txt"
if [[ -f "$file" ]]; then
iniConfig " = " "\"" "$file"
iniGet "ssid"
local ssid="$ini_value"
iniGet "psk"
local psk="$ini_value"
create_${mgmt_tool}_config_wifi "wpa" "$ssid" "$psk" "$iface"
gui_connect_wifi "$iface"
else
printMsgs "dialog" "File 'wifikeyfile.txt' not found on the boot partition!"
fi
;;
esac
else
break
fi
done
}