B4R Question OTA-update via https

peacemaker

Expert
Licensed User
Longtime User
Hi, All

I prepared and used this code for OTA ESP32: https://www.b4x.com/android/forum/threads/esp32-ota-update-from-server-via-wifi-only.149206/.
Now i need the universal variant including esp8266, but SDK are different.
But AI can help a lot to make the code, but strange that if HTTPS:// link of the .bin file is used - the server reply as 400 error. Server log is clear.

Why ?
Http:// links work OK with esp32 and esp8266. But why not https ?

module 'espota':
Private Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Private bc As ByteConverter
    Dim FullPath(200) As Byte
    Dim tim As Timer
End Sub


Sub OTA_Update
    Dim b() As Byte = others.ReplaceString(GlobalStore.Slot2, "\/", "/")
    If b.Length <= 0 Then
        Log("Empty URL for OTA-update")
        Return
    End If
    Log("OTA-update downloading: ", b)
    Dim URL1 As String = Main.bc.StringFromBytes(b)
 
    espwdt.Stop
    espwdt.Start(260000)
    Main.timAPI.Enabled = False    'pause working with server
    Dim result As Boolean = Start(URL1)
    If result = False Then
        Dim s As String  = JoinStrings(Array As String(others.DeviceName, ": OTA-update error: ", "(", URL1 , ")"))
        Log(s)
        webapi.SendRelayRequest(0, s)
    Else
        Log("OTA update is OK, restarting")
        webapi.SendRelayRequest(0, JoinStrings(Array As String(others.DeviceName, ": firmware was updated (", URL1, ")")))
    End If
    tim.Initialize("tim_tick", 5000)
    tim.Enabled = True
End Sub

Sub tim_tick
    tim.Enabled = False
    others.restart(9)  'restart ESP MCU
End Sub

Sub Start(URL1 As String) As Boolean
    Log("OTA starting...")
    Dim b() As Byte = URL1
    b = others.ReplaceString(b, "\/", "/")
    If b = "" Then
        Log("OTA URL is empty")
        Return False
    End If
    bc.ArrayCopy(b, FullPath)
    Return RunNative("updateFIRMWARE", Null)
End Sub


#if C
#ifdef ESP32
  #include "WiFi.h"
  #include "HTTPClient.h"
  #include "Update.h"
  #include "WiFiClientSecure.h"
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
  #include <ESP8266HTTPClient.h>
  #include <WiFiClientSecure.h>
#endif

B4R::Object returnvalue_espota;

B4R::Object* updateFIRMWARE(B4R::Object* o)
{
  char* url = (char*)b4r_espota::_fullpath->data;
 
  bool isHttps = (strncmp(url, "https://", 8) == 0);
 
  HTTPClient http;

  if (isHttps) {
    WiFiClientSecure client;
    client.setInsecure(); // disable certificate check
    http.begin(client, url);
  } else {
    WiFiClient client;
    http.begin(client, url);
  }

  http.addHeader("User-Agent", "esp_my_project");
  int httpCode = http.GET();
 
  if (httpCode != HTTP_CODE_OK) {
    ::Serial.printf("[HTTP] GET failed, code: %d\n", httpCode);
    http.end();
    return returnvalue_espota.wrapNumber((byte)0);
  }
 
  int contentLen = http.getSize();
  if (contentLen <= 0) {
    ::Serial.println("Error: Invalid content length");
    http.end();
    return returnvalue_espota.wrapNumber((byte)0);
  }

  if (!Update.begin(contentLen)) {
    ::Serial.println("Error: Update.begin() failed");
    http.end();
    return returnvalue_espota.wrapNumber((byte)0);
  }

  ::Serial.printf("Downloading firmware (%d bytes)...\n", contentLen);

  WiFiClient* stream = http.getStreamPtr();
  size_t written = Update.writeStream(*stream);

  if (written != (size_t)contentLen) {
    ::Serial.printf("Error: Written %u != expected %d\n", written, contentLen);
    http.end();
    return returnvalue_espota.wrapNumber((byte)0);
  }

  if (!Update.end()) {
    ::Serial.println("Error: Update.end() failed");
    http.end();
    return returnvalue_espota.wrapNumber((byte)0);
  }

  http.end();

  if (Update.isFinished()) {
    ::Serial.println("OTA update successful!");
    return returnvalue_espota.wrapNumber((byte)1);
  } else {
    ::Serial.println("OTA update not finished");
    return returnvalue_espota.wrapNumber((byte)0);
  }
}
#End If

Usage like:
B4X:
GlobalStore.Put(2, "https://server.com/ota/update.bin")
espota.OTA_Update

Depending:
GlobalStore: https://www.b4x.com/android/forum/threads/module-globalstore-global-objects-storage.73863/
espwdt: https://www.b4x.com/android/forum/threads/esp32-watchdog.149346/post-1035353
 
Last edited:
Top