Bluetooth (简体中文)

From ArchWiki

Tango-preferences-desktop-locale.png本文或本节需要翻译。要贡献翻译,请访问简体中文翻译团队Tango-preferences-desktop-locale.png

附注: Last updated 2022-6-23 + some sections are still untranslated. See Talk:Bluetooth (简体中文)#翻译需要跟进[损坏的链接:无效的章节](在 Talk: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
提示: 要自动化 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 右键菜单添加“通过蓝牙发送”
    • 打开蓝牙设置面板来接收文件;只有在蓝牙设置面板打开时才能接收文件。
    • To add a Bluetooth entry to the Send To menu in Thunar's file properties menu, see instructions here. (The command that needs to be configured is 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 中手动更改配对密钥,以便它们在两个系统中匹配。

配置

首先在 Arch Linux 中配对设备。然后重新启动到另一个操作系统并配对设备。现在需要提取配对密钥,但首先要关闭蓝牙设备以防止尝试连接。

对于 macOS

启动到 macOS,然后打开终端。

  • 如果系统版本为 Sierra 或更低的版本,运行
# defaults read /private/var/root/Library/Preferences/blued.plist LinkKeys > ~/bt_keys.txt
  • 如果系统版本为 High Sierra 或更高的版本,运行
# defaults read /private/var/root/Library/Preferences/com.apple.bluetoothd.plist LinkKeys > ~/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

bt_keys.txt 文件复制到可由 Arch Linux 读取的驱动器。然后重新启动到 Arch Linux。

完成配置

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

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

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

# cd device-MAC-address

编辑 info 文件,改变 [LinkKey] 中列出的密钥。例如:

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

然后重新启动 bluetooth.servicepulseaudio(使用 pulseaudio -k && pulseaudio --start)。

现在应该可以连接到你的设备了。

注意: 取决于蓝牙管理器,可能需要完全重启才能重新连接到设备。

配置

开机后自动启动

蓝牙在重启后默认不会自动启动。命令 hciconfig hci0 up 已经被弃用,参阅 release note。你只需要将 AutoEnable=true 添加在 /etc/bluetooth/main.conf 底部的 [Policy] 下面:

/etc/bluetooth/main.conf
[Policy]
AutoEnable=true

启动后自动可被发现

如果设备应该总是可见或者可以直接连接:

/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"

音频

通常你需要采取额外的步骤去整合针对蓝牙的音频服务。下面的章节会给出相关细节。

查看Bluetooth headset页面获得更多关于蓝牙音频和蓝牙耳机的信息。

PulseAudio

要使用蓝牙耳机或音响的话要先安装 pulseaudio-bluetooth。 要确认重新启动pulseaudio来使得安装生效:pulseaudio -k。默认的PulseAudio配置就可以直接用蓝牙耳机或音响了。

注意: 有时要用 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.pngThis article or section is out of date.Tango-view-refresh-red.png

Reason: Replace hciconfig with newer commands. (Discuss in Talk:Bluetooth (简体中文))

弃用的 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

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

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.

设备配对后过一会儿又断开

如果运行 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,打开蓝牙适配器,让设备可见,重新扫描配对。因为蓝牙管理器不一样,有时需要重启系统。

设备连接不了,日志里有错误

如果你在连接设备时看见 journalctl 的输出有类似的消息:

a2dp-source profile connect failed for 9C:64:40:22:E1:3F: Protocol not available

安装 pulseaudio-bluetooth 再重启 PulseAudio。这个错误在文件传输是也会有。

设备扫描不出来

有的节能蓝牙设备用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 就可以获取你的设备并正常配对了。