PyBluez over HCI 在 Raspberry Pi Compute Module with ESP32 上奇怪地工作

PyBluez over HCI working oddly on Raspberry Pi Compute Module with ESP32

我在连接到 ESP32 的自定义主板中使用 Raspberry PI 计算模块 3,使用 UART 上的 HCI 通过蓝牙连接到移动设备 phone。它部分工作: phone 能够与设备配对,设备可以在 bluetoothctl UI 中看到 phone,SDPtool 可以看到设备公开的服务(RFCOMM)。

但是,当我使用 pybluez 时,某些功能不起作用: 首先,我尝试将该设备用作蓝牙从设备。这是我的首选配置。 btmon 显示 phone 正在尝试连接,但 pybluez 从未通过 sock.accept()。该代码与您在 pybluez github 上的示例中看到的几乎完全相同,我已经成功地使用了相同的代码 Raspberry Pi 零 W(带有集成蓝牙)成功。

phone 在 socket.connect() 命令中显示以下错误: W/System.err: java.io.IOException: 读取失败,套接字可能关闭或超时,读取 ret: -1 W/System.err: 在 android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:698) W/System.err: 在 android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:710) W/System.err: 在 android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:387)

很难在 Pi 设备的日志中找到任何有价值的东西,但我确实在 btmon 中看到了这个:

ACL Data RX: Handle 128 flags 0x02 dlen 14 [hci0] 75.711662 L2CAP: Command Reject (0x01) ident 5 len 6 Reason: Invalid CID in request (0x0002) Destination CID: 0 Source CID: 0

我还尝试使用 Android hack 直接使用通道 ID 而不是 UUID 进行连接(基本上跳过了 SDP 查找)- 我使用 sdptool 浏览本地获得了通道 ID ,这导致了同样的错误。

在竭尽全力地尝试了不同的事情之后,我转而尝试使用 phone 作为蓝牙从设备而不是设备。在这里我看到了更多的成功,但仍然没有按预期工作: 来自 pybluez 的 discover_devices 没有报告任何设备,尽管 phone 和 bluetoothctl 都显示设备已配对。但是,如果我在 bluetoothctl 中看到的设备地址中进行硬编码,我实际上能够连接。

我确信蓝牙配置出了问题,也许是 bluez 或 pybluez 的版本,但我找不到其他人报告过此类问题。我注意到我在蓝牙服务上使用兼容模式开关(否则它根本不起作用)。我相信Bluez版本是5.43。

有人见过这样的事吗?对解决这些问题(不同版本的 bluez 等)有什么建议吗?

我最终确实解决了这个问题,但我不确定是哪个更改造成的:

  1. 我把波特率降低到115200。
  2. 我在固件flash中把它切换到了经典蓝牙。
  3. 我禁用了蓝牙睡眠。

这三个更改中的一个一定已经成功了

ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT);
if (ret != ESP_OK) {
    ESP_LOGE(tag, "Bluetooth Controller initialize failed: %s", esp_err_to_name(ret));
    return;
}

ret = esp_bt_sleep_disable();
if (ret != ESP_OK) {
    ESP_LOGE(tag, "Bluetooth Sleep Disable Failed: %s", esp_err_to_name(ret));
    return;
}