2020-07-04 20:27:19 +02:00
#!/bin/sh
2020-06-07 20:56:01 +02:00
SCAN_PERIOD=5
2020-06-28 14:43:34 +02:00
AUTOTRUST=false
2020-06-08 21:29:02 +02:00
#locations of blacklist and hard coded list of paired devices (watch out, need to modify Makefile as well if you want to change these values and still use make install)
2020-06-07 20:56:01 +02:00
BLACKLIST=${XDG_DATA_HOME:-$HOME/.local/share}/bt/blacklist
PAIRLIST=${XDG_DATA_HOME:-$HOME/.local/share}/bt/paired
2020-06-28 14:04:09 +02:00
actions="pair
disconnect
unpair"
2020-06-09 20:20:35 +02:00
2020-07-04 20:27:19 +02:00
[ "$AUTOTRUST" = false ] && actions="${actions}
2020-06-28 14:43:34 +02:00
trust"
2020-06-07 20:56:01 +02:00
#Checks for necessary programs to be present. Very unlikely not to be present but let's just err on the safer side.
2020-06-09 18:33:27 +02:00
for prog in dmenu bluetoothctl awk cat date nl; do
2020-06-07 20:56:01 +02:00
if ! hash "$prog" 2>/dev/null; then
printf 'bthandler: %s: command not found\n' "$prog" >&2
exit 127
fi
done
2020-06-28 14:38:32 +02:00
power(){
powerstatus="$( bluetoothctl show | grep Powered | awk '{print $2}' )"
[ "$powerstatus" = "no" ] && [ "$1" = on ] && bluetoothctl power on
[ "$powerstatus" = "yes" ] && [ "$1" = off ] && bluetoothctl power off
2020-06-28 14:04:09 +02:00
}
2020-06-28 14:38:32 +02:00
scan(){
scanstatus="$( bluetoothctl show | grep Discovering | awk '{print $2}' )"
2020-07-04 20:27:19 +02:00
if [ "$1" = on ]; then
2020-06-29 15:19:25 +02:00
#sets variable in case scanning was already on before the start of bt
[ "$start_scan" = "" ] && start_scan="$( date +'%s' )"
2020-06-28 14:38:32 +02:00
if [ "$scanstatus" = "no" ]; then
bluetoothctl scan on &
start_scan="$( date +'%s' )"
fi
elif [ "$1" = off ]; then
if [ "$scanstatus" = "yes" ]; then
bluetoothctl scan off
fi
fi
2020-06-28 14:04:09 +02:00
}
#start scanning as early as possible to speed up pairing process
#=> maybe use an option to do this? Otherwise ever invocation of bt powers on the controller.
2020-06-28 14:38:32 +02:00
power on
scan on
2020-06-09 18:20:51 +02:00
2020-06-07 20:56:01 +02:00
#Compile list of all Bluetooth IDS of paired devices (from bluetoothctl and from hardcoded list)
2020-06-08 21:29:02 +02:00
bt_IDS="$( ( bluetoothctl paired-devices && cat "$PAIRLIST" ) | sort -u | awk '{print $2}' )"
2020-06-07 20:56:01 +02:00
#Compile list of all device Names of paired devices (from bluetoothctl and from hardcoded list)
2020-06-08 21:29:02 +02:00
paired_devices="$( ( bluetoothctl paired-devices && cat "$PAIRLIST" ) | sort -u | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' )"
2020-06-07 20:56:01 +02:00
2020-06-08 21:29:02 +02:00
disp_devices="$( echo "$paired_devices" | grep -vf "$BLACKLIST" )"
2020-06-07 20:56:01 +02:00
2020-06-28 14:38:32 +02:00
#detects current power mode of controller and adjusts options accordingly
2020-06-28 14:04:09 +02:00
poweroption="$( echo "$powerstatus" | sed 's/yes/power off/; s/no/power on/' )"
2020-06-07 20:56:01 +02:00
#Don't print empty device list, removes unnecessary empty choice in dmenu
2020-06-28 14:04:09 +02:00
[ "$disp_devices" = "" ] && choice=$( printf "%s\n%s" "$poweroption" "$actions" | dmenu -i -p 'What BT action would you like to perform:' )
[ "$disp_devices" != "" ] && choice=$( ( echo "$disp_devices" && printf "%s\n%s" "$poweroption" "$actions" ) | dmenu -i -p 'What BT action would you like to perform:' )
2020-06-07 20:56:01 +02:00
cleanup(){
2020-06-28 14:38:32 +02:00
scan off
2020-06-07 20:56:01 +02:00
exit 0
}
2020-06-09 18:20:51 +02:00
pair(){
#since this function can get called indefinitely, make sure to always be scanning and controller has power in the case that it got deactived by some other process.
2020-06-28 14:38:32 +02:00
power on
scan on
#check whether $SCAN_PERIOD seconds has already passed since starting scanning, if not, wait for the rest of that time.
2020-06-09 18:20:51 +02:00
if [ $((( "$(date +'%s')" - "$start_scan" ))) -lt $SCAN_PERIOD ]; then
sleep_period="$((( "$SCAN_PERIOD" - "$( date +'%s')" + "$start_scan" )))"
2020-06-09 18:33:27 +02:00
if [ "$sleep_period" -eq 1 ]; then
notify-send "Bluetooth" "Searching for devices, please wait 1 second"
else
notify-send "Bluetooth" "Searching for devices, please wait $sleep_period seconds"
fi
2020-06-09 18:20:51 +02:00
sleep "$sleep_period"
fi
2020-07-04 20:27:19 +02:00
all_devices="$( bluetoothctl devices )"
if [ "$paired_devices" = "" ]; then
new_devices="$( echo "$all_devices" | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' )"
bt_IDS="$( echo "$all_devices" | awk '{print $2}' )"
2020-06-28 14:04:09 +02:00
else
2020-07-04 20:27:19 +02:00
echo "$paired_devices" > /tmp/paired_devices$$
filtered_devices="$( echo "$all_devices" | grep -vf "/tmp/paired_devices$$")"
bt_IDS="$( echo "$filtered_devices" | awk '{print $2}' )"
new_devices="$( echo "$filtered_devices" | awk '{for (i=3; i<NF; i++) printf $i " "; print $NF}' )"
rm /tmp/paired_devices$$
2020-06-28 14:04:09 +02:00
fi
2020-07-04 20:27:19 +02:00
[ "$new_devices" = "" ] && options="rescan" || options=$(echo "$new_devices" && echo 'rescan')
2020-06-28 14:04:09 +02:00
choice=$( echo "$options" | dmenu -l 10 -i -p 'pair with which device?' )
2020-06-09 18:20:51 +02:00
if [ -n "$choice" ]; then
if [ "$choice" = "rescan" ]; then
start_scan="$( date +'%s')"
pair
2020-07-04 20:27:19 +02:00
else
echo all:"$all_devices"
echo choice:"$choice"
echo new:"$new_devices"
dev_no=$( echo "$new_devices" | nl | grep "$choice" | awk '{print $1}')
echo dev_no:$dev_no
dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' )
echo bt_IDS:"$bt_IDS"
echo devid:$dev_id
#only attempt to connect if pairing succeeds
bluetoothctl pair "$dev_id" && ( pair_succesful=true && bluetoothctl connect "$dev_id" ) || pair_succesful=false
if $AUTOTRUST; then
bluetoothctl trust "$dev_id"
fi
#if device is not already hard coded as paired, add to paired devices list
if [ "$( grep "$dev_id" "$PAIRLIST")" = "" ] || [ "$(wc -l "$PAIRLIST")" -eq 0 ] && $pair_succesful
then
echo to be added to "$PAIRLIST":
echo Device "$dev_id" "$choice"
echo Device "$dev_id" "$choice" >> "$PAIRLIST"
fi
2020-06-09 18:20:51 +02:00
fi
fi
}
2020-06-07 20:56:01 +02:00
case $choice in
2020-06-28 14:04:09 +02:00
"turn on") bluetoothctl power on;;
"turn off") bluetoothctl power off;;
2020-06-07 20:56:01 +02:00
"scan on") bluetoothctl power on && echo power on && sleep 2
2020-06-28 14:04:09 +02:00
([ -n "$TERMINAL" ] && $TERMINAL -e bluetoothctl scan on ) || st bluetoothctl scan on;;
2020-06-09 18:20:51 +02:00
"pair") pair;;
2020-06-08 21:29:02 +02:00
"unpair") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?')
if [ -n "$choice" ]; then
2020-06-08 21:53:13 +02:00
dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}')
dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' )
2020-06-08 21:29:02 +02:00
bluetoothctl remove "$dev_id"
2020-06-07 20:56:01 +02:00
#remove device to unpair from hard coded paired devices list
new_paired_list="$( grep -v "$dev_id" "$PAIRLIST" )"
2020-07-04 20:27:19 +02:00
if [ "$new_paired_list" != "" ]
then
echo "$new_paired_list" > "$PAIRLIST"
else
rm -rf "$PAIRLIST"
touch "$PAIRLIST"
fi
2020-06-28 14:04:09 +02:00
fi;;
2020-06-09 20:20:35 +02:00
"trust") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?')
if [ -n "$choice" ]; then
dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}')
dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' )
bluetoothctl trust "$dev_id"
2020-06-28 14:04:09 +02:00
fi;;
"disconnect") choice=$( echo "$paired_devices" | dmenu -l 10 -i -p 'remove which paired device?')
if [ -n "$choice" ]; then
dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}')
dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}' )
bluetoothctl disconnect "$dev_id"
fi;;
2020-06-28 14:38:32 +02:00
*)
echo "$choice"
2020-06-28 14:04:09 +02:00
dev_no=$( echo "$paired_devices" | nl | grep -P "[0-9]+\t$choice$" | awk '{print $1}')
2020-07-04 20:27:19 +02:00
[ "$dev_no" != "" ] && dev_id=$( echo "$bt_IDS" | nl | grep -P "^.*$dev_no\t" | awk '{print $2}')
if [ -n "$dev_id" ]; then
power on
bluetoothctl pair "$dev_id"
bluetoothctl connect "$dev_id"
fi;;
2020-06-07 20:56:01 +02:00
esac