通过withoutResponse发送时,核心蓝牙数据包丢失



在iOS上,一些数据包通过BLE丢失。

在我们具有类型.withoutResponse的特征上,我们当然检查canSendWriteWithoutResponsefunc peripheralIsReady(toSendWriteWithoutResponse peripheral: CBPeripheral)。文件中也对此进行了说明。

另一方面,如果将写入类型指定为CBCharacteristicWriteType.withoutResponse,核心蓝牙尝试写下价值,但不能保证成功。如果写不出来在这种情况下成功,您不会收到通知,也不会收到指示故障原因的错误。

有人知道我如何在不切换到withResponse的情况下解决这个问题吗?

BLE是一个分布式协议。总是有可能丢失数据。确保您没有丢失数据的唯一方法是接收一些数据已正确接收的通知(通常称为确认的ACK(。实现这一目标的标准BLE方法是做出回应。但是,如果你不想使用标准的ACK方案,你可以自由地实现自己的ACK方案。

例如,您可以创建一个";确认";您的中央订阅的外围设备中的特征。当您发送写入时,您将等待,直到收到该特征的通知。如果您在超时后没有看到通知,则可能已丢失写入。这在更高层重新实现了标准的带响应写入系统。

我研究的几个BLE协议实际上是串行协议(我们写入一个特性,并读取来自同一特性的响应(。我们经常将ACK直接实现到串行协议中(例如,返回<msgid>OK(,而不需要BLE写入响应。

另一种解决方案是写入特性,然后读取特性,看看它是否更新了,前提是特性以这种方式对称(许多不是(。我很确定,这里没有写缓存会咬到你,因为BLE读写通常不是对称的,但在依赖它之前,你应该仔细检查一下。(请参阅2019年和2017年的核心蓝牙WWDC视频。(

与所有分布式系统一样,也永远不可能知道数据丢失了。有可能数据到达了,但响应丢失了。这就是分布式协议的本质,只需要将其配置到系统中即可。这就是为什么可以建立一个至少传递一次消息的系统(前提是传递是可能的(,或者一个最多传递一个消息的系统,但不可能建立一个完全传递的系统。

如果你无法控制你的外围设备,而且它不提供任何错误检测机制,那么你在中央(电话(侧就无能为力了。要构建容错分布式协议,双方必须进行一些合作。

最新更新