蓝牙

来自 Arch Linux 中文维基
(重定向自Bluetooth

蓝牙(Bluetooth)是一个短距离无线通信标准,用于在手机、计算机和其他电子设备之间通信。在 Linux 中,权威的蓝牙协议栈实现是 BlueZ

安装[编辑 | 编辑源代码]

  1. 安装 bluez,这个软件包提供蓝牙协议栈。
  2. 安装 bluez-utils,这个软件包提供 bluetoothctl 实用程序。另外,也可以安装 bluez-utils-compatAUR 来获得#弃用的 BlueZ 工具
  3. btusb 内核模块是通用蓝牙驱动。检查模块是否已加载。如果还没有,先加载模块
  4. 启动/启用 bluetooth.service
注意:
  • 蓝牙守护程序默认只会向属于 lp 的用户暴露 bnep0 设备。如果要连接到蓝牙设备的话,需先将用户添加到这个组。可以在 /usr/share/dbus-1/system.d/bluetooth.conf 中修改需要加入的组。
  • 一些蓝牙适配器和无线网卡绑定(例如 Intel Centrino)。这些蓝牙适配器需要先启用无线网卡(在笔记本上通常通过键盘快捷键)才能被内核识别。
  • 一些蓝牙适配器(例如 Broadcom)和网络适配器冲突。因此,需要确保在网络服务启动之前连接蓝牙。
  • 一些工具(例如 hcitool 和 hciconfig)已被上游弃用,并且不再包含在 bluez-utils 中。这些工具将不会被更新,因此建议更新脚本,避免使用它们。如果还是想用,安装 bluez-utils-compatAUR。参见 FS#53110Bluez 邮件列表

前端[编辑 | 编辑源代码]

控制台[编辑 | 编辑源代码]

  • bluetoothctl — 在 shell 中配对设备是最简单可靠的方法之一。
http://www.bluez.org/ || bluez-utils
  • bluetuith — 为终端界面提供蓝牙管理器,可以方便的配对和管理设备,具有 OBEX 文件传输和鼠标支持。
https://www.github.com/darkhz/bluetuith || bluetuithAUR
提示:要自动化 bluetoothctl 命令,使用 echo -e "command1\ncommand2\n" | bluetoothctlbluetoothctl -- command

图形界面[编辑 | 编辑源代码]

以下软件包提供图形界面来自定义蓝牙。

  • GNOME BluetoothGNOME 的蓝牙工具。
    • gnome-bluetooth-3.0 提供后端(gnome-bluetooth 已过时)
    • gnome-shell 提供状态托盘
    • gnome-control-center 可通过图形界面配置蓝牙。可以在活动预览输入“蓝牙”或者运行 gnome-control-center bluetooth 进行配置。
    • 你还可以直接运行 bluetooth-sendto 命令来把文件发送到远程设备。
    • nautilus-bluetoothAUR 在 Nautilus 右键菜单添加“通过蓝牙发送”
    • 打开蓝牙设置面板来接收文件;只有在蓝牙设置面板打开时才能接收文件。
    • 要在 Thunar 的“发送到”菜单中添加蓝牙选项,请查看这里的指导。(使用 bluetooth-sendto %F 命令)。
https://wiki.gnome.org/Projects/GnomeBluetooth ||
  • BluedevilKDE 的蓝牙工具。如果 Dolphin 和系统托盘里没有蓝牙图标,就在系统托盘选项里启用,或者添加一个挂件。点击图标或在 KDE 系统设置里都可以配置蓝牙。
https://invent.kde.org/plasma/bluedevil || bluedevil
  • Blueberry — Linux Mint 的独立版 GNOME Bluetooth,可在所有桌面环境工作。Blueberry 不支持通过 Obex Object 推送来接收文件。
https://github.com/linuxmint/blueberry || blueberry
  • Blueman — 全功能蓝牙管理器。
https://github.com/blueman-project/blueman || blueman
  • ObexFTP — 用来和启动了 OBEX 的设备传输文件的工具。
http://dev.zuckschwerdt.org/openobex/wiki/ObexFtp || obexftpAUR

配对[编辑 | 编辑源代码]

注意: 使用蓝牙设备之前,先检查它有没有被 rfkill 禁用。

这一小节介绍直接用 bluetoothctl 配置 bluez5 的方法,如果你已经有前端工具(比如 GNOME Bluetooth)的话就不需要了。

实际的步骤取决于设备和它的输入功能。以下是使用 bluetoothctl 配对设备的一般步骤。

运行 bluetoothctl 交互命令。输入 help 来获取帮助。

  1. (可选操作)使用 select MAC_address 选择一个默认的蓝牙接收器。
  2. (可选操作)如果蓝牙设备已经关闭,使用命令 power on 打开蓝牙。蓝牙默认是开启的,请参考#默认电源状态
  3. 使用命令 devices 获得要配对的设备的 MAC 地址。
  4. 如果设备没有出现在上一步的列表中,使用命令 scan on 去搜索发现所有可配对的设备。
  5. 使用命令 agent on 打开代理或者选择一个特定的代理:如果在 agent 命令后按下两次 tab 键,应该就能看到可用代理的列表。蓝牙代理用于管理蓝牙“配对码”。它可以回复外部发来的“配对码”,也可以主动发送。大部分情况下使用 default-agent 应该就足够了。[1]
  6. 使用命令 pair MAC_address 配对设备(可用 tab 键补全 MAC 地址)。
  7. 如果配对设备不需要 PIN,那么你可能需要手动将设备添加到信任列表。使用命令 trust MAC_address
  8. 使用命令 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 中配对设备。然后重新启动到另一个操作系统,再次配对设备。接下来需要提取配对密钥,但首先要关闭蓝牙设备以防止其尝试重新连接。

注意: 部分罗技产品的 MAC 地址可能会在和新系统配对后自增1,比如 arch:Logitech MX Master 和 Logitech 604 Lightspeed。请检查你的设备是否有这种情况,配置过程中需要考虑这一点。

对于 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 设备,只需要一个密钥。如果这个设备有多个密钥(比如 LTKIRK),那么这一个蓝牙 5.1 设备,配置方法参见#准备蓝牙 5.1 密钥

最后,重启进入 Linux,然后跳到#完成配置步骤

在 Linux 上提取密钥[编辑 | 编辑源代码]
注意: 如果 Windows 分区启用了 Bitlocker 加密,则无法从 Linux 中使用 chntpw 访问

进入 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或更高的版本:
    1. 打开“钥匙串”,搜索 Bluetooth。
    2. 按日期排序。
    3. 如果刚刚移除并重连设备,则可以直接选择最新的设备。设备名可能是MobileBluetooth (较旧的蓝牙设备) 或者只是一个UUID (蓝牙5.1+)。
    4. 双击此项,检查MAC地址和你的设备是否一致。
    5. 勾选“显示密码”复选框,然后重复输入两次你的密码。
    6. 复制密码显示区域中的文本,它实际上是个 XML 文件 (⌘+a ⌘+c)
    7. 把文本粘贴到~/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

注意: 反转可以用这段 Python 代码完成:
>>> 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密钥[编辑 | 编辑源代码]

Tango-view-fullscreen.png这篇文章的某些内容需要扩充。Tango-view-fullscreen.png

原因: We are still working on getting a comprehensive idea of how these work across vendors. For now, documenting specific devices' compatibility with these methods is helpful - especially non-Logitech data points. (在 Talk:Bluetooth#Bluetooth 5.1 Devices 中讨论)

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
  • Copy IRK.
  • Remove the spaces between the hex octets.
? IdentityResolvingKey.Key
  • Copy LTK.
  • Remove the spaces between the hex octets.
? 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
  • Copy IRK.
  • Reverse the order of the octets.
  • Copy Remote IRK.
  • Convert from base64 to hex.
IdentityResolvingKey.Key
  • Copy LTK. Remove the spaces between the hexadecimal octets.
  • Copy Remote Encryption > Long-term Key.
  • Convert from base64 to hex.
LongTermKey.Key
  • Copy ERand.
  • Reverse the order of the octets.
  • Convert the whole number to decimal.
  • Copy Remote Encryption > Random Number.
  • Convert from base64 to hex.
  • Reverse the order of the octets.
LongTermKey.Rand
  • Copy EDIV.
  • Reverse the order of the octets.
  • Convert the whole number to decimal.
  • Copy Remote Encryption > Encrypted Diversifier.
  • Convert from base64 to hex.
  • Reverse the order of the octets.
LongTermKey.EDiv
Other devices
  • Copy LTK.
  • Remove the spaces between the hex octets.
  • Copy Remote IRK.
  • Convert from base64 to hex.
LongTermKey.Key
  • Copy ERand.
  • Reverse the order of the octets.
  • Convert the whole number to decimal.
  • Copy Remote Encryption > Long-term Key.
  • Convert from base64 to hex.
LongTermKey.Rand
  • Copy EDIV.
  • Remove the spaces between the hex octets.
  • Copy Remote Encryption > Encrypted Diversifier.
  • Convert from base64 to hex.
  • Reverse the order of the octets.
LongTermKey.EDiv
注意:
>>> "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 of 48 4D AF CD 0F 92 22 88 0A 52 9A F4 76 DA 8B 94 makes for a LongTermKey.Key of 484DAFCD0F9222880A529AF476DA8B94.
  • An ERand of 63 02 84 B8 5D 40 44 DF makes for a Rand of 16088054540146049635.
  • An EDIV of 37520 makes for an EDiv of 37520.

完成配置[编辑 | 编辑源代码]

获得密钥后,切换用户为 root,然后输入:

# cd /var/lib/bluetooth/BT-Adapter-MAC-address

在此处可以找到每个已配对蓝牙设备的文件夹。对于要与 Arch 和双启动配对的每个设备,执行以下操作:

# cd device-MAC-address
注意: 若使用的是会在配队后自增MAC地址的设备,请在这一步改成将MAC地址文件夹改成自增后的。可以直接从Windows复制MAC地址过来,也可以手动自增(注意到每个8bit字节都是一个两位十六进制数)。

如果的设备不是蓝牙5.1设备(只有一个密钥),编辑 info 文件,改变 [LinkKey] 中列出的密钥。例如:

info
[LinkKey]
Key=XXXXXXXXXXXXXXX
注意: 确保所有字母都大写,并且删除所有空格。

如果是蓝牙5.1的多个密钥,那么则应将所有的密钥文件复制到对应的MAC地址目录。

然后 重新启动 bluetooth.servicepulseaudio(使用 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 ratexmodmap),可以创建一个可执行脚本:

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]

注意: 有时要用 pavucontrol 选择音频的输出设备。

如果你有全局的 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[编辑 | 编辑源代码]

注意: Bluez5 已经不再直接集成对 ALSA 的支持,目前只对 PulseAudio 提供支持。如果你不能或者不想使用PulseAudio,请参考下面的命令。

首先,确认你的蓝牙音频设备已经正确配对且已经连接到系统。

然后,安装 bluez-alsa-gitAUR,启动(和使能) bluealsa 服务, 并增加当前用户到 audio 组。

执行下面的命令确认一切是否像预想地那样工作(替换下面的 XX:XX:XX:XX:XX:XXFILE.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

疑难解答[编辑 | 编辑源代码]

Tango-view-refresh-red.png本文内容或本节内容已经过期。Tango-view-refresh-red.png

原因: Replace hciconfig with newer commands. (在Talk:蓝牙讨论)

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).