Bluetooth
Bluetooth 是一种用于蜂窝电话、计算机和其他电子设备短距离无线互连的标准。在 Linux 中,Bluetooth 协议栈的规范实现是 BlueZ。
安装
- 安装 bluez 软件包,它提供了 Bluetooth 协议栈。
- 安装 bluez-utils 软件包,它提供了 bluetoothctl 实用程序。另外安装 bluez-deprecated-tools 以便拥有 已弃用的 BlueZ 工具。
- 通用的 Bluetooth 驱动程序是
btusb
内核模块。 检查 该模块是否已加载。如果未加载,则 加载该模块。 - 启动/启用
bluetooth.service
。
- 一些蓝牙适配器与 Wi-Fi 卡捆绑在一起(例如,较旧的 Intel Centrino 卡)。这些适配器需要首先启用 Wi-Fi 卡(通常是笔记本电脑上的键盘快捷键),以便内核可以看到蓝牙适配器。
- 一些蓝牙卡(例如 Broadcom)与网络适配器冲突。因此,您需要确保您的蓝牙设备在网络服务启动之前连接。
- 诸如 hcitool 和 hciconfig 之类的一些工具已在上游弃用,并且不再包含在 bluez-utils 中。由于这些工具将不再更新,因此建议更新脚本以避免使用它们。如果您仍然希望使用它们,请另外安装 bluez-deprecated-tools。有关更多信息,请参见 FS#53110 和 Bluez 邮件列表。
- 自 2024 年以来,bluez-obex 和 bluez-mesh 已从 bluez 中分离出来。因此,如果您计划通过蓝牙传输文件,则需要安装 bluez-obex,并且需要启用用户服务
obex.service
。
前端
命令行
- bluetoothctl — 从 shell 配对设备是最简单和最可靠的选择之一。
- bluetuith — 通过终端用户界面提供蓝牙管理器,以便更轻松地进行配对和设备/适配器管理,并支持 OBEX 文件传输和鼠标。
- bluetui — 用于管理蓝牙设备的 TUI。
echo -e "command1\ncommand2\n" | bluetoothctl
或 bluetoothctl -- command
。图形界面
以下软件包允许使用图形界面自定义蓝牙。
- GNOME Bluetooth — GNOME 的蓝牙工具。
- gnome-bluetooth-3.0 提供了后端(gnome-bluetooth 现在是旧版本)
- gnome-shell 提供了状态监视器小程序
- gnome-control-center 提供了配置前端 GUI,可以通过在“活动”概览中键入“Bluetooth”或使用
gnome-control-center bluetooth
命令来访问。 - 您还可以直接启动
bluetooth-sendto
命令以将文件发送到远程设备。 - nautilus-bluetoothAUR 向 Nautilus 的右键菜单添加“通过蓝牙发送”条目
- 要接收文件,请打开蓝牙设置面板;您只能在蓝牙面板打开时接收。
- 要将蓝牙条目添加到 Thunar 文件属性菜单中的“发送到”菜单,请参阅 此处 的说明。(需要配置的命令是
bluetooth-sendto %F
)。
- Bluedevil — KDE 的蓝牙工具。如果 Dolphin 和系统托盘中没有可见的蓝牙图标,请在系统托盘选项中启用它或添加小部件。您可以通过单击图标来配置 Bluedevil 并检测蓝牙设备。也可以从 KDE 系统设置中使用界面。
- Blueberry — Linux Mint 的 GNOME Bluetooth 衍生版本,可在所有桌面环境中使用。Blueberry 不支持通过 Obex Object Push 接收文件。
- Blueman — 功能齐全的蓝牙管理器。
- ObexFTP — 一种用于与任何启用 OBEX 的设备传输文件的工具。
- Overskride — 一个简单而强大的蓝牙客户端。
配对
本节介绍如何通过 bluetoothctl(1) 命令行工具直接配置 bluez,如果您正在使用其他前端工具(例如 GNOME 蓝牙),则可能不需要这样做。
确切的步骤取决于所涉及的设备及其输入功能。以下是使用 bluetoothctl 配对设备的一般outline。
启动 bluetoothctl
交互式命令。输入 help
获取可用命令列表。
- (可选)使用
select MAC_address
选择默认控制器。 - (可选)如果设备设置为关闭,则输入
power on
以打开控制器的电源。 默认情况下它是开启的;请参阅 #默认适配器电源状态。 - 输入
devices
获取要配对设备的 MAC 地址。 - 如果设备尚未在列表中,使用
scan on
命令进入设备发现模式。 - 使用
agent on
开启代理,或选择特定的代理:如果您在agent
后按两次 Tab 键,您应该会看到可用代理的列表。蓝牙代理是管理蓝牙“配对码”的程序。它可以响应传入的“配对码”,也可以发送一个配对码。在大多数情况下,default-agent
应该是合适的。[1] - 输入
pair MAC_address
进行配对(支持 Tab 键补全)。 - 如果使用没有 PIN 码的设备,可能需要在成功重新连接之前手动信任该设备。输入
trust MAC_address
以执行此操作。 - 输入
connect MAC_address
以建立连接。
一个会话示例可能如下所示
$ bluetoothctl
[NEW] Controller 00:10:20:30:40:50 hostname [default] [bluetooth]# agent KeyboardOnly Agent registered [bluetooth]# default-agent Default agent request successful [bluetooth]# power on Changing power on succeeded [CHG] Controller 00:10:20:30:40:50 Powered: yes [bluetooth]# scan on Discovery started [CHG] Controller 00:10:20:30:40:50 Discovering: yes [NEW] Device 00:12:34:56:78:90 device name [CHG] Device 00:12:34:56:78:90 LegacyPairing: yes [bluetooth]# pair 00:12:34:56:78:90 Attempting to pair with 00:12:34:56:78:90 [CHG] Device 00:12:34:56:78:90 Connected: yes [CHG] Device 00:12:34:56:78:90 Connected: no [CHG] Device 00:12:34:56:78:90 Connected: yes Request PIN code [agent] Enter PIN code: 1234 [CHG] Device 00:12:34:56:78:90 Paired: yes Pairing successful [CHG] Device 00:12:34:56:78:90 Connected: no [bluetooth]# connect 00:12:34:56:78:90 Attempting to connect to 00:12:34:56:78:90 [CHG] Device 00:12:34:56:78:90 Connected: yes Connection successful
双启动配对
要在双启动设置中配对设备,您需要更改 Linux 安装上的配对密钥,使其与 Windows 或 macOS 使用的密钥一致。
此页面仅描述手动方法。要自动化此过程,请参阅 bt-dualboot 项目 和相关仓库。 对于半自动化过程,请使用 bluetooth-dualboot 脚本,它不会编辑任何文件,但可以帮助您运行正确的命令并剪切粘贴正确的值。
设置
要执行此操作,首先在您的 Arch Linux 安装上配对您的设备。然后重启进入另一个操作系统并配对设备。现在您需要提取配对密钥,但首先关闭蓝牙设备以防止任何连接尝试。
对于 Windows
您可以在 Linux 或 Windows 上提取您的蓝牙密钥
在 Windows 上提取
首先,启动进入 Windows。
包含链接密钥的注册表项可能只能由 SYSTEM 账户 访问,该账户无法登录。因此,您将需要 Microsoft 官方 Windows Sysinternals 站点提供的 PsExec 工具,以便以 SYSTEM
身份运行 regedit.exe
。
下载 PsTools,并解压 PsExec64.exe
。
在 命令 shell 的管理员实例中,从解压后的 EXE 所在位置,启动注册表编辑器
.\PsExec64.exe -s -i regedit.exe
在注册表编辑器中,导航到以下注册表项
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys
在此注册表项中,每个蓝牙适配器都有一个子项,以 MAC 地址命名。如果存在多个子项,并且您不确定要使用哪个子项,请按照 本指南 查找所需蓝牙适配器的 MAC 地址。
在所需适配器的注册表项中,每个配对设备都有一个名称-值对,名称是其 MAC 地址。此外,您可能会看到一些以 MAC 地址命名的子项,每个子项都包含名称类似 LTK
或 IRK
的名称-值对。这些子项(如果有)用于蓝牙 5.1 设备。如果您尝试共享的设备具有子项,则它是蓝牙 5.1 设备。如果它没有子项,只有名称-值对,则它不是蓝牙 5.1 设备。
右键单击适配器的注册表项,并将其导出为 .reg 文件。这是一个文本文件,您可以从中复制密钥。如前所述,它包含非蓝牙 5.1 设备的名称-值对中的配对密钥,以及蓝牙 5.1 设备的每个设备子项中的配对密钥(和一些其他信息)。使此文件可用于您的 Linux 安装并重启进入 Linux。
如果您要共享的设备不是蓝牙 5.1 设备,请跳转到 #保存配置。如果它是蓝牙 5.1 设备,您需要在完成之前对配对密钥和相关信息进行一些修改。请参阅 #准备蓝牙 5.1 密钥 以了解如何操作。
在 Linux 上提取
启动进入 Arch。安装 chntpw。挂载您的 Windows 系统驱动器。
$ cd /path/to/windows/system/Windows/System32/config $ chntpw -e SYSTEM
在 chntpw
环境中,运行
> cd CurrentControlSet\Services\BTHPORT\Parameters\Keys
您可能会看到 ControlSet00X
而不是 CurrentControlSet
(使用 ls 检查)
> cd ControlSet00X\Services\BTHPORT\Parameters\Keys
然后获取您的蓝牙适配器的 MAC 地址并进入其文件夹
> ls > cd your-device's-mac-address
对您的配对设备执行相同的操作。如果这不是蓝牙 5.1 设备,您将只看到配对密钥
> ls
Node has 0 subkeys and 1 values size type value name [value if type DWORD] 16 REG_BINARY <123456789876>
如果是这样,通过 hex
获取您的设备密钥
> hex 123456789876
:00000 XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX (some other chars)
“XX”是配对密钥。记下哪些密钥映射到哪些 MAC 地址。
如果这是蓝牙 5.1 设备,那么您将看到与一个设备对应的多个密钥。
Node has 0 subkeys and 8 values size type value name [value if type DWORD] 16 3 REG_BINARY <LTK> 4 4 REG_DWORD <KeyLength> 16 [0x10] 8 b REG_QWORD <ERand> 4 4 REG_DWORD <EDIV> 37520 [0x9290] 16 3 REG_BINARY <IRK> 8 b REG_QWORD <Address> 4 4 REG_DWORD <AddressType> 1 [0x1] 4 4 REG_DWORD <AuthReq> 45 [0x2d]
请参阅 #准备蓝牙 5.1 密钥 以了解如何使用这些密钥,使用 hex value_name
获取请求的值。
最后,要将密钥导入到您的 Linux 安装中,请继续 #保存配置。
对于 macOS
启动进入 macOS
- 对于 macOS Monterey 或更新版本
- 打开“钥匙串访问”并搜索“Bluetooth”。
- 按日期排序。
- 如果您最近移除并重新连接了设备,那么您可以简单地按修改日期对密钥进行排序,并选择最新的密钥。它可能被称为 MobileBluetooth(对于较旧的蓝牙设备)或者只是一个 UUID(对于蓝牙 5.1+)。
- 双击该条目。检查“帐户”字段中的 MAC 地址是否与您的设备的 MAC 地址匹配。
- 单击“显示密码”复选框。您现在需要输入您的密码,两次。
- 复制密码字段中的文本,它实际上是一个 XML 文件 (
⌘+a
⌘+c
) - 将文本粘贴到您主目录中的
bt_keys.txt
中。
- 对于 High Sierra 或更新版本,在终端中运行以下命令
# defaults read /private/var/root/Library/Preferences/com.apple.bluetoothd.plist LinkKeys > ~/bt_keys.txt
- 对于 Sierra 或更旧版本,在终端中运行以下命令
# defaults read /private/var/root/Library/Preferences/blued.plist LinkKeys > ~/bt_keys.txt
~/.bt_keys.txt
文件现在包含已建立的蓝牙密钥。对于较旧版本的 macOS(High Sierra 及更旧版本),您必须在继续操作之前反转密钥。例如,98 54 2f aa bb cc dd ee ff gg hh ii jj kk ll mm
变为 MM LL KK JJ GG FF EE DD CC BB AA 2F 54 98
。
>>> key = "98 54 2f aa bb cc dd ee ff gg hh ii jj kk ll mm" >>> " ".join(reversed(key.strip().split()))
如果这是一个蓝牙 5.1 设备,那么将有多个密钥对应于一个设备。请参阅 #准备蓝牙 5.1 密钥 以了解如何使用这些密钥。
最后,要将密钥导入到您的 Linux 安装中,请重启进入 Linux 并继续 #保存配置。
准备蓝牙 5.1 密钥
如果您在按照 #对于 Windows 或 #对于 macOS 操作时观察到蓝牙 5.1 密钥的存在,您必须在将它们导入 Linux 之前对其值应用某些转换。创建请求的文件及其相应的内容,以便安装在 #保存配置 中。此过程将取决于设备,并且某些值必须进行操作;下面提供了用于执行此操作的代码实用程序。
设备 | 源密钥和转换(Windows) | 源密钥和转换(macOS) | 目标密钥文件 |
---|---|---|---|
|
|
? | IdentityResolvingKey.Key
|
|
? | SlaveLongTermKey.Key 和 PeripheralLongTermKey.Key | |
ERand 和 EDIV 应为 0 |
随机数 和 加密多样化器 应为 0 。 |
– | |
|
|
? | IdentityResolvingKey.Key
|
|
? | LocalSignatureKey.Key
| |
|
? | LongTermKey.Key
| |
|
? | LongTermKey.EncSize
| |
|
? | LongTermKey.EDiv
| |
|
? | LongTermKey.Rand
| |
|
|
? | RemoteSignatureKey.Key
|
|
|
|
IdentityResolvingKey.Key
|
|
|
LongTermKey.Key
| |
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
| |
其他设备 |
|
|
LongTermKey.Key
|
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
| |
Xbox 无线控制器 |
|
? | SlaveLongTermKey.Key
|
>>> "key_value".replace(" ", "")
- 此 Python 代码仅执行八位字节反转
>>> ERand=" 63 02 84 B8 5D 40 44 DF " >>> ERand=list(reversed(ERand.strip().split()))
- 此 Python 代码执行某些设备所需的额外十进制转换
>>> int("".join(ERand), 16) 16088054540146049635
- 此 Python 代码执行 base64 到十六进制的转换
binascii.hexlify(base64.decodebytes(b'...')).upper()
- 此 Python 代码执行完整的 macOS 加密多样化器转换
struct.unpack('<H', base64.decodebytes(b'...'))
- 此 Python 代码执行完整的 macOS 随机数转换
struct.unpack('<Q', base64.decodebytes(b'...'))
对于一般情况的示例
LTK
为48 4D AF CD 0F 92 22 88 0A 52 9A F4 76 DA 8B 94
时,LongTermKey.Key
为484DAFCD0F9222880A529AF476DA8B94
。ERand
为63 02 84 B8 5D 40 44 DF
时,Rand
为16088054540146049635
。EDIV
为37520
时,EDiv
为37520
。
保存配置
现在您已经有了密钥,请切换用户到 root,然后继续执行以下操作
# cd /var/lib/bluetooth/BT-Adapter-MAC-address
在这里您将找到每个配对蓝牙设备的文件夹。对于您要与 Arch 和双启动配对的每个设备,请执行以下操作
# cd device-MAC-address
如果您有配对密钥(即,这不是蓝牙 5.1 设备),则编辑 info
文件并更改 [LinkKey]
下的密钥。例如:
info
[LinkKey] Key=XXXXXXXXXXXXXXX
如果您有多个密钥,例如在蓝牙 5.1 中,请编辑 info
文件并将所有适用的密钥替换为记录的值。例如,对于 Xbox One S 无线控制器
info
[IdentityResolvingKey] Key=<IdentityResolvingKey.Key> [PeripheralLongTermKey] Key=<PeripheralLongTermKey.Key> [SlaveLongTermKey] Key=<SlaveLongTermKey.Key>
然后重启 bluetooth.service
和 pulseaudio
(使用 pulseaudio -k && pulseaudio --start
)。
您现在应该能够连接到您的设备了。
配置
默认适配器电源状态
从 bluez 5.65 开始,BlueZ 的默认行为是在启动服务或从挂起恢复时开启所有蓝牙适配器。[2]
如果您希望适配器不自动启用(例如,在您希望节省电池的便携式设备上),请在 /etc/bluetooth/main.conf
的 [Policy]
部分中设置 AutoEnable=false
/etc/bluetooth/main.conf
[Policy] AutoEnable=false
仍然可以通过运行 #配对 中描述的 power on
手动打开适配器。
启动时可发现
如果设备应始终可见且可直接连接
/etc/bluetooth/main.conf
[General] DiscoverableTimeout = 0
挂起唤醒
要允许蓝牙键盘、鼠标等从挂起状态唤醒系统。首先,检查 BIOS 设置并确保未禁用 USB 唤醒。在许多情况下,来自主板的蓝牙是 USB 设备。
为蓝牙适配器添加新的 udev 规则(USB 无线控制器基类,蓝牙编程接口协议)以启用从挂起状态唤醒
/etc/udev/rules.d/91-bluetooth-wakeup.rules
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", \ ATTR{bDeviceClass}=="e0", \ ATTR{bDeviceProtocol}=="01", \ ATTR{bDeviceSubClass}=="01", \ ATTR{power/wakeup}="enabled"
要在唤醒后自动重新配置您的蓝牙键盘,例如使其具有不同的键映射或按键重复率(有关详细信息,请参阅 Xorg/键盘配置#调整按键延迟和速率 和 xmodmap),创建一个可执行脚本
configure_keyboard.sh
#!/bin/sh export DISPLAY=:0 xset r rate 220 30 xmodmap /your/path/to/.Xmodmap
然后创建另一个如上的 udev 规则
/etc/udev/rules.d/92-keyboard-reconfiguration-wakeup.rules
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", \ ATTR{bDeviceClass}=="e0", \ ATTR{bDeviceProtocol}=="01", \ ATTR{bDeviceSubClass}=="01" \ RUN+="/your/path/to/configure_keyboard.sh"
启用实验性功能
Bluez 堆栈将新的、可能存在 bug 的功能放在 D-Bus 实验性和内核实验性选项之后。这些选项下包含的功能随时间变化,因为实验性功能被确定为稳定且不再需要该选项(例如:启用 D-Bus 实验性接口当前允许报告旧耳机的电池电量)。要启用这些功能,请取消注释配置中相应的行
/etc/bluetooth/main.conf
... # Enables D-Bus experimental interfaces # Possible values: true or false #Experimental = true # Enables kernel experimental features, alternatively a list of UUIDs # can be given. # Possible values: true,false,<UUID List> # Possible UUIDS: ... # Defaults to false. #KernelExperimental = true
或者,您可以编辑 bluetooth.service
以添加 --experimental
或 --kernel
标志,例如此 drop-in 文件
/etc/systemd/system/bluetooth.service.d/override.conf
[Service] ExecStart= ExecStart=/usr/lib/bluetooth/bluetoothd --experimental
无论哪种方式,您都必须然后重启 bluetooth.service
。
音频
您通常需要采取额外的步骤将音频服务器与蓝牙集成。这在以下部分中详细介绍。
有关蓝牙音频和蓝牙耳机的更多信息,请参阅 蓝牙耳机 页面。
PulseAudio
为了能够使用蓝牙耳机或音箱等音频设备,您需要安装额外的 pulseaudio-bluetooth 软件包。请务必重启 pulseaudio 以使安装生效:pulseaudio -k
。使用默认的 PulseAudio 安装(特别是,使用带有打包的 default.pa
的用户实例),您应该能够立即将音频从蓝牙设备流式传输到您的扬声器。[3]
如果您有系统范围的 PulseAudio 设置,请确保运行守护进程的用户(通常是 pulse
)在 lp
组中,并在您的 PulseAudio 配置中加载蓝牙模块
/etc/pulse/system.pa
... load-module module-bluetooth-policy load-module module-bluetooth-discover ...
可选地,如果您想将所有音频自动切换到蓝牙设备,请添加 load-module module-switch-on-connect
。
PipeWire
截至 v0.3.19 版本,PipeWire 默认启用其蓝牙支持。
ALSA
首先,确保您的蓝牙音频设备已正确配对并连接到系统。
然后,安装 bluez-alsa-gitAUR,启动(并启用)bluealsa
服务,并将您的用户添加到 audio
组。
运行以下命令以检查一切是否按预期工作(替换下面的 XX:XX:XX:XX:XX:XX
和 FILE.wav
)
$ aplay -D bluealsa:SRV=org.bluealsa,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp FILE.wav
最后,将以下行添加到您的 ~/.asoundrc
~/.asoundrc
defaults.bluealsa { service "org.bluealsa" device "XX:XX:XX:XX:XX:XX" profile "a2dp" }
现在您可以使用 bluealsa
设备来连接您的蓝牙音频设备。音量管理通常通过带有 -D bluealsa
选项的 alsamixer
进行。
蓝牙串口
要使蓝牙串口通信在蓝牙转串口模块(HC-05、HC-06)上工作,请执行以下步骤
使用 上面 描述的方法,使用 bluetoothctl
配对您的蓝牙设备。
安装 bluez-deprecated-tools,因为它提供了一些较新工具中缺少的功能。
将配对的设备 MAC 地址绑定到 tty 终端
# rfcomm bind rfcomm0 MAC_address_of_Bluetooth_device
现在您可以打开 /dev/rfcomm0
进行串口通信
$ picocom /dev/rfcomm0 -b 115200
故障排除
通用故障排除
调试
为了进行调试,首先停止 bluetooth.service
。
然后使用 -d
参数启动它
# /usr/lib/bluetooth/bluetoothd -n -d
另一种选择是通过 btmon
工具。
已弃用的 BlueZ 工具
八个 BlueZ 工具 已被弃用 并从 bluez-utils 中移除,尽管并非所有工具都被较新的工具取代。bluez-deprecated-tools 软件包现在提供了这些已弃用的工具。
已弃用的工具 | 最可能的替代品 |
---|---|
gatttool | btgatt-client, D-Bus Gatt API[死链接 2023-10-29 ⓘ] |
hciattach | btattach |
hciconfig | btmgmt(和 bluetoothctl?) |
hcidump | btmon(和 btsnoop) |
hcitool | 缺失,D-Bus Device API[死链接 2023-10-29 ⓘ] 可用 |
rfcomm | 缺失,使用 D-Bus Profile1 API[死链接 2023-10-29 ⓘ] 实现? |
ciptool | |
sdptool | 缺失,功能似乎分散在不同的 D-Bus 对象中:Profile[死链接 2023-10-29 ⓘ], Advertising[死链接 2023-10-29 ⓘ], 以及 device[死链接 2023-10-29 ⓘ] 和 adapter[死链接 2023-10-29 ⓘ] 中的 UUID 数组。 |
服务问题
systemd:条件检查导致蓝牙服务被跳过
bluetooth.service
只需要目录 /sys/class/bluetooth
存在,该目录应由内核模块 bluetooth
创建,而内核模块 bluetooth
仅在 systemd-udev
实际找到可用的蓝牙硬件设备时才会被自动加载。
如果您的 /sys/class/bluetooth
不存在,请检查您的内核蓝牙模块是否已通过 lsmod
加载。如果未加载,并且您认为您有蓝牙设备,您可以尝试通过加载蓝牙模块和重启 bluetooth.service
来手动启动它们。
在加载 bluetooth
模块时,您还应该加载相应的内核蓝牙驱动程序,最有可能的是 btusb
,但也可能是 btrtl,btintel,btbcm,bnep,btusb
等。
检查 bluetooth.service
的 单元状态 以查看它是否已启动。
另请参阅 Debian 错误报告日志 - #853207。
如果 bluetooth.service
成功启动,您仍然有可能无法正常使用蓝牙(例如,当您 scan on
时,bluetoothctl
会显示类似 org.Bluez.Error.NotReady
的内容)。如果发生这种情况,请尝试重启您的计算机,并再次检查:目录 /sys/class/bluetooth
是否存在;lsmod
是否包含正确的蓝牙模块;日志中的日志消息;等等。systemd-udev
应该会自动检测到您的蓝牙硬件,而无需再次手动更改。
蓝牙立即唤醒挂起到空闲设备
在能够 挂起到空闲/S2idle/S0ix/现代待机 的系统上,蓝牙控制器将在睡眠期间保持启用状态。如果连接了任何蓝牙设备,这通常会导致系统在 进入睡眠后立即唤醒。
为了防止这种情况,您可以在进入睡眠状态之前完全禁用蓝牙 - 安装 bluez-utils 并创建此文件
/etc/systemd/system/bluetooth-disable-before-sleep.service
[Unit] Description=Disable Bluetooth before going to sleep Before=sleep.target Before=suspend.target Before=hybrid-sleep.target Before=suspend-then-hibernate.target StopWhenUnneeded=yes [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/bin/bluetoothctl power off ExecStop=/usr/bin/bluetoothctl power on [Install] WantedBy=sleep.target WantedBy=suspend.target WantedBy=hybrid-sleep.target WantedBy=suspend-then-hibernate.target
启用此服务并检查蓝牙设备是否在进入睡眠状态时断开连接,以及蓝牙是否在系统唤醒后重新启动。
如果正在使用此解决方法,使用蓝牙鼠标/键盘唤醒系统 将不起作用。
在无头/服务器系统上注销后蓝牙关闭
这可能有多种原因
- PulseAudio 和 PipeWire 默认作为用户服务运行,一旦最后一个会话结束,这些服务就会终止。为用户启用 持久 以解决此问题。
- 此外,当使用 WirePlumber 和 PipeWire 运行(通常是这种情况)时,WirePlumber 运行一个“logind-monitor”,它在登录时启用蓝牙,并在注销时禁用蓝牙。有关修复方法,请参阅 WirePlumber#在注销后保持蓝牙运行 / 无头蓝牙。
适配器问题
hcitool scan:未找到设备
- 在某些笔记本电脑上(例如 Dell Studio 15、Lenovo Thinkpad X1),您必须将蓝牙模式从 HID 切换到 HCI。安装 bluez-hid2hci 软件包,然后 udev 应该会自动执行此操作。或者,您可以运行此命令手动切换到 HCI
# /usr/lib/udev/hid2hci
- 如果设备没有显示,并且您的机器上安装了 Windows 操作系统,请尝试启动它并从 Windows 启用蓝牙适配器。
- 有时,这个简单的命令也有帮助
# bluetoothctl power on
bluetoothctl:没有可用的默认控制器
某些主板蓝牙控制器存在错误。要查看这是否可能是问题所在,请运行 journalctl | grep hci
。如果出现类似“command tx timeout”或“Reading Intel version command failed”的条目,请关闭电脑并物理拔下电源线几秒钟。这会强制控制器重新加载固件(而标准的重启不会)。请参阅 此处 的错误报告。
确保设备没有被 rfkill 阻止。
如果使用 USBGuard,请确保它没有阻止设备。请参阅 USBGuard#允许蓝牙控制器。
某些英特尔网卡(例如 8260)也可能发生无法被蓝牙服务正确识别的情况。在某些情况下,使用已弃用的 bluez-deprecated-tools 代替 bluez-utils 据报道已修复此问题。
这也可能是由省电措施引起的,在这种情况下,添加 内核参数 btusb.enable_autosuspend=n
是一种可能的解决方案。另请参阅 Red Hat Bugzilla – Bug 1573562。
有时卸载并加载不带选项的 btusb
有助于使控制器恢复正常
# modprobe -r btusb # modprobe btusb
当加密狗是 CSR 克隆 时,也可能发生这种情况。
rfkill unblock:无法取消阻止
如果您的设备仍然被软阻止,并且您运行 ConnMan,请尝试此操作
$ connmanctl enable bluetooth
蓝牙 USB 加密狗
如果您正在使用 USB 加密狗,您应该检查您的蓝牙加密狗是否被识别。您可以通过在插入 USB 加密狗时以 root 身份运行 journalctl -f
(或检查 /var/log/messages.log
)来做到这一点。它应该看起来像下面这样(注意 hci)
Feb 20 15:00:24 hostname kernel: [ 2661.349823] usb 4-1: new full-speed USB device number 3 using uhci_hcd Feb 20 15:00:24 hostname bluetoothd[4568]: HCI dev 0 registered Feb 20 15:00:24 hostname bluetoothd[4568]: Listening for HCI events on hci0 Feb 20 15:00:25 hostname bluetoothd[4568]: HCI dev 0 up Feb 20 15:00:25 hostname bluetoothd[4568]: Adapter /org/bluez/4568/hci0 has been enabled
如果您只获得前两行,您可能会看到它找到了设备,但您需要启动它。示例
# btmgmt
[mgmt]# info Index list with 1 item hci0: Primary controller addr 00:1A:7D:DA:71:10 version 6 manufacturer 10 class 0x000000 supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr current settings: connectable discoverable bondable ssp br/edr le secure-conn name Mozart short name [mgmt]# select hci0 Selected index 0 [hci0]# power up hci0 Set Powered complete, settings: powered connectable discoverable bondable ssp br/edr le secure-conn [hci0]# info hci0: Primary controller addr 00:1A:7D:DA:71:10 version 6 manufacturer 10 class 0x1c0104 supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr current settings: powered connectable discoverable bondable ssp br/edr le secure-conn
或
# bluetoothctl
[bluetooth]# show Controller 00:1A:7D:DA:71:10 (public) Name: Mozart Alias: Mozart Class: 0x0000095c Powered: no Discoverable: yes Pairable: yes [bluetooth]# power on [CHG] Controller 00:1A:7D:DA:71:10 Class: 0x001c0104 Changing power on succeeded [CHG] Controller 00:1A:7D:DA:71:10 Powered: yes [bluetooth]# show Controller 00:1A:7D:DA:71:10 (public) Name: Mozart Alias: Mozart Class: 0x001c0104 Powered: yes Discoverable: yes Pairable: yes
要验证设备是否被检测到,您可以使用 btmgmt
,它是 bluez-utils
的一部分。您可以通过发出以下命令来获取可用设备及其标识符和 MAC 地址的列表
$ btmgmt info
Index list with 1 item hci0: Primary controller addr 00:1A:7D:DA:71:10 version 6 manufacturer 10 class 0x1c0104 supported settings: powered connectable fast-connectable discoverable bondable link-security ssp br/edr hs le advertising secure-conn debug-keys privacy static-addr current settings: powered connectable discoverable bondable ssp br/edr le secure-conn
可以根据 官方规范 中的表格,检查蓝牙版本与 HCI 版本的映射关系。例如,在之前的输出中,HCI 版本 6 是蓝牙版本 4.0。
有关设备的更多详细信息,可以使用已弃用的 hciconfig
。(bluez-deprecated-tools)
$ hciconfig -a hci0
hci0: Type: USB BD Address: 00:1B:DC:0F:DB:40 ACL MTU: 310:10 SCO MTU: 64:8 UP RUNNING PSCAN ISCAN RX bytes:1226 acl:0 sco:0 events:27 errors:0 TX bytes:351 acl:0 sco:0 commands:26 errors:0 Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH HOLD SNIFF PARK Link mode: SLAVE ACCEPT Name: 'BlueZ (0)' Class: 0x000100 Service Classes: Unspecified Device Class: Computer, Uncategorized HCI Ver: 2.0 (0x3) HCI Rev: 0xc5c LMP Ver: 2.0 (0x3) LMP Subver: 0xc5c Manufacturer: Cambridge Silicon Radio (10)
音频设备在距离加密狗较短距离处开始跳音
如果其他设备共享同一个 USB 主机,它们可能会 中断与音频设备的通信。确保它是连接到其总线的唯一设备。例如
$ lsusb
Bus 002 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode) Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 001 Device 004: ID 048d:1345 Integrated Technology Express, Inc. Multi Cardreader Bus 001 Device 003: ID 0424:a700 Standard Microsystems Corp. 2 Port Hub Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
CSR 加密狗 0a12:0001
设备 ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
存在回归错误,目前仅在内核版本 5.17 和 < 6.0 中工作。有关更多信息,请参阅 内核错误 60824。
罗技蓝牙 USB 加密狗
有些罗技加密狗(例如罗技 MX5000)可以在两种模式下工作:嵌入式和 HCI。在嵌入式模式下,加密狗模拟 USB 设备,因此您的电脑会认为您正在使用普通的 USB 鼠标/键盘。
如果您按住 USB BT 迷你接收器上的小红按钮,它将启用另一种模式。按住 BT 加密狗上的红色按钮并将其插入电脑,在按住按钮 3-5 秒后,蓝牙图标将出现在系统托盘中。讨论
或者,您可以安装 bluez-hid2hci 软件包。当您连接罗技加密狗时,它将自动切换。
富士康 / 鸿海 / 光宝 Broadcom 设备
其中一些设备需要在启动时将固件刷入设备。
在 AUR 上搜索 broadcom 时,可以找到一些固件,一个值得注意的软件包是 broadcom-bt-firmwareAUR,它为 多种网卡 提供了文件。
或者,固件可以从 Microsoft Windows .hex 文件转换为 .hcd 文件,使用 hex2hcd (它随 bluez-utils 一起安装)。
为了获得正确的 .hex 文件,请尝试搜索使用 lsusb 获取的设备 vendor:product 代码,例如
Bus 002 Device 004: ID 04ca:2006 Lite-On Technology Corp. Broadcom BCM43142A0 Bluetooth Device
或
Bus 004 Device 004: Id 0489:e031 Foxconn / Hon Hai
或者,启动进入 Windows(虚拟机安装即可)并从设备管理器实用程序中获取固件名称。如果您想知道设备的型号,但在 lsusb 中看不到,您可能会在 lsusb -v 中看到 iProduct
。
.hex 文件可以从下载的 Windows 驱动程序中提取,而无需运行 Windows。下载正确的驱动程序,例如 Bluetooth Widcomm[死链 2023-09-16 ⓘ]。根据格式,提取文件可能需要 unrar 或 cabextract。要找出众多 .hex 文件中哪个是适合您的文件,请查看 Win32/bcbtums-win7x86-brcm.inf
文件并搜索 [RAMUSBE031.CopyList]
,其中 E031
应替换为您的设备的产品代码(lsusb 中的第二个十六进制数字),并使用大写字母。在下面您应该看到正确的 .hex 文件名。
获得 .hcd 文件后,将其复制到 /lib/firmware/brcm/BCM.hcd
- 此文件名由 dmesg 建议,并且在您的情况下可能会更改,因此请检查您的 dmesg 输出以进行验证。然后重新加载 btusb 模块
# rmmod btusb # modprobe btusb
设备现在应该可用了。请参阅 BBS#162688 以获取有关使这些更改持久化的信息。
英特尔组合 Wi-Fi 和蓝牙卡
请参阅 无线网络配置#蓝牙共存。
在 Windows 双启动系统上使用联发科 MT7921 或 MT7961
在双启动系统中,如果 Windows 和 Linux 的蓝牙固件版本不同,则重启到 Windows 后蓝牙适配器将无法工作。
防止这种情况的最佳方法是为每个操作系统更新蓝牙驱动程序(尤其是固件)到最新版本。
如果您找不到 Windows 的最新版本驱动程序(或固件),您可以从 Arch Linux 复制最新的固件文件 /usr/lib/firmware/mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin.xz
并解压到 Windows(例如 C:\WINDOWS\system32\DRIVERS\
,您可以在 Windows 的设备管理器中找到固件文件路径)。
适配器在挂起/恢复后消失
首先,找到适配器的供应商 ID 和产品 ID。例如
$ lsusb -tv
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M ID 1d6b:0002 Linux Foundation 2.0 root hub ... |__ Port 3: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M ID 8087:0025 Intel Corp. |__ Port 3: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M ID 8087:0025 Intel Corp. ...
在这种情况下,供应商 ID 是 8087,产品 ID 是 0025。
然后,使用 usb_modeswitch 重置适配器
# usb_modeswitch -R -v vendor_ID -p product_ID
配对和连接问题
计算机不可见
如果您的手机无法发现您的计算机,请启用可发现模式
# bluetoothctl discoverable on
验证可发现模式是否已开启
# bluetoothctl show
Powered: yes Discoverable: yes Pairable: yes
/etc/bluetooth/main.conf
中的 DiscoverableTimeout
和 PairableTimeout
。如果计算机仍然没有显示,请尝试按如下方式更改 /etc/bluetooth/main.conf
中的设备类别
# Default device class. Only the major and minor device class bits are # considered. #Class = 0x000100 # Computer Type (from default config) Class = 0x100100 # (Object-Transfer Service & Computer Type)
main.conf
中的 Class
会在设备初始化后被覆盖,因此请使用 hciconfig hci0 class 100100
直接设置类别。一位用户报告说,这是使其计算机对手机可见的唯一解决方案。LG 电视(和一些其他电视)可以从其音频设备中发现,因此使用 000414
(条形音箱类别)将使此类设备出现。
请参阅 https://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html 以生成蓝牙设备/服务类别。
设备连接,然后在几 moments 后断开连接
如果您在日志中看到如下消息,并且您的设备无法连接或在连接后不久断开连接
bluetoothd: Unable to get connect data for Headset Voice gateway: getpeername: Transport endpoint is not connected (107) bluetoothd: connect error: Connection refused (111)
这可能是因为您已经使用同一蓝牙适配器(例如,双启动)将设备与另一个操作系统配对。某些设备无法处理与同一 MAC 地址(即蓝牙适配器)关联的多个配对。请按照 #双启动配对 上的说明解决此问题。
设备未在扫描中显示
某些使用蓝牙低功耗的设备在使用 bluetoothctl 扫描时不会出现,例如 Logitech MX Master。您可以使用 transport le
进行扫描。
# bluetoothctl
[bluetooth]# menu scan [bluetooth]# transport le [bluetooth]# back [bluetooth]# scan on [bluetooth]# devices ... Device XX:XX:XX:XX:XX:XX DA V2 X <---- low energy device here
连接它们的另一种方法是安装 bluez-deprecated-tools,然后 启动 bluetooth.service
并执行
# bluetoothctl
[NEW] Controller (MAC) myhostname [default] [bluetooth]# power on [CHG] Controller (MAC) Class: 0x0c010c Changing power on succeeded [CHG] Controller (MAC) Powered: yes [bluetooth]# scan on Discovery started [CHG] Controller (MAC) Discovering: yes
在另一个终端中
# hcitool lescan
等待直到您的设备出现,然后 Ctrl+c
hcitool。bluetoothctl 现在应该看到您的设备并正常配对。
使用英特尔公司 AX200 蓝牙无法发现任何 BLE 设备
似乎 BLE 被动扫描在此设备上已损坏。有关更多详细信息,请参阅 上游错误报告。
睡眠后无法重新连接
您可能会注意到,在设备进入睡眠状态后,或者在计算机从挂起状态唤醒后,您无法自动重新连接到设备。
例如,您会在日志中注意到以下错误
bluetoothd[487]: Authentication attempt without agent bluetoothd[487]: Access denied: org.bluez.Error.Rejected
这可能是因为该设备未标记为受信任。请参阅 #配对。
设备特定问题
蓝牙鼠标滞后 / 断开连接 / 无响应
请参阅 蓝牙鼠标#故障排除。
如果正在使用 pipewire(而不是 pulseaudio-bluetooth),但 pipewire 的实例未运行,则蓝牙音频设备将无法连接。启动 pipewire.service
用户单元 或播放一些音频以启动 pipewire 守护程序,然后尝试再次连接音频设备。
耳机和鼠标之间的干扰
如果您在使用蓝牙鼠标和键盘时同时遇到音频卡顿,您可以尝试以下操作,如 #23 https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/424215 中所引用
# hciconfig hci0 lm ACCEPT,MASTER # hciconfig hci0 lp HOLD,SNIFF,PARK
TP-LINK UB400 和 Xbox 控制器持续连接/断开连接
使用以下设置
/etc/bluetooth/main.conf
... [General] JustWorksRepairing = always FastConnectable = true Class = 0x000100 ... [GATT] ReconnectIntervals=1,1,2,3,5,8,13,21,34,55 AutoEnable=true ...
然后 重启 bluetooth.service
。
您可以在 xpadneo 上的相关讨论 中看到相关信息,但不需要 xpadneo 驱动程序。
文件传输问题
gnome-bluetooth
如果您在尝试在 bluetooth-properties 中启用接收文件时看到此消息
Bluetooth OBEX start failed: Invalid path Bluetooth FTP start failed: Invalid path
然后确保 XDG 用户目录 存在。
由于符号链接导致无法接收传输的文件
如果传入的文件传输在其他功能正常的蓝牙连接上失败,则问题可能是由于文件传输路径中的符号链接。日志中会出现如下信息
Jun 18 11:18:13 ember obexd[3338969]: open(/home/me/.cache/obexd/MOC740): Operation not permitted (1)
如果错误消息中显示的路径包含符号链接,则 obexd 默认情况下 将不接受它。可以使用 obex.service
用户服务 的 drop-in 文件 在初始化时覆盖此行为
~/.config/systemd/user/obex.service.d/10-symlink.conf
[Service] ExecStart= ExecStart=/usr/lib/bluetooth/obexd --symlinks
然后 重新加载 调用用户的 systemd 管理器配置并 重启 obex.service
用户单元。