-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathota.h
204 lines (158 loc) · 7.9 KB
/
ota.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
/**************************************************************************************************
*
* Over The Air updates (OTA) - 02Aug23
* MODIFIED FOR USE WITH ESP32CamDemo (no log, different header)
*
* part of the BasicWebserver sketch - https://github.com/alanesq/BasicWebserver
*
* If using an esp32cam module In Arduino IDE Select "ESP32 dev module" not "ESP32-cam" with PSRAM enabled
*
**************************************************************************************************
Make sure partition with OTA enabled is selected
To enable/disable OTA updates see setting at top of main sketch (#define ENABLE_OTA 1)
Then access with http://<esp ip address>/ota
**************************************************************************************************/
#if defined ESP32
#include <Update.h>
#endif
// forward declarations (i.e. details of all functions in this file)
void otaSetup();
void handleOTA();
// some useful html/css
const char colRed[] = "<span style='color:red;'>"; // red text
const char colGreen[] = "<span style='color:green;'>"; // green text
const char colBlue[] = "<span style='color:blue;'>"; // blue text
const char colEnd[] = "</span>"; // end coloured text
const char htmlSpace[] = " "; // leave a space (see 'HTML entity')
// ----------------------------------------------------------------
// -enable OTA
// ----------------------------------------------------------------
// Enable OTA updates, called when correct password has been entered
void otaSetup() {
OTAEnabled = 1; // flag that OTA has been enabled
// esp32 version (using webserver.h)
#if defined ESP32
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "Update Failed!, rebooting..." : "Update complete, rebooting...");
delay(2000);
ESP.restart();
delay(2000);
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
if (serialDebug) Serial.setDebugOutput(true);
if (serialDebug) Serial.printf("Update: %s\n", upload.filename.c_str());
if (!Update.begin()) { //start with max available size
if (serialDebug) Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
if (serialDebug) Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
if (serialDebug) Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
if (serialDebug) Update.printError(Serial);
}
if (serialDebug) Serial.setDebugOutput(false);
} else {
if (serialDebug) Serial.printf("Update Failed Unexpectedly (likely broken connection): status=%d\n", upload.status);
}
});
#endif
// esp8266 version (using ESP8266WebServer.h)
#if defined ESP8266
server.on("/update", HTTP_POST, []() {
server.sendHeader("Connection", "close");
server.send(200, "text/plain", (Update.hasError()) ? "Update Failed!, rebooting..." : "Update complete, rebooting...");
delay(2000);
ESP.restart();
delay(2000);
}, []() {
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
if (serialDebug) Serial.setDebugOutput(true);
WiFiUDP::stopAll();
if (serialDebug) 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
if (serialDebug) Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) {
if (serialDebug) Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
if (serialDebug) Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
} else {
if (serialDebug) Update.printError(Serial);
}
if (serialDebug) Serial.setDebugOutput(false);
}
yield();
});
#endif
}
// ----------------------------------------------------------------
// -OTA web page requested i.e. http://x.x.x.x/ota
// ----------------------------------------------------------------
// Request OTA password or implement OTA update if already entered
void handleOTA(){
WiFiClient client = server.client(); // open link with client
// check if valid password supplied
if (server.hasArg("pwd")) {
if (server.arg("pwd") == OTAPassword) otaSetup(); // Enable over The Air updates (OTA)
}
// -----------------------------------------
if (OTAEnabled == 0) {
// OTA is not enabled so request password to enable it
sendHeader(client, stitle);
// This is the below javascript/html compacted to save flash memory via https://www.textfixer.com/html/compress-html-compression.php
client.print (R"=====(<form name='loginForm'> <table width='20%' bgcolor='A09F9F' align='center'> <tr> <td colspan=2> <center><font size=4><b>Enter OTA password</b></font></center><br> </td> <br> </tr><tr> <td>Password:</td> <td><input type='Password' size=25 name='pwd'><br></td><br><br> </tr><tr> <td><input type='submit' onclick='check(this.form)' value='Login'></td> </tr> </table> </form> <script> function check(form) { window.open('/ota?pwd=' + form.pwd.value , '_self') } </script>)=====");
/*
client.print (R"=====(
<form name='loginForm'>
<table width='20%' bgcolor='A09F9F' align='center'>
<tr>
<td colspan=2>
<center><font size=4><b>Enter OTA password</b></font></center><br>
</td><br>
</tr><tr>
<td>Password:</td>
<td><input type='Password' size=25 name='pwd'><br></td><br><br>
</tr><tr>
<td><input type='submit' onclick='check(this.form)' value='Login'></td>
</tr>
</table>
</form>
<script>
function check(form)
{
window.open('/ota?pwd=' + form.pwd.value , '_self')
}
</script>
)=====");
*/
sendFooter(client); // close web page
}
// -----------------------------------------
if (OTAEnabled == 1) { // if OTA is enabled implement it
sendHeader(client, stitle);
client.write("<br><H1>Update firmware</H1><br>\n");
client.printf("Current version = %s, %s \n\n", stitle, sversion);
client.write("<form method='POST' action='/update' enctype='multipart/form-data'>\n");
client.write("<input type='file' style='width: 300px' name='update'>\n");
client.write("<br><br><input type='submit' value='Update'></form><br>\n");
client.write("<br><br>Device will reboot when upload complete");
client.printf("%s <br>To disable OTA restart device<br> %s \n", colRed, colEnd);
sendFooter(client); // close web page
}
// -----------------------------------------
// close html page
delay(3);
client.stop();
}
// ---------------------------------------------- end ----------------------------------------------