我正在开发一个 BLE 外围应用程序,该应用程序连接到中央设备并遇到数据丢失问题。 在我的 Android 应用程序中,我使用了三个 ATT 特征。
//服务器使用Notification发送数据给客户端
BluetoothGattCharacteristic char_tx = 新的BluetoothGattCharacteristic(MCHP_BLE_UART_TX, 蓝牙GattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
//客户端使用ATT_WRITE_CMD向服务器发送数据
BluetoothGattCharacteristic char_rx = 新的BluetoothGattCharacteristic(MCHP_BLE_UART_RX, 蓝牙GattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE, BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
//信用控制。信用用于流量控制 客户端使用 ATT_WRITE_REQUEST 向服务器发送信用
BluetoothGattCharacteristic char_control = 新的BluetoothGattCharacteristic(MCHP_BLE_UART_CONTROL, 蓝牙GattCharacteristic.PROPERTY_WRITE |蓝牙GattCharacteristic.PROPERTY_WRITE_NO_RESPONSE | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
通知正在按预期工作。
我发现从客户端发送到服务器的ATT写入命令会丢失
测试手机:Samsung A54 5G/Android 13。同样的问题也出现在另一款Android手机:Galaxy S22/Android 12上
测试步骤:客户端(设备)发送信用和数据到服务器(APP)。
测试结果: 我的外围应用程序比较发送和接收的数据并显示数据不正确。 检查BT空中日志和HCI日志,传输数据正确。 最后我发现BluetoothGattServerCallback onCharacteristicWriteReuest函数没有被调用。当服务器收到一个 ATT 写请求并在服务器回复写响应之前收到另一个 ATT 写命令时,就会发生这种情况。在BTSnoop日志中可以看到。框架 1440、1443、1444
如果服务器在回复写响应后收到写命令,则不会出现此问题。 我的问题是为什么不调用 onCharacteristicWriteReuest 回调?我使用不同的特性来传输数据。 这是 Android BLE 外设 API 的限制还是错误?我尝试用 google 搜索有关 Android ble 外设和外设 API 的用法,但找不到。 任何有解决方案或一些好的参考资料的人将不胜感激。
onCharacteristicWriteRequest
回调未被调用的原因有很多。您可以检查以下事项:
回调注册:确保您已将
BluetoothGattServerCallback
正确注册到 BluetoothGattServer
实例。仔细检查您是否已正确实施 onCharacteristicWriteRequest
方法。
权限:确保您的特征 (
MCHP_BLE_UART_CONTROL
) 的权限设置正确。由于您期待写入请求,因此应启用读取和写入权限。
连接状态:验证客户端和服务器设备之间的连接是否稳定。如果连接间歇性或不稳定,可能会阻止服务器接收写入请求。
并发问题:检查代码中是否存在可能阻止调用
onCharacteristicWriteRequest
回调的并发问题。确保您的回调实现不会被任何其他操作阻止。
蓝牙堆栈:请考虑该问题可能与您正在测试的 Android 设备上的蓝牙堆栈有关。有时,某些设备或 Android 版本的蓝牙实现可能存在错误或限制。
您应该能够确定
onCharacteristicWriteRequest
回调未被调用的根本原因,并解决 BLE 外设应用程序中的数据丢失问题。