Go Down

Topic: Download an updated sketch remotely (Read 3344 times) previous topic - next topic

ninora

Juraj,
This is fantastic! much needed utility.
I did see a timeout so added client.setTimeout(5000);, other than that, fabulous!
Thanks a lot!


ninora

To avoid restarting on bad binary I am looking for a way to verify the downloaded file checksum using CRC32 (or other method?).


Is it possible to access the written buffer once the read/write loop completes so I don't have to hold another buffer in memory?

Juraj

TCP verifies the transfer over network. The library verifies the size. How do you want to send the CRC?
if you use the SD version, you can check the file.

ninora

In my implementation the board receives an instruction from the server to update itself with server/port/path information, with that I can send the expected CRC.
I am not using SD, just the boards (MKR and Nano 33).

Juraj

#19
Mar 26, 2020, 07:22 am Last Edit: Mar 26, 2020, 07:22 am by Juraj
In my implementation the board receives an instruction from the server to update itself with server/port/path information, with that I can send the expected CRC.
I am not using SD, just the boards (MKR and Nano 33).

if you your code is based on OTASketchDownload, then you can add the calculation here


Code: [Select]
 while (length > 0) {
   if (!client.readBytes(&b, 1)) // reading a byte with timeout
     break;
   InternalStorage.write(b);
   length--;
 }

b is one byte copied from download stream into internal storage

ninora

Yes, this is what I used and again, thanks a lot for providing this helpful code.

There's not enough RAM to create an image of the file and CRC it and I have no idea how to use the byte by byte info and turn it into the desired file's signature.

Juraj


ninora

The utilities I looked at provide hashed checksum, not a straightforward aggregated sum of the bytes stream.  I am sure there is a way to combine the two but this is out of my league.

ninora

When I run the OTA code on MKR 1010 WiFi it runs well but I am having troubles defining "transport" for use with MKR ETH Shield.

Code: [Select]
#include <WiFiNINA.h>
#include <Ethernet.h>
#include <ArduinoOTA.h>
#include <ArduinoHttpClient.h>

#define ETH

#ifdef ETH
  EthernetClient transport;
#else
  WiFiSSLClient transport;
#endif
  


void setup() {
  Serial.begin(115200);
  while (!Serial)

  while (WiFi.begin("ssid", "password") != WL_CONNECTED) {
  }

  #ifdef ETH
    byte mac[6];
    WiFi.macAddress(mac);

    while (Ethernet.begin(mac) == 0) {
    }
  #endif


  bool someCondition = true;
  if (someCondition) {
    handleSketchDownload();
  }

}

void loop() {
  //
}



void handleSketchDownload() {
  
  Serial.println("Updating");
  HttpClient client(transport, "server.com", 443);
  client.get("/path/file.bin");

  int statusCode = client.responseStatusCode();
  if (statusCode != 200) {
    client.stop();
    Serial.print("Error ");
    Serial.println(statusCode);
    return;
  }

  long length = client.contentLength();
  if (length == HttpClient::kNoContentLengthHeader) {
    client.stop();
    Serial.println("Server didn't provide Content-length header. Can't continue with update");
    return;
  }
  
  if (!InternalStorage.open(length)) {
    client.stop();
    Serial.println("Not enough space");
    return;
  }
  
  client.setTimeout(5000);

  byte b;
  while (length > 0) {
    if (!client.readBytes(&b, 1)) // reading a byte with timeout
    break;
    InternalStorage.write(b);
    length--;
  }
  
  InternalStorage.close();
  client.stop();
  
  if (length > 0) {
    Serial.print("Timeout after ");
    Serial.print(length);
    Serial.println(" bytes");
    return;
  }

  Serial.flush();
  InternalStorage.apply(); // this doesn't return
}


Without #define ETH update works well.
With #define ETH I get "Error 400".

Where is my mistake?
Thanks!

Juraj


ninora

https
Error -2
Which I assume means 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

Juraj

Error -2
Which I assume means 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

no. you connect to https port without encryption

ninora

Not sure what you mean, HTTPS calls are possible using ETH sheild over MKR WIFI, where is the limitation?

Juraj

Not sure what you mean, HTTPS calls are possible using ETH sheild over MKR WIFI, where is the limitation?
no. the Ethernet library's EthernetClient doesn't do encryption

ninora

Thanks for the tip, it works well with port 80.

Go Up