Skip to content

Instantly share code, notes, and snippets.

@JMishou
Created December 30, 2017 05:11
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save JMishou/60cb762047b735685e8a09cd2eb42a60 to your computer and use it in GitHub Desktop.
Save JMishou/60cb762047b735685e8a09cd2eb42a60 to your computer and use it in GitHub Desktop.
ESPAsyncWebServer webupdate
/*
__/\\\\____________/\\\\__/\\\\\\\\\\\_____/\\\\\\\\\\\____/\\\________/\\\_
_\/\\\\\\________/\\\\\\_\/////\\\///____/\\\/////////\\\_\/\\\_______\/\\\_
_\/\\\//\\\____/\\\//\\\_____\/\\\______\//\\\______\///__\/\\\_______\/\\\_
_\/\\\\///\\\/\\\/_\/\\\_____\/\\\_______\////\\\_________\/\\\\\\\\\\\\\\\_
_\/\\\__\///\\\/___\/\\\_____\/\\\__________\////\\\______\/\\\/////////\\\_
_\/\\\____\///_____\/\\\_____\/\\\_____________\////\\\___\/\\\_______\/\\\_
_\/\\\_____________\/\\\_____\/\\\______/\\\______\//\\\__\/\\\_______\/\\\_
_\/\\\_____________\/\\\__/\\\\\\\\\\\_\///\\\\\\\\\\\/___\/\\\_______\/\\\_
_\///______________\///__\///////////____\///////////_____\///________\///__
Ported WebUpdate example from Examples>>ESP8266WebServer>>WebUpdate to ESPAsyncWebServer
To upload through terminal you can use: curl -F "image=@firmware.bin" esp8266-webupdate.local/update
*/
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
const char* host = "espasync-webupdate";
const char* ssid = "*******";
const char* password = "*******";
AsyncWebServer server(80);
const char* serverIndex = "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
bool restartRequired = false; // Set this flag in the callbacks to restart ESP in the main loop
void setup(void){
Serial.begin(115200);
Serial.setDebugOutput(true);
WiFi.hostname(host);
WiFi.mode(WIFI_AP_STA);
WiFi.softAP(host);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.printf("STA: Failed!\n");
WiFi.disconnect(false);
delay(1000);
WiFi.begin(ssid, password);
}
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
AsyncWebServerResponse *response = request->beginResponse(200, "text/html", serverIndex);
response->addHeader("Connection", "close");
response->addHeader("Access-Control-Allow-Origin", "*");
request->send(response);
});
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
// the request handler is triggered after the upload has finished...
// create the response, add header, and send response
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", (Update.hasError())?"FAIL":"OK");
response->addHeader("Connection", "close");
response->addHeader("Access-Control-Allow-Origin", "*");
restartRequired = true; // Tell the main loop to restart the ESP
request->send(response);
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
//Upload handler chunks in data
if(!index){ // if index == 0 then this is the first frame of data
Serial.printf("UploadStart: %s\n", filename.c_str());
Serial.setDebugOutput(true);
// calculate sketch space required for the update
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if(!Update.begin(maxSketchSpace)){//start with max available size
Update.printError(Serial);
}
Update.runAsync(true); // tell the updaterClass to run in async mode
}
//Write chunked data to the free sketch space
if(Update.write(data, len) != len){
Update.printError(Serial);
}
if(final){ // if the final flag is set then this is the last frame of data
if(Update.end(true)){ //true to set the size to the current progress
Serial.printf("Update Success: %u B\nRebooting...\n", index+len);
} else {
Update.printError(Serial);
}
Serial.setDebugOutput(false);
}
});
server.onNotFound([](AsyncWebServerRequest *request){
Serial.printf("NOT_FOUND: ");
if(request->method() == HTTP_GET)
Serial.printf("GET");
else if(request->method() == HTTP_POST)
Serial.printf("POST");
else if(request->method() == HTTP_DELETE)
Serial.printf("DELETE");
else if(request->method() == HTTP_PUT)
Serial.printf("PUT");
else if(request->method() == HTTP_PATCH)
Serial.printf("PATCH");
else if(request->method() == HTTP_HEAD)
Serial.printf("HEAD");
else if(request->method() == HTTP_OPTIONS)
Serial.printf("OPTIONS");
else
Serial.printf("UNKNOWN");
Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str());
if(request->contentLength()){
Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str());
Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength());
}
int headers = request->headers();
int i;
for(i=0;i<headers;i++){
AsyncWebHeader* h = request->getHeader(i);
Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str());
}
int params = request->params();
for(i=0;i<params;i++){
AsyncWebParameter* p = request->getParam(i);
if(p->isFile()){
Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size());
} else if(p->isPost()){
Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str());
} else {
Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str());
}
}
request->send(404);
});
server.begin();
}
void loop(void){
if (restartRequired){ // check the flag here to determine if a restart is required
Serial.printf("Restarting ESP\n\r");
restartRequired = false;
ESP.restart();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment