forked from rvdbreemen/OTGW-firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOTGW-ModUpdateServer-impl.h
178 lines (163 loc) · 6.31 KB
/
OTGW-ModUpdateServer-impl.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
/*
***************************************************************************
** 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 <Arduino.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
#include <ESP8266WebServer.h>
#include <WiFiUdp.h>
#include <flash_hal.h>
#include <FS.h>
#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"(<html charset="UTF-8">
<body>
<h1>ESP8266 Flash utility</h1>
<form method='POST' action='?cmd=0' enctype='multipart/form-data'>
<input type='hidden' name='cmd' value='0'>
<input type='file' accept='ino.bin' name='update'>
<input type='submit' value='Flash Firmware'>
</form>
<form method='POST' action='?cmd=100' enctype='multipart/form-data'>
<input type='hidden' name='cmd' value='100'>
<input type='file' accept='LittleFS.bin' name='update'>
<input type='submit' value='Flash LittleFS'>
</form>
</html>)";
static const char successResponse[] PROGMEM =
"<META http-equiv=\"refresh\" content=\"15;URL=/\">Update <b>Success</b>!<br>Wait for DSMR-logger to reboot...";
**/
template <typename ServerType>
ESP8266HTTPUpdateServerTemplate<ServerType>::ESP8266HTTPUpdateServerTemplate(bool serial_debug)
{
_serial_output = serial_debug;
_server = NULL;
_username = emptyString;
_password = emptyString;
_authenticated = false;
}
template <typename ServerType>
void ESP8266HTTPUpdateServerTemplate<ServerType>::setup(ESP8266WebServerTemplate<ServerType> *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 <typename ServerType>
void ESP8266HTTPUpdateServerTemplate<ServerType>::setIndexPage(const char *indexPage)
{
_serverIndex = indexPage;
}
template <typename ServerType>
void ESP8266HTTPUpdateServerTemplate<ServerType>::setSuccessPage(const char *successPage)
{
_serverSuccess = successPage;
}
template <typename ServerType>
void ESP8266HTTPUpdateServerTemplate<ServerType>::_setUpdaterError()
{
if (_serial_output) Update.printError(OTGWSerial);
StreamString str;
Update.printError(str);
_updaterError = str.c_str();
}
};