【问题标题】:Rate limiting a CoreBluetooth write without response速率限制 CoreBluetooth 写入而不响应
【发布时间】:2021-01-05 20:28:16
【问题描述】:

我正在通过 CoreBluetooth 向 BLE 设备发送一个大型二进制文件,以更新设备上的固件。但是,我遇到了一个问题,即 CoreBluetooth 没有对写入进行速率限制,并且发送消息太快以至于设备无法接收所有消息。确保 CoreBluetooth 等待足够长的时间以确保所有消息都已发送(不冻结 UI 队列)的最佳方法是什么?

我当前的代码是:

    private func sendOTAUpgrade(data: [UInt8], complete: @escaping () -> Void) {
        let packets = makePackets(size: 20, arr: data)
        var count = 0
        
        for packet in packets {
            firmwareUpgradePercentComplete = Double(count)/Double(packets.count)
            print("Sent packet - \(firmwareUpgradePercentComplete*100)% complete")
            let data = NSData(bytes: packet, length: 20)
            self.connectedPeripheral?.writeValue(data as Data, for: self.otcDataCharacteristic!, type: CBCharacteristicWriteType.withoutResponse)
            count += 1
        }
        
        complete()
    }

【问题讨论】:

  • 这个问题的答案是“写响应”,让固件在准备好接收更多数据时提供响应。如果你不能做到这一点,那么你将不得不限制自己。这意味着一定数量的asyncAfter 调用,或者sleep 调用,如果你在自己的线程上,或者你想通过任何你喜欢的机制进行任何类型的暂停。但是,如果您的问题是如何使用 BLE 来处理这个问题,那么答案是“使用响应;这就是它们的用途。” (或者,如果您控制固件,则对 BLE 实施流量控制。)
  • 更好的是,如果您的设备支持它,请使用 L2Cap 通道。

标签: swift bluetooth-lowenergy core-bluetooth


【解决方案1】:

有多种方法。如果你想坚持.withoutResponse,你应该检查canSendWriteWithoutResponse,如果这个属性是真的你可以再写一次。如果它是假的,你需要等到peripheralIsReady 被调用。

这样你就可以写出一些可靠的数据了。

成绩单 CoreBluetooth WWDC 2017 会议的新功能

今年,我们通过一个名为的新属性增强了 CBPeripheral canSendWriteWithoutResponse。

所以如果你在写之前调用它并且它返回yes, 这是我们对您的承诺,您的数据不会被丢弃 在我们有机会将软件发送到远程外围设备之前。

如果返回 no,当我们 准备好了,我们会回调 peripheralIsReady

根据您的目标,您可能需要在外围设备中实现一些流量控制。如果这不可能,可能有一个实用的解决方案来检查您的设备可以处理多少数据。因此,队列可以帮助在发送时获得一些控制,而无需切换到 .writeWithResponse

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-29
    • 2021-09-16
    • 2021-07-23
    • 2021-10-20
    相关资源
    最近更新 更多