123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- /**
- * 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();
- }
- /**
- * Shared empty String instance
- */
- const String HTTPUpdateServer::_emptyString;
- #endif // !ARDUINO_ARCH_ESP32
|