EDIT:
As per Juraj request, I am adding the code as a guide you can use to get ideas. You can't run it as is, you would need to add variable declaration and wrap it in a function.
As updating wrong file will most likely brick your board, I would just add that before running this code I check the filename to make sure it is the correct BIN for the board downloading it, I am using constants like WIFI, GSM, and board name and expect to see them in the filename.
I also send the file length from the server as part of the MQTT update request and check it against my own bytes count and I am not relying on TCP to provide an error on corrupted data and do a my own checksum test.
#include <ArduinoOTA.h> // https://github.com/jandrassy/ArduinoOTA
// Access the file
HttpClient client(*transport, upgradeServer, upgradePort);
client.get(upgradePath);
int statusCode = client.responseStatusCode();
/*
0 HTTP_SUCCESS
-1 HTTP_ERROR_CONNECTION_FAILED The end of the headers has been reached. This consumes the '\n' Could not connect to the server
-2 HTTP_ERROR_API This call was made when the HttpClient class wasn't expecting it to be called.
Usually indicates your code is using the class incorrectly
-3 HTTP_ERROR_TIMED_OUT Spent too long waiting for a reply
-4 HTTP_ERROR_INVALID_RESPONSE The response from the server is invalid, is it definitely an HTTP server?
*/
if (statusCode != 200) {
client.stop();
// here you can do something with statusCode like notifying over MQTT
}
long length = client.contentLength();
if (length == HttpClient::kNoContentLengthHeader) {
client.stop();
//Server didn't provide Content-length header, abort.
return;
}
if (!InternalStorage.open(length)) {
client.stop();
// Not enough space to store the file, abort.
return;
}
// Start update, length holds the file size in bytes
client.setTimeout(5000);
byte b;
bool ok;
long fileLength = length;
unsigned long otaStartMillis = millis();
int localChecksum = 0;
while (length > 0) {
ok = client.readBytes(&b, 1);
if (!ok) {
// Abort, stopped after ((millis() - otaStartMillis)/1000) Sec
return;
}
InternalStorage.write(b);
int bValue = (int)b;
localChecksum = localChecksum + bValue;
length--;
}
InternalStorage.close();
client.stop();
if (localChecksum != remoteCkecksum) {
// Checksum mismatch, abort.
return;
}
if (length > 0) {
// Timeout at byte length, abort.
return;
}
InternalStorage.apply(); // this doesn't return, board should restart
Serial.println("Update failed"); //shown only if update failed
Another opportunity to thank Jurak for this library!