streamFirmware

open suspend override fun streamFirmware(data: ByteArray, chunkSize: Int, onProgress: suspend (Float) -> Unit): Result<Unit>(source)

Streams firmware to the device. The ESP32 OTA loader is an ACK-paced byte stream: it drains its receive buffer and emits exactly ONE response per drain — an ACK while more data is expected, or the terminal OK once the final byte is received and the image verified. To keep a deterministic 1-write → 1-response cadence at any MTU, each chunk is sent as a single GATT write no larger than the negotiated write payload. A chunk that exceeded the payload would fragment into multiple writes that the device coalesces into one response, desyncing our response accounting (the cause of the prior ACK-timeout hang at MTU 512, where a 512-byte chunk split into 509, 3).

Because we write one chunk then await its single response before writing the next, only one chunk is ever outstanding, so the device's byte-stream receive buffer holds exactly one chunk per drain — keeping the cadence a deterministic 1 write → 1 response. Branch on response type (never on a fragment count): success requires an explicit terminal OK, and any ERR fails the transfer, so a late device error can never be reported as success.