Hi,
I am trying to reproduce DFU functionality from the nRF Connect for Android app.
I want to be able to flash my firmware OTA from my app.
The problem I am getting is that sometimes it sends the packages and sometimes it doesn't, but when it works after that I cannot see that few seconds of validation that happened in the nRF app.
It seems like all the packages are sent, but it doesn't switch the firmware.
Maybe someone did it before me, it seems like a prevalent thing.
I am using Xamarin Forms so it's all in C#. Here is my code for that.
private async Task<bool> FlashFirmware(IDevice device) { // Get the firmware binary data var firmwareData = await PickFirmwareFileAsync(); if (firmwareData == null || firmwareData.Length == 0) { SHFTLOG.Instance.Error("BLEM", "Invalid firmware data."); return false; } try { if (device == null) { SHFTLOG.Instance.Error("BLEM", "Invalid device."); return false; } SHFTLOG.Instance.Debug("BLEM", "Starting firmware flash process for device " + device.Id); // DFU service and characteristic UUIDs string dfuServiceUUID = "8d53dc1d-1db7-4cd3-868b-8a527460aa84"; string dfuCharacteristicUUID = "da2e7828-fbce-4e01-ae9e-261174997c48"; var service = await device.GetServiceAsync(Guid.Parse(dfuServiceUUID)); if (service == null) { SHFTLOG.Instance.Error("BLEM", "DFU service not found on device."); return false; } var characteristic = await service.GetCharacteristicAsync(Guid.Parse(dfuCharacteristicUUID)); if (characteristic == null) { SHFTLOG.Instance.Error("BLEM", "DFU characteristic not found on device."); return false; } // Initialize DFU process byte[] initPacket = new byte[] { 0x01, 0x04 }; // Example initialization packet await characteristic.WriteAsync(initPacket); SHFTLOG.Instance.Debug("BLEM", "Sent DFU initialization packet."); // Write firmware data in chunks int chunkSize = 20; // Max BLE payload size for (int i = 0; i < firmwareData.Length; i += chunkSize) { int bytesToSend = Math.Min(chunkSize, firmwareData.Length - i); byte[] chunk = new byte[bytesToSend]; Array.Copy(firmwareData, i, chunk, 0, bytesToSend); await characteristic.WriteAsync(chunk); SHFTLOG.Instance.Debug("BLEM", $"Sent firmware chunk {i / chunkSize + 1}"); } // Finalize DFU process byte[] finalizePacket = new byte[] { 0x01, 0x05 }; // Example finalize packet await characteristic.WriteAsync(finalizePacket); SHFTLOG.Instance.Debug("BLEM", "Sent DFU finalize packet."); byte[] validateDfuCommand = new byte[] { 0x03 }; await characteristic.WriteAsync(validateDfuCommand); // Wait for confirmation var (responseData, resultCode) = await characteristic.ReadAsync(); if (responseData[0] == 0x01 && resultCode == 0) // Assuming 0 resultCode indicates success { Console.WriteLine("DFU completed successfully."); } else { Console.WriteLine("DFU failed. Result code: " + resultCode); } SHFTLOG.Instance.Debug("BLEM", "Firmware flash process completed successfully."); return true; } catch (Exception ex) { SHFTLOG.Instance.Error("BLEM", "Exception during firmware flash: " + ex.Message); return false; } }