GNOME Bluetooth 自动重连问题的解决
系统版本: Fedora 32
GNOME版本: 3.36.2
问题分析
很久之前买了个天猫精灵X1蓝牙音响,周末偶尔也会用台式机连一下看看电影啥的。
但是GNOME bluetooth 有个问题就是,第一次可以配对成功并连接上,下次开机重启后它就不会自动连接了。并且就算你想手动点击连接,也非常大的概率无法成功,大部分情况下,你尝试点击那个连接的开关它会马上切换到未连接的状态,如图示:
当然,如果有耐心的话,多点击几次,还是有可能成功的。比如像我这样点了14下才成功:
当然,要不是我sudo journalctl -f -u bluetooth
打开了日志,我可能会认为这个按钮是“自动反弹”的而放弃继续点击。
现在我们知道了,只要耐心的点,总有一次会成功的。
我们来看看日志:
❯ sudo journalctl -f -u bluetooth
[sudo] password for ttys3:
-- Logs begin at Thu 2020-01-09 03:44:38 CST. --
May 20 20:07:43 8700k.localhost bluetoothd[2771]: Exit
May 20 20:07:43 8700k.localhost systemd[1]: bluetooth.service: Succeeded.
May 20 20:07:43 8700k.localhost systemd[1]: Stopped Bluetooth service.
-- Reboot --
May 20 20:08:17 8700k.localhost systemd[1]: Starting Bluetooth service...
May 20 20:08:17 8700k.localhost bluetoothd[2768]: Bluetooth daemon 5.54
May 20 20:08:17 8700k.localhost systemd[1]: Started Bluetooth service.
May 20 20:08:17 8700k.localhost bluetoothd[2768]: Starting SDP server
May 20 20:08:17 8700k.localhost bluetoothd[2768]: Bluetooth management interface 1.15 initialized
May 20 20:08:34 8700k.localhost bluetoothd[2768]: Endpoint registered: sender=:1.76 path=/MediaEndpoint/A2DPSink/sbc
May 20 20:08:34 8700k.localhost bluetoothd[2768]: Endpoint registered: sender=:1.76 path=/MediaEndpoint/A2DPSource/sbc
May 20 20:11:12 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:14 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:16 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:17 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:18 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:19 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:20 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:21 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:22 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:24 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:25 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:26 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:27 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:28 8700k.localhost bluetoothd[2768]: connect error: Device or resource busy (16)
May 20 20:11:32 8700k.localhost bluetoothd[2768]: /org/bluez/hci0/dev_18_BC_5A_A5_54_DB/sep1/fd0: fd(46) ready
可见没法连接成功的情况都是connect error: Device or resource busy (16)
, 而连接成功的情况则是/org/bluez/hci0/dev_18_BC_5A_A5_54_DB/sep1/fd3: fd(43) ready
这种。
好了,现在我们总结一下问题:
- 首次配对是可以连接成功并正常使用的
- 系统重启后蓝牙音响没有自动连接。手动点击要点十多下才可能成功。
- 根据条件1,我们尝试重启后删除蓝牙音响并重新配对也是OK的。
无论是一次又一次的删除和添加配对,还是每次开机点十几下连接个蓝牙音响,都挺麻烦的,有没有办法让它开机自动重连蓝牙音响呢?
办法当然是有的。
解决开机自动重连问题
bluez
这个Bluetooth utilities包里,包含了bluetoothctl
这个实用工具,我们可以用它来完成自动连接。
新建一文件 /opt/scripts/bluetooth-auto-connect.sh
(/opt/scripts
目录不存在,自己新建一个即可), 内容如下:
#!/bin/sh
DEVICE="18:BC:5A:A5:54:DB"
BLCTL=/usr/bin/bluetoothctl
$BLCTL power on
$BLCTL agent on
$BLCTL default-agent
if $BLCTL info $DEVICE; then
$BLCTL trust $DEVICE && $BLCTL connect $DEVICE
fi
18:BC:5A:A5:54:DB
是蓝牙音响的MAC地址(注意这个设备是已经成功配对过的)。
注意这里我们执行了trust
命令,这是必要的。要不然无法连接成功。
MAC地址可以通过Gnome图片界面查看到,也可以用命令行:
❯ bluetoothctl devices
Device 03:D1:64:4D:26:A1 03-D1-64-4D-26-A1
Device 70:0E:47:34:2A:F1 70-0E-47-34-2A-F1
Device 62:BB:F2:90:DC:7A 62-BB-F2-90-DC-7A
Device 1E:0F:C3:CF:6D:AF 1E-0F-C3-CF-6D-AF
Device 18:BC:5A:A5:54:DB X1(F0:6B)
18:BC:5A:A5:54:DB
就是天猫精灵X1的MAC了。
然后我们在Gnome的自动启动目录~/.config/autostart
下新建一desktop文件bluetooth-auto-connect.desktop
, 内容如下:
[Desktop Entry]
Name=bluetooth-auto-connect
GenericName=bluetooth-auto-connect
Exec=/opt/scripts/bluetooth-auto-connect.sh
Terminal=false
Icon=bash
Categories=Audio
Type=Application
StartupNotify=false
X-GNOME-Autostart-enabled=true
这样就能在用户登录后自动执行蓝牙连接了。
如果开启了selinux, 注意设置一下:
sudo chcon -t bin_t /opt/scripts/bluetooth-auto-connect.sh
连接成功后可以通过以下命令查看蓝牙设备信息:
❯ bluetoothctl info 18:BC:5A:A5:54:DB
Device 18:BC:5A:A5:54:DB (public)
Name: X1(F0:6B)
Alias: X1(F0:6B)
Class: 0x002c0414
Icon: audio-card
Paired: yes
Trusted: yes
Blocked: no
Connected: yes
LegacyPairing: no
UUID: Audio Sink (0000110b-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
UUID: A/V Remote Control (0000110e-0000-1000-8000-00805f9b34fb)
UUID: PnP Information (00001200-0000-1000-8000-00805f9b34fb)
UUID: Generic Access Profile (00001800-0000-1000-8000-00805f9b34fb)
UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
Modalias: bluetooth:v000Fp1200d1436
开机连接成功后自动切换
如果你希望PulseAudio自动连接到新发现的输出设备, 可以修改/etc/pulse/default.pa
, 增加:
# bluetooth: automatically switch to newly-connected devices
# https://wiki.archlinux.org/index.php/Bluetooth_headset#Setting_up_auto_connection
load-module module-switch-on-connect
或者添加到pulse用户配置文件~/.config/pulse/default.pa
也OK。 文件不存在则新建一个或从/etc/pulse/default.pa
copy一个过来。
什么是PulseAudio?
PulseAudio 是在 GNOME 或 KDE 等桌面环境中广泛使用的音频服务。它在内核音频组件(比如ALSA 和 OSS)和应用程序之间充当代理的角色。 PulseAudio经常和ALSA协同使用。
所以PulseAudio它是一个middleware, 应用程序想要输出声音,可以找Pulse,然后Pulse再找底层的组件比如ALSA。
当然,PulseAudio并不是必须的。一些应用程序,比如DeaDBeeF和SMPlayer 允许用户配置声音输出。 比如DeaDBeeF就有三个选择,ALSA, OSS或 Pulse。当选择为ALSA时,DeaDBeeF还会允许你选择用哪个设备输出声音。
一般来说,我们让应用程序都使用PulseAudio
, 然后让PulseAudio
统一管理会比较好。 比如我们将输出设备从Audioengine D1切换到天猫精灵X1时, 所有应用程序就统一切换了,假如是单独用ALSA
设置的,那还得单个去改,挺麻烦的。
参数文档
https://wiki.archlinux.org/index.php/PulseAudio
https://wiki.debian.org/BluetoothUser#Can.27t_reconnect_after_sleep
https://wiki.archlinux.org/index.php/Bluetooth_headset#Configuration_via_CLI