绑定和连接后 BlueZ BLE 加密特征读取失败

BlueZ BLE Ecrypted Characteristic Read fails after bonding and connecting

我正在使用 Raspberry Pi 作为 BLE 外设和 nRF Connect 工具作为 BLE 客户端。在 Raspberry Pi 中,我在 Bluez 测试文件夹中给出 运行 Simple Agent Test Program, Advertisement Program and Gatt Server Program

从nRF Connect Tool,我首先绑定了设备并连接了设备。我附上了该过程的 dbus 日志。

  1. 绑定时,日志显示如下

signal time=1595076323.849939 sender=:1.15 -> destination=(null destination) serial=863 path=/org/bluez/hci0/dev_04_C8_07_BC_23_7A; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged

  string "org.bluez.Device1"
   array [
      dict entry(
         string "Connected"
         variant             boolean true
      )
   ]
   array [
   ]
method call time=1595076324.986873 sender=:1.15 -> destination=:1.79 serial=864 path=/test/agent; interface=org.bluez.Agent1; member=RequestConfirmation
   object path "/org/bluez/hci0/dev_04_C8_07_BC_23_7A"
   uint32 243301
  1. 连接时,日志显示如下:

     signal time=1595076345.854856 sender=:1.15 -> destination=(null destination) serial=868 path=/; interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
    object path "/org/bluez/hci0/dev_7A_5D_49_4F_ED_08"
    array [
       dict entry(
          string "org.freedesktop.DBus.Introspectable"
          array [
          ]
       )
       dict entry(
          string "org.bluez.Device1"
          array [
             dict entry(
                string "Address"
                variant                   string "7A:5D:49:4F:ED:08"
             )
             dict entry(
                string "AddressType"
                variant                   string "random"
             )
             dict entry(
                string "Alias"
                variant                   string "7A-5D-49-4F-ED-08"
             )
             dict entry(
                string "Paired"
                variant                   boolean false
             )
             dict entry(
                string "Trusted"
                variant                   boolean false
             )
             dict entry(
                string "Blocked"
                variant                   boolean false
             )
             dict entry(
                string "LegacyPairing"
                variant                   boolean false
             )
             dict entry(
                string "Connected"
                variant                   boolean true
             )
             dict entry(
                string "UUIDs"
                variant                   array [
                   ]
             )
             dict entry(
                string "Adapter"
                variant                   object path "/org/bluez/hci0"
             )
             dict entry(
                string "ServicesResolved"
                variant                   boolean false
             )
          ]
       )
       dict entry(
          string "org.freedesktop.DBus.Properties"
          array [
          ]
       )
    ]
    

我对以下内容感到困惑:

  1. 虽然绑定和连接路径不同:/org/bluez/hci0/dev_04_C8_07_BC_23_7A/org/bluez/hci0/dev_7A_5D_49_4F_ED_08。这是否意味着对于 Rasperry Pi,设备在绑定和连接时看起来不同?

  2. 如果它是绑定的,那么在连接时 Paired 和 Trusted 字段不应该是 True(从日志来看不是)?

  3. 尝试读取加密特征时,绑定被删除,连接也断开。

所以,经过几个小时的反复试验,我能够一致地重现失败案例和成功案例。

失败案例:

  1. 启动 Pi。
  2. 启动代理、广告和 gatt 服务器。
  3. 绑定设备。连接它。
  4. 尝试读取加密特征。失败了。

成功案例:

  1. 启动 Pi。
  2. 重启蓝牙服务。
  3. 启动代理、广告和 gatt 服务器。
  4. 绑定设备。连接它。
  5. 尝试读取加密特征。成功了。

因此,暂时的解决方法似乎是在启动后重新启动蓝牙服务,然后再启动代理和广告。

解决根本原因: 这个Github link.

给出了这个问题的解决方案

After much digging, I noticed that this problem is caused by the state the bluetooth chip is in at the time BlueZ is fired up (you can check the state with hciconfig hci0). If it's in "UP RUNNING" state or in "UP RUNNING PSCAN ISCAN" state, BlueZ complains with one or more of these:

Failed to set mode: Rejected (0x0b) Failed to set mode: Rejected (0x0b) Failed to set privacy: Rejected (0x0b)

But if it's in "DOWN" state, BlueZ starts with no issues. So, you first have to do hciconfig hci0 down before the bluetooth service starts up. But before you can use hciconfig, you also need to ensure the sys-subsystem-bluetooth-devices-hci0.device service has started!

方案一:

I ended up disabling the automatic boot sequence, and run this script instead:

systemctl start sys-subsystem-bluetooth-devices-hci0.device; hciconfig hci0 down; systemctl start bluetooth

方案二:

Delaying the running of bthelper by a couple of seconds fixed this issue for me, without me having to disable the automatic boot sequence and run any manual commands.

I added an ExecStartPre line to /lib/systemd/system/bthelper@.service such that the Service section now looks like this:

[Service]
Type=simple
ExecStartPre=/bin/sleep 2
ExecStart=/usr/bin/bthelper %I

我尝试了解决方案 2,它奏效了。