0

I have an running and working system which is an ESP32 with an LAN8720 to communicate over the internet.

Now just plane HTTP requests (via the WiFiClientSecure client) work like a charm. But I also need (over https) to update the device.

Now I currently have this code:

#include <Arduino.h>
#include <Update.h>
#include <HTTPUpdate.h>

WiFiClientSecure otaClient;

Serial.println("Preparing to update");

// Do OTA update
otaClient.setInsecure(); //skip verification of SSL cert

if (!otaClient.connect(DIGITAL_HQ_BASE_URL, 443)) {
    Serial.println("Could not connect.");
}

otaClient.print("GET "); // watch the space!
otaClient.print(DIGITAL_HQ_BINARY_ENDPOINT); // API endpoint
otaClient.println(" HTTP/1.1"); // watch the space!
otaClient.print("Host: ");
otaClient.println(DIGITAL_HQ_BASE_URL);
otaClient.println("Connection: keep-alive"); // Don't close, since we need to perform OTA
otaClient.print("User-Agent: ");
otaClient.println(DIGITAL_HQ_USER_AGENT);
otaClient.println("Cache-Control: no-cache");
otaClient.println();

unsigned long timeout = millis();
while (otaClient.available() == 0) {
    if (millis() - timeout > 5000) {
        Serial.println("Client Timeout !");
        otaClient.stop();
        return;
    }
}

while (otaClient.available()) {
    // read line till /n
    String line = otaClient.readStringUntil('\n');
    // remove space, to check if the line is end of headers
    line.trim();

    // if the the line is empty,
    // this is end of headers
    // break the while and feed the
    // remaining `client` to the
    // Update.writeStream();
    if (!line.length()) {
        //headers ended
        break; // and get the OTA started
    }

    // Check if the HTTP Response is 200
    // else break and Exit Update
    if (line.startsWith("HTTP/1.1")) {
        if (line.indexOf("200") < 0) {
            Serial.println("Got a non 200 status code from server. Exiting OTA Update.");
            break;
        }
    }

    // extract headers here
    // Start with content length
    if (line.startsWith("Content-Length: ")) {
        contentLength = atol((getHeaderValue(line, "Content-Length: ")).c_str());
        Serial.println("Got " + String(contentLength) + " bytes from server");
    }

    // Next, the content type
    if (line.startsWith("Content-Type: ")) {
        String contentType = getHeaderValue(line, "Content-Type: ");
        Serial.println("Got " + contentType + " payload.");
        if (contentType == "application/octet-stream") {
            isValidContentType = true;
        }
    }
}

Serial.println("contentLength : " + String(contentLength) + ", isValidContentType : " + String(isValidContentType));

if (contentLength && isValidContentType) {
    // Check if there is enough to OTA Update
    bool canBegin = Update.begin(contentLength);

    // If yes, begin
    if (canBegin) {
        Serial.println("Begin OTA. This may take 2 - 5 mins to complete. Things might be quite for a while.. Patience!");
        // No activity would appear on the Serial monitor
        // So be patient. This may take 2 - 5mins to complete
        size_t written = Update.writeStream(otaClient);

        if (written == contentLength) {
            Serial.println("Written : " + String(written) + " successfully");
        } else {
            Serial.println("Written only : " + ConvertFormatBytes(written) + "/" + ConvertFormatBytes(contentLength));
            // retry??
            // execOTA();
        }

        if (Update.end()) {
            Serial.println("OTA done!");
            if (Update.isFinished()) {
                Serial.println("Update successfully completed. Rebooting.");
                ESP.restart();
            } else {
                Serial.println("Update not finished? Something went wrong!");
            }
        } else {
            Serial.println("Error Occurred. Error #: " + String(Update.getError()));
        }
    } else {
        // not enough space to begin OTA
        // Understand the partitions and
        // space availability
        Serial.println("Not enough space to begin OTA");
        otaClient.stop();
    }
} else {
    Serial.println("There was no content in the response");
    otaClient.stop();
}

This runs without errors, but is frozen on the Preparing to update console message. Anyone who has an idea what I'm doing wrong here?

The file NEEDS to come from an https domain.

2
  • did you turn off WiFi? Commented Apr 27, 2021 at 15:29
  • @Juraj I did not, now I've added WiFi.mode(WIFI_OFF); to disable the wifi. Beside of this, I have updated my code (see the updated topic) and now I have the issue that the program isn't fully loaded. (Written only : 31.55KB/898.28KB) Any idea on this? Commented Apr 27, 2021 at 16:15

1 Answer 1

0

I suggest you use OTAdrive for SSL. Check this example for OTA over HTTPS.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.