蓝牙
蓝牙(Bluetooth)是一个短距离无线通信标准,用于在手机、计算机和其他电子设备之间通信。在 Linux 中,权威的蓝牙协议栈实现是 BlueZ。
安装[编辑 | 编辑源代码]
- 安装 bluez包,这个软件包提供蓝牙协议栈。
- 安装 bluez-utils包,这个软件包提供
bluetoothctl
实用程序。另外,也可以安装 bluez-utils-compatAUR 来获得#弃用的 BlueZ 工具。 btusb
内核模块是通用蓝牙驱动。检查模块是否已加载。如果还没有,先加载模块。- 启动/启用
bluetooth.service
。
- 蓝牙守护程序默认只会向属于
lp
组的用户暴露 bnep0 设备。如果要连接到蓝牙设备的话,需先将用户添加到这个组。可以在/usr/share/dbus-1/system.d/bluetooth.conf
中修改需要加入的组。 - 一些蓝牙适配器和无线网卡绑定(例如 Intel Centrino)。这些蓝牙适配器需要先启用无线网卡(在笔记本上通常通过键盘快捷键)才能被内核识别。
- 一些蓝牙适配器(例如 Broadcom)和网络适配器冲突。因此,需要确保在网络服务启动之前连接蓝牙。
- 一些工具(例如 hcitool 和 hciconfig)已被上游弃用,并且不再包含在 bluez-utils包 中。这些工具将不会被更新,因此建议更新脚本,避免使用它们。如果还是想用,安装 bluez-utils-compatAUR。参见 FS#53110 和 Bluez 邮件列表。
前端[编辑 | 编辑源代码]
控制台[编辑 | 编辑源代码]
- 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,然后解压出 PsExe64.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密钥[编辑 | 编辑源代码]
If you observed the presence of Bluetooth 5.1 keys while following #For Windows or #For macOS, you must apply certain transformations to their values before importing them into Linux. Create the requested files with their appropriate contents, for installation in #Finishing up. This process will depend on the device, and some of the values have to be manipulated; code utilities for doing so are provided below.
Device | Source Key and Transformations (Windows) | Source Key and Transformations (macOS) | Destination Key File |
---|---|---|---|
Logitech MX Master 3 |
|
? | IdentityResolvingKey.Key
|
|
? | SlaveLongTermKey.Key and PeripheralLongTermKey.Key
| |
ERand and EDIV should be 0
|
Random Number and Encrypted Diversifier should be 0 .
|
– | |
ThinkPad TrackPoint Keyboard II, Pebble M350 mouse, Logitech G604 Lightspeed mouse |
|
|
IdentityResolvingKey.Key
|
|
|
LongTermKey.Key
| |
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
| |
Other devices |
|
|
LongTermKey.Key
|
|
|
LongTermKey.Rand
| |
|
|
LongTermKey.EDiv
|
- To just remove the spaces from a value, you can use this online tool or this Python code:
>>> "key_value".replace(" ", "")
- This Python code does only the octet reversal:
>>> ERand=" 63 02 84 B8 5D 40 44 DF " >>> ERand=list(reversed(ERand.strip().split()))
- This Python code does the additional decimal conversion required for some:
>>> int("".join(ERand), 16) 16088054540146049635
- This Python code does the base64 to hex conversion:
binascii.hexlify(base64.decodebytes(b'...')).upper()
- This Python code does the full macOS Encrypted Diversifier conversion:
struct.unpack('<H', base64.decodebytes(b'...'))
- This Python code does the full macOS Random Number conversion:
struct.unpack('<H', base64.decodebytes(b'...'))
For an example of the general case:
- An
LTK
of48 4D AF CD 0F 92 22 88 0A 52 9A F4 76 DA 8B 94
makes for aLongTermKey.Key
of484DAFCD0F9222880A529AF476DA8B94
. - An
ERand
of63 02 84 B8 5D 40 44 DF
makes for aRand
of16088054540146049635
. - An
EDIV
of37520
makes for anEDiv
of37520
.
完成配置[编辑 | 编辑源代码]
获得密钥后,切换用户为 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
)。
现在应该可以连接到你的设备了。
配置[编辑 | 编辑源代码]
默认电源状态[编辑 | 编辑源代码]
As of bluez包 5.65, BlueZ' default behavior is to power on all Bluetooth adapters when starting the service or resuming from suspend. [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"
Enabling experimental features[编辑 | 编辑源代码]
The Bluez stack keeps new, potentially buggy features behind the D-Bus experimental and kernel experimental options. The functionality included under these varies over time, as experimental features are determined to be stable and no longer require the option. To enable these, uncomment the corresponding line in the configuration:
/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
Alternatively, you can edit the bluetooth.service
to add the --experimental
or --kernel
flag, like this drop-in file:
/etc/systemd/system/bluetooth.service.d/override.conf
[Service] ExecStart= ExecStart=/usr/lib/bluetooth/bluetoothd --experimental
Either way, you must then restart the 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-utils-compatAUR,因为它提供了我们需要的特定的功能,这些功能没有被新工具支持。
绑定已经配对的设备的MAC地址到tty终端:
# rfcomm bind rfcomm0 MAC_address_of_Bluetooth_device
现在你可以打开 /dev/rfcomm0
来进行串口通信:
$ picocom /dev/rfcomm0 -b 115200
疑难解答[编辑 | 编辑源代码]
Debugging[编辑 | 编辑源代码]
In order to debug, first stop bluetooth.service
.
And then start it with the -d
parameter:
# /usr/lib/bluetooth/bluetoothd -n -d
Another option is via the btmon
tool.
弃用的 BlueZ 工具[编辑 | 编辑源代码]
Eight BlueZ tools were deprecated and removed from bluez-utils包, although not all of them were superseded by newer tools. The bluez-utils-compatAUR package provides an alternative version of bluez-utils包 with the deprecated tools.
Deprecated tool | Most likely replacement |
---|---|
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[编辑 | 编辑源代码]
如果接收文件时出现以下信息:
Bluetooth OBEX start failed: Invalid path Bluetooth FTP start failed: Invalid path
确保 XDG user directories 存在。
蓝牙USB电子狗[编辑 | 编辑源代码]
如果你在使用USB电子狗,你要先检查蓝牙电子狗是否被识别。插入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)
Audio devices start to skip at short distance from dongle[编辑 | 编辑源代码]
If other devices share the same USB host, they can interrupt communication with audio devices. Make sure it is the only device attached to its bus. For example:
$ 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 dongle 0a12:0001[编辑 | 编辑源代码]
The device ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
has a regression bug, and currently only works in the kernel version 5.17 and < 6.0. For more information, see Kernel Bug 60824.
Logitech Bluetooth USB Dongle[编辑 | 编辑源代码]
There are Logitech dongles (ex. Logitech MX5000) that can work in two modes: Embedded and HCI. In embedded mode dongle emulates a USB device so it seems to your PC that you are using a normal USB mouse/keyoard.
If you hold the little red Button on the USB BT mini-receiver it will enable the other mode. Hold the red button on the BT dongle and plug it into the computer, and after 3-5 seconds of holding the button, the Bluetooth icon will appear in the system tray. Discussion
Alternatively, you can install the bluez-hid2hci包 package. When you connect your Logitech dongle it will automatically switch.
hcitool scan: Device not found[编辑 | 编辑源代码]
- On some Dell laptops (e.g. Studio 15) you have to switch the Bluetooth mode from HID to HCI. Install the bluez-hid2hci包 package, then udev should do this automatically. Alternatively, you can run this command to switch to HCI manually:
# /usr/lib/udev/hid2hci
- If the device will not show up and you have a Windows operating system on your machine, try booting it and enable the bluetooth adapter from windows.
- Sometimes also this simple command helps:
# hciconfig hci0 up
bluetoothctl: No default controller available[编辑 | 编辑源代码]
There is a bug with some motherboard bluetooth controllers. To see if this might be the issue, run journalctl | grep hci
. If there are entries like "command tx timeout" or "Reading Intel version command failed", then power off your pc and physically unplug the power cable for a few seconds. This forces the controller to reload the firmware (while a standard reboot will not). See bug report here.
Make sure the device is not being blocked by rfkill.
It might also happen with some intel cards (such as the 8260) to not be picked up correctly by the Bluetooth service. In some cases, using the deprecated bluez-utils-compatAUR in lieu of bluez-utils包 have reportedly fixed the issue.
This might also be caused by power saving measures, in which case adding the kernel parameter btusb.enable_autosuspend=n
is a potential solution. See also Red Hat Bugzilla – Bug 1573562.
Sometimes unloading and loading btusb
without options helps to get the controller back:
# modprobe -r btusb # modprobe btusb
It may occur also when the dongle is a CSR clone
systemd: Condition check resulted in Bluetooth service being skipped[编辑 | 编辑源代码]
bluetooth.service
only requires the directory /sys/class/bluetooth
to exist, which should be created by kernel module bluetooth
, which is only autoloaded by systemd-udev
if it actually finds a working Bluetooth hardware device.
If your /sys/class/bluetooth
does not exist, check if your kernel Bluetooth module is loaded by lsmod
. If not, and you believe you have a Bluetooth device, you can try manually starting them by loading the Bluetooth module and restarting bluetooth.service
.
You should also load your corresponding kernel Bluetooth driver when loading the bluetooth
module, most likely btusb
, but can also be btrtl,btintel,btbcm,bnep,btusb
etc.
Check bluetooth.service
's unit status to see whether it started.
See also Debian Bug report logs - #853207.
If bluetooth.service
started successfully, but there is chance that you still cannot use Bluetooth normally (e.g. bluetoothctl
says something like org.Bluez.Error.NotReady
when you scan on
). If this happens, try rebooting your computer, and double-check: whether directory /sys/class/bluetooth
exists; whether lsmod
includes correct Bluetooth modules; log messages in the journal; etc. systemd-udev
should pickup your Bluetooth hardware automatically without manual changes again.
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
检查设备可见超时和配对超时Try changing device class in /etc/bluetooth/main.conf
as following:
# Default device class. Only the major and minor device class bits are # considered. #Class = 0x000100 (from default config) Class = 0x100100
This was the only solution to make my computer visible for my phone.
Foxconn / Hon Hai / Lite-On Broadcom device[编辑 | 编辑源代码]
Some of these devices require the firmware to be flashed into the device at boot. The firmware is not provided but can converted from a Microsoft Windows .hex file into a .hcd using hex2hcd (which is installed with bluez-utils包).
In order to get the right .hex file, try searching the device vendor:product code obtained with lsusb, for example:
... 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
Alternatively, boot into Windows (a virtual machine installation will suffice) and get the firmware name from the Device Manager utility. If you want to know the model of your device but cannot see it in lsusb, you might see it in lsusb -v as iProduct
.
The .hex file can be extracted from the downloaded Windows driver without having to run Windows for it. Download the right driver, for example Bluetooth Widcomm (listed among the drivers for Lifebook P771[失效链接 2022-09-17 ⓘ]), which contains the drivers for many Broadcomm devices. In case of Bluetooth Widcomm, the driver is a self-extracting RAR archive, so it can be extracted using unrar包 x. To find out which of the many .hex files is the right one for you, look in the file Win32/bcbtums-win7x86-brcm.inf
and search for [RAMUSBE031.CopyList]
, where E031
should be replaced with the product code (the second hex number in lsusb) of your device in upper-case. Underneath you should see the file name of the right .hex file.
Once you have the .hcd file, copy it into /lib/firmware/brcm/BCM.hcd
- this filename is suggested by dmesg
and it may change in your case so check your dmesg output in order to verify. Then reload the btusb module:
# rmmod btusb # modprobe btusb
In some cases (with older kernels?), you have to flash the .hcd file with the brcm_patchram_plus utility, provided by brcm_patchram_plus-gitAUR[损坏的链接:package not found]. First, make sure in dmesg that the device is recognized by btusb as a bluetooth device. Then, run the following (replace 04ca 2006 with your vendor product pair):
# echo '04ca 2006' > /sys/bus/usb/drivers/btusb/new_id
Turn on the device:
# hciconfig hci0 up
Flash the firmware:
# brcm_patchram_plus_usb --patchram fw-04ca_2006.hcd hci0
The device should now be available. See BBS#162688 for information on making these changes persistent.
Intel combined WiFi and Bluetooth cards[编辑 | 编辑源代码]
See 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。可以安装 bluez-utils-compatAUR再 启动 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[编辑 | 编辑源代码]
If incoming file transfers fail on an an otherwise functional Bluetooth connection, the problem may be due to symlinks in your file transfer path. Logs like this would appear in the journal:
Jun 18 11:18:13 ember obexd[3338969]: open(/home/me/.cache/obexd/MOC740): Operation not permitted (1)
If the path shown in the error message contains a symlink, then obexd by default will not accept it. The behavior can be overridden on initialization using a drop-in file for the obex.service
user service:
~/.config/systemd/user/obex.service.d/10-symlink.conf
[Service] ExecStart= ExecStart=/usr/lib/bluetooth/obexd --symlinks
Then reload the systemd manager configuration of the calling user and restart the obex.service
user unit.
Interference between Headphones and Mouse[编辑 | 编辑源代码]
If you experience audio stuttering while using a Bluetooth mouse and keyboard simultaneously, you can try the following as referenced in #23 https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/424215
# hciconfig hci0 lm ACCEPT,MASTER # hciconfig hci0 lp HOLD,SNIFF,PARK
Bluetooth mouse laggy movements[编辑 | 编辑源代码]
Try to edit the file /var/lib/bluetooth/XX:XX:XX:XX:XX:XX/YY:YY:YY:YY:YY:YY/info
(XX:XX:XX:XX:XX:XX
- your Bluetooth adapter MAC address, YY:YY:YY:YY:YY:YY
- your mouse MAC address) and add these lines:
[ConnectionParameters] MinInterval=6 MaxInterval=9 Latency=44 Timeout=216
You can see your local adapter MAC address by running the command hcitool dev
. You can see the MAC addresses of currently connected remote devices by running the command hcitool con
.
Adapter disappears after suspend/resume[编辑 | 编辑源代码]
First, find vendor and product ID of the adapter. For example:
$ 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. ...
In this case, the vendor ID is 8087 and the product ID is 0025.
Then, use usb_modeswitch包 to reset the adapter:
# usb_modeswitch -R -v vendor_ID -p product_ID
Problems with all BLE devices on kernel 5.9+[编辑 | 编辑源代码]
Starting with v5.9, the kernel Bluetooth stack tries to use link-layer privacy on BLE connections. If the device works after pairing but does not survive a reboot or suspend, it is probably because of this.
To workaround [4] this issue, open /var/lib/bluetooth/adapter_mac/device_mac/info
, remove the following lines, and restart bluetooth.service
:
[IdentityResolvingKey] Key=...
See the relevant discussion on the Arch forum.
Bluetooth immediately waking up suspend-to-idle devices[编辑 | 编辑源代码]
On systems capable of suspend-to-idle/S2idle/S0ix/Modern Standby, Bluetooth controllers will stay enabled during sleep. This will usually cause the system to wake up immediately after going to sleep if any Bluetooth device is connected.
To prevent this, you can disable Bluetooth completely before going to sleep - install bluez-utils包 and create this file:
/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
Enable this service and check if Bluetooth devices disconnect when going to sleep, and whenever Bluetooth goes back up after waking up the system.
If this workaround is in use, waking up the system with a Bluetooth mouse/keyboard will not work.
Continually connect/disconnect with TP-LINK UB400 and Xbox controller[编辑 | 编辑源代码]
Use the settings below:
/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 ...
Then restart the bluetooth.service
.
You can see relevant discussion on xpadneo but the xpadneo driver is not needed.
Mediatek MT7921 or MT7961 on dual boot with windows[编辑 | 编辑源代码]
On dual boot systems, if Bluetooth firmware versions are different for Windows and Linux, the Bluetooth adapter is not working after rebooting to Windows.
The best way to prevent this is updating the Bluetooth drivers (especially firmware) with latest version for each OS.
If you cannot find the latest version driver (or firmware) for Windows, you can copy the latest firmware file /usr/lib/firmware/mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin.xz
from Arch Linux and extract to Windows (e.g. C:\WINDOWS\system32\DRIVERS\
, you can find the firmware file path in the device manager on Windows).