Skip to content

Commit 205d30e

Browse files
authored
Merge pull request #587 from sidey79/dev-ota-updater
WIP: Added OTA updater option from esp8266
2 parents ccfca4b + 7dc75ea commit 205d30e

File tree

3 files changed

+108
-0
lines changed

3 files changed

+108
-0
lines changed

WiFiManager.cpp

+93
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ void WiFiManager::setupConfigPortal() {
469469
}
470470

471471
/* Setup httpd callbacks, web pages: root, wifi config pages, SO captive portal detectors and not found. */
472+
472473
server->on(String(FPSTR(R_root)).c_str(), std::bind(&WiFiManager::handleRoot, this));
473474
server->on(String(FPSTR(R_wifi)).c_str(), std::bind(&WiFiManager::handleWifi, this, true));
474475
server->on(String(FPSTR(R_wifinoscan)).c_str(), std::bind(&WiFiManager::handleWifi, this, false));
@@ -483,6 +484,9 @@ void WiFiManager::setupConfigPortal() {
483484
server->on(String(FPSTR(R_status)).c_str(), std::bind(&WiFiManager::handleWiFiStatus, this));
484485
server->onNotFound (std::bind(&WiFiManager::handleNotFound, this));
485486

487+
server->on((String)FPSTR(R_update), std::bind(&WiFiManager::handleUpdate, this));
488+
server->on((String)FPSTR(R_updatedone), HTTP_POST, std::bind(&WiFiManager::handleUpdateDone, this), std::bind(&WiFiManager::handleUpdating, this));
489+
486490
server->begin(); // Web server start
487491
DEBUG_WM(DEBUG_VERBOSE,F("HTTP server started"));
488492

@@ -2693,3 +2697,92 @@ void WiFiManager::WiFi_autoReconnect(){
26932697
// }
26942698
#endif
26952699
}
2700+
2701+
// Called when /u is requested
2702+
void WiFiManager::handleUpdate() {
2703+
DEBUG_WM(DEBUG_VERBOSE,F("<- Handle update"));
2704+
if (captivePortal()) return; // If captive portal redirect instead of displaying the page
2705+
String page = getHTTPHead(FPSTR(S_options)); // @token options
2706+
String str = FPSTR(HTTP_ROOT_MAIN);
2707+
str.replace(FPSTR(T_v), configPortalActive ? _apName : WiFi.localIP().toString()); // use ip if ap is not active for heading
2708+
page += str;
2709+
2710+
page += FPSTR(HTTP_UPDATE);
2711+
page += FPSTR(HTTP_END);
2712+
2713+
server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
2714+
server->send(200, FPSTR(HTTP_HEAD_CT), page);
2715+
2716+
}
2717+
2718+
void WiFiManager::handleUpdating(){
2719+
if (captivePortal()) return; // If captive portal redirect instead of displaying the page
2720+
// handler for the file upload, get's the sketch bytes, and writes
2721+
// them through the Update object
2722+
HTTPUpload& upload = server->upload();
2723+
if (upload.status == UPLOAD_FILE_START) {
2724+
Serial.setDebugOutput(true);
2725+
2726+
#ifdef ESP8266
2727+
WiFiUDP::stopAll();
2728+
#elif defined(ESP32)
2729+
// Think we do not need to stop WiFIUDP because we haven't started a listener
2730+
#endif
2731+
Serial.printf("Update: %s\r\n", upload.filename.c_str());
2732+
#ifdef ESP8266
2733+
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
2734+
#elif defined(ESP32)
2735+
uint32_t maxSketchSpace = (ESP.getFlashChipSize() - 0x1000) & 0xFFFFF000;
2736+
2737+
#endif
2738+
2739+
if (!Update.begin(maxSketchSpace)) { // start with max available size
2740+
Update.printError(Serial);
2741+
}
2742+
} else if (upload.status == UPLOAD_FILE_WRITE) {
2743+
Serial.print(".");
2744+
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
2745+
Update.printError(Serial);
2746+
}
2747+
} else if (upload.status == UPLOAD_FILE_END) {
2748+
if (Update.end(true)) { // true to set the size to the current progress
2749+
Serial.printf("Updated: %u bytes\r\nRebooting...\r\n", upload.totalSize);
2750+
} else {
2751+
Update.printError(Serial);
2752+
}
2753+
Serial.setDebugOutput(false);
2754+
} else if (upload.status == UPLOAD_FILE_ABORTED) {
2755+
Update.end();
2756+
DEBUG_WM(F("<- Update was aborted"));
2757+
}
2758+
delay(0);
2759+
} // handleUpdating
2760+
2761+
void WiFiManager::handleUpdateDone() {
2762+
DEBUG_WM(DEBUG_VERBOSE, F("<- Handle update done"));
2763+
if (captivePortal()) return; // If captive portal redirect instead of displaying the page
2764+
2765+
String page = getHTTPHead(FPSTR(S_options)); // @token options
2766+
String str = FPSTR(HTTP_ROOT_MAIN);
2767+
str.replace(FPSTR(T_v), configPortalActive ? _apName : WiFi.localIP().toString()); // use ip if ap is not active for heading
2768+
page += str;
2769+
2770+
if (Update.hasError()) {
2771+
page += FPSTR(HTTP_UPDATE_FAIL);
2772+
DEBUG_WM(F("update failed"));
2773+
}
2774+
else {
2775+
page += FPSTR(HTTP_UPDATE_OK);
2776+
DEBUG_WM(F("update ok"));
2777+
2778+
}
2779+
page += FPSTR(HTTP_END);
2780+
2781+
server->sendHeader(FPSTR(HTTP_HEAD_CL), String(page.length()));
2782+
server->send(200, FPSTR(HTTP_HEAD_CT), page);
2783+
2784+
delay(1000); // send page
2785+
if (!Update.hasError()) {
2786+
ESP.restart();
2787+
}
2788+
}

WiFiManager.h

+6
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
#include <WiFi.h>
5757
#include <esp_wifi.h>
58+
#include <Update.h>
5859

5960
#define WIFI_getChipId() (uint32_t)ESP.getEfuseMac()
6061
#define WM_WIFIOPEN WIFI_AUTH_OPEN
@@ -408,6 +409,11 @@ class WiFiManager
408409
boolean configPortalHasTimeout();
409410
uint8_t processConfigPortal();
410411
void stopCaptivePortal();
412+
// OTA Update handler
413+
void handleUpdate();
414+
void handleUpdating();
415+
void handleUpdateDone();
416+
411417

412418
// wifi platform abstractions
413419
bool WiFi_Mode(WiFiMode_t m);

strings_en.h

+9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const char * const HTTP_PORTAL_MENU[] PROGMEM = {
2424
"<form action='/info' method='get'><button>Info</button></form><br/>\n", // MENU_INFO
2525
"<form action='/param' method='get'><button>Setup</button></form><br/>\n",//MENU_PARAM
2626
"<form action='/close' method='get'><button>Close</button></form><br/>\n", // MENU_CLOSE
27+
"<form action='/update' method='get'><button>Update</button></form><br/>\n",// MENU_UPDATE
2728
"<form action='/restart' method='get'><button>Restart</button></form><br/>\n",// MENU_RESTART
2829
"<form action='/exit' method='get'><button>Exit</button></form><br/>\n", // MENU_EXIT
2930
"<form action='/erase' method='get'><button class='D'>Erase</button></form><br/>\n", // MENU_ERASE
@@ -99,6 +100,8 @@ const char HTTP_HELP[] PROGMEM =
99100
"<td>Parameter page</td></tr>"
100101
"<tr><td><a href='/info'>/info</a></td>"
101102
"<td>Information page</td></tr>"
103+
"<tr><td><a href='/u'>/u</a></td>"
104+
"<td>OTA Update</td></tr>"
102105
"<tr><td><a href='/close'>/close</a></td>"
103106
"<td>Close the captiveportal popup,configportal will remain active</td></tr>"
104107
"<tr><td><a href='/exit'>/exit</a></td>"
@@ -110,6 +113,10 @@ const char HTTP_HELP[] PROGMEM =
110113
"</table>"
111114
"<p/>More information about WiFiManager at <a href='https://github.com/tzapu/WiFiManager'>https://github.com/tzapu/WiFiManager</a>.";
112115

116+
const char HTTP_UPDATE[] PROGMEM = "<form method='POST' action='update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
117+
const char HTTP_UPDATE_FAIL[] PROGMEM = "Update Failed!";
118+
const char HTTP_UPDATE_OK[] PROGMEM = "Update OK! Rebooting now...";
119+
113120
#ifdef JSTEST
114121
const char HTTP_JS[] PROGMEM =
115122
"<script>function postAjax(url, data, success) {"
@@ -236,6 +243,8 @@ const char R_exit[] PROGMEM = "/exit";
236243
const char R_close[] PROGMEM = "/close";
237244
const char R_erase[] PROGMEM = "/erase";
238245
const char R_status[] PROGMEM = "/status";
246+
const char R_update[] PROGMEM = "/u";
247+
const char R_updatedone[] PROGMEM = "/update";
239248

240249

241250
//Strings

0 commit comments

Comments
 (0)