Open krupis opened 2 years ago
Hello,
Here is the code that I use for upgrade my esp32 via OTA using SIM808:
void OTA()
{
// New OTA update, clear and send user notification
Serial.println(F("Starting OTA update..."));
Update.begin();
mCRC32.reset();
// Download OTA update splitted on small files of size DOWNLOAD_FILE_MAX_SIZE
uint16_t fileIndex = mOTA_SizeDownloaded / DOWNLOAD_FILE_MAX_SIZE;
char fileName[32];
sprintf(fileName, "/static/%s_%03d", mOTA_Version, fileIndex);
uint32_t fileSize = (mOTA_Size - mOTA_SizeDownloaded > DOWNLOAD_FILE_MAX_SIZE) ? DOWNLOAD_FILE_MAX_SIZE
: mOTA_Size % mOTA_SizeDownloaded;
Serial.printf("Downloading file %s (%u bytes)\n", fileName, fileSize);
uint8_t buffer[fileSize];
uint32_t numBytes = mSIM.DownloadFile(fileName, buffer, fileSize);
// Check downloaded file size
if (numBytes != fileSize) {
Serial.printf("Error downloading file %s...\n", fileName);
mOTA_Attempts++;
if (mOTA_Attempts >= OTA_MAX_ATTEMPTS) {
Serial.println(F("Max OTA attempts reached, aborting..."));
Update.abort();
}
return;
}
// Write new data
Update.write(buffer, numBytes);
mCRC32.update<uint8_t>(buffer, numBytes);
mOTA_SizeDownloaded += numBytes;
Serial.printf("%u of %u OTA Downloaded\n", mOTA_SizeDownloaded, mOTA_Size);
mOTA_Attempts = 0;
if (mOTA_SizeDownloaded != mOTA_Size) {
return;
}
// All downloaded, check CRC32
if (mOTA_CRC32 != mCRC32.finalize()) {
Serial.println(F("Invalid checksum, aborting..."));
Update.abort();
return;
}
// Apply
Serial.println(F("OTA Ready, restarting..."));
Update.end(true);
ESP.restart();
}
Code for download file:
/**
* Download file using http Connection
* WARNING: buffer must be pre-allocated
*/
uint32_t DownloadFile(const char* file, uint8_t* buffer, uint32_t size)
{
if (!file || !buffer || size <= 0) {
return 0;
}
// Connect to network
if (!mSIM->isGprsConnected()) {
connectGSM();
}
// Connect to server
Serial.print(F("Connecting to server..."));
if (!mSIM_Client->connect(mServer, HTTP_PORT, HTTP_TIMEOUT_SEC)) {
Serial.println(F(" FAIL"));
return 0;
}
Serial.println(F(" OK!"));
mSIM_Client->print(String("GET ") + file + " HTTP/1.0\r\n");
mSIM_Client->print(String("Host: ") + mServer + ":" + HTTP_PORT + "\r\n");
mSIM_Client->print("Connection: close\r\n\r\n");
// Parse header
Serial.println(F("Waiting for response header"));
uint32_t clientReadStartTime = millis();
String headerBuffer;
bool finishedHeader = false;
uint32_t contentLength = 0;
while (!finishedHeader) {
int nlPos;
if (mSIM_Client->available()) {
clientReadStartTime = millis();
while (mSIM_Client->available()) {
char c = mSIM_Client->read();
headerBuffer += c;
/*// Uncomment the lines below to see the data coming into the buffer
if (isprint(c))
Serial.print(reinterpret_cast<char> (c));
else
Serial.print('*');*/
if (headerBuffer.indexOf(F("\r\n")) >= 0) {
break;
}
}
} else if (millis() - clientReadStartTime > DOWNLOAD_FILE_TIMEOUT) {
Serial.println(F(">>> Client Timeout !"));
break;
}
// See if we have a new line.
nlPos = headerBuffer.indexOf(F("\r\n"));
if (nlPos > 0) {
headerBuffer.toLowerCase();
// Check if line contains content-length
if (headerBuffer.startsWith(F("content-length:"))) {
contentLength = headerBuffer.substring(headerBuffer.indexOf(':') + 1).toInt();
}
headerBuffer.remove(0, nlPos + 2); // remove the line
} else if (nlPos == 0) {
// if the new line is empty (i.e. "\r\n" is at the beginning of the line), we are done with the header.
finishedHeader = true;
}
}
if (contentLength != size || !finishedHeader) {
Serial.println(F("Error parsing header content-length size or different sizes\n"));
mSIM_Client->stop();
return 0;
}
// Read content
Serial.println(F("Reading response data"));
uint32_t readLength = 0;
clientReadStartTime = millis();
while (readLength < contentLength && mSIM_Client->connected() && millis() - clientReadStartTime < DOWNLOAD_FILE_TIMEOUT) {
while (mSIM_Client->available()) {
buffer[readLength++] = mSIM_Client->read();
clientReadStartTime = millis();
}
}
mSIM_Client->stop();
return readLength;
}
I hope that it help you.
Regards, Adrián.
Hey. Your code looks like Arduino code. I am looking for esp-idf alternative for GSM OTA
@adrianca88 Thanks for sharing this code. Is there a possibility to share a complete example? This would very helpful.
Hey. The code that I have uploaded ( my initial forum post ) is the complete example for the GSM OTA. You just need to change a few things:
const char apn[] = "omnitel"; const char user[] = "omni"; const char pass[] = "omni";
and the server must be changed according to what you use. Also, keep in mind that the example is built on lilygo esp32 module and it has the following pinout for the GSM module:
so if you dont have lilygo board, you may need to change those as well. The rest should be fine
@krupis Thank you very much!
Thanks
Hello. I would like to know whether it is possible to use the OTA over the GSM in the esp-idf platform. The OTA code I have found posted in the issue #133 works perfectly fine in Arduino platform, however, I am trying to move away from Arduino towards the esp-idf and I wonder whether I could port this code to work for esp-idf. The full code is here: