I am trying to implement OTA with ESP32 and thinking of using HTTP multipart/form-data as a protocol. Since I don't have a broad background in this protocol type, I wonder how I can receive HTTP multipart/form-data(file) from the server (to ESP32).
Could you give me any code examples, useful libraries, or general flow of it?
Also, I am currently using HTTPClient.h to post data to the server. Is this library enough to implement HTTP multipart form, or do I need the other one?
FYI, my OTA scenario is as below:
- (ESP32->server) check if there are any required updates
- (server->ESP32) send whether there exists any update
- (ESP32->server) request updates
- (server->ESP32) send firmware update file(s)
- (ESP32) receive the file(s) and reboot the device
Thank you in advance!
CodePudding user response:
Here's a function that will do one file upload and one field of data using POST
void UploadToDataverse() {
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
// Length (with one extra character for the null terminator)
int str_len = DATASET_REPOSITORY_URL.length() 1;
// Prepare the character array (the buffer)
char char_url [str_len];
// Copy it over
DATASET_REPOSITORY_URL.toCharArray(char_url, str_len);
if (!client.connect(char_url, 8080)) {
Serial.println("Cloud server URL connection FAILED!");
Serial.println(char_url);
int server_status = client.connected();
Serial.println("Server status code: " String(server_status));
return;
}
Serial.println("Connected to the Dataverse.");
String lineEnd = "\n";
String twoHyphens = "--";
String boundary = String("*****") String("AaB03x") String("*****");
String charset="UTF-8";
client.println("POST /Home/Index HTTP/1.1");
client.println("Host: " SERVER_URL);
client.println("Connection: Keep-Alive");
client.println("ENCTYPE: multipart/form-data");
client.println("User-Agent: AeonLabs LDAD");
client.println("Content-Type: multipart/form-data; boundary=" String(boundary));
client.println();
client.println(String(lineEnd) String(twoHyphens) String(boundary) String(twoHyphens) String(lineEnd));
client.println("Content-Disposition: form-data; name=\"file\"; filename=\"" String(EXPERIMENTAL_DATA_FILENAME) "\"" String(lineEnd));
client.println("Content-Transfer-Encoding: binary" String(lineEnd) String(lineEnd));
// send 'jsonData' >>> send multipart form data after file data...
String data2Send = "{\"description\":\"My description.\",\"categories\":[\"Data\"], \"restrict\":\"false\", \"tabIngest\":\"false\"}";
client.println(String(lineEnd) String(twoHyphens) String(boundary) String(twoHyphens) String(lineEnd));
client.println("Content-Disposition: form-data; name=\"jsonData\"");
client.println(lineEnd);
client.println("Content-Type: text/plain; charset=" String(charset));
client.println(lineEnd);
client.println(lineEnd);
client.println(data2Send);
client.println(lineEnd);
//client.flush();
// Start sending dataset file
File file = FFat.open(EXPERIMENTAL_DATA_FILENAME, FILE_READ);
client.println(String(lineEnd) String(twoHyphens) String(boundary) String(twoHyphens) String(lineEnd));
client.println("Content-Disposition: form-data; name=\"file\";filename=\"" String(EXPERIMENTAL_DATA_FILENAME) "\"" String(lineEnd));
client.println(lineEnd);
while (file.available()){
client.write(file.read());
}
file.close();
// finnish the wrapper
client.println(lineEnd);
client.flush();
client.println(String(lineEnd) String(twoHyphens) String(boundary) String(twoHyphens) String(lineEnd));
Serial.println(">>><<<");
Serial.println("Response:");
while (client.connected()) {
if (client.available()) {
String response = client.readStringUntil('\n');
Serial.println(response.c_str());
}
}
client.stop();
}
else {
Serial.println("WiFi Disconnected");
if (connect2WIFInetowrk()){
UploadToDataverse();
}
}
}
CodePudding user response:
I think what you need is to use the Mongoose OS implementation for your ESP32. Its pretty straightforward, and all your remote OTA update requirement will be satisfied.
Thank You, Hope it helps