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