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

90 lines
2.6 KiB
Markdown

# 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()`:
```kotlin
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.