Si los auriculares pierden el emparejamiento (p. ej. al emparejarlos con otro aparato) el PC sigue viéndolos como Paired: yes y connect falla siempre con br-connection-key-missing. Ahora, ante ese error, se borra el dispositivo, se busca, se vuelve a emparejar y se conecta. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
100 lines
3.1 KiB
Bash
Executable file
100 lines
3.1 KiB
Bash
Executable file
#!/bin/sh
|
|
# Menú de bluetooth con dmenu (clic izquierdo en BT de la barra). Arriba, los
|
|
# dispositivos conocidos (emparejados o de confianza; = conectado): elegir
|
|
# uno lo desconecta si está conectado y, si no, lo busca y se conecta (y lo
|
|
# vuelve a emparejar si hace falta). Debajo, buscar y emparejar uno nuevo y
|
|
# apagar el adaptador. Si está apagado, ofrece encenderlo.
|
|
|
|
avisar() {
|
|
notify-send -h string:x-dunst-stack-tag:bluetooth -i bluetooth "Bluetooth" "$1"
|
|
}
|
|
|
|
# "Device AA:BB:CC:DD:EE:FF Nombre" -> "Nombre (AA:BB:CC:DD:EE:FF)"
|
|
lista() { sed -n 's/^Device \([^ ]*\) \(.*\)/\2 (\1)/p'; }
|
|
mac() { printf '%s\n' "$1" | sed 's/.*(\([^)]*\))$/\1/'; }
|
|
buscar() { bluetoothctl --timeout "$1" scan on >/dev/null; }
|
|
|
|
# Sin agente, bluetoothctl no puede emparejar; los auriculares no piden PIN.
|
|
emparejar() {
|
|
bluetoothctl --agent NoInputNoOutput pair "$1" >/dev/null &&
|
|
bluetoothctl trust "$1" >/dev/null
|
|
}
|
|
|
|
# conectar MAC: si no está emparejado lo empareja; si no está a la vista, lo
|
|
# busca unos segundos y lo vuelve a intentar. Si el dispositivo ha olvidado el
|
|
# emparejamiento (br-connection-key-missing), lo borra y lo empareja de nuevo.
|
|
conectar() {
|
|
if ! bluetoothctl info "$1" | grep -q 'Paired: yes'; then
|
|
emparejar "$1" || { buscar 8 && emparejar "$1"; } || return 1
|
|
fi
|
|
salida=$(bluetoothctl connect "$1" 2>&1) && return 0
|
|
case $salida in
|
|
*key-missing*)
|
|
bluetoothctl remove "$1" >/dev/null
|
|
buscar 8 && emparejar "$1" && bluetoothctl connect "$1" >/dev/null
|
|
;;
|
|
*)
|
|
buscar 8 && bluetoothctl connect "$1" >/dev/null
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# conectar_y_avisar "Nombre (MAC)"
|
|
conectar_y_avisar() {
|
|
nombre=${1% (*}
|
|
avisar "Conectando: $nombre..."
|
|
if conectar "$(mac "$1")"; then
|
|
avisar "Conectado: $nombre"
|
|
elif ! pgrep -x wireplumber >/dev/null; then
|
|
avisar "No se pudo conectar $nombre: wireplumber no está en marcha (sin él no hay audio)"
|
|
else
|
|
avisar "No se pudo conectar $nombre: ¿está encendido y cerca?"
|
|
fi
|
|
}
|
|
|
|
if ! bluetoothctl show | grep -q 'Powered: yes'; then
|
|
[ "$(echo Encender | menu -p Bluetooth:)" = Encender ] || exit 0
|
|
bluetoothctl power on >/dev/null
|
|
pkill -USR1 -x slstatus
|
|
fi
|
|
|
|
conectados=$(bluetoothctl devices Connected | lista)
|
|
conocidos=$({ bluetoothctl devices Paired; bluetoothctl devices Trusted; } | lista | sort -u)
|
|
|
|
opcion=$(
|
|
printf '%s\n' "$conocidos" | while IFS= read -r d; do
|
|
[ -n "$d" ] || continue
|
|
if printf '%s\n' "$conectados" | grep -qxF "$d"; then
|
|
echo " $d"
|
|
else
|
|
echo " $d"
|
|
fi
|
|
done
|
|
echo " Buscar dispositivos"
|
|
echo " Apagar"
|
|
)
|
|
opcion=$(printf '%s\n' "$opcion" | menu -p Bluetooth:)
|
|
|
|
case $opcion in
|
|
'') exit 0 ;;
|
|
*" Apagar")
|
|
bluetoothctl power off >/dev/null
|
|
;;
|
|
*" Buscar dispositivos")
|
|
avisar "Buscando dispositivos durante 10 s..."
|
|
buscar 10
|
|
nuevo=$(bluetoothctl devices | lista | awk -v e="$conocidos" '
|
|
BEGIN { n = split(e, a, "\n"); for (i = 1; i <= n; i++) visto[a[i]] }
|
|
!($0 in visto)' | menu -p Emparejar:)
|
|
[ -n "$nuevo" ] || exit 0
|
|
conectar_y_avisar "$nuevo"
|
|
;;
|
|
" "*)
|
|
bluetoothctl disconnect "$(mac "$opcion")" >/dev/null &&
|
|
avisar "Desconectado: ${opcion#" "}"
|
|
;;
|
|
*)
|
|
conectar_y_avisar "${opcion#" "}"
|
|
;;
|
|
esac
|
|
pkill -USR1 -x slstatus
|