Willow Barraco: 1 WIP: sxmo_bluetoothmenu.sh: allow to select the default controller 1 files changed, 173 insertions(+), 57 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~mil/sxmo-devel/patches/51674/mbox | git am -3Learn more about email & git
Being able to select between multiple controller become necessary when you connect a bluetooth dongle to any devices wich already have an internal bluetooth hardware. Atm we use the default controller, which is completely random, and based on which one the daemons detected first. To do so, we re-implement most of the bluetoothctl command using expect. It is lighter and smarter than spaming the bluetoothctl commands. It also simplify the scanning jobs, because we can do both scanning and connecting with the same bluetoothctl interactive client. And it also become necessary to allow the users to select the controller they want. Because the bluetoothctl command only allow to run one command. We can not chain "select $ctn" and "connect $dev" by example. This also stop displaying some bluetoothctl prompt on a background terminal. To debug, the user can just run sxmo_bluetoothmenu.sh in a terminal. Also contains some minor code improvements. Signed-off-by: Willow Barraco <contact@willowbarraco.fr> --- To be considered as an early WIP. I'd like to get feedback about using expect. I pretty enjoyed discovering this tool today, and think it fit well in the sxmo toolbox. I'll sit on this patch for a while, to detect issues, and to make it bullet-proof. scripts/core/sxmo_bluetoothmenu.sh | 230 ++++++++++++++++++++++------- 1 file changed, 173 insertions(+), 57 deletions(-) diff --git a/scripts/core/sxmo_bluetoothmenu.sh b/scripts/core/sxmo_bluetoothmenu.sh index 8aaadc55..9d0f10f5 100755 --- a/scripts/core/sxmo_bluetoothmenu.sh +++ b/scripts/core/sxmo_bluetoothmenu.sh @@ -12,9 +12,7 @@ set -e SIMPLE_MODE=yes -_prompt() { - sxmo_dmenu.sh -i "$@" -} +controller="$(bluetoothctl list | grep "\[default\]" | cut -d" " -f2)" _device_list() { bluetoothctl devices | \ @@ -63,31 +61,49 @@ _restart_bluetooth() { } _full_reconnection() { - sxmo_terminal.sh sh -c " -notify-send 'Make the device discoverable' + notify-send 'Make the device discoverable' + expect - "$controller" "$1" <<-'EOF' + lassign $argv controller mac -bluetoothctl remove '$1' -sxmo_jobs.sh start bluetooth_scan bluetoothctl --timeout 300 scan on + spawn bluetoothctl -a NoInputNoOutput -sleep 5 + send -- "select $controller\r" -while : ; do - timeout 7 bluetoothctl connect '$1' - if bluetoothctl info '$1' | grep -q 'Connected: yes'; then - break - fi - sleep 1 -done -" - sxmo_jobs.sh stop bluetooth_scan -} + send -- "remove $mac\r" + expect { + "Device has been removed" { + expect "Device $mac" + } + "Device $mac not available" + } -_notify_failure() { - notify-send "Something failed" + send -- "scan on\r" + expect "Discovery started" + send -- "devices\r" + + set timeout 5 + expect { + timeout {send -- "devices\r"; exp_continue} + "Device $mac" { + sleep 1 + send -- "connect $mac\r" + expect { + "Connection successful" {send -- "exit\r"} + "Operation already in progress" {sleep 1; exp_continue} + timeout { + sleep 1 + send -- "connect $mac\r" + exp_continue + } + } + } + } + wait + EOF } _can_fail() { - "$@" || _notify_failure + "$@" || notify-send "Something failed" } _show_toggle() { @@ -103,9 +119,30 @@ toggle_connection() { MAC="$(printf "%s\n" "$DEVICE" | awk '{print $NF}')" if printf "%s\n" "$PICK" | grep -q "$icon_a2x"; then - _can_fail timeout 7 sxmo_terminal.sh bluetoothctl disconnect "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 7 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "disconnect $mac\r" + expect "Successful disconnected" + send -- "exit\r" + wait + EOF else - _can_fail timeout 7 sxmo_terminal.sh bluetoothctl connect "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 7 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "connect $mac\r" + expect { + "Operation already in progress" {sleep 1} + "Connection successful" + } + send -- "exit\r" + wait + EOF fi } @@ -121,17 +158,16 @@ device_loop() { CONNECTED="$(printf "%s\n" "$INFO" | grep "Connected:" | awk '{print $NF}')" PICK="$( - cat <<EOF | -$icon_ret Return -$icon_rld Refresh -Paired $(_show_toggle "$PAIRED") -Trusted $(_show_toggle "$TRUSTED") -Connected $(_show_toggle "$CONNECTED") -Blocked $(_show_toggle "$BLOCKED") -$icon_ror Clean re-connection -$icon_trh Remove -EOF - _prompt -p "$DEVICE" -I "$INDEX" + cat <<-EOF | sxmo_dmenu.sh -i -p "$DEVICE" -I "$INDEX" + $icon_ret Return + $icon_rld Refresh + Paired $(_show_toggle "$PAIRED") + Trusted $(_show_toggle "$TRUSTED") + Connected $(_show_toggle "$CONNECTED") + Blocked $(_show_toggle "$BLOCKED") + $icon_ror Clean re-connection + $icon_trh Remove + EOF )" case "$PICK" in @@ -145,23 +181,68 @@ EOF ;; "Paired $icon_tof") INDEX=2 - _can_fail timeout 7 sxmo_terminal.sh bluetoothctl "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "pair $mac\r" + expect "Pairing successful" + send -- "exit\r" + wait + EOF ;; "Trusted $icon_ton") INDEX=3 - _can_fail sxmo_terminal.sh bluetoothctl untrust "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "untrust $mac\r" + expect "untrust succeeded" + send -- "exit\r" + wait + EOF ;; "Trusted $icon_tof") INDEX=3 - _can_fail sxmo_terminal.sh bluetoothctl trust "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "trust $mac\r" + expect "trust succeeded" + send -- "exit\r" + wait + EOF ;; "Connected $icon_ton") INDEX=4 - _can_fail timeout 7 sxmo_terminal.sh bluetoothctl disconnect "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "disconnect $mac\r" + expect "Successful disconnected" + send -- "exit\r" + wait + EOF ;; "Connected $icon_tof") INDEX=4 - _can_fail timeout 7 sxmo_terminal.sh bluetoothctl "$MAC" + _can_fail expect - "$controller" "$MAC" <<-'EOF' + lassign $argv controller mac + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "connect $mac\r" + expect "Connection successful" + send -- "exit\r" + wait + EOF ;; "Blocked $icon_ton") INDEX=5 @@ -175,10 +256,11 @@ EOF ;; "$icon_trh Remove") INDEX=7 - (confirm_menu -p "Remove this device ?" \ - && _can_fail sxmo_terminal.sh bluetoothctl remove "$MAC") \ - || continue - return + if confirm_menu -p "Remove this device ?"; then + if _can_fail bluetoothctl remove "$MAC"; then + return + fi + fi ;; esac sleep 0.5 @@ -188,23 +270,28 @@ EOF main_loop() { INDEX=0 while : ; do - INFO="$(bluetoothctl show)" + INFO="$(bluetoothctl show "$controller")" DISCOVERING="$(printf "%s\n" "$INFO" | grep "Discovering:" | awk '{print $NF}')" PAIRABLE="$(printf "%s\n" "$INFO" | grep "Pairable:" | awk '{print $NF}')" + CONTROLLERS="$(bluetoothctl <<-EOF | grep ^Controller | sort -u | sed "s|^Controller|$icon_rss|" + select $controller + list + EOF + )" DEVICES="$(_device_list)" PICK="$( - cat <<EOF | -$icon_cls Close Menu -$icon_rld Refresh -$icon_pwr Restart daemon -Simple mode $(_show_toggle "$SIMPLE_MODE") -Pairable $(_show_toggle "$PAIRABLE") -Discovering $(_show_toggle "$DISCOVERING") -$DEVICES -EOF - _prompt -p "$icon_bth Bluetooth" -I "$INDEX" + cat <<-EOF | sxmo_dmenu.sh -i -p "$icon_bth Bluetooth" -I "$INDEX" + $icon_cls Close Menu + $icon_rld Refresh + $icon_pwr Restart daemon + Simple mode $(_show_toggle "$SIMPLE_MODE") + Pairable $(_show_toggle "$PAIRABLE") + Discovering $(_show_toggle "$DISCOVERING") + $CONTROLLERS + $DEVICES + EOF )" case "$PICK" in @@ -229,12 +316,30 @@ EOF INDEX=3 ;; "Pairable $icon_ton") - bluetoothctl pairable off INDEX=4 + _can_fail expect - "$controller" <<-'EOF' + lassign $argv controller + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "pairable off\r" + expect "Changing pairable off succeeded" + send -- "exit\r" + wait + EOF ;; "Pairable $icon_tof") - bluetoothctl pairable on INDEX=4 + _can_fail expect - "$controller" <<-'EOF' + lassign $argv controller + set timeout 5 + spawn bluetoothctl -a NoInputNoOutput + send -- "select $controller\r" + send -- "pairable on\r" + expect "Changing pairable on succeeded" + send -- "exit\r" + wait + EOF ;; "Discovering $icon_ton") INDEX=5 @@ -242,11 +347,22 @@ EOF sleep 0.5 ;; "Discovering $icon_tof") - sxmo_jobs.sh start bluetooth_scan bluetoothctl --timeout 60 scan on > /dev/null + sxmo_jobs.sh start bluetooth_scan expect -c " + spawn bluetoothctl -a NoInputNoOutput + send -- \"select $controller\r\" + send -- \"scan on\r\" + sleep 60 + send -- \"exit\r\" + wait + " notify-send "Scanning for 60 seconds" INDEX=5 sleep 0.5 ;; + "$icon_rss"*) + INDEX=0 + controller="$(printf %s "$PICK" | cut -d" " -f2)" + ;; *) INDEX=0 -- 2.45.0
builds.sr.ht <builds@sr.ht>sxmo-utils/patches/test.yml: SUCCESS in 22s [WIP: sxmo_bluetoothmenu.sh: allow to select the default controller][0] from [Willow Barraco][1] [0]: https://lists.sr.ht/~mil/sxmo-devel/patches/51674 [1]: mailto:contact@willowbarraco.fr ✓ #1214743 SUCCESS sxmo-utils/patches/test.yml https://builds.sr.ht/~mil/job/1214743
Marked as superseded by a non WIP patch!