Skip to content

Commit 0c8c7ab

Browse files
authored
Merge branch 'master' into tests/sync-arduino-h
2 parents e59f926 + 3308386 commit 0c8c7ab

File tree

15 files changed

+294
-186
lines changed

15 files changed

+294
-186
lines changed

bootloaders/eboot/eboot.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,10 @@ int main()
229229
ets_wdt_enable();
230230

231231
ets_putc('0'+res); ets_putc('\n');
232-
232+
#if 0
233+
//devyte: this verify step below (cmp:) only works when the end of copy operation above does not overwrite the
234+
//beginning of the image in the empty area, see #7458. Disabling for now.
235+
//TODO: replace the below verify with hash type, crc, or similar.
233236
// Verify the copy
234237
ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':');
235238
if (res == 0) {
@@ -239,6 +242,7 @@ int main()
239242
}
240243

241244
ets_putc('0'+res); ets_putc('\n');
245+
#endif
242246
if (res == 0) {
243247
cmd.action = ACTION_LOAD_APP;
244248
cmd.args[0] = cmd.args[1];

bootloaders/eboot/eboot.elf

-680 Bytes
Binary file not shown.

cores/esp8266/Updater.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ UpdaterClass::UpdaterClass()
3535
, _startAddress(0)
3636
, _currentAddress(0)
3737
, _command(U_FLASH)
38+
, _ledPin(-1)
3839
, _hash(nullptr)
3940
, _verify(nullptr)
4041
, _progress_callback(nullptr)

cores/esp8266/core_esp8266_features.h

+14-2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ namespace arduino
8585
// level 0 will enable ALL interrupts,
8686
//
8787
#ifndef CORE_MOCK
88+
8889
#define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state) :: "memory"); state;}))
8990
#define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
9091

@@ -95,10 +96,21 @@ inline uint32_t esp_get_cycle_count() {
9596
return ccount;
9697
}
9798

98-
#else
99+
inline uint32_t esp_get_program_counter() __attribute__((always_inline));
100+
inline uint32_t esp_get_program_counter() {
101+
uint32_t pc;
102+
__asm__ __volatile__("movi %0, ." : "=r" (pc) : : ); // ©earlephilhower
103+
return pc;
104+
}
105+
106+
#else // CORE_MOCK
107+
99108
#define xt_rsil(level) (level)
100109
#define xt_wsr_ps(state) do { (void)(state); } while (0)
101-
#endif // ifndef CORE_MOCK
110+
111+
inline uint32_t esp_get_program_counter() { return 0; }
112+
113+
#endif // CORE_MOCK
102114

103115

104116
// Tools for preloading code into the flash cache

cores/esp8266/heap.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line)
164164
if (inISR && (uint32_t)file >= 0x40200000) {
165165
DEBUG_HEAP_PRINTF("File: %p", file);
166166
} else if (!inISR && (uint32_t)file >= 0x40200000) {
167-
char buf[ets_strlen(file)] __attribute__ ((aligned(4)));
167+
char buf[ets_strlen(file) + 1] __attribute__((aligned(4)));
168168
ets_strcpy(buf, file);
169169
DEBUG_HEAP_PRINTF(buf);
170170
} else {

cores/esp8266/umm_malloc/umm_local.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ int ICACHE_FLASH_ATTR umm_info_safe_printf_P(const char *fmt, ...) {
206206
the PROGMEM address must be word (4 bytes) aligned. The destination
207207
address for ets_memcpy must also be word-aligned.
208208
*/
209-
char ram_buf[ets_strlen(fmt)] __attribute__ ((aligned(4)));
209+
char ram_buf[ets_strlen(fmt) + 1] __attribute__((aligned(4)));
210210
ets_strcpy(ram_buf, fmt);
211211
va_list argPtr;
212212
va_start(argPtr, fmt);

libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void loop() {
5050
Serial.print("[HTTPS] begin...\n");
5151

5252
// configure server and url
53-
const uint8_t fingerprint[20] = {0xEB, 0xD9, 0xDF, 0x37, 0xC2, 0xCC, 0x84, 0x89, 0x00, 0xA0, 0x58, 0x52, 0x24, 0x04, 0xE4, 0x37, 0x3E, 0x2B, 0xF1, 0x41};
53+
const uint8_t fingerprint[20] = {0x15, 0x77, 0xdc, 0x04, 0x7c, 0x00, 0xf8, 0x70, 0x09, 0x34, 0x24, 0xf4, 0xd3, 0xa1, 0x7a, 0x6c, 0x1e, 0xa3, 0xe0, 0x2a};
5454

5555
client->setFingerprint(fingerprint);
5656

libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino

+61-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const int led = 13;
1717

1818
void handleRoot() {
1919
digitalWrite(led, 1);
20-
server.send(200, "text/plain", "hello from esp8266!");
20+
server.send(200, "text/plain", "hello from esp8266!\r\n");
2121
digitalWrite(led, 0);
2222
}
2323

@@ -86,6 +86,66 @@ void setup(void) {
8686

8787
server.onNotFound(handleNotFound);
8888

89+
/////////////////////////////////////////////////////////
90+
// Hook examples
91+
92+
server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) {
93+
(void)method; // GET, PUT, ...
94+
(void)url; // example: /root/myfile.html
95+
(void)client; // the webserver tcp client connection
96+
(void)contentType; // contentType(".html") => "text/html"
97+
Serial.printf("A useless web hook has passed\n");
98+
Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter());
99+
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
100+
});
101+
102+
server.addHook([](const String&, const String & url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) {
103+
if (url.startsWith("/fail")) {
104+
Serial.printf("An always failing web hook has been triggered\n");
105+
return ESP8266WebServer::CLIENT_MUST_STOP;
106+
}
107+
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
108+
});
109+
110+
server.addHook([](const String&, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction) {
111+
if (url.startsWith("/dump")) {
112+
Serial.printf("The dumper web hook is on the run\n");
113+
114+
// Here the request is not interpreted, so we cannot for sure
115+
// swallow the exact amount matching the full request+content,
116+
// hence the tcp connection cannot be handled anymore by the
117+
// webserver.
118+
#ifdef STREAMTO_API
119+
// we are lucky
120+
client->toWithTimeout(Serial, 500);
121+
#else
122+
auto last = millis();
123+
while ((millis() - last) < 500) {
124+
char buf[32];
125+
size_t len = client->read((uint8_t*)buf, sizeof(buf));
126+
if (len > 0) {
127+
Serial.printf("(<%d> chars)", (int)len);
128+
Serial.write(buf, len);
129+
last = millis();
130+
}
131+
}
132+
#endif
133+
// Two choices: return MUST STOP and webserver will close it
134+
// (we already have the example with '/fail' hook)
135+
// or IS GIVEN and webserver will forget it
136+
// trying with IS GIVEN and storing it on a dumb WiFiClient.
137+
// check the client connection: it should not immediately be closed
138+
// (make another '/dump' one to close the first)
139+
Serial.printf("\nTelling server to forget this connection\n");
140+
static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter
141+
return ESP8266WebServer::CLIENT_IS_GIVEN;
142+
}
143+
return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE;
144+
});
145+
146+
// Hook examples
147+
/////////////////////////////////////////////////////////
148+
89149
server.begin();
90150
Serial.println("HTTP server started");
91151
}

libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h

+44-36
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,12 @@
2828
#include "FS.h"
2929
#include "detail/RequestHandlersImpl.h"
3030

31-
//#define DEBUG_ESP_HTTP_SERVER
32-
#ifdef DEBUG_ESP_PORT
33-
#define DEBUG_OUTPUT DEBUG_ESP_PORT
34-
#else
35-
#define DEBUG_OUTPUT Serial
36-
#endif
37-
3831
static const char AUTHORIZATION_HEADER[] PROGMEM = "Authorization";
3932
static const char qop_auth[] PROGMEM = "qop=auth";
4033
static const char qop_auth_quoted[] PROGMEM = "qop=\"auth\"";
4134
static const char WWW_Authenticate[] PROGMEM = "WWW-Authenticate";
4235
static const char Content_Length[] PROGMEM = "Content-Length";
4336

44-
4537
template <typename ServerType>
4638
ESP8266WebServerTemplate<ServerType>::ESP8266WebServerTemplate(IPAddress addr, int port)
4739
: _server(addr, port)
@@ -171,9 +163,7 @@ bool ESP8266WebServerTemplate<ServerType>::authenticateDigest(const String& user
171163
String authReq = header(FPSTR(AUTHORIZATION_HEADER));
172164
if(authReq.startsWith(F("Digest"))) {
173165
authReq = authReq.substring(7);
174-
#ifdef DEBUG_ESP_HTTP_SERVER
175-
DEBUG_OUTPUT.println(authReq);
176-
#endif
166+
DBGWS("%s\n", authReq.c_str());
177167
String _username = _extractParam(authReq,F("username=\""));
178168
if(!_username.length() || _username != String(username)) {
179169
authReq = "";
@@ -200,9 +190,7 @@ bool ESP8266WebServerTemplate<ServerType>::authenticateDigest(const String& user
200190
_nc = _extractParam(authReq, F("nc="), ',');
201191
_cnonce = _extractParam(authReq, F("cnonce=\""));
202192
}
203-
#ifdef DEBUG_ESP_HTTP_SERVER
204-
DEBUG_OUTPUT.println("Hash of user:realm:pass=" + H1);
205-
#endif
193+
DBGWS("Hash of user:realm:pass=%s\n", H1.c_str());
206194
MD5Builder md5;
207195
md5.begin();
208196
if(_currentMethod == HTTP_GET){
@@ -218,9 +206,7 @@ bool ESP8266WebServerTemplate<ServerType>::authenticateDigest(const String& user
218206
}
219207
md5.calculate();
220208
String _H2 = md5.toString();
221-
#ifdef DEBUG_ESP_HTTP_SERVER
222-
DEBUG_OUTPUT.println("Hash of GET:uri=" + _H2);
223-
#endif
209+
DBGWS("Hash of GET:uri=%s\n", _H2.c_str());
224210
md5.begin();
225211
if(authReq.indexOf(FPSTR(qop_auth)) != -1 || authReq.indexOf(FPSTR(qop_auth_quoted)) != -1) {
226212
md5.add(H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2);
@@ -229,9 +215,7 @@ bool ESP8266WebServerTemplate<ServerType>::authenticateDigest(const String& user
229215
}
230216
md5.calculate();
231217
String _responsecheck = md5.toString();
232-
#ifdef DEBUG_ESP_HTTP_SERVER
233-
DEBUG_OUTPUT.println("The Proper response=" +_responsecheck);
234-
#endif
218+
DBGWS("The Proper response=%s\n", _responsecheck.c_str());
235219
if(_response == _responsecheck){
236220
authReq = "";
237221
return true;
@@ -315,9 +299,7 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
315299
return;
316300
}
317301

318-
#ifdef DEBUG_ESP_HTTP_SERVER
319-
DEBUG_OUTPUT.println("New client");
320-
#endif
302+
DBGWS("New client\n");
321303

322304
_currentClient = client;
323305
_currentStatus = HC_WAIT_READ;
@@ -327,6 +309,13 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
327309
bool keepCurrentClient = false;
328310
bool callYield = false;
329311

312+
DBGWS("http-server loop: conn=%d avail=%d status=%s\n",
313+
_currentClient.connected(), _currentClient.available(),
314+
_currentStatus==HC_NONE?"none":
315+
_currentStatus==HC_WAIT_READ?"wait-read":
316+
_currentStatus==HC_WAIT_CLOSE?"wait-close":
317+
"??");
318+
330319
if (_currentClient.connected() || _currentClient.available()) {
331320
if (_currentClient.available() && _keepAlive) {
332321
_currentStatus = HC_WAIT_READ;
@@ -339,34 +328,57 @@ void ESP8266WebServerTemplate<ServerType>::handleClient() {
339328
case HC_WAIT_READ:
340329
// Wait for data from client to become available
341330
if (_currentClient.available()) {
342-
if (_parseRequest(_currentClient)) {
331+
switch (_parseRequest(_currentClient))
332+
{
333+
case CLIENT_REQUEST_CAN_CONTINUE:
343334
_currentClient.setTimeout(HTTP_MAX_SEND_WAIT);
344335
_contentLength = CONTENT_LENGTH_NOT_SET;
345336
_handleRequest();
346-
347-
if (_currentClient.connected()) {
337+
/* fallthrough */
338+
case CLIENT_REQUEST_IS_HANDLED:
339+
if (_currentClient.connected() || _currentClient.available()) {
348340
_currentStatus = HC_WAIT_CLOSE;
349341
_statusChange = millis();
350342
keepCurrentClient = true;
351343
}
352-
}
353-
} else { // !_currentClient.available()
344+
else
345+
DBGWS("webserver: peer has closed after served\n");
346+
break;
347+
case CLIENT_MUST_STOP:
348+
DBGWS("Close client\n");
349+
_currentClient.stop();
350+
break;
351+
case CLIENT_IS_GIVEN:
352+
// client must not be stopped but must not be handled here anymore
353+
// (example: tcp connection given to websocket)
354+
DBGWS("Give client\n");
355+
break;
356+
} // switch _parseRequest()
357+
} else {
358+
// !_currentClient.available(): waiting for more data
354359
if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) {
355360
keepCurrentClient = true;
356361
}
362+
else
363+
DBGWS("webserver: closing after read timeout\n");
357364
callYield = true;
358365
}
359366
break;
360367
case HC_WAIT_CLOSE:
361368
// Wait for client to close the connection
362-
if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) {
369+
if (!_server.available() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) {
363370
keepCurrentClient = true;
364371
callYield = true;
372+
if (_currentClient.available())
373+
// continue serving current client
374+
_currentStatus = HC_WAIT_READ;
365375
}
366-
}
376+
break;
377+
} // switch _currentStatus
367378
}
368379

369380
if (!keepCurrentClient) {
381+
DBGWS("Drop client\n");
370382
_currentClient = ClientType();
371383
_currentStatus = HC_NONE;
372384
_currentUpload.reset();
@@ -687,17 +699,13 @@ template <typename ServerType>
687699
void ESP8266WebServerTemplate<ServerType>::_handleRequest() {
688700
bool handled = false;
689701
if (!_currentHandler){
690-
#ifdef DEBUG_ESP_HTTP_SERVER
691-
DEBUG_OUTPUT.println("request handler not found");
692-
#endif
702+
DBGWS("request handler not found\n");
693703
}
694704
else {
695705
handled = _currentHandler->handle(*this, _currentMethod, _currentUri);
696-
#ifdef DEBUG_ESP_HTTP_SERVER
697706
if (!handled) {
698-
DEBUG_OUTPUT.println("request handler failed to handle request");
707+
DBGWS("request handler failed to handle request\n");
699708
}
700-
#endif
701709
}
702710
if (!handled && _notFoundHandler) {
703711
_notFoundHandler();

0 commit comments

Comments
 (0)