Jus*_*tin 4 android bluetooth-lowenergy
我在外围设备上使用了两个ATT特性实现了双工BLE通信(本质上就像是串行TX/RX电缆) - 一个是可写的,另一个是可读的通知.除报告的写入速度外,一切都按预期工作.
当我调用以下代码时:
txCharacteristic.setValue(data);
boolean queuedOk =
connectedPeripheralGatt.writeCharacteristic(txCharacteristic);
Run Code Online (Sandbox Code Playgroud)
该onCharacteristicWrite回调被几乎立即触发,然后我重复上面的代码片段上的特征应用下一个数据片段.当接收方报告正确的速度(大约10 KB/s)时,从收集的时间戳开始测量onCharacteristicWriteRequest,发送方报告令人难以置信的速度(如50 - 300 KB/s),并报告已完成将所有数据推送到writeCharacteristic,虽然接收方仍在接收传入数据.
因此,显然onCharacteristicWriteRequest正在调用,而大多数数据仍在前往目标设备.
当我将数据从外围设备发送到中央设备时,同样的事情发生了,只有这一次onNotificationSent外围设备处于其速度并且onCharacteristicChanged中央正在报告正确的速度.
是否有更多或更不可靠的方法来近似测量来自发送方的输出数据速率而不打开ACK(出于性能原因我不想这样做)?
数据本身完好无损,我正在使用0.5 - 5兆字节大小的图像文件进行测试,图像总是在接收端正确解码.
为了最大化吞吐量,可写特性设置为不可靠,如下所示:
BluetoothGattCharacteristic rxCharacteristic = new BluetoothGattCharacteristic(UUID.fromString(RX_CHARACTERISTIC_UUID),
BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE,
BluetoothGattCharacteristic.PERMISSION_WRITE);
rxCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
Run Code Online (Sandbox Code Playgroud)
我不确定我是否使用过PROPERTY_WRITE_NO_RESPONSE,WRITE_TYPE_NO_RESPONSE但是从一些网站上的某些文章中可以看出,这两者都是一个很好的做法.如我错了请纠正我.
我的理解是这样的设置,我不能指望在接收侧的数据的真正的确认,但我仍然期望onCharacteristicWrite和onNotificationSent自己将至少提供逼真的时刻,当数据被实际发送的源设备的检测.相反,似乎有一个非常大的缓存消耗我的数据并报告它几乎立即发送.
Emi*_*mil 11
你是对的.
如果使用"write with response",则在远程发回写入响应后将调用onCharacteristicWrite回调.但是,如果您使用"无响应写入",Android会有一个流控制机制来缓冲您编写的数据.它的工作原理如下:
该应用程序写入一个数据包 蓝牙堆栈将此数据包放入其内部缓冲区.如果在将此数据包排入队列后缓冲区中仍有更多空间,则会调用onCharacteristicWrite回调,因此您可以立即写入另一个数据包.当缓冲区已满时,它等待调用onCharacteristicWrite回调,直到缓冲区中现有50%的空间(如果我没记错).
只要内部缓冲区中有数据包,它就会尝试将它们写入蓝牙控制器,蓝牙控制器也可以缓存有限数量的数据包.蓝牙控制器通过HCI将"数量的数据包完成"事件发送回Android的蓝牙堆栈,表明远程设备的链路层已确认数据包.(这并不表示远程应用程序没有收到它;只是远程蓝牙控制器收到它.)如果蓝牙控制器中没有可用空间,它将等到有空间.
这比它在iOS上的工作方式要聪明得多.如果您发送了大量"带响应的写入"数据包,如果内部缓冲区已满,它们将在被发送之前被丢弃.(这可以通过每隔10个数据包发送"带响应的写入"来解决).
不幸的是(对于您的情况),Android的蓝牙堆栈在远程链路层确认数据包时不会向应用程序发送回调,因此您必须以onCharacteristicWrite回调为基础.但是,您可以在每个第10个数据包左右向另一个方向发送状态通知,我认为这会给您带来良好的结果.如果Android的蓝牙堆栈在收到链路层确认时会发送onCharacteristicWrite回调,那么每个连接事件只会将速度降低到一个数据包.
如果链接有时因监督超时而断开连接,您应该知道我之前发布的错误报告:https://issuetracker.google.com/issues/37121017.
关于你的属性/权限问题,这可能是相同的事情,但蓝牙团队决定将这些问题分开.权限种类与ATT协议有关,告诉蓝牙堆栈允许客户端做什么.这些属性只是另一方可以阅读的一些属性,以便了解它的特征类型.
| 归档时间: |
|
| 查看次数: |
4178 次 |
| 最近记录: |