Project_SylDa/docs/superpowers/specs/2026-07-30-ota-improvements-design.md
2026-07-30 19:04:34 +02:00

2.6 KiB

OTA Improvements — post code review

Datum: 2026-07-30 Branch: feature/ble-ota

Doel

Zes code review aanbevelingen implementeren voor robuustere OTA firmware update, in volgorde van prioriteit.


1. ESP SHA256 verificatie

ESP (src/main.cpp)

In onWrite() voor de BLE OTA characteristic:

  • Android stuurt SHA256 hash van firmware.bin als laatste chunk (32 bytes, chunkIndex == totalChunks)
  • ESP herkent laatste chunk aan dataLen == 32 in combinatie met chunkIndex >= totalChunks
  • Bij ontvangst: esp_ota_end(update_handle) afronden, dan esp_ota_get_app_elf_sha256(update_handle, computedSha) aanroepen
  • memcmp(computedSha, expectedSha, 32) — bij mismatch:
    • abortOta(update_handle) → bestaande partitie blijft actief
    • NAK-notificatie sturen naar Android (0x01)
  • Bij match:
    • ACK-notificatie sturen (0x00)
    • esp_ota_set_boot_partition(update_handle)
    • esp_restart()

Android (OtaManager.kt)

  • Na laatste data-chunk: SHA256 van firmware.bin berekenen met java.security.MessageDigest.getInstance("SHA-256")
  • 32-byte hash als aparte chunk sturen met chunkIndex = totalChunks + 1
  • Wachten op ACK/NAK response van ESP (punt 2)

2. OTA notification handling (Android)

BleRelayManager.kt

  • onCharacteristicChanged() in OTA callback doorsturen naar OtaManager.otaNotificationHandler(bytes: ByteArray)

OtaManager.kt

  • otaNotificationHandler(bytes): leest bytes[0] — 0x00=ACK, 0x01=NAK
  • ACK → sendNextChunk(), update progress
  • NAK → retry huidige chunk (max 3x per chunk)
  • Timeout: na versturen chunk, 2s timer — geen antwoord = retry (max 3x)
  • Bij overschrijding max retries: OTA abort met foutmelding in dialog

3+4. Dynamische chunk size + setMTU(512)

ESP

  • NimBLEDevice::setMTU(512) aanroepen in setupBLE()

Android

  • OTA_CHUNK_DATA_SIZE vervangen door chunkDataSize variabele
  • onMtuChanged(mtu: Int) callback → chunkDataSize = mtu - 3 - 4 (ATT header + chunk header)
  • Default: 248 (valt terug als MTU nog niet onderhandeld is)
  • Chunk header blijft 4 bytes: [chunkIndex:2][totalChunks:2]

5. writeCharacteristic return check

OtaManager.kt

In sendOtaData():

val success = bleRelayManager.writeOtaCharacteristic(chunk)
if (!success) {
    retriesLeft--
    if (retriesLeft <= 0) abortOta()
    else retryCurrentChunk()
}

6. otaStatusText widget verwijderen

  • otaStatusText verwijderen uit activity_settings.xml
  • otaStatusText property verwijderen uit SettingsActivity.kt

De progress bar in de OTA dialog toont al percentage — aparte statuswidget is overbodig.