diff --git a/android/app/src/main/java/nl/eddydevink/sylda/BleRelayManager.kt b/android/app/src/main/java/nl/eddydevink/sylda/BleRelayManager.kt index 3dc4e23..846e382 100644 --- a/android/app/src/main/java/nl/eddydevink/sylda/BleRelayManager.kt +++ b/android/app/src/main/java/nl/eddydevink/sylda/BleRelayManager.kt @@ -59,6 +59,7 @@ class BleRelayManager( private var otaCharacteristic: BluetoothGattCharacteristic? = null private var espVersion: String? = null private var appVersion: String = "" + private var negotiatedMtu: Int = 23 interface OtaNotifyCallback { fun onOtaNotify(status: Int, seq: Int) @@ -229,6 +230,8 @@ class BleRelayManager( fun getEspVersion(): String? = espVersion + fun getNegotiatedMtu(): Int = negotiatedMtu + @SuppressLint("MissingPermission") private fun connectToDevice(device: android.bluetooth.BluetoothDevice) { handler.post { callbacks.onStatusChanged(BleStatus.Connecting) } @@ -274,6 +277,7 @@ class BleRelayManager( @SuppressLint("MissingPermission") override fun onMtuChanged(gatt: android.bluetooth.BluetoothGatt, mtu: Int, status: Int) { Log.d(TAG, "MTU changed to $mtu") + negotiatedMtu = mtu val service = gatt.getService(SERVICE_UUID) if (service != null) { relayCharacteristic = service.getCharacteristic(CHARACTERISTIC_UUID) diff --git a/android/app/src/main/java/nl/eddydevink/sylda/OtaManager.kt b/android/app/src/main/java/nl/eddydevink/sylda/OtaManager.kt index f6197a0..ab99f57 100644 --- a/android/app/src/main/java/nl/eddydevink/sylda/OtaManager.kt +++ b/android/app/src/main/java/nl/eddydevink/sylda/OtaManager.kt @@ -18,15 +18,12 @@ class OtaManager( ) { companion object { private const val TAG = "OtaManager" - private const val OTA_CHUNK_DATA_SIZE = 248 private const val OTA_CMD_START: Byte = 0x10 - private const val OTA_STATUS_ACK: Byte = 0x00 - private const val OTA_STATUS_COMPLETE: Byte = 0x10 - private const val OTA_STATUS_ERROR: Byte = 0x11 private const val OTA_START_TIMEOUT_MS = 10000L private const val OTA_CHUNK_TIMEOUT_MS = 2000L private const val OTA_FINAL_TIMEOUT_MS = 10000L private const val MAX_RETRIES = 3 + private const val OTA_ESP_MAX_CHUNK = 500 } interface OtaCallback { @@ -36,10 +33,16 @@ class OtaManager( } private var firmwareData: ByteArray? = null + private var chunkDataSize: Int = 248 + + private fun calculateChunkSize(mtu: Int): Int { + return minOf(maxOf(mtu - 3 - 4, 20), OTA_ESP_MAX_CHUNK) + } fun loadFirmware(): Boolean { return try { firmwareData = context.assets.open("firmware/firmware.bin").readBytes() + chunkDataSize = calculateChunkSize(relayManager.getNegotiatedMtu()) true } catch (e: Exception) { Log.e(TAG, "Failed to load firmware", e) @@ -85,13 +88,13 @@ class OtaManager( } } catch (_: kotlinx.coroutines.TimeoutCancellationException) {} - val totalChunks = (fw.size + OTA_CHUNK_DATA_SIZE - 1) / OTA_CHUNK_DATA_SIZE + val totalChunks = (fw.size + chunkDataSize - 1) / chunkDataSize var seq = 0 var offset = 0 while (offset < fw.size) { val remaining = fw.size - offset - val chunkSize = minOf(remaining, OTA_CHUNK_DATA_SIZE) + val chunkSize = minOf(remaining, chunkDataSize) val packet = ByteBuffer.allocate(4 + chunkSize).order(ByteOrder.BIG_ENDIAN) packet.putInt(seq) diff --git a/src/main.cpp b/src/main.cpp index 73aa58e..c8f2568 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -338,6 +338,7 @@ void setup() { } Serial.println("LED blink done, starting BLE..."); + NimBLEDevice::setMTU(512); NimBLEDevice::init("SylDa_Server"); NimBLEServer *pServer = NimBLEDevice::createServer();