0

I am writing an OTA BLE firmware update between flutter Android app and an Espressif ESP32.

Basically, the flutter app sends chunks of data that the firmware expect: the chunk bears the chunkIndex so that the firmware can check nothing is missing since the last reception.

The issue I have is that not all chunks arrive to the firmware, and as it detects that issue, simply breaks the update as expected.

Note that the size of the chunk and its header is of 365 bytes (the MTU I negotiated).

As you can see — in the hope to have better comms — I introduced an extra delay which I'd like to be as short as possible (possibly 0) as I use the withoutResponse: false. Duration of the write is about 80msecs as per my logs.

A remark I've made is that if I use the withoutResponse: true, the comm is far better.

Another remark is that other BLE characteristics are actively exchanging information during the transfert process. Is that something that could create issue?

I really need something rock solid. So what am I doing wrong?

for (int i = 0; i < chunksCount; i++) {
   final chunk = [
        OTA_RX_FB_RECEIVE_DATA_CHUNK,
        i >> 8,
        i & 0xff,
        chunkSize >> 8,
        chunkSize & 0xff
      ];
      chunk.addAll(dataChunk);
      log("OTA: whole chunk with header: ${chunk.length} bytes");

   try {
      log("OTA: writing…");
      final start = DateTime.now();
      await bleFirmwareUpdateTxCharacteristic.write(data
          //,withoutResponse: true
          );
      final d = DateTime.now().difference(start).inMilliseconds;
      log("OTA: written in ${d}msecs, now wait a bit");
      await Future.delayed(otaBleDelay);
      log("OTA: written, done waiting");
    } catch (e) {
      error("OTA: smartboxFirmwareUpdateBleWrite() error $e");
    }```

Stéphane de Luca
  • 12,745
  • 9
  • 57
  • 95
  • Is the dropped chunk random, or is there a pattern in where it happens? Without response will be faster because you are essentially writing to the platform's queue and returning. You won't be timing the actual time it takes to be received by the other device. – Dan Harms May 24 '22 at 13:13
  • I see no pattern: what I can say is that it happens very quickly in the first 10 chunks. Regarding the timing I measure, it is the await time of the write with response: it is not the message round trip? – Stéphane de Luca May 24 '22 at 13:18
  • withResponse = true will wait for the round trip, but it doesn't add any resilience unless you want to resend. – Dan Harms May 24 '22 at 13:20
  • Is your sender the central or peripheral in this case? – Dan Harms May 24 '22 at 13:30
  • It is the peripheral. – Stéphane de Luca May 24 '22 at 13:33
  • @DanHarms Any thought Dan? I think about making a v2 protocol with handshake: the central asks for chunks and the app simply send them over. This way the speed of transmission will be set by the handshake itself. What do you think? – Stéphane de Luca May 24 '22 at 14:33
  • I don't believe the issue is the cadence, at least not from the mobile side. I'm not familiar with Arduino's BT stack, though, so maybe it needs something that is more controlled. – Dan Harms May 24 '22 at 14:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244999/discussion-between-dan-harms-and-stephane-de-luca). – Dan Harms May 24 '22 at 15:19

0 Answers0