是否可以为CBCharacteristicWriteWithoutResponse实现流量控制?

时间:2017-05-16 08:32:53

标签: ios objective-c bluetooth-lowenergy

是否可以使用类型为writeValue的{​​{1}}并且仍然有一些流量控制来避免比BLE堆栈实际发送数据更快地发送数据?目前它适用于Android但不适用于iOS。

长篇故事。

我之前在Android上通过BLE实现了双工通信通道。它基本上使用两个ATT特性 - 一个是write / writeWithoutResponse,另一个是需要通知的。

在Android上,即使我使用writeWithoutResponse,Android也会向我发送CBCharacteristicWriteWithoutResponse回调信号,表示数据包至少已达到BLE堆栈,在此回调中,我发送出下一个大小为当前ATT_MTU的数据包-3个字节。

这很好,数据完好无损地到达目标,我可以达到大约10 KB / s的传输速度。

但是在iOS上存在问题。使用类型为onCharacteristicWrite的{​​{1}}时,iOS(至少iOS 8)不会调用writeValue,这是预期和记录的行为。因此,我无法知道数据包是否已达到BLE堆栈。我能做的最好是在循环中调用CBCharacteristicWriteWithoutResponse。此外,didWriteValueForCharacteristic似乎是非阻塞(异步)。结果,并非我的所有数据都到达外围设备。在日志中,我看到传入的数据流过早停止。我的猜测是,如果我过快地调用writeValue,iOS就会不小心覆盖以前缓存的可写特征值,从而错过了一些数据字节。

如果我将writeValuewriteValue一起使用,它可以正常工作,并且有什么奇怪的 - 即使我忽略writeValue并且只是致电CBCharacteristicWriteWithResponse它也能正常工作在一个循环中。似乎,didWriteValueForCharacteristic iOS正在做一些内部管理并使用BLE确认来避免覆盖特征的当前值,因此数据按顺序发送而没有任何损失。

当然,我不希望使用writeValue获得可靠的写入,但至少使其适用于大多数情况。如果它适用于Android,那为什么它不适用于iOS?

1 个答案:

答案 0 :(得分:1)

Apple的实施很糟糕。我见过的所有其他实现都有适当的流量控制。如果你不想在BLE之上实现一些类似TCP的高级层,那么你可以做的就是简单地坚持使用Write Without Response数据包,但是将每个第10个数据包作为Write With Response发送。那么你不会(很有可能)没有得到任何丢包。这可能只是一个小的性能下降。您还应该增加MTU以进一步提高吞吐量。