updateFirmware method
Future<void>
updateFirmware(
- BluetoothDevice device,
- int updateType,
- int firmwareType,
- BluetoothService service,
- BluetoothCharacteristic dataUUID,
- BluetoothCharacteristic controlUUID, {
- String? binFilePath,
- String? url,
override
sendPArt function ends here
Implementation
@override
Future<void> updateFirmware(
BluetoothDevice device,
int updateType,
int firmwareType,
BluetoothService service,
BluetoothCharacteristic dataUUID,
BluetoothCharacteristic controlUUID,
{String? binFilePath,
String? url}) async {
if (updateType == 1) {
final bleRepo = BleRepository();
/// Get MTU size from the device
int mtuSize = 200;
print("MTU size of current device $mtuSize");
/// Prepare a byte list to write MTU size to controlCharacteristic
Uint8List byteList = Uint8List(2);
byteList[0] = mtuSize & 0xFF;
byteList[1] = (mtuSize >> 8) & 0xFF;
List<Uint8List> binaryChunks;
/// Choose firmware source based on firmwareType
if (firmwareType == 1 && binFilePath != null && binFilePath.isNotEmpty) {
binaryChunks = await _readBinaryFile(binFilePath, mtuSize);
} else if (firmwareType == 2) {
binaryChunks = await _getFirmwareFromPicker(mtuSize);
} else if (firmwareType == 3 && url != null && url.isNotEmpty) {
binaryChunks = await _getFirmwareFromUrl(url, mtuSize);
} else {
binaryChunks = [];
}
/// Write x01 to the controlCharacteristic and check if it returns value of 0x02
await bleRepo.writeDataCharacteristic(writeCharacteristic, byteList);
await bleRepo.writeDataCharacteristic(
notifyCharacteristic, Uint8List.fromList([1]));
/// Read value from controlCharacteristic
List<int> value = await bleRepo
.readCharacteristic(notifyCharacteristic)
.timeout(Duration(seconds: 10));
print('value returned is this ------- ${value[0]}');
int packageNumber = 0;
print('Before Progress');
for (Uint8List chunk in binaryChunks) {
/// Write firmware chunks to dataCharacteristic
await bleRepo.writeDataCharacteristic(writeCharacteristic, chunk);
packageNumber++;
double progress = (packageNumber / binaryChunks.length) * 100;
int roundedProgress = progress.round(); // Rounded off progress value
print(
'Writing package number $packageNumber of ${binaryChunks.length} to ESP32');
print('Progress: $roundedProgress%');
_percentageController.add(roundedProgress);
}
/// Write x04 to the controlCharacteristic to finish the update process
await bleRepo.writeDataCharacteristic(
notifyCharacteristic, Uint8List.fromList([4]));
/// Check if controlCharacteristic reads 0x05, indicating OTA update finished
value = await bleRepo
.readCharacteristic(notifyCharacteristic)
.timeout(Duration(seconds: 600));
print('value returned is this ------- ${value[0]}');
if (value[0] == 5) {
print('OTA update finished');
firmwareUpdate = true; // Firmware update was successful
} else {
print('OTA update failed');
firmwareUpdate = false; // Firmware update failed
}
} else if (updateType == 2) {
final bleRepo = BleRepository();
/// Get MTU size from the device
int mtuSize = await device.mtu.first;
print("MTU size of current device $mtuSize");
/// Prepare a byte list to write MTU size to controlCharacteristic
Uint8List byteList = Uint8List(2);
byteList[0] = 200 & 0xFF;
byteList[1] = (200 >> 8) & 0xFF;
Uint8List? binFile;
/// Choose firmware source based on firmwareType
if (firmwareType == 1 && binFilePath != null) {
ByteData fileData = await rootBundle.load(binFilePath);
List<int> bytes = fileData.buffer.asUint8List();
binFile = Uint8List.fromList(bytes);
print("Bin file after conversion is $binFile");
print("Bin file length after conversion is ${binFile.length}");
} else if (firmwareType == 2) {
binFile = await _getFirmwareFromPickerArduino(200);
print("binFile is $binFile");
} else if (firmwareType == 3 && url != null && url.isNotEmpty) {
binFile = await _getFirmwareFromUrlArduino(url, mtuSize);
} else {
binFile = Uint8List(0);
}
print('before printing file Length');
int fileLen = binFile.length;
int fileParts = (fileLen / part).ceil();
print("this is the fileParts : $fileParts");
///1. Start stream which listens to the notification advertisement
await notifyCharacteristic.setNotifyValue(true);
subscription = notifyCharacteristic.onValueReceived.listen((value) async {
print("received value is $value");
double progress = (value[2] / fileParts) * 100;
int roundedProgress = progress.round();
/// Rounded off progress value
print('Writing part number ${value[2]} of $fileParts to ESP32');
print('Progress: $roundedProgress%');
_percentageController.add(roundedProgress);
if (value[0] == 0xF1)
/// this basically is checking listener stream
{
Uint8List bytes = Uint8List.fromList([
value[1],
value[2],
]);
ByteData byteData = ByteData.sublistView(bytes);
int nxt = byteData.getUint16(0);
/// Used getUint16 for a 2-byte integer
print("--------- nxt -------- $nxt");
sendPart(nxt, binFile!);
}
if (value[0] == 0x0F) {
print("OTA Update complete");
}
if (value[0] == 0xF2) {
print("New bin file installation begins on esp32");
}
});
///2. Send 0xFD first to start reading
Uint8List byteListData = Uint8List(1);
byteList[0] = 0xFD;
await bleRepo.writeDataCharacteristic(writeCharacteristic, byteListData);
///3. Send 0xFE appended with other info
///--------> 2nd step create and then send file size
Uint8List fileSize = Uint8List(5);
fileSize[0] = 0xFE; // The fixed byte
fileSize[1] = (fileLen >> 24) & 0xFF; // Most significant byte of fileLen
fileSize[2] = (fileLen >> 16) & 0xFF; // Second most significant byte
fileSize[3] = (fileLen >> 8) & 0xFF; // Third most significant byte
fileSize[4] = fileLen & 0xFF; // Least significant byte
print(
"this is file size : $fileSize"); // this is where it is sent to esp32
await bleRepo.writeDataCharacteristic(writeCharacteristic, fileSize);
///4. Send 0xFF appended with other info - see code below
///--------> 3rd step create and then send otaInfo
Uint8List otaInfo = Uint8List(5);
otaInfo[0] = 0xFF;
otaInfo[1] = (fileParts ~/ 256);
otaInfo[2] = (fileParts % 256);
otaInfo[3] = (mtu ~/ 256);
otaInfo[4] = (mtu % 256);
print("this is otaInfo : $otaInfo"); // this is where it is sent to esp32
await bleRepo.writeDataCharacteristic(writeCharacteristic, otaInfo);
///5. Divide bin file into parts
int packageNumber = 0;
sendPart(0, binFile);
double progress = (packageNumber / fileParts) * 100;
int roundedProgress = progress.round(); // Rounded off progress value
print('Writing part number $packageNumber of $fileParts to ESP32');
print('Progress: $roundedProgress%');
_percentageController.add(roundedProgress);
}
}