parent
da8bf23e93
commit
324c6b7d5c
@ -0,0 +1,130 @@ |
||||
/**
|
||||
* Ported the ESP8266HTTPUpdateServer published by Arduino-core to |
||||
* provide the web browser based OTA update on the ESP32 platform. |
||||
* @file HTTPUpdateServer.cpp |
||||
* @author hieromon@gmail.com |
||||
* @version 0.9.10 |
||||
* @date 2019-06-06 |
||||
* @copyright MIT license. |
||||
*/ |
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32 |
||||
// This class will available only EPS32 actually.
|
||||
|
||||
#include <Arduino.h> |
||||
#include <WiFiClient.h> |
||||
#include <WiFiServer.h> |
||||
#include <WebServer.h> |
||||
#include <WiFiUdp.h> |
||||
#include <Update.h> |
||||
#include "StreamString.h" |
||||
#include "HTTPUpdateServer.h" |
||||
|
||||
static const char serverIndex[] PROGMEM = R"( |
||||
<html><body> |
||||
<form method='POST' action='' enctype='multipart/form-data'> |
||||
<input type='file' name='update'> |
||||
<input type='submit' value='Update'> |
||||
</form> |
||||
</body></html> |
||||
)"; |
||||
|
||||
static const char successResponse[] PROGMEM =
|
||||
"<meta http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...\n"; |
||||
|
||||
/**
|
||||
* Setup for the web update. Register the authentication procedure and |
||||
* binary file upload handler required to update the actual sketch binary by OTA. |
||||
* @param server A pointer to the WebServer instance |
||||
* @param path URI of the update handler |
||||
* @param username Username for authentication |
||||
* @arama password Password for authentication |
||||
*/ |
||||
void HTTPUpdateServer::setup(WebServer* server, const String& path, const String& username, const String& password) { |
||||
_server = server; |
||||
_username = username; |
||||
_password = password; |
||||
|
||||
// handler for the /update form page
|
||||
_server->on(path.c_str(), HTTP_GET, [&] () { |
||||
if (_username != emptyString && _password != emptyString && !_server->authenticate(_username.c_str(), _password.c_str())) |
||||
return _server->requestAuthentication(); |
||||
_server->send_P(200, PSTR("text/html"), serverIndex); |
||||
}); |
||||
|
||||
// handler for the /update form POST (once file upload finishes)
|
||||
_server->on(path.c_str(), HTTP_POST, [&] () { |
||||
if(!_authenticated) |
||||
return _server->requestAuthentication(); |
||||
if (Update.hasError()) { |
||||
_server->send(200, F("text/html"), String(F("Update error: ")) + _updaterError); |
||||
} |
||||
else { |
||||
_server->client().setNoDelay(true); |
||||
_server->send_P(200, PSTR("text/html"), successResponse); |
||||
delay(100); |
||||
_server->client().stop(); |
||||
ESP.restart(); |
||||
} |
||||
}, [&] () { |
||||
// handler for the file upload, get's the sketch bytes, and writes
|
||||
// them through the Update object
|
||||
HTTPUpload& upload = _server->upload(); |
||||
|
||||
if (upload.status == UPLOAD_FILE_START) { |
||||
_updaterError = String(); |
||||
if (_serial_output) |
||||
Serial.setDebugOutput(true); |
||||
|
||||
_authenticated = (_username == emptyString || _password == emptyString || _server->authenticate(_username.c_str(), _password.c_str())); |
||||
if (!_authenticated) { |
||||
if (_serial_output) |
||||
Serial.println("Unauthenticated Update"); |
||||
return; |
||||
} |
||||
|
||||
if (_serial_output) |
||||
Serial.printf("Update: %s\n", upload.filename.c_str()); |
||||
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; |
||||
if (!Update.begin(maxSketchSpace)) { //start with max available size
|
||||
_setUpdaterError(); |
||||
} |
||||
} |
||||
else if (_authenticated && upload.status == UPLOAD_FILE_WRITE && !_updaterError.length()) { |
||||
if (_serial_output) |
||||
Serial.print('.'); |
||||
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) |
||||
_setUpdaterError(); |
||||
} |
||||
else if (_authenticated && upload.status == UPLOAD_FILE_END && !_updaterError.length()) { |
||||
if (Update.end(true)) { //true to set the size to the current progress
|
||||
if (_serial_output) |
||||
Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); |
||||
} |
||||
else { |
||||
_setUpdaterError(); |
||||
} |
||||
if (_serial_output) |
||||
Serial.setDebugOutput(false); |
||||
} |
||||
else if (_authenticated && upload.status == UPLOAD_FILE_ABORTED) { |
||||
Update.end(); |
||||
if (_serial_output) |
||||
Serial.println("Update was aborted"); |
||||
} |
||||
delay(0); |
||||
}); |
||||
} |
||||
|
||||
/**
|
||||
* Convert the update error code to string for notation. |
||||
*/ |
||||
void HTTPUpdateServer::_setUpdaterError() { |
||||
if (_serial_output) |
||||
Update.printError(Serial); |
||||
StreamString str; |
||||
Update.printError(str); |
||||
_updaterError = str.c_str(); |
||||
} |
||||
|
||||
#endif // !ARDUINO_ARCH_ESP32
|
@ -0,0 +1,42 @@ |
||||
/**
|
||||
* Ported the ESP8266HTTPUpdateServer published by Arduino-core to |
||||
* provide the web browser based OTA update on the ESP32 platform. |
||||
* @file HTTPUpdateServer.h |
||||
* @author hieromon@gmail.com |
||||
* @version 0.9.10 |
||||
* @date 2019-06-06 |
||||
* @copyright MIT license. |
||||
*/ |
||||
|
||||
#ifndef __HTTP_UPDATE_SERVER_H |
||||
#define __HTTP_UPDATE_SERVER_H |
||||
|
||||
#ifdef ARDUINO_ARCH_ESP32 |
||||
// This class will available only EPS32 actually.
|
||||
|
||||
class WebServer; |
||||
|
||||
class HTTPUpdateServer { |
||||
public: |
||||
explicit HTTPUpdateServer(bool serial_debug = false) : _serial_output(serial_debug), _server(nullptr), _username(emptyString), _password(emptyString), _authenticated(false) {} |
||||
~HTTPUpdateServer() {} |
||||
void setup(WebServer* server) { setup(server, emptyString, emptyString); } |
||||
void setup(WebServer* server, const String& path) { setup(server, path, emptyString, emptyString); } |
||||
void setup(WebServer* server, const String& username, const String& password) { setup(server, "/update", username, password); } |
||||
void setup(WebServer* server, const String& path, const String& username, const String& password); |
||||
void updateCredentials(const String& username, const String& password) { _username = username; _password = password; } |
||||
|
||||
protected: |
||||
void _setUpdaterError(); |
||||
|
||||
private: |
||||
bool _serial_output; |
||||
WebServer* _server; |
||||
String _username; |
||||
String _password; |
||||
bool _authenticated; |
||||
String _updaterError; |
||||
}; |
||||
|
||||
#endif // !ARDUINO_ARCH_ESP32
|
||||
#endif // !__HTTP_UPDATE_SERVER_H
|
Loading…
Reference in new issue