Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ It will provide a webpage for updating the firmware/filesystem of `ESP8266` or `
- Update credentials customization (default: `No credentials`)
- Username
- Password
- Update Events:
- onUpdateBegin
- onUpdateEnd
- Force Aborting Update using events
- FileSystem Options:
- SPIFFS
- LittleFS
Expand All @@ -60,25 +64,44 @@ This Library is available in `Arduino Library Repository` and `PIO` and you can
```
2. Create an object from `ESPAsyncHTTPUpdateServer`
``` C++
ESPAsyncHTTPUpdateServer _updateServer;
AsyncWebServer _server(80);
ESPAsyncHTTPUpdateServer updateServer;
AsyncWebServer server(80);
```
3. Setup the update server before starting the webServer
``` C++
_updateServer.setup(&_server);
_server.begin();
updateServer.setup(&server);
server.begin();
```
#### Custom Route
``` C++
_updateServer.setup(&_server, "/customroute");
updateServer.setup(&server, "/customroute");
```
#### Credentials
``` C++
_updateServer.setup(&_server, "username", "password");
updateServer.setup(&server, "username", "password");
```
or
``` C++
_updateServer.setup(&_server, "/customroute", "username", "password");
updateServer.setup(&server, "/customroute", "username", "password");
```
#### Events
```c++
updateServer.onUpdateBegin = [](const UpdateType type, int &result)
{
//...
};

updateServer.onUpdateEnd = [](const UpdateType type, int &result)
{
//...
};
```
#### Aborting the update
```c++
updateServer.onUpdateBegin = [](const UpdateType type, int &result)
{
result = UpdateResult::UPDATE_ABORT;
};
```

### Styling and Customizing OTA Page
Expand Down
12 changes: 12 additions & 0 deletions examples/simple_server/simple_server.ino
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ void setup() {

//setup the updateServer with credentials
updateServer.setup(&server, "admin", "admin");
//hook to update events if you need to
updateServer.onUpdateBegin = [](const UpdateType type, int &result)
{
//you can force abort the update like this if you need to:
//result = UpdateResult::UPDATE_ABORT;
Serial.println("Update started : " + String(type));
};
updateServer.onUpdateEnd = [](const UpdateType type, int &result)
{
Serial.println("Update finished : " + String(type) + " result: " + String(result));
};

server.begin();
}

Expand Down
53 changes: 43 additions & 10 deletions src/ESPAsyncHTTPUpdateServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path,
if(_username != emptyString && _password != emptyString)
if( !request->authenticate(_username.c_str(), _password.c_str()))
return request->requestAuthentication();
#ifdef ESP32
AsyncWebServerResponse* response = request->beginResponse(200, "text/html", serverIndex, sizeof(serverIndex));
#else
AsyncWebServerResponse* response = request->beginResponse_P(200, "text/html", serverIndex, sizeof(serverIndex));
#endif
response->addHeader("Content-Encoding", "gzip");
request->send(response); });

Expand All @@ -105,29 +109,37 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path,
if (!_authenticated)
return request->requestAuthentication();

if (Update.hasError())
if (_updateResult != UpdateResult::UPDATE_OK)
{
AsyncWebServerResponse *response = request->beginResponse(200, F("text/html"), String(F("Update error: ")) + _updaterError);
AsyncWebServerResponse *response = request->beginResponse(200, F("text/html"), Update.hasError() ? String(F("Update error: ")) + _updaterError : "Update aborted by server.");
response->addHeader("Access-Control-Allow-Headers", "*");
response->addHeader("Access-Control-Allow-Origin", "*");
response->addHeader("Connection", "close");
request->send(response);
}
else
{
#ifdef ESP32
request->send(200, PSTR("text/html"), successResponse);
#else
request->send_P(200, PSTR("text/html"), successResponse);
restartTimer.once_ms(1000, ESP.restart);
#endif
Log("Rebooting...\n");
restartTimer.once_ms(1000,[]{ ESP.restart(); });
} },
[&](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
{
// handler for the file upload, gets the sketch bytes, and writes
// them through the Update object

String inputName = request->getParam("name")->value();
_updateType = request->getParam("name")->value() == "filesystem"?
UpdateType::FILE_SYSTEM :
UpdateType::FIRMWARE;

if (!index)
{
_updaterError.clear();

#ifdef ESPASYNCHTTPUPDATESERVER_DEBUG
ESPASYNCHTTPUPDATESERVER_SerialOutput.setDebugOutput(true);
#endif
Expand All @@ -137,13 +149,27 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path,
Log("Unauthenticated Update\n");
return;
}

if (onUpdateBegin)
{
_updateResult = UpdateResult::UPDATE_OK;
onUpdateBegin(_updateType, _updateResult);
if (_updateResult != UpdateResult::UPDATE_OK)
{
Log("Update aborted by server: %d\n", _updateResult);
if(onUpdateEnd)
onUpdateEnd(_updateType, _updateResult);
return;
}
}

Log("Update: %s\n", filename.c_str());
#ifdef ESP8266
Update.runAsync(true);
#endif
if (inputName == "filesystem")
if (_updateType == UpdateType::FILE_SYSTEM)
{
Log("updating filesystem");
Log("updating filesystem\n");
#ifdef ESP8266
int command = U_FS;
size_t fsSize = ((size_t)FS_end - (size_t)FS_start);
Expand All @@ -165,25 +191,28 @@ void ESPAsyncHTTPUpdateServer::setup(AsyncWebServer *server, const String &path,
}
else
{
Log("updating flash");
Log("updating flash\n");
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace, U_FLASH)) // start with max available size
_setUpdaterError();
}
}

if (_authenticated && len && !_updaterError.length())
if (_authenticated && len && _updateResult == UpdateResult::UPDATE_OK)
{
Log(".");
if (Update.write(data, len) != len)
_setUpdaterError();
}

if (_authenticated && final && !_updaterError.length())
if (_authenticated && final && _updateResult == UpdateResult::UPDATE_OK)
{
if (Update.end(true))
{ // true to set the size to the current progress
Log("Update Success: \nRebooting...\n");
Log("Update Success.\n");
_updateResult = UpdateResult::UPDATE_OK;
if(onUpdateEnd)
onUpdateEnd(_updateType, _updateResult);
}
else
_setUpdaterError();
Expand All @@ -204,4 +233,8 @@ void ESPAsyncHTTPUpdateServer::_setUpdaterError()
StreamString str;
Update.printError(str);
_updaterError = str.c_str();

_updateResult = UpdateResult::UPDATE_ERROR;
if(onUpdateEnd)
onUpdateEnd(_updateType, _updateResult);
}
20 changes: 20 additions & 0 deletions src/ESPAsyncHTTPUpdateServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,27 @@

#include <ESPAsyncWebServer.h>

enum UpdateType
{
FIRMWARE,
FILE_SYSTEM
};

enum UpdateResult
{
UPDATE_OK,
UPDATE_ABORT,
UPDATE_ERROR,
};

typedef void (*ESPAsyncHTTPUpdateServer_event)(const UpdateType type, int &result);

class ESPAsyncHTTPUpdateServer
{
public:
ESPAsyncHTTPUpdateServer_event onUpdateBegin = NULL;
ESPAsyncHTTPUpdateServer_event onUpdateEnd = NULL;

ESPAsyncHTTPUpdateServer();

void setup(AsyncWebServer *server)
Expand Down Expand Up @@ -40,6 +58,8 @@ class ESPAsyncHTTPUpdateServer
String _password;
bool _authenticated;
String _updaterError;
UpdateType _updateType;
int _updateResult;
};

#endif