藍牙

出自 Arch Linux 中文维基

藍牙(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,然後解壓出 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 設備,只需要一個密鑰。如果這個設備有多個密鑰(比如 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密鑰[編輯 | 編輯原始碼]

這篇文章的某些內容需要擴充。

原因: 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 中討論)

若在#對於 Windows#對於 macOS小節中發現藍牙5.1密鑰,則需在導入Linux系統前對它們的值進行一些轉換。在執行#完成配置步驟前,需創建好所需的文件,並填入恰當的內容。本步驟因設備而異,參照下表。一部分值的需要進行特殊操作,相關的實用程序也一併提供在下。

設備 原始密鑰與所需的轉換 (Windows) 原始密鑰與所需的轉換 (macOS) 目標密鑰文件
Logitech MX Master 3
  • 複製 IRK
  • 刪除十六進制字節之間的空格
? IdentityResolvingKey.Key
  • 複製 LTK.
  • 刪除十六進制字節之間的空格
? SlaveLongTermKey.KeyPeripheralLongTermKey.Key
ERandEDIV 應為 0 Random NumberEncrypted Diversifier 應為 0.
ThinkPad TrackPoint Keyboard II, Pebble M350 mouse, Logitech G604 Lightspeed mouse
  • 複製 IRK
  • 反轉十六進制字節的順序
  • 複製 Remote IRK
  • 將其從base64轉換為十六進制
IdentityResolvingKey.Key
  • 複製 LTK,刪除十六進制字節之間的空格
  • 複製 Remote Encryption > Long-term Key.
  • 將其從base64轉換為十六進制
LongTermKey.Key
  • 複製 ERand
  • 反轉十六進制字節的順序
  • 整體轉換為十進制
  • 複製 Remote Encryption > Random Number
  • 將其從base64轉換為十六進制
  • 反轉十六進制字節的順序
LongTermKey.Rand
  • 複製 EDIV
  • 反轉十六進制字節的順序
  • 整體轉換為十進制
  • 複製 Remote Encryption > Encrypted Diversifier
  • 將其從base64轉換為十六進制
  • 反轉十六進制字節的順序
LongTermKey.EDiv
Logitech M585/M590
  • 複製 IRK
  • 反轉十六進制字節的順序
IdentityResolvingKey.Key
  • 複製 LTK,刪除十六進制字節之間的空格
LongTermKey.Key
  • 複製 ERand
  • 反轉十六進制字節的順序
  • 整體轉換為十進制
LongTermKey.Rand
  • 複製 EDIV
  • 整體轉換為十進制(可直接複製deword的十進制值)
LongTermKey.EDiv
其他設備
  • 複製 LTK
  • 刪除16進制字節之間的空格
  • 複製 Remote IRK
  • 將其從base64轉換為十六進制
LongTermKey.Key
  • 複製 ERand
  • 反轉十六進制字節的順序
  • 整體轉換為十進制
  • 複製 Remote Encryption > Long-term Key
  • 將其從base64轉換為十六進制
LongTermKey.Rand
  • 複製 EDIV
  • 刪除16進制字節之間的空格
  • 複製 Remote Encryption > Encrypted Diversifier
  • 將其從base64轉換為十六進制
  • 反轉十六進制字節的順序
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'...'))

例如,在通常情況下:

  • LTK48 4D AF CD 0F 92 22 88 0A 52 9A F4 76 DA 8B 94,轉換為 LongTermKey.Key 應為 484DAFCD0F9222880A529AF476DA8B94.
  • ERand63 02 84 B8 5D 40 44 DF, 轉換為 Rand 應為 16088054540146049635.
  • EDIV37520,轉換為EDiv 應為 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)。

現在應該可以連接到你的設備了。

注意: 取決於藍牙管理器,可能需要完全重啟才能重新連接到設備。

配置[編輯 | 編輯原始碼]

默認電源狀態[編輯 | 編輯原始碼]

截至 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 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"

啟用實驗性功能[編輯 | 編輯原始碼]

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]

注意: 有時要用 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

疑難解答[編輯 | 編輯原始碼]

本文內容或本節內容已經過期。

原因: Replace hciconfig with newer commands. (在Talk:藍牙討論)

Debugging(排除故障)[編輯 | 編輯原始碼]

為了調試,首先停止 bluetooth.service

然後用-d參數:

# /usr/lib/bluetooth/bluetoothd -n -d

另一種選擇是用btmon工具。

棄用的 BlueZ 工具[編輯 | 編輯原始碼]

八個BlueZ tools已經棄用 並從bluez-utils 中移除,儘管並非所有這些都被更新的工具所取代。The bluez-utils-compatAUR 提供了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.serviceunit 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中看不到,你能作為iProductlsusb-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-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(由於符號連結,無法接收傳輸的文件)[編輯 | 編輯原始碼]

如果在功能正常的藍牙連接上傳入文件傳輸失敗,則問題可能是由於文件傳輸路徑中的符號連結造成的。日誌中會顯示這樣的日誌:

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上的設備管理器中找到固件文件路徑)。

  1. 在軟件開發中,回歸錯誤是指在新版本或新功能中引入的錯誤,這導致現有功能或已修復的錯誤再次出現。 回歸錯誤可能是由於代碼更改、庫更新、配置更改等原因導致的。它們通常表現為程序中的錯誤、異常、崩潰或數據不一致。
  2. 比如省電模式,可能導致藍牙服務默認關閉
  3. https://lkml.kernel.org/lkml/D577711C-4AF5-4E82-8A17-E766B64E15A9@holtmann.org/