Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NetworkManager Support #2261

Merged
merged 35 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
30dafc9
moved config files in subdir
AlvinSchiller Feb 14, 2024
499310d
renamed autohotspot resources.
AlvinSchiller Feb 14, 2024
7a1e07f
updates from v3.
AlvinSchiller Feb 14, 2024
467e86f
refactored config file handling to functions.
AlvinSchiller Feb 14, 2024
cc8b2b0
add service enablement check
AlvinSchiller Feb 14, 2024
6dbe04d
update tests
AlvinSchiller Feb 14, 2024
cda3654
add uninstall before installation on updates
AlvinSchiller Feb 14, 2024
cda586a
fix tests
AlvinSchiller Feb 14, 2024
b299072
add support for NetworkManager
AlvinSchiller Feb 14, 2024
b045a6e
fix tests
AlvinSchiller Feb 14, 2024
f007561
add tests for network management
AlvinSchiller Feb 14, 2024
7ee69fd
fix mpd test if not installed
AlvinSchiller Feb 14, 2024
feefb0a
start service instead of script.
AlvinSchiller Feb 15, 2024
485cb9e
remove wpa_cli references (not needed).
AlvinSchiller Feb 15, 2024
2dd31b8
Merge branch 'develop' into test/networkmanager
AlvinSchiller Feb 26, 2024
d3d9252
updated installation wifi setup
AlvinSchiller Mar 8, 2024
6a22888
updated wifi ui
AlvinSchiller Mar 8, 2024
73812ca
changed order of logic to always get the current file state
AlvinSchiller Mar 7, 2024
197cb08
simplify ui wifi logic
AlvinSchiller Mar 8, 2024
b96aa34
set active connection readonly
AlvinSchiller Mar 8, 2024
db7acf9
reorder active connection to front.
AlvinSchiller Mar 8, 2024
127379e
remove unneccary comment
AlvinSchiller Mar 10, 2024
a8626bb
test added. some changes needed
AlvinSchiller Mar 10, 2024
d7c4d0e
fixed ci var definition
AlvinSchiller Mar 11, 2024
47102fe
changed test order
AlvinSchiller Mar 11, 2024
3966012
updated logs for network settings
AlvinSchiller Mar 11, 2024
601744f
extracted get passphrase function. use also in tests
AlvinSchiller Mar 12, 2024
7034ca0
restored dhcpcd wpa conf setup. fixed tests
AlvinSchiller Mar 12, 2024
baf567c
fix autohotspot setup
AlvinSchiller Mar 12, 2024
04f21d1
update ci tests scripts. renamed
AlvinSchiller Mar 12, 2024
f1eb030
improve readability and update tests parameter
AlvinSchiller Mar 12, 2024
d839067
removed log output
AlvinSchiller Mar 12, 2024
26bbdbd
change default for wifi/staticip setup to "no"
AlvinSchiller Mar 13, 2024
cf6a3ad
removed hotstpot userscript.
AlvinSchiller Mar 19, 2024
cfdd18c
only show *.sh files as userscripts
AlvinSchiller Mar 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test_docker_debian_codename_sub.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,10 @@ jobs:
fail-fast: false
matrix:
username: ['pi']
test_script: ['run_installation_tests.sh', 'run_installation_tests2.sh', 'run_installation_tests3.sh']
test_script: ['run_installation_classic.sh', 'run_installation_tests2.sh', 'run_installation_tests3.sh', 'run_installation_dhcpcd.sh', 'run_installation_NetworkManager.sh']
include:
- username: 'hans'
test_script: 'run_installation_tests.sh'
test_script: 'run_installation_classic.sh'


steps:
Expand Down
1 change: 1 addition & 0 deletions ci/Dockerfile.debian
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ FROM test-user as test-code
ARG GIT_BRANCH
ARG GIT_URL

ENV CI_RUNNING=true
ENV GIT_BRANCH=$GIT_BRANCH GIT_URL=$GIT_URL

COPY --chown=root:$TEST_USER_GROUP --chmod=770 packages.txt packages-raspberrypi.txt ./
Expand Down

This file was deleted.

353 changes: 353 additions & 0 deletions misc/sampleconfigs/autohotspot/NetworkManager/autohotspot
Original file line number Diff line number Diff line change
@@ -0,0 +1,353 @@
#!/bin/bash
#version 0.8
#date 12 Dec 2023
#Copyright Graeme Richards - RaspberryConnect.com
#Released under the GPL3 Licence (https://www.gnu.org/licenses/gpl-3.0.en.html)

#Script to automatically switch to an Access Point when no Wifi connection is available
#Developed on a Raspberry Pi PiOS Bookworm for use with Network Manager

#Additions where made for the Phoniebox project
#https://github.com/MiczFlor/RPi-Jukebox-RFID

#Device Names
wdev0='%WIFI_INTERFACE%' #wifi device that AP will work on

#AP setup
ap_profile_name='%AUTOHOTSPOT_PROFILE%'
ap_ssid='%AUTOHOTSPOT_SSID%'
ap_pw='%AUTOHOTSPOT_PASSWORD%'
ap_ip='%AUTOHOTSPOT_IP%/24'
ap_gate='%IP_WITHOUT_LAST_SEGMENT%.254'

timer_service_name='%AUTOHOTSPOT_TIMER_NAME%'

#If wifi is disabled in Network Manager, then enable it automatically.
#if set to 'false' then wifi will stay off and no AccessPoint will be generated or Network Connection will be available.
re_enable_wifi=false

#If true, check if timer is active. Will have been disabled if arg -a used.
re_enable_timer=false

#*************************************
#*****No user editable lines below****

NO_SSID='NoSSid'

profiles=() #Currently Available Profiles
active="" #The active connection
active_ap=false #is the active profile an AP y/n
nw_profile=() #saved NW Profiles
ap_profile=() #The saved AP profiles
ssidChk=("$NO_SSID")
force_hotspot=false

#Function is NM installed and running
check_prerequisite() {
if systemctl -all list-unit-files NetworkManager.service | grep "could not be found" >/dev/null 2>&1 ;then
if systemctl -all list-unit-files dhcpcd.service | grep "(running)" >/dev/null 2>&1 ;then
echo "This script is not compatible with the network setup."
echo "Please use the dhcpcd version"
else
echo "Network Manager is not managing the Wifi on this device"
echo "Unable to continue."
fi
exit 1
else
local isnm="$( systemctl status NetworkManager | grep '(running)' )"
if echo "$isnm" | grep -v "(running)" ;then >/dev/null 2>&1; #NM not running
echo "Network Manager is required but is not the active system network service"
echo "Unable to continue."
exit 1
fi
fi
}

#Function get all wifi profiles
saved_profiles()
{
ap_profile=()
nw_profile=()
local n="$(nmcli -t -f TYPE,NAME,AUTOCONNECT-PRIORITY con show)" #Capture Output
n="$(awk 1 ORS=':' <(echo "$n"))" #Replaces LF with : Delimeter
local profiles=()
readarray -d ':' -t profiles < <(printf "%s" "$n") #Change to array output
if [ ! -z "$profiles" ]; then
for (( c=0; c<=${#profiles[@]}; c+=3 )) #array of profiles
do
if [ ! -z "${profiles[$c+1]}" ] ; then
local conn="$(nmcli con show "${profiles[$c+1]}" | grep 'wireless.mode')" #show mode infurstructure, AP
local mode=()
readarray -d ':' -t mode < <(printf "%s" "$conn")
local mode2="$(echo "${mode[1]}" | sed 's/[[:blank:]]//g')"
if [ "$mode2" = "ap" ]; then
ap_profile+=("${profiles[$c+1]}")
echo "AP Profile: ${profiles[$c+1]}"
elif [ "$mode2" = "infrastructure" ]; then
nw_profile+=("${profiles[$c+1]}")
echo "NW Profile: ${profiles[$c+1]}"
fi
fi
done
fi
}

#Function what is the current active wifi
active_wifi()
{
local act="$(nmcli -t -f TYPE,NAME,DEVICE con show --active | grep "$wdev0")" #List of active devices
act="$(awk 1 ORS=':' <(echo "$act"))" #Replaces LF with : Delimeter
local active_name=()
readarray -d ':' -t active_name < <(printf "%s" "$act") #Change to array output
if [ ! -z "$active_name" ]; then
active="${active_name[1]}"
else
active=""
fi
}

#Function is the current Connection an AP
is_active_ap()
{
active_ap=false
if [ ! -z "$active" ] ; then
for i in "${ap_profile[@]}"
do
if [[ $i == "$active" ]]; then
active_ap=true
break
fi
done
fi
}

#Function IW SSID scan
nearby_ssids_iw()
{
if [ ${#nw_profile[@]} -eq 0 ]; then #only scan if NW profiles exists#
return
fi

#Check to see what SSID's and MAC addresses are in range
echo "SSID availability check"
local i=0; j=0
while [ $i -eq 0 ]
do
local scanreply=$(iw dev "$wdev0" scan ap-force 2>&1)
local ssidreply=$(echo "$scanreply" | egrep "^BSS|SSID:")
if [ $j -ge 5 ]; then
ssidreply=""
i=1
elif [ -z "$ssidreply" ] ; then
echo "Error scan SSID's, try $j: $scanreply"
j=$((j + 1))
sleep 2
else
#success
i=1
fi
done

ssidChk=()
for profile in "${nw_profile[@]}"
do
echo "Assessing profile: ${profile}"
local idssid=$(nmcli -t con show "${profile}" | grep "wireless.ssid")
if (echo "$ssidreply" | grep -F -- "${idssid:21}" ) >/dev/null 2>&1
then
echo "Valid SSID detected, assessing Wifi status"
ssidChk+="${profile}"
fi
done

if [ "${#ssidChk[@]}" -eq 0 ]; then
echo "No Valid SSID detected"
ssidChk+="$NO_SSID"
fi
}

check_device()
{
echo "Device availability check"
local j=0
while [ true ] #wait for wifi if busy, usb wifi is slower.
do
if [ $j -ge 5 ]; then
echo "No wifi device '$wdev0' connected"
exit 1
elif (nmcli device show "$wdev0" 2>&1 >/dev/null) ; then
echo "Wifi device '$wdev0' available"
if (rfkill list wifi -rno HARD,SOFT | grep -i "unblocked.*unblocked") >/dev/null 2>&1 ; then
return
else
if [[ $re_enable_wifi = true ]] ; then
nmcli radio wifi on
echo "Wifi has been re-activated"
sleep 10 #delay to allow wifi to initialise
return
else
echo "Wifi is deactivated"
exit 0
fi
fi
else
j=$((j + 1))
sleep 2
fi
done
}

#Activate AP profile
start_ap()
{
local ex=0
for i in "${ap_profile[@]}"
do
if [[ $i == "$ap_profile_name" ]]; then
ex=1 #known saved AP profile is available
break
fi
done
if [ $ex -eq 0 ];then
ap_new_profile #if known AP profile not found, create it
fi
nmcli con up "$ap_profile_name" >/dev/null 2>&1
sleep 3 #give time for ap to be setup
active_wifi
is_active_ap
if [ "$active_ap" = true ]; then
echo "Access Point started"
local curip="$(nmcli -t con show $active | grep IP4.ADDRESS)"
readarray -d ':' -t ipid < <(printf "%s" "$curip")
local showip="$(echo "${ipid[1]}" | sed 's/[[:blank:]]//g')"
if [ ! -z $showip ]; then
echo "AP on IP Address ${showip::-3}"
fi
else
echo "AP failed to be created."
fi
}

#Activate NW profile
start_nw()
{
if [ "$active_ap" = true ]; then
echo "The active profile is $active. Shutting down"
nmcli con down "$active" >/dev/null 2>&1
fi

local active_nw=""
for i in "${nw_profile[@]}"
do
echo "Checking: $i"
con="$(nmcli con up $i)"
if ( echo "$con" | grep 'Connection successfully activated' ) >/dev/null 2>&1; then
echo "Connection was good"
active_wifi
active_nw="$active"
elif ( echo "$con" | grep 'Connection activation failed' ) >/dev/null 2>&1; then
echo "Unable to make a connection. Check the password is ok for the ssid ${nw_profile[$c]}"
active_nw=""
else
echo "Unable to confirm the connection status"
active_nw=""
fi
if [ ! -z "$active_nw" ] ;then
echo "A valid connection has been made with $i"
break
fi
done

if [ -z "$active_nw" ] ;then
echo "A network connection has not been made with any known ssid. Activating access point"
start_ap
fi
}

#Function Create AP profile
ap_new_profile()
{
echo "Create a AP profile ${ap_profile_name}"
nmcli device wifi hotspot ifname $wdev0 con-name "$ap_profile_name" ssid "$ap_ssid" band bg password "$ap_pw" >/dev/null 2>&1
nmcli con mod "$ap_profile_name" ipv4.method shared ipv4.addr "$ap_ip" ipv4.gateway "$ap_gate" >/dev/null 2>&1
ap_profile+=("$ap_profile_name")
}

#Main
check_prerequisite
check_device

while getopts "aht" opt; do
case $opt in
a )
force_hotspot=true
;;
t )
re_enable_timer=true
;;
h )
sc="$(basename $0)"
echo -e "\nby default the $sc script will setup a connection to a WiFi network where a profile exists"
echo "otherwise an Access Point called $ap_ssid will be created. Using ip address $ap_ip"
echo "The local wifi signals will be check every 2 minutes. If a known SSID comes into range"
echo "the Access Point will be shutdown and a connection to the Wifi network will be made."
echo "using sudo $sc -a will activate the Access Point regardless of any existing WiFi profile"
echo "and stop the timed checks. Use sudo $sc to return to normal use."
exit
;;
* )
echo "option not valid"
exit
;;
esac
done

saved_profiles #get list of saved profile
active_wifi
is_active_ap
echo -e "The active profile is $active\n"

if [ "$force_hotspot" = true ]; then
if [ ! "$active_ap" = true ]; then
systemctl stop "$timer_service_name"
start_ap
elif [ ! "$active" = "$ap_profile_name" ]; then #Other AP is running, swap to this one
nmcli con down "$active"
start_ap
else
echo "Access Point $active is already running"
fi
else
if [ ! -z "$active" ]; then #Active Profile Yes
if [ "$active_ap" = true ]; then #Yes it's an AP profile
nearby_ssids_iw #scan for nearby SSID's
if [ "${ssidChk[0]}" != "$NO_SSID" ]; then #known ssid in range
start_nw
elif [ ! "$active" = "$ap_profile_name" ]; then #Other AP is running, swap to this one
nmcli con down "$active"
start_ap
fi
fi
else #no active profile
nearby_ssids_iw #scan for nearby SSID's
if [ "${ssidChk[0]}" != "$NO_SSID" ]; then #known ssid in range
start_nw
else
start_ap
fi
fi

if [[ $re_enable_timer = true ]] ; then
#check if timer is active. Will have been disabled if arg -a used.
tup="$(systemctl list-timers | grep '${timer_service_name}')"
if [ -z "$tup" ];then
systemctl start "$timer_service_name"
echo "Reactivated timer"
fi
fi
fi

active_wifi
is_active_ap
echo -e "\nThe Wifi profile in use is: $active"
echo -e "Is this a local access point? $active_ap\n"
11 changes: 11 additions & 0 deletions misc/sampleconfigs/autohotspot/NetworkManager/autohotspot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[Unit]
Description=Automatically generates an wifi hotspot when a valid SSID is not in range
After=multi-user.target
Requires=network-online.target

[Service]
Type=simple
ExecStart=%AUTOHOTSPOT_SCRIPT%

[Install]
WantedBy=multi-user.target
Loading
Loading