/* *************************************************************************** ** Program : MonUpdateServer-impl.h ** Modified to work with OTGW Nodoshop Hardware Watchdog ** ** This is the ESP8266HTTPUpdateServer.h file ** Created and modified by Ivan Grokhotkov, Miguel Angel Ajo, Earle Philhower and many others ** see: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPUpdateServer ** ** ... and then modified by Willem Aandewiel ** ** License and credits ** Arduino IDE is developed and maintained by the Arduino team. The IDE is licensed under GPL. ** ** ESP8266 core includes an xtensa gcc toolchain, which is also under GPL. ** *************************************************************************** */ #include #include #include #include #include #include #include #include "StreamString.h" #include "Wire.h" #include "OTGW-ModUpdateServer.h" #ifndef Debug //#warning Debug() was not defined! #define Debug(...) ({ OTGWSerial.print(__VA_ARGS__); }) #define Debugln(...) ({ OTGWSerial.println(__VA_ARGS__); }) #define Debugf(...) ({ OTGWSerial.printf(__VA_ARGS__); }) //#else // #warning Seems Debug() is already defined! #endif namespace esp8266httpupdateserver { using namespace esp8266webserver; /** static const char serverIndex2[] PROGMEM = R"(

ESP8266 Flash utility

)"; static const char successResponse[] PROGMEM = "Update Success!
Wait for DSMR-logger to reboot..."; **/ template ESP8266HTTPUpdateServerTemplate::ESP8266HTTPUpdateServerTemplate(bool serial_debug) { _serial_output = serial_debug; _server = NULL; _username = emptyString; _password = emptyString; _authenticated = false; } template void ESP8266HTTPUpdateServerTemplate::setup(ESP8266WebServerTemplate *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"), _serverSuccess); _server->client().stop(); delay(1000); ESP.restart(); delay(3000); } },[&](){ // 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.clear(); // if (_serial_output) // OTGWSerial.setDebugOutput(true); _authenticated = (_username == emptyString || _password == emptyString || _server->authenticate(_username.c_str(), _password.c_str())); if(!_authenticated){ if (_serial_output) Debugln("Unauthenticated Update\n"); return; } WiFiUDP::stopAll(); if (_serial_output) Debugf("Update: %s\r\n", upload.filename.c_str()); if (upload.name == "filesystem") { size_t fsSize = ((size_t) &_FS_end - (size_t) &_FS_start); close_all_fs(); if (!Update.begin(fsSize, U_FS)){//start with max available size if (_serial_output) Update.printError(OTGWSerial); } } else { uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; if (!Update.begin(maxSketchSpace, U_FLASH)){//start with max available size _setUpdaterError(); } } } else if(_authenticated && upload.status == UPLOAD_FILE_WRITE && !_updaterError.length()){ if (_serial_output) {Debug("."); blinkLEDnow(LED1);} // Feed the dog before it bites! Wire.beginTransmission(0x26); Wire.write(0xA5); Wire.endTransmission(); // End of feeding hack 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) Debugf("\r\nUpdate Success: %u\r\nRebooting...\r\n", upload.totalSize); } else { _setUpdaterError(); } // if (_serial_output) // OTGWSerial.setDebugOutput(false); } else if(_authenticated && upload.status == UPLOAD_FILE_ABORTED){ Update.end(); if (_serial_output) Debugln("Update was aborted"); } delay(0); }); } template void ESP8266HTTPUpdateServerTemplate::setIndexPage(const char *indexPage) { _serverIndex = indexPage; } template void ESP8266HTTPUpdateServerTemplate::setSuccessPage(const char *successPage) { _serverSuccess = successPage; } template void ESP8266HTTPUpdateServerTemplate::_setUpdaterError() { if (_serial_output) Update.printError(OTGWSerial); StreamString str; Update.printError(str); _updaterError = str.c_str(); } };