MacOS writeWithoutResponse #1589
-
I am working on this issue: intercreate/smpclient#30 Initiallly I suspected an issue wherein this send method: async def send(self, data: bytes) -> None:
for offset in range(0, len(data), self.mtu):
await self._client.write_gatt_char(
self._smp_characteristic, data[offset : offset + self.mtu], response=False
) was overwhelming the peripheral with the manual fragmentation getting sent as fast as possible at MTU. After some experimentation I cannot reproduce the issue on the M3 that I'm borrowing, but obviously another user is able to reproduce reliably. However, if that were the case, it appears that this callback should be called: https://developer.apple.com/documentation/corebluetooth/cbperipheraldelegate/peripheralisready(tosendwritewithoutresponse:) So I added it to the PeripheralDelegate class: def peripheralIsReady_toSendWriteWithoutResponse_(self, peripheral: CBPeripheral, characteristic: CBCharacteristic) -> None:
logger.error("Called!") But it is never called. I have also modified the Client class here: async def write_gatt_char(
self,
characteristic: BleakGATTCharacteristic,
data: Buffer,
response: bool,
) -> None:
value = NSData.alloc().initWithBytes_length_(data, len(data))
await self._delegate.write_characteristic(
characteristic.obj,
value,
(
CBCharacteristicWriteWithResponse
if response
else CBCharacteristicWriteWithoutResponse
),
)
while self._peripheral.canSendWriteWithoutResponse() != True:
logger.error("Not ready to send!")
await asyncio.sleep(0.010)
logger.debug(f"Write Characteristic {characteristic.uuid} : {data}") That's using this API: https://developer.apple.com/documentation/corebluetooth/cbperipheral/cansendwritewithoutresponse And interestingly I do see that the canSendWriteWithoutResponse flag is false for the first ~5 iterations after each write_gatt_char (~50ms). I think it doesn't matter though because I suspect that the OS has some buffer and doesn't care that the write isn't going to be transmitted right away. This would be more of an issue if you cared about some time sensitive write (in which case don't use a desktop OS and BLE). Any help would be appreciated, thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
As the name implies, when you write without a response, there is no way to get backpressure from the peripheral to know if it is keeping up with the incoming messages. So you can either do write with response and have it be slower or have some kind of occasional notification from the peripheral to indicate that it is ready for more data. |
Beta Was this translation helpful? Give feedback.
As the name implies, when you write without a response, there is no way to get backpressure from the peripheral to know if it is keeping up with the incoming messages. So you can either do write with response and have it be slower or have some kind of occasional notification from the peripheral to indicate that it is ready for more data.