藍牙 - Arch Linux 中文维基

跳至內容

# 藍牙

出自 Arch Linux 中文维基

相關文章

- 藍牙滑鼠
- 藍牙耳機

翻譯狀態：

- 本文（或部分內容）譯自 Bluetooth，最近一次同步於 2022-12-31，若英文版本有所更改，則您可以幫助同步與翻譯更改的內容。
- 您可以在 ArchWiki 的對應頁面找到本文翻譯的原始修訂歷史。
- 本文可能與英文原文存在出入。

藍牙（Bluetooth）是一個短距離無線通信標準，用於在手機、計算機和其他電子設備之間通信。在 Linux 中，權威的藍牙協議棧實現是 BlueZ。

## 安裝

1. 安裝 bluez包，這個軟體包提供藍牙協議棧。
2. 安裝 bluez-utils包，這個軟體包提供 `bluetoothctl` 實用程序。另外，也可以安裝 bluez-deprecated-tools包 來獲得#棄用的 BlueZ 工具。
3. `btusb` 內核模塊是通用藍牙驅動。檢查模塊是否已加載。如果還沒有，先加載模塊。
4. 啟動/啟用 `bluetooth.service`。

注意：

- 藍牙守護程序默認只會向屬於 `lp` 組的用戶暴露 bnep0 設備。如果要連接到藍牙設備的話，需先將用戶添加到這個組。可以在 `/usr/share/dbus-1/system.d/bluetooth.conf` 中修改需要加入的組。
- 一些藍牙適配器和無線網卡綁定（例如 Intel Centrino）。這些藍牙適配器需要先啟用無線網卡（在筆記本上通常通過鍵盤快捷鍵）才能被內核識別。
- 一些藍牙適配器（例如 Broadcom）和網絡適配器衝突。因此，需要確保在網絡服務啟動之前連接藍牙。
- 一些工具（例如 hcitool 和 hciconfig）已被上游棄用，並且不再包含在 bluez-utils包 中。這些工具將不會被更新，因此建議更新腳本，避免使用它們。如果還是想用，安裝 bluez-deprecated-tools包。參見 FS#53110 和 Bluez 郵件列表。
- 從此 commit 開始， bluez-obex包 和 bluez-mesh包 已經從 bluez包 中獨立出來，因此如果要通過藍牙傳輸文件，必須安裝 bluez-obex包。

### 前端

#### 控制台

- bluetoothctl — 在 shell 中配對設備是最簡單可靠的方法之一。

  http://www.bluez.org/ || bluez-utils包

- bluetuith — 為終端界面提供藍牙管理器，可以方便的配對和管理設備，具有 OBEX 文件傳輸和滑鼠支持。

  https://www.github.com/darkhz/bluetuith || bluetuithAUR

提示：要自動化 bluetoothctl 命令，使用 `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` 命令）。

  https://wiki.gnome.org/Projects/GnomeBluetooth ||

- Bluedevil — KDE 的藍牙工具。如果 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 系統的情況，僅需確保 `/var/lib/bluetooth/BT-Adapter-MAC-address` 下的所有文件在兩個系統中相同即可。既可以複製，也可以通過連結實現。

而對於 Windows 或 MacOS，需要在 Linux 下手動更改配對密鑰，以使其與 Windows 或 macOS 下的密鑰保持一致。

這裡只介紹手動配置的方法，自動化方法參見 bt-dualboot 等項目。如果需要半自動化工具，考慮使用 bluetooth-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 設備，只需要一個密鑰。如果這個設備有多個密鑰（比如 `LTK` 或 `IRK`），那麼這是一個藍牙 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

如果該環境下沒有 `CurrentControlSet`，但存在 `ControlSet00X`，那麼執行

    > cd ControlSet00X\Services\BTHPORT\Parameters\Keys

這裡可能僅有一個以藍牙適配器的 MAC 地址為名的子密鑰。 使用 `ls` 查看並 `cd` 進去：

    > ls
    > cd your-adapter's-mac-address

該適配器下的子密鑰名就是適配器配對的設備的 MAC 地址。 使用 `ls`查看，並 `cd` 進入所有你想要在雙系統下配對的設備：

    > ls
    > cd your-device's-mac-address

如果不是藍牙 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"
    >>> " ".join(reversed(key.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 Anywhere 3S Logitech MX Master 3 Logitech MX Master 3S Logitech MX Keys Logitech MX Keys Mini Logitech MX Mechanical Xbox One S Wireless Controller | 複製 `IRK` 刪除十六進制字節之間的空格 | ? | `IdentityResolvingKey.Key`
複製 `LTK`. 刪除十六進制字節之間的空格 | ? | `SlaveLongTermKey.Key` 與 `PeripheralLongTermKey.Key`
`ERand` 和 `EDIV` 應為 `0` | Random Number 與 Encrypted Diversifier 應為 `0`. | –
Logitech MX Anywhere 2S | Copy `IRK`. Remove the spaces between the hex octets. | ? | `IdentityResolvingKey.Key`
Copy `CSRK`. Remove the spaces between the hex octets. | ? | `LocalSignatureKey.Key`
Copy `LTK`. Remove the spaces between the hex octets. | ? | `LongTermKey.Key`
Copy `KeyLength`. Convert the whole number to decimal. | ? | `LongTermKey.EncSize`
Copy `EDIV`. Convert the whole number to decimal. | ? | `LongTermKey.EDiv`
Copy `ERand`. Reverse the order of the octets. Convert the whole number to decimal. | ? | `LongTermKey.Rand`
Royal Kludge F68 keyboard is like the Logitech MX Anywhere 2S | Also copy `CSRKInbound` too. Remove the spaces between the hex octets. | ? | `RemoteSignatureKey.Key`
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轉換為小端十進制數字（參見下方 Python 腳本） | `LongTermKey.Rand`
複製 `EDIV` 反轉十六進制字節的順序 整體轉換為十進制 | 複製 Remote Encryption > Encrypted Diversifier 將其從base64轉換為小端十進制數字（參見下方 Python 腳本） | `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`
Xbox wireless controller | Copy `LTK`. Remove the spaces between the hex octets. | ? | `SlaveLongTermKey.Key`

注意：

- 刪除十六進制字節間的空格，可使用 這一在線工具 或這段 Python 代碼:

    >>> "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('<Q', base64.decodebytes(b'...'))

例如，在通常情況下:

- `LTK` 為 `48 4D AF CD 0F 92 22 88 0A 52 9A F4 76 DA 8B 94`，轉換為 `LongTermKey.Key` 應為 `484DAFCD0F9222880A529AF476DA8B94`.
- `ERand` 為 `63 02 84 B8 5D 40 44 DF`， 轉換為 `Rand` 應為 `16088054540146049635`.
- `EDIV` 為 `37520`，轉換為`EDiv` 應為 `37520`.

#### 保存配置

獲得密鑰後，切換用戶為 root，然後輸入：

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

在此處可以找到每個已配對藍牙設備的文件夾。對於要與 Arch 和雙啟動配對的每個設備，執行以下操作：

    # cd device-MAC-address

注意：若使用的是會在配隊後自增MAC地址的設備，請在這一步改成將MAC地址文件夾改成自增後的。可以直接從Windows複製MAC地址過來，也可以手動自增（注意到每個8bit字節都是一個兩位十六進制數）。

如果的設備不是藍牙5.1設備（只有一個密鑰），編輯 `info` 文件，改變 `[LinkKey]` 中列出的密鑰。例如：

    info

    [LinkKey]
    Key=XXXXXXXXXXXXXXX

注意：確保所有字母都大寫，並且刪除所有空格。

如果有多個藍牙 5.1 的密鑰，編輯 `info` 文件並將所有適用的密鑰替換為記錄的值。例如，對於 Xbox One S 無線手柄：

    info

    [IdentityResolvingKey]
    Key=<IdentityResolvingKey.Key>

    [PeripheralLongTermKey]
    Key=<PeripheralLongTermKey.Key>

    [SlaveLongTermKey]
    Key=<SlaveLongTermKey.Key>

然後重新啟動 `bluetooth.service` 和 `pulseaudio`（使用 `pulseaudio -k && pulseaudio --start`）。

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

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

## 配置

### 默認電源狀態

截至 bluez包 5.65, 它的默認行為是在啟動服務或從掛起恢復時打開所有藍牙適配器的電源[2]

如果希望藍牙在重啟後不自動啟動(比如要在行動裝置中節省電量)。需要將 `AutoEnable=false` 添加在 `/etc/bluetooth/main.conf` 底部的 `[Policy]` 下面：

    /etc/bluetooth/main.conf

    [Policy]
    AutoEnable=false

禁用後可以用 `power on` 命令開啟。

### 啟動後自動可被發現

如果設備應該總是可見或者可以直接連接：

    /etc/bluetooth/main.conf

    [General]
    DiscoverableTimeout = 0

### 從掛起中喚醒

允許藍牙滑鼠或者藍牙鍵盤將系統從掛起中喚醒。首先，檢查bios設置確認從USB中喚醒功能沒有被禁止。許多情況下，藍牙在主板上被看作是USB設備。

獲得藍牙適配器的廠商代碼和設備ID。

    $ lsusb | grep bluetooth -i

    Bus 001 Device 002: ID 8087:0039 Intel Corp. AX200 Bluetooth

針對（上面適配器的）廠商代碼和設備ID增加新的udev規則來允許從掛起中喚醒。

    /etc/udev/rules.d/91-keyboard-mouse-wakeup.rules

    SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0039" RUN+="/bin/sh -c 'echo enabled > /sys$env{DEVPATH}/../power/wakeup;'"

如果系統喚醒後，要自動重新配置藍牙鍵盤，例如，設置不同的鍵盤布局或者按鍵重複速度（相關細節，查看Xorg/Keyboard configuration#Adjusting typematic delay and rate 和 xmodmap），可以創建一個可執行腳本：

    configure_keyboard.sh

    #!/bin/sh
    export DISPLAY=:0
    xset r rate 220 30
    xmodmap /your/path/to/.Xmodmap

然後創建一個像上面一樣的額外的udev規則。

    /etc/udev/rules.d/92-keyboard-reconfiguration-wakeup.rules

    SUBSYSTEM=="usb", ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0039" RUN+="/your/path/to/configure_keyboard.sh"

### 啟用實驗性功能

Bluez 堆棧將新的、有可能出現錯誤的功能放在 D-Bus 實驗性和內核實驗性選項後面。這些功能隨著時間的推移而變化，因為實驗性功能被確定為穩定，不再需要該選項。要啟用這些功能，請取消配置中相應行的注釋：

    /etc/bluetooth/main.conf

    ...

    # Enables D-Bus experimental interfaces
    # Possible values: true or false
    #Experimental = true

    # Enables kernel experimental features, alternatively a list of UUIDs
    # can be given.
    # Possible values: true,false,<UUID List>
    # Possible UUIDS:
    ...
    # Defaults to false.
    #KernelExperimental = true

或者說， 你可以編輯 `bluetooth.service` 來添加 `--experimental` 或者 `--kernel` 標識，類似這個 drop-in file:

    /etc/systemd/system/bluetooth.service.d/override.conf

    [Service]
    ExecStart=
    ExecStart=/usr/lib/bluetooth/bluetoothd --experimental

無論是哪種方式，你都必須在之後重啟 `bluetooth.service`

## 音頻

通常你需要採取額外的步驟去整合針對藍牙的音頻服務。下面的章節會給出相關細節。

查看藍牙耳機頁面獲得更多關於藍牙音頻和藍牙耳機的信息。

### PulseAudio

要使用藍牙耳機或音響的話要先安裝 pulseaudio-bluetooth包。 要確認重新啟動pulseaudio來使得安裝生效：`pulseaudio -k`。默認的PulseAudio配置就可以直接用藍牙耳機或音響了。[3]。

注意：有時要用 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:XX` 和 `FILE.wav`）：

    $ aplay -D bluealsa:SRV=org.bluealsa,DEV=XX:XX:XX:XX:XX:XX,PROFILE=a2dp FILE.wav

最後，增加下面的配置行到你的 `~/.asoundrc` ：

    ~/.asoundrc

    defaults.bluealsa {
        service "org.bluealsa"
        device "XX:XX:XX:XX:XX:XX"
        profile "a2dp"
    }

現在你可以使用`bluealsa`設備來訪問你的藍牙音頻設備。可以使用帶有參數 `-D bluealsa` 的命令 `alsamixer` 來進行音量管理。

## 藍牙串口

如果要在Bluetooth-to-Serial模塊 (HC-05, HC-06）上進行藍牙串口通信，需要執行下面的步驟：

使用 `bluetoothctl` 配對你的藍牙設備，像上面所描述的那樣。

安裝 bluez-deprecated-tools包，因為它提供了我們需要的特定的功能，這些功能沒有被新工具支持。

綁定已經配對的設備的MAC地址到tty終端：

    # rfcomm bind rfcomm0 MAC_address_of_Bluetooth_device

現在你可以打開 `/dev/rfcomm0` 來進行串口通信：

    $ picocom /dev/rfcomm0 -b 115200

## 疑難解答

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

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

### Debugging（排除故障）

為了調試，首先停止 `bluetooth.service`。

然後用-d參數：

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

另一種選擇是用`btmon`工具。

### 棄用的 BlueZ 工具

八個BlueZ tools已經棄用並從bluez-utils包 中移除,儘管並非所有這些都被更新的工具所取代。bluez-deprecated-tools包 提供了bluez-utils包 的替代版本包，使用了不推薦使用的工具。

不推薦的工具 | 推薦的替代品
--- | ---
gatttool | btgatt-client, D-Bus Gatt API
hciattach | btattach
hciconfig | btmgmt (and bluetoothctl?)
hcidump | btmon (and btsnoop)
hcitool | missing, D-Bus Device API available
rfcomm | missing, implement with D-Bus Profile1 API?
ciptool
sdptool | missing, functionality seems to be scattered over different D-Bus objects: Profile, Advertising, and the UUIDs arrays in device and adapter.

### gnome-bluetooth（gnome桌面環境下的藍牙管理器）

如果接收文件時出現以下信息：

    Bluetooth OBEX start failed: Invalid path
    Bluetooth FTP start failed: Invalid path

確保 XDG user directories 存在。

### 外置USB藍牙/2.4GHz接收器

如果你在使用外置USB藍牙/2.4GHz接收器，你要先檢查藍牙接收器是否被識別。插入USB接收器後可通過 `journalctl -f` 檢測（或查看 `/var/log/messages.log`）。 可能像下面這樣:(注意hci）：

    Feb 20 15:00:24 hostname kernel: [ 2661.349823] usb 4-1: new full-speed USB device number 3 using uhci_hcd
    Feb 20 15:00:24 hostname bluetoothd[4568]: HCI dev 0 registered
    Feb 20 15:00:24 hostname bluetoothd[4568]: Listening for HCI events on hci0
    Feb 20 15:00:25 hostname bluetoothd[4568]: HCI dev 0 up
    Feb 20 15:00:25 hostname bluetoothd[4568]: Adapter /org/bluez/4568/hci0 has been enabled

如果只有前兩行，說明系統找到了設備而只需要啟動它。 例：

    hciconfig -a hci0

    hci0:	Type: USB
    	BD Address: 00:00:00:00:00:00 ACL MTU: 0:0 SCO MTU: 0:0
    	DOWN
    	RX bytes:0 acl:0 sco:0 events:0 errors:0
            TX bytes:0 acl:0 sco:0 commands:0 errors:

    # hciconfig hci0 up

    hciconfig -a hci0

    hci0:	Type: USB
    	BD Address: 00:02:72:C4:7C:06 ACL MTU: 377:10 SCO MTU: 64:8
    	UP RUNNING
    	RX bytes:348 acl:0 sco:0 events:11 errors:0
            TX bytes:38 acl:0 sco:0 commands:11 errors:0

用 `bluez-utils` 裡的 `hcitool` 檢查設備是否被檢測到。 要獲取可用設備和他們的標識和MAC地址可以輸入：

    $ hcitool dev

    Devices:
            hci0	00:1B:DC:0F:DB:40

設備的詳細信息可以用`hciconfig`獲取 ：

    $ hciconfig -a hci0

    hci0:   Type: USB
            BD Address: 00:1B:DC:0F:DB:40 ACL MTU: 310:10 SCO MTU: 64:8
            UP RUNNING PSCAN ISCAN
            RX bytes:1226 acl:0 sco:0 events:27 errors:0
            TX bytes:351 acl:0 sco:0 commands:26 errors:0
            Features: 0xff 0xff 0x8f 0xfe 0x9b 0xf9 0x00 0x80
            Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3
            Link policy: RSWITCH HOLD SNIFF PARK
            Link mode: SLAVE ACCEPT
            Name: 'BlueZ (0)'
            Class: 0x000100
            Service Classes: Unspecified
            Device Class: Computer, Uncategorized
            HCI Ver: 2.0 (0x3) HCI Rev: 0xc5c LMP Ver: 2.0 (0x3) LMP Subver: 0xc5c
            Manufacturer: Cambridge Silicon Radio (10)

#### 音頻設備開始在離USB接收器較近的距離來回切換

如果有其他設備（和當前設備）共用同一個USB主機，它們可能會中斷與音頻設備的通信。 確保它是唯一連接到其總線的設備。例如：

    $ lsusb

    Bus 002 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
    Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 001 Device 004: ID 048d:1345 Integrated Technology Express, Inc. Multi Cardreader
    Bus 001 Device 003: ID 0424:a700 Standard Microsystems Corp. 2 Port Hub
    Bus 001 Device 002: ID 8087:0024 Intel Corp. Integrated Rate Matching Hub
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

#### CSR 接收器 0a12:0001

該設備 `ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)` 有一個回歸錯誤[1], 目前僅適用於5.17和<6.0版本的內核。若想獲得更多相關信息，請參閱Kernel Bug 60824.

### 羅技雙模外置藍牙/2.4GHz可切換USB接收器

羅技的外置USB接收器 （例如羅技MX5000）可以在兩種模式下運行：2.4GHz接收器模式（模擬USB模式）和HCI（藍牙模式）。在2.4GHz接收器模式下，接收器模擬了USB設備，所以在您的計算機上，您就像在用普通的USB有線滑鼠/鍵盤一樣。

如果您按住接收器上的紅色小按鈕，它會啟用其他模式。按住接收器上的紅色按鈕並將其插入計算機，按住按鈕3-5秒後，將以藍牙模式接入設備。藍牙圖標會出現在系統托盤裡。討論

或者，您可以安裝bluez-hid2hci包當您連接羅技的接收器時，它可以自動切換模式。

### hcitool掃描：找不到設備

- 在一些戴爾筆記本電腦（例如Studio 15）上，您必須將藍牙模式從HID切換到HCI。安裝bluez-hid2hci包，那麼udev應該會自動執行此操作。或者，您可以運行此命令手動切換到HCI：

    # /usr/lib/udev/hid2hci

- 如果設備沒有顯示，並且您的計算機上有Windows系統，請嘗試引導它並從Windows啟用藍牙適配器。

- 有時，如下這個簡單的命令能幫到您：

    # hciconfig hci0 up

### bluetoothctl: No default controller available（沒有可用的默認控制項）

一些主板藍牙控制項出現錯誤。要查看這是否是問題所在，請運行`journalctl|grep-hci`。如果出現「Command tx timeout」或「Failed to read Intel version command」之類的報錯，請關閉電腦電源，並拔下電源線幾秒鐘。這會強制控制項重新加載固件（而標準重新啟動不會）。請參閱此處的錯誤報告。

確保設備沒有被rfkill阻止。

藍牙服務（軟體）無法正確識別一些英特爾設備（硬體）（如8260）也可能發生這種情況。在某些情況下，使用不推薦使用的bluez utils compataAUR來代替bluez utils包據報道已經解決了這個問題。

這也可能是由電源策略[2]引起的，在這種情況下，添加內核參數`btusb.enable_autosuspend=n`是一個潛在的解決方案。另請參閱Red Hat Bugzilla–Bug 1573562。

有時，在沒有選項的情況下重新加載`btusb`有助於恢復控制項：

    # modprobe -r btusb
    # modprobe btusb

當接收器是CSR克隆時也可能發生這種情況

### systemd: Condition check resulted in Bluetooth service being skipped（條件檢查導致跳過藍牙服務）

`bluetooth.service`只需要存在於`/sys/class/bluetooth` 目錄即可，該目錄應由內核模塊 `bluetooth`創建，只有當 `systemd-udev` 真正找到一個工作的藍牙硬體設備時，它才會自動加載。

如果您的`/sys/class/bluetooth` 不存在，請檢查您的內核藍牙模塊是否由`lsmod`加載。如果沒有， 並且您很確定自己有藍牙設備， 您可以嘗試通過加載藍牙模塊並重新啟動`bluetooth.service`，來重新啟動這些服務。

在加載`bluetooth`模塊時，您還應該加載相應的內核藍牙驅動程序，一般用`btusb`,但是也可以用`btrtl,btintel,btbcm,bnep,btusb` 等。

檢查`bluetooth.service`的 unit status （單元狀態），看看它是否啟動。

另請參閱 Debian Bug report logs - #853207.

如果 `bluetooth.service` 成功啟動，但有可能您仍然無法正常使用藍牙(例如， `bluetoothctl` 在您`scan on`時顯示類似`org.Bluez.Error.NotReady` )。如果發生這種情況，請嘗試重新啟動計算機，並仔細檢查：目錄`/sys/class/bluetooth` 是否存在； `lsmod` 是否包括正確的藍牙模塊；在 journal中記錄的信息; 等。 `systemd-udev` 應該自動檢測出您的藍牙硬體，而無需再次手動更改。

### rfkill unblock：不能unblock

如果你的設備unblock後依然是soft blocked，試試：

    $ connmanctl enable bluetooth

### 電腦藍牙不可見

手機藍牙掃描不到電腦？啟動PSCAN和ISCAN：

    # enable PSCAN and ISCAN
    $ hciconfig hci0 piscan
    # check it worked

    $ hciconfig

    hci0:   Type: USB
            BD Address: 00:12:34:56:78:9A ACL MTU: 192:8 SCO MTU: 64:8
            UP RUNNING PSCAN ISCAN
            RX bytes:20425 acl:115 sco:0 events:526 errors:0
            TX bytes:5543 acl:84 sco:0 commands:340 errors:0

注意：在 `/etc/bluetooth/main.conf` 檢查設備可見超時和配對超時

嘗試在 `/etc/bluetooth/main.conf` 中更改設備類，如下所示：

    # Default device class. Only the major and minor device class bits are
    # considered.
    #Class = 0x000100 (from default config)
    Class = 0x100100

這是讓我的電腦對我的手機可見的唯一解決方案。

### Foxconn / Hon Hai / Lite-On Broadcom device（富士康/鴻海/光寶/博通 設備）

其中一些設備需要在啟動時將固件快閃記憶體到設備中。沒有提供固件，但可以使用hex2hcd包（與bluez utils包一起安裝）將Microsoft Windows.hex文件轉換為.hcd包)。

為了獲得正確的.hex文件，請嘗試搜索設備供應商：使用lsusb獲得的產品代碼，例如：

       ...
       Bus 002 Device 004: ID 04ca:2006 Lite-On Technology Corp. Broadcom BCM43142A0 Bluetooth Device
       ...

or

       Bus 004 Device 004: Id 0489:e031 Foxconn / Hon Hai

或者，啟動到Windows（安裝虛擬機即可），並從設備管理器獲取固件名稱。如果你想知道你的設備的型號，但在lsusb中看不到，你能作為`iProduct`用lsusb-v看到它。

也可以從下載的Windows驅動程序中提取.hex文件，而無需為其運行Windows。下載合適的驅動程序，例如 Bluetooth Widcomm ( 在為Lifebook P771[失效連結 2022-09-17 ⓘ] 提供的驅動中有列出)，其中包含許多Broadcomm設備的驅動程序。在藍牙Widcomm的情況下，驅動程序是一個自提取的RAR檔案，因此可以使用unrar包提取包 x。T要找出眾多.hex文件中哪一個最適合您，請查找文件`Win32/bcbtums-win7x86-brcm.inf`並搜索`[RAMUSBE031.CopyList]`，其中`E031` 應替換為大寫的設備的產品代碼(lsusb中的第二個十六進制數)。在下面，您應該看到正確的.hex文件的文件名。

您有了.hcd文件，就把它複製到`/lib/firmware/brcm/BCM.hcd` 中——這個文件名是`dmesg`建議的，在您的情況下可能會更改，所以請檢查您的dmesg 輸出以進行驗證。然後重新加載btusb模塊：

    # rmmod btusb
    # modprobe btusb

在某些情況下（使用較舊的內核？），您必須使用brcm_patchram_plus utility來快閃記憶體.hcd文件，該實用程序由brcm_patchram_plus-gitAUR[損壞的連結：package not found] 提供。首先，確保dmesg 中的設備被btusb識別為藍牙設備。然後，運行以下操作（用您的供應商產品替換04ca 2006）：

    # echo '04ca 2006' > /sys/bus/usb/drivers/btusb/new_id

啟用設備：

    # hciconfig hci0 up

寫入固件

    # brcm_patchram_plus_usb --patchram fw-04ca_2006.hcd hci0

該設備現在應該可用。請參閱 BBS#162688 ，了解有關使這些更改持久化的信息。

### Intel combined WiFi and Bluetooth cards(英特爾集成式WIFI和藍牙）

請參閱Wireless network configuration#Bluetooth coexistence.

### 設備配對成功，一段時間後意外斷開

如果運行 `journalctl`有以下結果，並且你的設備配對後過一會兒又斷開：

    bluetoothd: Unable to get connect data for Headset Voice gateway: getpeername: Transport endpoint is not connected (107)
    bluetoothd: connect error: Connection refused (111)

這可能是因為你在其它作業系統中用同樣的藍牙適配器配對了這個設備（比如雙系統）。有的設備不能處理與同一MAC地址相關聯的多個不同配對。你可以移除設備後重新配對：

    $ bluetoothctl
    [bluetooth]# devices
    Device XX:XX:XX:XX:XX:XX My Device
    [bluetooth]# remove XX:XX:XX:XX:XX:XX

再重啟 `bluetooth.service`，打開藍牙適配器，讓設備可見，重新掃描配對。因為藍牙管理器不一樣，有時需要重啟系統。

### 掃描不到設備

有的節能藍牙設備用bluetoothctl掃描不到，比如某些藍牙滑鼠(如Logitech MX Master)。可以嘗試使用`transport le`來掃描設備:

    # bluetoothctl

    [bluetooth]# menu scan
    [bluetooth]# transport le
    [bluetooth]# back
    [bluetooth]# scan on
    [bluetooth]# devices
    ...
    Device XX:XX:XX:XX:XX:XX device name <---- 這個就是你的設備

另一種方法是安裝 bluez-deprecated-tools包 再啟動 `bluetooth.service` 再輸入：

    # bluetoothctl
    [NEW] Controller (MAC) myhostname [default]
    [bluetooth]# power on
    [CHG] Controller (MAC) Class: 0x0c010c
    Changing power on succeeded
    [CHG] Controller (MAC) Powered: yes
    [bluetooth]# scan on
    Discovery started
    [CHG] Controller (MAC) Discovering: yes

在另一個終端裡輸入：

    # hcitool lescan

等待你的設備出現，再按 Ctrl+C。 bluetoothctl 就可以獲取你的設備並正常配對了。

### Cannot receive transferred files due to symlink（由於符號連結，無法接收傳輸的文件）

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

    Jun 18 11:18:13 ember obexd[3338969]: open(/home/me/.cache/obexd/MOC740): Operation not permitted (1)

如果錯誤消息中顯示的路徑包含符號連結，則obexd默認情況下不會接受它。初始化時可以使用`obex.service`用戶服務的Drop-in file覆蓋該行為：

    ~/.config/systemd/user/obex.service.d/10-symlink.conf

    [Service]
    ExecStart=
    ExecStart=/usr/lib/bluetooth/obexd --symlinks

然後重新加載調用用戶的systemd管理器配置，並重新啟動`obex.service`用戶單元。

### 耳機和滑鼠之間的干擾

如果您在同時使用藍牙滑鼠和鍵盤時遇到音頻斷斷續續的問題，您可以嘗試以下#23中提到的方法 https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/424215

    # hciconfig hci0 lm ACCEPT,MASTER
    # hciconfig hci0 lp HOLD,SNIFF,PARK

### 藍牙滑鼠動作延遲

嘗試編輯文件 `/var/lib/bluetooth/XX:XX:XX:XX:XX:XX/YY:YY:YY:YY:YY:YY/info` (`XX:XX:XX:XX:XX:XX`-您的藍牙適配器MAC地址，`YY:YY:YY:YY:YY:YY` -您的滑鼠MAC地址），並添加以下行：

    [ConnectionParameters]
    MinInterval=6
    MaxInterval=9
    Latency=44
    Timeout=216

您可以通過運行`hcitool dev`命令查看本地適配器的MAC地址。您可以通過執行`hcitool con`命令查看當前連接的遠程設備的MAC地址。

### 掛起/休眠後適配器消失

首先，查找適配器的供應商和產品ID。例如：

    $ lsusb -tv

    /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
        ID 1d6b:0002 Linux Foundation 2.0 root hub
        ...
        |__ Port 3: Dev 3, If 0, Class=Wireless, Driver=btusb, 12M
            ID 8087:0025 Intel Corp.
        |__ Port 3: Dev 3, If 1, Class=Wireless, Driver=btusb, 12M
            ID 8087:0025 Intel Corp.
        ...

在以上的例子中，供應商ID是8087，產品ID是0025。

然後，使用 usb_modeswitch包重置你指定的適配器：

    # usb_modeswitch -R -v vendor_ID -p product_ID

### Problems with all BLE devices on kernel （5.9+內核版本5.9以上所有BLE設備的問題）

從v5.9開始，內核藍牙堆棧嘗試在BLE連接上使用鏈路層隱私。如果設備在配對後工作，但無法在重新啟動或掛起後繼續運行，可能是因為這個原因。

要解決[3]此問題，請打開`/var/lib/bluetooth/adapter_mac/device_mac/info`刪除以下行，然後重新啟動`bluetooth.service`:

    [IdentityResolvingKey]
    Key=...

請參閱Arch論壇上的相關討論。

### Bluetooth immediately waking up suspend-to-idle devices（藍牙突然喚醒掛起的空閒設備）

在能夠掛起到空閒 suspend-to-idle/S2idle/S0ix/Modern Standby的系統上，藍牙控制項將在睡眠期間保持啟用狀態。如果連接了藍牙設備，這通常會導致系統在進入睡眠狀態後立即喚醒。

為了防止這種情況，你可以在啟用睡眠模式前完全禁用藍牙——安裝T bluez-utils包 並創建此文件：

    /etc/systemd/system/bluetooth-disable-before-sleep.service

    [Unit]
    Description=Disable Bluetooth before going to sleep
    Before=sleep.target
    Before=suspend.target
    Before=hybrid-sleep.target
    Before=suspend-then-hibernate.target
    StopWhenUnneeded=yes

    [Service]
    Type=oneshot
    RemainAfterExit=yes

    ExecStart=/usr/bin/bluetoothctl power off
    ExecStop=/usr/bin/bluetoothctl power on

    [Install]
    WantedBy=sleep.target
    WantedBy=suspend.target
    WantedBy=hybrid-sleep.target
    WantedBy=suspend-then-hibernate.target

啟用此服務並檢查藍牙設備在進入睡眠狀態時是否斷開連接，以及在喚醒系統後藍牙何時恢復連接。

如果使用此解決方法，則使用藍牙滑鼠/鍵盤喚醒系統將不起作用。

### 持續連接/斷開與TP-LINK UB400和Xbox手柄的連接

使用以下設置：

    /etc/bluetooth/main.conf

    ...
    [General
    JustWorksRepairing = always
    FastConnectable = true
    Class = 0x000100
    ...
    [GATT]
    ReconnectIntervals=1,1,2,3,5,8,13,21,34,55
    AutoEnable=true
    ...

然後重新啟用`bluetooth.service`.

你可以參閱discussion on xpadneo 但不需要xpadneo驅動程序

### Mediatek MT7921或MT7961在帶有windows的雙啟動系統上

在雙啟動系統上，如果Windows和Linux的藍牙固件版本不同，則藍牙適配器在重新啟動到Windows後無法工作。

防止這種情況的最佳方法是為每個作業系統更新最新版本的藍牙驅動程序（尤其是固件）。

如果找不到Windows的最新版本驅動程序（或固件），可以從Arch Linux複製最新的固件文件`/usr/lib/firmware/mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin.xz` 並提取到Windows(例如`C:\WINDOWS\system32\DRIVERS\`，可以在Windows上的設備管理器中找到固件文件路徑）。

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

分類：​

- 藍牙
- 使用「模板:過時」標記的頁面或章節
- 包含失效連結的頁面
- 包含損壞的軟體包連結的頁面

藍牙
新增話題