蓝牙
蓝牙 是一种用于蜂窝电话、计算机和其他电子设备短距离无线互连的标准。在 Linux 中,蓝牙协议栈的规范实现是 BlueZ。
安装
- 安装 提供蓝牙协议栈的 bluez 软件包。
- 安装 提供 bluetoothctl 工具的 bluez-utils 软件包。 此外,安装 bluez-deprecated-tools 以拥有 已弃用的 BlueZ 工具。
- 通用的蓝牙驱动程序是
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,可以通过在“活动”概览中键入“蓝牙”或使用
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 Bluetooth),则可能不需要这样做。
确切的步骤取决于所涉及的设备及其输入功能。 以下是使用 bluetoothctl 配对设备的一般概述。
启动 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 安装,然后重启进入它。
如果您要共享的设备不是蓝牙 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 或更高版本
- 打开“钥匙串访问”并搜索“蓝牙”。
- 按日期排序。
- 如果您最近删除并重新连接了设备,那么您可以简单地按修改日期对密钥进行排序,然后选择最新的密钥。 它可能称为 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 堆栈将新的、可能存在错误的特性保留在 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
标志,例如此放置文件
/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
PipeWire 从 v0.3.19 开始默认启用其蓝牙支持。
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
创建,只有当 systemd-udev
实际找到可用的蓝牙硬件设备时,才会自动加载该模块。
如果您的 /sys/class/bluetooth
不存在,请检查您的内核蓝牙模块是否已通过 lsmod
加载。如果没有,并且您认为您有蓝牙设备,您可以尝试通过加载蓝牙模块和重启 bluetooth.service
来手动启动它们。
当加载 bluetooth
模块时,您还应该加载相应的内核蓝牙驱动程序,最可能是 btusb
,但也可能是 btrtl,btintel,btbcm,bnep,btusb
等。
检查 bluetooth.service
的单元状态以查看它是否已启动。
另请参阅 Debian Bug report logs - #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 中有效。有关更多信息,请参阅 Kernel Bug 60824。
罗技蓝牙 USB 适配器
有罗技适配器(例如 Logitech MX5000)可以在两种模式下工作:嵌入式和 HCI。在嵌入式模式下,适配器模拟 USB 设备,因此您的 PC 似乎您正在使用普通的 USB 鼠标/键盘。
如果您按住 USB BT 迷你接收器上的小红按钮,它将启用另一种模式。按住 BT 适配器上的红色按钮并将其插入计算机,并在按住按钮 3-5 秒后,蓝牙图标将出现在系统托盘中。讨论
或者,您可以安装 bluez-hid2hci 软件包。当您连接罗技适配器时,它将自动切换。
富士康 / 鸿海 / 光宝 Broadcom 设备
其中一些设备需要在启动时将固件刷入设备。
在 AUR 上搜索 broadcom 时,可以找到一些固件,一个值得注意的软件包是 broadcom-bt-firmwareAUR,它为 多个网卡 提供了文件。
或者,可以使用 hex2hcd(与 bluez-utils 一起安装)将固件从 Microsoft Windows .hex 文件转换为 .hcd。
为了获得正确的 .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
。
可以从下载的 Windows 驱动程序中提取 .hex 文件,而无需运行 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 和蓝牙组合网卡
请参阅 Wireless network configuration#蓝牙共存。
在与 Windows 双启动的 Mediatek 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。例如
$ 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 以生成蓝牙设备/服务类别。
设备连接后,几秒钟后断开连接
如果您在日志中看到如下消息,并且您的设备无法连接或在连接后不久断开连接
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 现在应该可以看到您的设备并正常配对。
无法使用 Intel Corp. AX200 蓝牙发现 BLE 设备
似乎此设备上的 BLE 被动扫描已损坏。有关更多详细信息,请参阅上游错误报告。
睡眠后无法重新连接
您可能会注意到,在设备进入睡眠状态后,或者在计算机从挂起状态唤醒后,您无法自动重新连接到设备。
例如,您会在日志中注意到以下错误
bluetoothd[487]: Authentication attempt without agent bluetoothd[487]: Access denied: org.bluez.Error.Rejected
这可能是因为该设备未标记为受信任。请参阅#配对。
设备特定问题
蓝牙鼠标延迟 / 断开连接 / 无响应
请参阅 Bluetooth mouse#故障排除。
如果正在使用 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
用户单元。