你好,
我们在Android上发现了一个问题。
android支持服务和特性缓存,缩短重新连接时间。
测试设置:
1.Android APP扫描DA14580并连接,服务发现。
2.Android APP绑定DA14580。
3.Android APP向特征A发送数据“write without response”
4.DA14580上的应用程序可以接收数据。
5.失去了联系。
6.android APP扫描,连接,再次发现服务。
7.Android APP向特征A发送数据“write without response”
8.DA14580上的应用程序无法接收数据。
我们检查了蓝牙OTA日志,发现:
第6步,APP从Android缓存中获取服务,OTA日志中没有服务发现过程。
我们尝试了DA14580的每个连接的服务变化,它工作得很好。
蓝牙规范没有定义在特性通信之前必须进行服务发现过程。
DA14580是否有问题,如何解决?
或者我们应该用DA14580的API来修复它?
谢谢和问候。
设备:
你好,王沃德,
据我们所知没有问题,你能不能用嗅探器检查write_no_response报文是否离开了android设备?另外,当您执行第二次写入时,它的值是否与之前相同?
由于MT_dialog
当我们快速发送大量写命令(在GATT中称为“无响应写入”)时,我们也注意到了这一点。我认为这是同样的问题,但不能100%肯定。
不管怎样,这个漏洞在Android源代码中,并通过以下更改引入:
https://android.googlesource.com/platform/hardware/libhardware/ + / 9 ef3c72……
https://android.googlesource.com/platform/packages/apps/Bluetooth/ + / 934 d…
当用户发送一个写命令时,写命令被发送到手机内部的蓝牙控制器,蓝牙控制器将其放入其outgoing队列中,onCharacteristicWrite立即被发送回用户,用户可以发送另一个写命令。然而,蓝牙控制器内部的队列只能容纳大约20-30个数据包。因此,他们创建了一种“拥塞控制”机制,其工作原理是这样的:当蓝牙控制器队列已满时,它不会直接发送onCharacteristicWrite,而是等待直到蓝牙控制器说它的队列不再满。通过这种方式,Android上的写入命令(“write without response”)是可靠的,因为数据包永远不会被丢弃,除非链路断开。然而,iOS并没有提供这种强大的功能,而是在蓝牙控制器队列满时无声地丢弃iOS应用程序发送的写入命令,而不会向用户发送错误消息。
上面介绍的Android源代码中的错误是,如果链路由于任何原因断开(链路丢失以及正常断开),而它是拥塞的(蓝牙控制器的队列目前是满的),回调指示现在有更多的空间在队列中,永远不会被发送到更高的层,当设备重新连接时,他们不会重置它,这将使后续的GATT操作永远不会收到他们的onCharacteristic*回调,这将使GATT对象处于“繁忙”状态,这意味着所有的GATT操作将失败并返回false。
我们目前使用的解决方法是,如果我们有一个挂起的写命令正在执行,我们得到一个断开连接的回调,我们关闭这个BluetoothGatt对象并创建一个新的对象(使用BluetoothDevice.connectGatt)。由于内部拥塞标志属于BluetoothGatt对象,因此在创建解决该问题的新对象时将其设置为false。
嗨Joacimwe,
谢谢你的提示,非常感谢。
MT_dialog