蓝牙
蓝牙(Bluetooth)是一个短距离无线通信标准,用于在手机、计算机和其他电子设备之间通信。在 Linux 中,权威的蓝牙协议栈实现是 BlueZ。
安装[编辑 | 编辑源代码]
- 安装 bluez包,这个软件包提供蓝牙协议栈。
- 安装 bluez-utils包,这个软件包提供
bluetoothctl
实用程序。另外,也可以安装 bluez-deprecated-tools包 来获得#弃用的 BlueZ 工具。 btusb
内核模块是通用蓝牙驱动。检查模块是否已加载。如果还没有,先加载模块。- 启动/启用
bluetooth.service
。
- 蓝牙守护程序默认只会向属于
lp
组的用户暴露 bnep0 设备。如果要连接到蓝牙设备的话,需先将用户添加到这个组。可以在/usr/share/dbus-1/system.d/bluetooth.conf
中修改需要加入的组。 - 一些蓝牙适配器和无线网卡绑定(例如 Intel Centrino)。这些蓝牙适配器需要先启用无线网卡(在笔记本上通常通过键盘快捷键)才能被内核识别。
- 一些蓝牙适配器(例如 Broadcom)和网络适配器冲突。因此,需要确保在网络服务启动之前连接蓝牙。
- 一些工具(例如 hcitool 和 hciconfig)已被上游弃用,并且不再包含在 bluez-utils包 中。这些工具将不会被更新,因此建议更新脚本,避免使用它们。如果还是想用,安装 bluez-deprecated-tools包。参见 FS#53110 和 Bluez 邮件列表。
- 从此 commit 开始, bluez-obex包 和 bluez-mesh包 已经从 bluez包 中独立出来,因此如果要通过蓝牙传输文件,必须安装 bluez-obex包。
前端[编辑 | 编辑源代码]
控制台[编辑 | 编辑源代码]
- bluetoothctl — 在 shell 中配对设备是最简单可靠的方法之一。
- bluetuith — 为终端界面提供蓝牙管理器,可以方便的配对和管理设备,具有 OBEX 文件传输和鼠标支持。
echo -e "command1\ncommand2\n" | bluetoothctl
或 bluetoothctl -- command
。图形界面[编辑 | 编辑源代码]
以下软件包提供图形界面来自定义蓝牙。
- GNOME Bluetooth — GNOME 的蓝牙工具。
- gnome-bluetooth-3.0包 提供后端(gnome-bluetooth包 已过时)
- gnome-shell包 提供状态托盘
- gnome-control-center包 可通过图形界面配置蓝牙。可以在活动预览输入“蓝牙”或者运行
gnome-control-center bluetooth
进行配置。 - 你还可以直接运行
bluetooth-sendto
命令来把文件发送到远程设备。 - nautilus-bluetoothAUR 在 Nautilus 右键菜单添加“通过蓝牙发送”
- 打开蓝牙设置面板来接收文件;只有在蓝牙设置面板打开时才能接收文件。
- 要在 Thunar 的“发送到”菜单中添加蓝牙选项,请查看这里的指导。(使用
bluetooth-sendto %F
命令)。
- Bluedevil — KDE 的蓝牙工具。如果 Dolphin 和系统托盘里没有蓝牙图标,就在系统托盘选项里启用,或者添加一个挂件。点击图标或在 KDE 系统设置里都可以配置蓝牙。
- Blueberry — Linux Mint 的独立版 GNOME Bluetooth,可在所有桌面环境工作。Blueberry 不支持通过 Obex Object 推送来接收文件。
- Blueman — 全功能蓝牙管理器。
- ObexFTP — 用来和启动了 OBEX 的设备传输文件的工具。
配对[编辑 | 编辑源代码]
这一小节介绍直接用 bluetoothctl 配置 bluez5 的方法,如果你已经有前端工具(比如 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 键补全 MAC 地址)。 - 如果配对设备不需要 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 等项目。
配置[编辑 | 编辑源代码]
首先,在 Arch Linux 中配对设备。然后重新启动到另一个操作系统,再次配对设备。接下来需要提取配对密钥,但首先要关闭蓝牙设备以防止其尝试重新连接。
对于 Windows[编辑 | 编辑源代码]
你可以选择进入 Windows 提取密钥,或是直接在 Linux 下进入 Windows 的系统分区,用 chntpw
工具提取密钥。
在 Windows 上提取密钥[编辑 | 编辑源代码]
首先进入 Windows。
存储配对密钥的注册表项只有 SYSTEM 用户能访问。但是,无法以 SYSTEM 用户的身份登录系统,要以 SYSTEM
的身份运行 regedit.exe
,必须借助微软的 Sysinternal 网站提供的 PsExec 工具。
下载 PsTools,然后解压出 PsExec64.exe
。
在解压出 EXE 的位置,以管理员身份打开命令提示符,启动注册表编辑器:
.\PsExec64.exe -s -i regedit.exe
在regedit中找到下面这一注册表项
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys
在此项中存储着每个蓝牙适配器的注册表项,按 MAC 地址列出。如果存在多个项目,可以按照这篇文章找到目标蓝牙适配器对应的 MAC 地址。
在目标适配器的表项中,每个已配对设备(也按照 MAC 地址列出)又各自对应一个二进制值。
对每个准备跨系统使用的设备,右键其整个注册表项,然后导出为 .reg 文件,之后可以从这个文件中复制密钥。
在此文件中,如果只有一个单独的二进制密钥,说明这个设备不是蓝牙 5.1 设备,只需要一个密钥。如果这个设备有多个密钥(比如 LTK
或 IRK
),那么这是一个蓝牙 5.1 设备,配置方法参见#准备蓝牙 5.1 密钥。
最后,重启进入 Linux,然后跳到#完成配置步骤
在 Linux 上提取密钥[编辑 | 编辑源代码]
进入 Arch Linux,安装 chntpw包,然后挂载 Windows 系统盘。
$ cd /path/to/windows/system/Windows/System32/config $ chntpw -e SYSTEM
在 chntpw
环境中,运行 ls
。你可能会看到 CurrentControlSet 或者 ControlSet00X,X 是任意数字。根据看到的名称,执行
> cd CurrentControlSet\Services\BTHPORT\Parameters\Keys
或者
> cd ControlSet00X\Services\BTHPORT\Parameters\Keys
接下来查看电脑蓝牙适配器的 MAC 地址,进入其对应的文件夹:
> ls > cd your-device's-mac-address
同样,再键入需要在双系统下使用的设备的 MAC 地址,进入其文件夹,如果不是蓝牙 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地址和你的设备是否一致。
- 勾选“显示密码”复选框,然后重复输入两次你的密码。
- 复制密码显示区域中的文本,它实际上是个 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}" >>> Key=list(reversed(ERand.strip().split()))
如果这是一个蓝牙 5.1 设备,将会有多个密钥与之对应。参考#准备蓝牙 5.1 密钥使用这些密钥。
最后,将 bt_keys.txt
文件复制到可由 Arch Linux 读取的驱动器。然后重新启动到 Arch Linux,跳到#完成配置小节继续。
准备蓝牙5.1密钥[编辑 | 编辑源代码]
若在#对于 Windows或#对于 macOS小节中发现蓝牙5.1密钥,则需在导入Linux系统前对它们的值进行一些转换。在执行#完成配置步骤前,需创建好所需的文件,并填入恰当的内容。本步骤因设备而异,参照下表。一部分值的需要进行特殊操作,相关的实用程序也一并提供在下。
设备 | 原始密钥与所需的转换 (Windows) | 原始密钥与所需的转换 (macOS) | 目标密钥文件 |
---|---|---|---|
Logitech MX Master 3 |
|
? | IdentityResolvingKey.Key
|
|
? | SlaveLongTermKey.Key 与 PeripheralLongTermKey.Key
| |
ERand 和 EDIV 应为 0
|
Random Number 与 Encrypted Diversifier 应为 0 .
|
– | |
ThinkPad TrackPoint Keyboard II, Pebble M350 mouse, Logitech G604 Lightspeed mouse |
|
|
IdentityResolvingKey.Key
|
|
|
LongTermKey.Key
| |
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
| |
Logitech M585/M590 |
|
IdentityResolvingKey.Key
| |
|
LongTermKey.Key
| ||
|
LongTermKey.Rand
| ||
|
LongTermKey.EDiv
| ||
其他设备 |
|
|
LongTermKey.Key
|
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
|
>>> "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 Encrypted Diversifier 的转换:
struct.unpack('<H', base64.decodebytes(b'...'))
- 这段Python代码完整完成 macOS Random Number 的转换:
struct.unpack('<H', 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的多个密钥,那么则应将所有的密钥文件复制到对应的MAC地址目录。
然后重新启动 bluetooth.service
和 pulseaudio
(使用 pulseaudio -k && pulseaudio --start
)。
现在应该可以连接到你的设备了。
配置[编辑 | 编辑源代码]
默认电源状态[编辑 | 编辑源代码]
截至 bluez包 5.65, 它的默认行为是在启动服务或从挂起恢复时打开所有蓝牙适配器的电源[2]
如果希望蓝牙在重启后不自动启动(比如要在移动设备中节省电量)。需要将 AutoEnable=false
添加在 /etc/bluetooth/main.conf
底部的 [Policy]
下面:
/etc/bluetooth/main.conf
[Policy] AutoEnable=false
禁用后可以用 power on
命令开启。
启动后自动可被发现[编辑 | 编辑源代码]
如果设备应该总是可见或者可以直接连接:
/etc/bluetooth/main.conf
[General] DiscoverableTimeout = 0
从挂起中唤醒[编辑 | 编辑源代码]
允许蓝牙鼠标或者蓝牙键盘将系统从挂起中唤醒。首先,检查bios设置确认从USB中唤醒功能没有被禁止。许多情况下,蓝牙在主板上被看作是USB设备。
获得蓝牙适配器的厂商代码和设备ID。
$ lsusb | grep bluetooth -i
Bus 001 Device 002: ID 8087:0039 Intel Corp. AX200 Bluetooth
针对(上面适配器的)厂商代码和设备ID增加新的udev规则来允许从挂起中唤醒。
/etc/udev/rules.d/91-keyboard-mouse-wakeup.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0039" RUN+="/bin/sh -c 'echo enabled > /sys$env{DEVPATH}/../power/wakeup;'"
如果系统唤醒后,要自动重新配置蓝牙键盘,例如,设置不同的键盘布局或者按键重复速度(相关细节,查看Xorg/Keyboard configuration#Adjusting typematic delay and rate 和 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
SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0039" RUN+="/your/path/to/configure_keyboard.sh"
启用实验性功能[编辑 | 编辑源代码]
Bluez 堆栈将新的、有可能出现错误的功能放在 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 file:
/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配置就可以直接用蓝牙耳机或音响了。[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
来进行音量管理。
蓝牙串口[编辑 | 编辑源代码]
如果要在Bluetooth-to-Serial模块 (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
疑难解答[编辑 | 编辑源代码]
Debugging(排除故障)[编辑 | 编辑源代码]
为了调试,首先停止 bluetooth.service
。
然后用-d参数:
# /usr/lib/bluetooth/bluetoothd -n -d
另一种选择是用btmon
工具。
弃用的 BlueZ 工具[编辑 | 编辑源代码]
八个BlueZ tools已经弃用并从bluez-utils包 中移除,尽管并非所有这些都被更新的工具所取代。bluez-deprecated-tools包 提供了bluez-utils包 的替代版本包,使用了不推荐使用的工具。
不推荐的工具 | 推荐的替代品 |
---|---|
gatttool | btgatt-client, D-Bus Gatt API |
hciattach | btattach |
hciconfig | btmgmt (and bluetoothctl?) |
hcidump | btmon (and btsnoop) |
hcitool | missing, D-Bus Device API available |
rfcomm | missing, implement with D-Bus Profile1 API? |
ciptool | |
sdptool | missing, functionality seems to be scattered over different D-Bus objects: Profile, Advertising, and the UUIDs arrays in device and adapter. |
gnome-bluetooth(gnome桌面环境下的蓝牙管理器)[编辑 | 编辑源代码]
如果接收文件时出现以下信息:
Bluetooth OBEX start failed: Invalid path Bluetooth FTP start failed: Invalid path
确保 XDG user directories 存在。
外置USB蓝牙/2.4GHz接收器[编辑 | 编辑源代码]
如果你在使用外置USB蓝牙/2.4GHz接收器,你要先检查蓝牙接收器是否被识别。插入USB接收器后可通过 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
如果只有前两行,说明系统找到了设备而只需要启动它。 例:
hciconfig -a hci0
hci0: Type: USB BD Address: 00:00:00:00:00:00 ACL MTU: 0:0 SCO MTU: 0:0 DOWN RX bytes:0 acl:0 sco:0 events:0 errors:0 TX bytes:0 acl:0 sco:0 commands:0 errors:
# hciconfig hci0 up
hciconfig -a hci0
hci0: Type: USB BD Address: 00:02:72:C4:7C:06 ACL MTU: 377:10 SCO MTU: 64:8 UP RUNNING RX bytes:348 acl:0 sco:0 events:11 errors:0 TX bytes:38 acl:0 sco:0 commands:11 errors:0
用 bluez-utils
里的 hcitool
检查设备是否被检测到。 要获取可用设备和他们的标识和MAC地址可以输入:
$ hcitool dev
Devices: hci0 00:1B:DC:0F:DB:40
设备的详细信息可以用hciconfig
获取 :
$ 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接收器较近的距离来回切换[编辑 | 编辑源代码]
如果有其他设备(和当前设备)共用同一个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)
有一个回归错误[1], 目前仅适用于5.17和<6.0版本的内核。若想获得更多相关信息,请参阅Kernel Bug 60824.
罗技双模外置蓝牙/2.4GHz可切换USB接收器[编辑 | 编辑源代码]
罗技的外置USB接收器 (例如罗技MX5000)可以在两种模式下运行:2.4GHz接收器模式(模拟USB模式)和HCI(蓝牙模式)。在2.4GHz接收器模式下,接收器模拟了USB设备,所以在您的计算机上,您就像在用普通的USB有线鼠标/键盘一样。
如果您按住接收器上的红色小按钮,它会启用其他模式。按住接收器上的红色按钮并将其插入计算机,按住按钮3-5秒后,将以蓝牙模式接入设备。蓝牙图标会出现在系统托盘里。讨论
或者,您可以安装bluez-hid2hci包当您连接罗技的接收器时,它可以自动切换模式。
hcitool扫描:找不到设备[编辑 | 编辑源代码]
- 在一些戴尔笔记本电脑(例如Studio 15)上,您必须将蓝牙模式从HID切换到HCI。安装bluez-hid2hci包,那么udev应该会自动执行此操作。或者,您可以运行此命令手动切换到HCI:
# /usr/lib/udev/hid2hci
- 如果设备没有显示,并且您的计算机上有Windows系统,请尝试引导它并从Windows启用蓝牙适配器。
- 有时,如下这个简单的命令能帮到您:
# hciconfig hci0 up
bluetoothctl: No default controller available(没有可用的默认控件)[编辑 | 编辑源代码]
一些主板蓝牙控件出现错误。要查看这是否是问题所在,请运行journalctl|grep-hci
。如果出现“Command tx timeout”或“Failed to read Intel version command”之类的报错,请关闭电脑电源,并拔下电源线几秒钟。这会强制控件重新加载固件(而标准重新启动不会)。请参阅此处的错误报告。
确保设备没有被rfkill阻止。
蓝牙服务(软件)无法正确识别一些英特尔设备(硬件)(如8260)也可能发生这种情况。在某些情况下,使用不推荐使用的bluez utils compataAUR来代替bluez utils包据报道已经解决了这个问题。
这也可能是由电源策略[2]引起的,在这种情况下,添加内核参数btusb.enable_autosuspend=n
是一个潜在的解决方案。另请参阅Red Hat Bugzilla–Bug 1573562。
有时,在没有选项的情况下重新加载btusb
有助于恢复控件:
# modprobe -r btusb # modprobe btusb
当接收器是CSR克隆时也可能发生这种情况
systemd: Condition check resulted in Bluetooth service being skipped(条件检查导致跳过蓝牙服务)[编辑 | 编辑源代码]
bluetooth.service
只需要存在于/sys/class/bluetooth
目录即可,该目录应由内核模块 bluetooth
创建,只有当 systemd-udev
真正找到一个工作的蓝牙硬件设备时,它才会自动加载。
如果您的/sys/class/bluetooth
不存在,请检查您的内核蓝牙模块是否由lsmod
加载。如果没有, 并且您很确定自己有蓝牙设备, 您可以尝试通过加载蓝牙模块并重新启动bluetooth.service
,来重新启动这些服务。
在加载bluetooth
模块时,您还应该加载相应的内核蓝牙驱动程序,一般用btusb
,但是也可以用btrtl,btintel,btbcm,bnep,btusb
等。
检查bluetooth.service
的 unit status (单元状态),看看它是否启动。
另请参阅 Debian Bug report logs - #853207.
如果 bluetooth.service
成功启动,但有可能您仍然无法正常使用蓝牙(例如, bluetoothctl
在您scan on
时显示类似org.Bluez.Error.NotReady
)。如果发生这种情况,请尝试重新启动计算机,并仔细检查:目录/sys/class/bluetooth
是否存在; lsmod
是否包括正确的蓝牙模块;在 journal中记录的信息; 等。 systemd-udev
应该自动检测出您的蓝牙硬件,而无需再次手动更改。
rfkill unblock:不能unblock[编辑 | 编辑源代码]
如果你的设备unblock后依然是soft blocked,试试:
$ connmanctl enable bluetooth
电脑蓝牙不可见[编辑 | 编辑源代码]
手机蓝牙扫描不到电脑?启动PSCAN和ISCAN:
# enable PSCAN and ISCAN $ hciconfig hci0 piscan # check it worked
$ hciconfig
hci0: Type: USB BD Address: 00:12:34:56:78:9A ACL MTU: 192:8 SCO MTU: 64:8 UP RUNNING PSCAN ISCAN RX bytes:20425 acl:115 sco:0 events:526 errors:0 TX bytes:5543 acl:84 sco:0 commands:340 errors:0
/etc/bluetooth/main.conf
检查设备可见超时和配对超时尝试在 /etc/bluetooth/main.conf
中更改设备类,如下所示:
# Default device class. Only the major and minor device class bits are # considered. #Class = 0x000100 (from default config) Class = 0x100100
这是让我的电脑对我的手机可见的唯一解决方案。
Foxconn / Hon Hai / Lite-On Broadcom device(富士康/鸿海/光宝/博通 设备)[编辑 | 编辑源代码]
其中一些设备需要在启动时将固件闪存到设备中。没有提供固件,但可以使用hex2hcd包(与bluez utils包一起安装)将Microsoft Windows.hex文件转换为.hcd包)。
为了获得正确的.hex文件,请尝试搜索设备供应商:使用lsusb获得的产品代码,例如:
... Bus 002 Device 004: ID 04ca:2006 Lite-On Technology Corp. Broadcom BCM43142A0 Bluetooth Device ...
or
Bus 004 Device 004: Id 0489:e031 Foxconn / Hon Hai
或者,启动到Windows(安装虚拟机即可),并从设备管理器获取固件名称。如果你想知道你的设备的型号,但在lsusb中看不到,你能作为iProduct
用lsusb-v看到它。
也可以从下载的Windows驱动程序中提取.hex文件,而无需为其运行Windows。下载合适的驱动程序,例如 Bluetooth Widcomm ( 在为Lifebook P771[失效链接 2022-09-17 ⓘ] 提供的驱动中有列出),其中包含许多Broadcomm设备的驱动程序。在蓝牙Widcomm的情况下,驱动程序是一个自提取的RAR档案,因此可以使用unrar包提取包 x。T要找出众多.hex文件中哪一个最适合您,请查找文件Win32/bcbtums-win7x86-brcm.inf
并搜索[RAMUSBE031.CopyList]
,其中E031
应替换为大写的设备的产品代码(lsusb中的第二个十六进制数)。在下面,您应该看到正确的.hex文件的文件名。
您有了.hcd文件,就把它复制到/lib/firmware/brcm/BCM.hcd
中——这个文件名是dmesg
建议的,在您的情况下可能会更改,所以请检查您的dmesg 输出以进行验证。然后重新加载btusb模块:
# rmmod btusb # modprobe btusb
在某些情况下(使用较旧的内核?),您必须使用brcm_patchram_plus utility来闪存.hcd文件,该实用程序由brcm_patchram_plus-gitAUR[损坏的链接:package not found] 提供。首先,确保dmesg 中的设备被btusb识别为蓝牙设备。然后,运行以下操作(用您的供应商产品替换04ca 2006):
# echo '04ca 2006' > /sys/bus/usb/drivers/btusb/new_id
启用设备:
# hciconfig hci0 up
写入固件
# brcm_patchram_plus_usb --patchram fw-04ca_2006.hcd hci0
该设备现在应该可用。请参阅 BBS#162688 ,了解有关使这些更改持久化的信息。
Intel combined WiFi and Bluetooth cards(英特尔集成式WIFI和蓝牙)[编辑 | 编辑源代码]
请参阅Wireless network configuration#Bluetooth coexistence.
设备配对成功,一段时间后意外断开[编辑 | 编辑源代码]
如果运行 journalctl
有以下结果,并且你的设备配对后过一会儿又断开:
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 [bluetooth]# devices Device XX:XX:XX:XX:XX:XX My Device [bluetooth]# remove XX:XX:XX:XX:XX:XX
再重启 bluetooth.service
,打开蓝牙适配器,让设备可见,重新扫描配对。因为蓝牙管理器不一样,有时需要重启系统。
扫描不到设备[编辑 | 编辑源代码]
有的节能蓝牙设备用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 device name <---- 这个就是你的设备
另一种方法是安装 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。 bluetoothctl 就可以获取你的设备并正常配对了。
Cannot receive transferred files due to symlink(由于符号链接,无法接收传输的文件)[编辑 | 编辑源代码]
如果在功能正常的蓝牙连接上传入文件传输失败,则问题可能是由于文件传输路径中的符号链接造成的。日志中会显示这样的日志:
Jun 18 11:18:13 ember obexd[3338969]: open(/home/me/.cache/obexd/MOC740): Operation not permitted (1)
如果错误消息中显示的路径包含符号链接,则obexd默认情况下不会接受它。初始化时可以使用obex.service
用户服务的Drop-in file覆盖该行为:
~/.config/systemd/user/obex.service.d/10-symlink.conf
[Service] ExecStart= ExecStart=/usr/lib/bluetooth/obexd --symlinks
然后重新加载调用用户的systemd管理器配置,并重新启动obex.service
用户单元。
耳机和鼠标之间的干扰[编辑 | 编辑源代码]
如果您在同时使用蓝牙鼠标和键盘时遇到音频断断续续的问题,您可以尝试以下#23中提到的方法 https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/424215
# hciconfig hci0 lm ACCEPT,MASTER # hciconfig hci0 lp HOLD,SNIFF,PARK
蓝牙鼠标动作延迟[编辑 | 编辑源代码]
尝试编辑文件 /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/YY:YY:YY:YY:YY:YY/info
(XX:XX:XX:XX:XX:XX
-您的蓝牙适配器MAC地址,YY:YY:YY:YY:YY:YY
-您的鼠标MAC地址),并添加以下行:
[ConnectionParameters] MinInterval=6 MaxInterval=9 Latency=44 Timeout=216
您可以通过运行hcitool dev
命令查看本地适配器的MAC地址。您可以通过执行hcitool con
命令查看当前连接的远程设备的MAC地址。
挂起/休眠后适配器消失[编辑 | 编辑源代码]
首先,查找适配器的供应商和产品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
Problems with all BLE devices on kernel (5.9+内核版本5.9以上所有BLE设备的问题)[编辑 | 编辑源代码]
从v5.9开始,内核蓝牙堆栈尝试在BLE连接上使用链路层隐私。如果设备在配对后工作,但无法在重新启动或挂起后继续运行,可能是因为这个原因。
要解决[3]此问题,请打开/var/lib/bluetooth/adapter_mac/device_mac/info
删除以下行,然后重新启动bluetooth.service
:
[IdentityResolvingKey] Key=...
请参阅Arch论坛上的相关讨论。
Bluetooth immediately waking up suspend-to-idle devices(蓝牙突然唤醒挂起的空闲设备)[编辑 | 编辑源代码]
在能够挂起到空闲 suspend-to-idle/S2idle/S0ix/Modern Standby的系统上,蓝牙控件将在睡眠期间保持启用状态。如果连接了蓝牙设备,这通常会导致系统在进入睡眠状态后立即唤醒。
为了防止这种情况,你可以在启用睡眠模式前完全禁用蓝牙——安装T 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
启用此服务并检查蓝牙设备在进入睡眠状态时是否断开连接,以及在唤醒系统后蓝牙何时恢复连接。
如果使用此解决方法,则使用蓝牙鼠标/键盘唤醒系统将不起作用。
持续连接/断开与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
.
你可以参阅discussion on xpadneo 但不需要xpadneo驱动程序
Mediatek MT7921或MT7961在带有windows的双启动系统上[编辑 | 编辑源代码]
在双启动系统上,如果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上的设备管理器中找到固件文件路径)。
- ↑ 在软件开发中,回归错误是指在新版本或新功能中引入的错误,这导致现有功能或已修复的错误再次出现。 回归错误可能是由于代码更改、库更新、配置更改等原因导致的。它们通常表现为程序中的错误、异常、崩溃或数据不一致。
- ↑ 比如省电模式,可能导致蓝牙服务默认关闭
- ↑ https://lkml.kernel.org/lkml/D577711C-4AF5-4E82-8A17-E766B64E15A9@holtmann.org/