From c94d36d80e2e632729df37c9104ee36312958270 Mon Sep 17 00:00:00 2001 From: Develo Date: Mon, 20 Jul 2020 23:24:51 -0400 Subject: [PATCH 01/12] Comment out verify step in eboot.c (#7468) * Comment out verify step in eboot.c Meant for #7458 , but still requires a recompiled eboot.elf. * Rebuild eboot.elf from changed source Co-authored-by: Earle F. Philhower, III --- bootloaders/eboot/eboot.c | 6 +++++- bootloaders/eboot/eboot.elf | Bin 45148 -> 44468 bytes 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index be67b0b6fe..6b3b316341 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -229,7 +229,10 @@ int main() ets_wdt_enable(); ets_putc('0'+res); ets_putc('\n'); - +#if 0 + //devyte: this verify step below (cmp:) only works when the end of copy operation above does not overwrite the + //beginning of the image in the empty area, see #7458. Disabling for now. + //TODO: replace the below verify with hash type, crc, or similar. // Verify the copy ets_putc('c'); ets_putc('m'); ets_putc('p'); ets_putc(':'); if (res == 0) { @@ -239,6 +242,7 @@ int main() } ets_putc('0'+res); ets_putc('\n'); +#endif if (res == 0) { cmd.action = ACTION_LOAD_APP; cmd.args[0] = cmd.args[1]; diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index 1a6e5bc2349dc2b728c36b69afa45e55444933d7..8c235c2087a1b2e72ba0ebb58ca69d24c202d202 100755 GIT binary patch delta 12571 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 delta 13320 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 SvF;(Y_CUU)>VOb?sQVuPn~OmJ From f42cf7a5a41e8808ad21b34bd6b6757df8adb4e1 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Wed, 22 Jul 2020 22:10:44 -0700 Subject: [PATCH 02/12] Fix uninitted class variables from #7464 (#7478) PR #7464 removed the reset of client authentication settings when server authentication settings were changed, however it never did initialize the client authentication information to nullptr in the constructor. This can result in crashes during connections when client certs are not applied. Fix by resetting the client authenticaion variables on object construction. --- libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp index 89621b3671..c94ac79e0f 100644 --- a/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp +++ b/libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp @@ -105,6 +105,9 @@ WiFiClientSecure::WiFiClientSecure() : WiFiClient() { _clear(); _clearAuthenticationSettings(); _certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived + _sk = nullptr; + _axtls_chain = nullptr; + _axtls_sk = nullptr; stack_thunk_add_ref(); } From 555c9ebdf84b461e56d0db76a22c2efa9851e43f Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Wed, 22 Jul 2020 22:26:00 -0700 Subject: [PATCH 03/12] Update FP for tls.mbed.org (#7479) --- .../examples/StreamHttpsClient/StreamHttpsClient.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino index 55009349fa..a69b9e35c6 100644 --- a/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino +++ b/libraries/ESP8266HTTPClient/examples/StreamHttpsClient/StreamHttpsClient.ino @@ -50,7 +50,7 @@ void loop() { Serial.print("[HTTPS] begin...\n"); // configure server and url - 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}; + 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}; client->setFingerprint(fingerprint); From 83fc47f6d97d6a82acb6cf2c856381bcd101f0c0 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 23 Jul 2020 07:34:21 +0200 Subject: [PATCH 04/12] Small update to ease manual release generation (#7467) --- package/build_boards_manager_package.sh | 50 +++++++++++++++---------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/package/build_boards_manager_package.sh b/package/build_boards_manager_package.sh index 5f459581df..05778d5487 100755 --- a/package/build_boards_manager_package.sh +++ b/package/build_boards_manager_package.sh @@ -1,25 +1,37 @@ #!/bin/bash -# Extract the release name from a release -# Default to draft tag name -ver=$(basename $(jq -e -r '.ref' "$GITHUB_EVENT_PATH")) -# If not available, try the publish tag name -if [ "$ver" == "null" ]; then - ver=$(jq -e -r '.release.tag_name' "$GITHUB_EVENT_PATH") -fi -# Fall back to the git description OTW (i.e. interactive) -if [ "$ver" == "null" ]; then - ver=$(git describe --tag) -fi -visiblever=$ver -plainver=$ver - -# Match 0.0.* as special-case early-access builds -if [ "${ver%.*}" = 0.0 ]; then - git tag -d ${ver} - ver=`git describe --tag HEAD` - plain_ver=$ver +if [ ! -z "${manualversion}" ]; then + + # manual-made release based on $manualversion + ver=${manualversion} + plain_ver=${ver} + visiblever=${ver} + [ -z "${REMOTE_URL}" ] && REMOTE_URL=https://github.com/esp8266/Arduino/releases/download + +else + + # Extract the release name from a release + + # Default to draft tag name + ver=$(basename $(jq -e -r '.ref' "$GITHUB_EVENT_PATH")) + # If not available, try the publish tag name + if [ "$ver" == "null" ]; then + ver=$(jq -e -r '.release.tag_name' "$GITHUB_EVENT_PATH") + fi + # Fall back to the git description OTW (i.e. interactive) + if [ "$ver" == "null" ]; then + ver=$(git describe --tag) + fi + visiblever=$ver + plainver=$ver + + # Match 0.0.* as special-case early-access builds + if [ "${ver%.*}" = 0.0 ]; then + git tag -d ${ver} + ver=`git describe --tag HEAD` + plain_ver=$ver + fi fi set -e From 0e1290695064ee3631e9290e3d91cead0c2fdcc4 Mon Sep 17 00:00:00 2001 From: Jorg Neves Bliesener Date: Sun, 26 Jul 2020 18:39:55 +0200 Subject: [PATCH 05/12] Initialize _ledPin (#7487) * Initialize _ledPin _ledPin should be initialized to -1 in the constructor to avoid setting a random pin when calling Updater::end without having called Updater::begin before. This happens, for example, in the Homie software * Fix field sequence --- cores/esp8266/Updater.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cores/esp8266/Updater.cpp b/cores/esp8266/Updater.cpp index 351a57746b..03bc5c3f8f 100644 --- a/cores/esp8266/Updater.cpp +++ b/cores/esp8266/Updater.cpp @@ -35,6 +35,7 @@ UpdaterClass::UpdaterClass() , _startAddress(0) , _currentAddress(0) , _command(U_FLASH) +, _ledPin(-1) , _hash(nullptr) , _verify(nullptr) , _progress_callback(nullptr) From e815b9219bee129f470a16c748117a59cfe45d96 Mon Sep 17 00:00:00 2001 From: M Hightower <27247790+mhightower83@users.noreply.github.com> Date: Sun, 26 Jul 2020 10:01:21 -0700 Subject: [PATCH 06/12] Correct stack string buffer length. (#7488) Co-authored-by: Earle F. Philhower, III --- cores/esp8266/heap.cpp | 2 +- cores/esp8266/umm_malloc/umm_local.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp8266/heap.cpp b/cores/esp8266/heap.cpp index 2001579ef0..3f549716f4 100644 --- a/cores/esp8266/heap.cpp +++ b/cores/esp8266/heap.cpp @@ -164,7 +164,7 @@ void ICACHE_RAM_ATTR print_loc(size_t size, const char* file, int line) if (inISR && (uint32_t)file >= 0x40200000) { DEBUG_HEAP_PRINTF("File: %p", file); } else if (!inISR && (uint32_t)file >= 0x40200000) { - char buf[ets_strlen(file)] __attribute__ ((aligned(4))); + char buf[ets_strlen(file) + 1] __attribute__((aligned(4))); ets_strcpy(buf, file); DEBUG_HEAP_PRINTF(buf); } else { diff --git a/cores/esp8266/umm_malloc/umm_local.c b/cores/esp8266/umm_malloc/umm_local.c index 8f83f4b4ac..392ef13c8f 100644 --- a/cores/esp8266/umm_malloc/umm_local.c +++ b/cores/esp8266/umm_malloc/umm_local.c @@ -206,7 +206,7 @@ int ICACHE_FLASH_ATTR umm_info_safe_printf_P(const char *fmt, ...) { the PROGMEM address must be word (4 bytes) aligned. The destination address for ets_memcpy must also be word-aligned. */ - char ram_buf[ets_strlen(fmt)] __attribute__ ((aligned(4))); + char ram_buf[ets_strlen(fmt) + 1] __attribute__((aligned(4))); ets_strcpy(ram_buf, fmt); va_list argPtr; va_start(argPtr, fmt); From 355b29161481d1ed68436f52a2f30e3c76b9f146 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Sun, 26 Jul 2020 10:11:14 -0700 Subject: [PATCH 07/12] CVE-2020-12638 workaround for WPA downgrade attack (#7486) * CVE-2020-12638 workaround for WPA downgrade attack When connected to an encrypted (WEP/WPA) router, a rogue packet can cause the ESP8266 WiFi stack to drop to an unecrypted rogue network of the same SSID. Handle this by dropping the WiFi connection immediately and reconnecting to the stored WPA/WEP network requested by the application, whenever the AUTHMODE changes to OPEN from a secured mode. https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors for more details. --- libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp index e026ea760a..abad142ed9 100644 --- a/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp +++ b/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp @@ -228,6 +228,16 @@ void ESP8266WiFiGenericClass::_eventCallback(void* arg) WiFiClient::stopAll(); } + if (event->event == EVENT_STAMODE_AUTHMODE_CHANGE) { + auto& src = event->event_info.auth_change; + if ((src.old_mode != AUTH_OPEN) && (src.new_mode == AUTH_OPEN)) { + // CVE-2020-12638 workaround. When we get a change to AUTH_OPEN from any other mode, drop the WiFi link because it's a downgrade attack + // TODO - When upgrading to 3.x.x with fix, remove this code + DEBUG_WIFI("WIFI_EVENT_STAMODE_AUTHMODE_CHANGE from encrypted(%d) to AUTH_OPEN, potential downgrade attack. Reconnecting WiFi. See CVE-2020-12638 for more details\n", src.old_mode); + WiFi.reconnect(); // Disconnects from STA and then reconnects + } + } + for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) { WiFiEventHandler &handler = *it; if (handler->canExpire() && handler.unique()) { From 63b41bcfab0dbf55a72192fead77c2d067213fc4 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Tue, 28 Jul 2020 12:11:00 -0700 Subject: [PATCH 08/12] Use root cert, not fingerprint for api.github.com (#7490) In the HTTPS example we were using a fingerprint which changes almost daily as the github.com certificates are regenerated. Replace this with a trust anchor based on the ultimate root CA that github.com uses to sign their certificates. Assuming they don't change CAs, this certificate should be good until 2030+ Fixes #7489 --- .../examples/HTTPSRequest/HTTPSRequest.ino | 71 ++++++++++++++----- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino b/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino index 000dbb2a14..82374b40cc 100644 --- a/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino +++ b/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino @@ -7,11 +7,6 @@ esp8266/Arduino project continuous integration build. - Limitations: - only RSA certificates - no support of Perfect Forward Secrecy (PFS) - TLSv1.2 is supported since version 2.4.0-rc1 - Created by Ivan Grokhotkov, 2015. This example is in public domain. */ @@ -30,14 +25,38 @@ const char* password = STAPSK; const char* host = "api.github.com"; const int httpsPort = 443; -// Use web browser to view and copy -// SHA1 fingerprint of the certificate -const char fingerprint[] PROGMEM = "5F F1 60 31 09 04 3E F2 90 D2 B0 8A 50 38 04 E8 37 9F BC 76"; +// DigiCert High Assurance EV Root CA +const char trustRoot[] PROGMEM = R"EOF( +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- +)EOF"; +X509List cert(trustRoot); void setup() { Serial.begin(115200); Serial.println(); - Serial.print("connecting to "); + Serial.print("Connecting to "); Serial.println(ssid); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); @@ -50,21 +69,37 @@ void setup() { Serial.println("IP address: "); Serial.println(WiFi.localIP()); + // Set time via NTP, as required for x.509 validation + configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov"); + + Serial.print("Waiting for NTP time sync: "); + time_t now = time(nullptr); + while (now < 8 * 3600 * 2) { + delay(500); + Serial.print("."); + now = time(nullptr); + } + Serial.println(""); + struct tm timeinfo; + gmtime_r(&now, &timeinfo); + Serial.print("Current time: "); + Serial.print(asctime(&timeinfo)); + // Use WiFiClientSecure class to create TLS connection WiFiClientSecure client; - Serial.print("connecting to "); + Serial.print("Connecting to "); Serial.println(host); - Serial.printf("Using fingerprint '%s'\n", fingerprint); - client.setFingerprint(fingerprint); + Serial.printf("Using certificate: %s\n", trustRoot); + client.setTrustAnchors(&cert); if (!client.connect(host, httpsPort)) { - Serial.println("connection failed"); + Serial.println("Connection failed"); return; } String url = "/repos/esp8266/Arduino/commits/master/status"; - Serial.print("requesting URL: "); + Serial.print("Requesting URL: "); Serial.println(url); client.print(String("GET ") + url + " HTTP/1.1\r\n" + @@ -72,11 +107,11 @@ void setup() { "User-Agent: BuildFailureDetectorESP8266\r\n" + "Connection: close\r\n\r\n"); - Serial.println("request sent"); + Serial.println("Request sent"); while (client.connected()) { String line = client.readStringUntil('\n'); if (line == "\r") { - Serial.println("headers received"); + Serial.println("Headers received"); break; } } @@ -86,11 +121,11 @@ void setup() { } else { Serial.println("esp8266/Arduino CI has failed"); } - Serial.println("reply was:"); + Serial.println("Reply was:"); Serial.println("=========="); Serial.println(line); Serial.println("=========="); - Serial.println("closing connection"); + Serial.println("Closing connection"); } void loop() { From 33083861c80bbcd5904f017ce7aa1b81df610679 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Tue, 28 Jul 2020 23:34:26 +0200 Subject: [PATCH 09/12] webserver hook: allow to handle external http protocol (#7459) * webhook api * simplify webserver debug printouts, move text to flash * Hook examples in HelloServer example * print executable code address in example * simplify example per @mcspr suggestion --- cores/esp8266/core_esp8266_features.h | 14 +- .../examples/HelloServer/HelloServer.ino | 62 +++++++- .../src/ESP8266WebServer-impl.h | 80 +++++----- .../ESP8266WebServer/src/ESP8266WebServer.h | 35 ++++- libraries/ESP8266WebServer/src/Parsing-impl.h | 140 +++++------------- 5 files changed, 187 insertions(+), 144 deletions(-) diff --git a/cores/esp8266/core_esp8266_features.h b/cores/esp8266/core_esp8266_features.h index d3b70f3dcc..5a2893a6ed 100644 --- a/cores/esp8266/core_esp8266_features.h +++ b/cores/esp8266/core_esp8266_features.h @@ -92,7 +92,19 @@ inline uint32_t esp_get_cycle_count() { __asm__ __volatile__("rsr %0,ccount":"=a"(ccount)); return ccount; } -#endif // not CORE_MOCK + +inline uint32_t esp_get_program_counter() __attribute__((always_inline)); +inline uint32_t esp_get_program_counter() { + uint32_t pc; + __asm__ __volatile__("movi %0, ." : "=r" (pc) : : ); // ©earlephilhower + return pc; +} + +#else // CORE_MOCK + +inline uint32_t esp_get_program_counter() { return 0; } + +#endif // CORE_MOCK // Tools for preloading code into the flash cache diff --git a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino index 1335c347af..6715f9ee41 100644 --- a/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino +++ b/libraries/ESP8266WebServer/examples/HelloServer/HelloServer.ino @@ -17,7 +17,7 @@ const int led = 13; void handleRoot() { digitalWrite(led, 1); - server.send(200, "text/plain", "hello from esp8266!"); + server.send(200, "text/plain", "hello from esp8266!\r\n"); digitalWrite(led, 0); } @@ -86,6 +86,66 @@ void setup(void) { server.onNotFound(handleNotFound); + ///////////////////////////////////////////////////////// + // Hook examples + + server.addHook([](const String & method, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction contentType) { + (void)method; // GET, PUT, ... + (void)url; // example: /root/myfile.html + (void)client; // the webserver tcp client connection + (void)contentType; // contentType(".html") => "text/html" + Serial.printf("A useless web hook has passed\n"); + Serial.printf("(this hook is in 0x%08x area (401x=IRAM 402x=FLASH))\n", esp_get_program_counter()); + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + server.addHook([](const String&, const String & url, WiFiClient*, ESP8266WebServer::ContentTypeFunction) { + if (url.startsWith("/fail")) { + Serial.printf("An always failing web hook has been triggered\n"); + return ESP8266WebServer::CLIENT_MUST_STOP; + } + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + server.addHook([](const String&, const String & url, WiFiClient * client, ESP8266WebServer::ContentTypeFunction) { + if (url.startsWith("/dump")) { + Serial.printf("The dumper web hook is on the run\n"); + + // Here the request is not interpreted, so we cannot for sure + // swallow the exact amount matching the full request+content, + // hence the tcp connection cannot be handled anymore by the + // webserver. +#ifdef STREAMTO_API + // we are lucky + client->toWithTimeout(Serial, 500); +#else + auto last = millis(); + while ((millis() - last) < 500) { + char buf[32]; + size_t len = client->read((uint8_t*)buf, sizeof(buf)); + if (len > 0) { + Serial.printf("(<%d> chars)", (int)len); + Serial.write(buf, len); + last = millis(); + } + } +#endif + // Two choices: return MUST STOP and webserver will close it + // (we already have the example with '/fail' hook) + // or IS GIVEN and webserver will forget it + // trying with IS GIVEN and storing it on a dumb WiFiClient. + // check the client connection: it should not immediately be closed + // (make another '/dump' one to close the first) + Serial.printf("\nTelling server to forget this connection\n"); + static WiFiClient forgetme = *client; // stop previous one if present and transfer client refcounter + return ESP8266WebServer::CLIENT_IS_GIVEN; + } + return ESP8266WebServer::CLIENT_REQUEST_CAN_CONTINUE; + }); + + // Hook examples + ///////////////////////////////////////////////////////// + server.begin(); Serial.println("HTTP server started"); } diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index ddde5756e9..ce0d5bf2ea 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -28,20 +28,12 @@ #include "FS.h" #include "detail/RequestHandlersImpl.h" -//#define DEBUG_ESP_HTTP_SERVER -#ifdef DEBUG_ESP_PORT -#define DEBUG_OUTPUT DEBUG_ESP_PORT -#else -#define DEBUG_OUTPUT Serial -#endif - static const char AUTHORIZATION_HEADER[] PROGMEM = "Authorization"; static const char qop_auth[] PROGMEM = "qop=auth"; static const char qop_auth_quoted[] PROGMEM = "qop=\"auth\""; static const char WWW_Authenticate[] PROGMEM = "WWW-Authenticate"; static const char Content_Length[] PROGMEM = "Content-Length"; - template ESP8266WebServerTemplate::ESP8266WebServerTemplate(IPAddress addr, int port) : _server(addr, port) @@ -171,9 +163,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user String authReq = header(FPSTR(AUTHORIZATION_HEADER)); if(authReq.startsWith(F("Digest"))) { authReq = authReq.substring(7); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println(authReq); - #endif + DBGWS("%s\n", authReq.c_str()); String _username = _extractParam(authReq,F("username=\"")); if(!_username.length() || _username != String(username)) { authReq = ""; @@ -200,9 +190,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user _nc = _extractParam(authReq, F("nc="), ','); _cnonce = _extractParam(authReq, F("cnonce=\"")); } - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Hash of user:realm:pass=" + H1); - #endif + DBGWS("Hash of user:realm:pass=%s\n", H1.c_str()); MD5Builder md5; md5.begin(); if(_currentMethod == HTTP_GET){ @@ -218,9 +206,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user } md5.calculate(); String _H2 = md5.toString(); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Hash of GET:uri=" + _H2); - #endif + DBGWS("Hash of GET:uri=%s\n", _H2.c_str()); md5.begin(); if(authReq.indexOf(FPSTR(qop_auth)) != -1 || authReq.indexOf(FPSTR(qop_auth_quoted)) != -1) { md5.add(H1 + ':' + _nonce + ':' + _nc + ':' + _cnonce + F(":auth:") + _H2); @@ -229,9 +215,7 @@ bool ESP8266WebServerTemplate::authenticateDigest(const String& user } md5.calculate(); String _responsecheck = md5.toString(); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("The Proper response=" +_responsecheck); - #endif + DBGWS("The Proper response=%s\n", _responsecheck.c_str()); if(_response == _responsecheck){ authReq = ""; return true; @@ -315,9 +299,7 @@ void ESP8266WebServerTemplate::handleClient() { return; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("New client"); -#endif + DBGWS("New client\n"); _currentClient = client; _currentStatus = HC_WAIT_READ; @@ -327,6 +309,13 @@ void ESP8266WebServerTemplate::handleClient() { bool keepCurrentClient = false; bool callYield = false; + DBGWS("http-server loop: conn=%d avail=%d status=%s\n", + _currentClient.connected(), _currentClient.available(), + _currentStatus==HC_NONE?"none": + _currentStatus==HC_WAIT_READ?"wait-read": + _currentStatus==HC_WAIT_CLOSE?"wait-close": + "??"); + if (_currentClient.connected() || _currentClient.available()) { if (_currentClient.available() && _keepAlive) { _currentStatus = HC_WAIT_READ; @@ -339,34 +328,57 @@ void ESP8266WebServerTemplate::handleClient() { case HC_WAIT_READ: // Wait for data from client to become available if (_currentClient.available()) { - if (_parseRequest(_currentClient)) { + switch (_parseRequest(_currentClient)) + { + case CLIENT_REQUEST_CAN_CONTINUE: _currentClient.setTimeout(HTTP_MAX_SEND_WAIT); _contentLength = CONTENT_LENGTH_NOT_SET; _handleRequest(); - - if (_currentClient.connected()) { + /* fallthrough */ + case CLIENT_REQUEST_IS_HANDLED: + if (_currentClient.connected() || _currentClient.available()) { _currentStatus = HC_WAIT_CLOSE; _statusChange = millis(); keepCurrentClient = true; } - } - } else { // !_currentClient.available() + else + DBGWS("webserver: peer has closed after served\n"); + break; + case CLIENT_MUST_STOP: + DBGWS("Close client\n"); + _currentClient.stop(); + break; + case CLIENT_IS_GIVEN: + // client must not be stopped but must not be handled here anymore + // (example: tcp connection given to websocket) + DBGWS("Give client\n"); + break; + } // switch _parseRequest() + } else { + // !_currentClient.available(): waiting for more data if (millis() - _statusChange <= HTTP_MAX_DATA_WAIT) { keepCurrentClient = true; } + else + DBGWS("webserver: closing after read timeout\n"); callYield = true; } break; case HC_WAIT_CLOSE: // Wait for client to close the connection - if (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT) { + if (!_server.available() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) { keepCurrentClient = true; callYield = true; + if (_currentClient.available()) + // continue serving current client + _currentStatus = HC_WAIT_READ; } - } + break; + } // switch _currentStatus } if (!keepCurrentClient) { + DBGWS("Drop client\n"); _currentClient = ClientType(); _currentStatus = HC_NONE; _currentUpload.reset(); @@ -687,17 +699,13 @@ template void ESP8266WebServerTemplate::_handleRequest() { bool handled = false; if (!_currentHandler){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("request handler not found"); -#endif + DBGWS("request handler not found\n"); } else { handled = _currentHandler->handle(*this, _currentMethod, _currentUri); -#ifdef DEBUG_ESP_HTTP_SERVER if (!handled) { - DEBUG_OUTPUT.println("request handler failed to handle request"); + DBGWS("request handler failed to handle request\n"); } -#endif } if (!handled && _notFoundHandler) { _notFoundHandler(); diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 2dc5201700..941be0b718 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -26,11 +26,24 @@ #include #include +#include #include #include #include "detail/mimetable.h" #include "Uri.h" +//#define DEBUG_ESP_HTTP_SERVER + +#ifdef DEBUG_ESP_HTTP_SERVER +#ifdef DEBUG_ESP_PORT +#define DBGWS(f,...) do { DEBUG_ESP_PORT.printf(PSTR(f), ##__VA_ARGS__); } while (0) +#else +#define DBGWS(f,...) do { Serial.printf(PSTR(f), ##__VA_ARGS__); } while (0) +#endif +#else +#define DBGWS(x...) do { (void)0; } while (0) +#endif + enum HTTPMethod { HTTP_ANY, HTTP_GET, HTTP_HEAD, HTTP_POST, HTTP_PUT, HTTP_PATCH, HTTP_DELETE, HTTP_OPTIONS }; enum HTTPUploadStatus { UPLOAD_FILE_START, UPLOAD_FILE_WRITE, UPLOAD_FILE_END, UPLOAD_FILE_ABORTED }; @@ -80,6 +93,9 @@ class ESP8266WebServerTemplate using ClientType = typename ServerType::ClientType; using RequestHandlerType = RequestHandler; using WebServerType = ESP8266WebServerTemplate; + enum ClientFuture { CLIENT_REQUEST_CAN_CONTINUE, CLIENT_REQUEST_IS_HANDLED, CLIENT_MUST_STOP, CLIENT_IS_GIVEN }; + typedef String (*ContentTypeFunction) (const String&); + using HookFunction = std::function; void begin(); void begin(uint16_t port); @@ -200,11 +216,25 @@ class ESP8266WebServerTemplate static String responseCodeToString(const int code); + void addHook (HookFunction hook) { + if (_hook) { + auto previousHook = _hook; + _hook = [previousHook, hook](const String& method, const String& url, WiFiClient* client, ContentTypeFunction contentType) { + auto whatNow = previousHook(method, url, client, contentType); + if (whatNow == CLIENT_REQUEST_CAN_CONTINUE) + return hook(method, url, client, contentType); + return whatNow; + }; + } else { + _hook = hook; + } + } + protected: void _addRequestHandler(RequestHandlerType* handler); void _handleRequest(); void _finalizeResponse(); - bool _parseRequest(ClientType& client); + ClientFuture _parseRequest(ClientType& client); void _parseArguments(const String& data); int _parseArgumentsPrivate(const String& data, std::function handler); bool _parseForm(ClientType& client, const String& boundary, uint32_t len); @@ -261,8 +291,7 @@ class ESP8266WebServerTemplate String _sopaque; String _srealm; // Store the Auth realm between Calls - - + HookFunction _hook; }; diff --git a/libraries/ESP8266WebServer/src/Parsing-impl.h b/libraries/ESP8266WebServer/src/Parsing-impl.h index 8d3fda2782..4bb6db8878 100644 --- a/libraries/ESP8266WebServer/src/Parsing-impl.h +++ b/libraries/ESP8266WebServer/src/Parsing-impl.h @@ -25,13 +25,6 @@ #include "ESP8266WebServer.h" #include "detail/mimetable.h" -//#define DEBUG_ESP_HTTP_SERVER -#ifdef DEBUG_ESP_PORT -#define DEBUG_OUTPUT DEBUG_ESP_PORT -#else -#define DEBUG_OUTPUT Serial -#endif - #ifndef WEBSERVER_MAX_POST_ARGS #define WEBSERVER_MAX_POST_ARGS 32 #endif @@ -61,17 +54,14 @@ static bool readBytesWithTimeout(typename ServerType::ClientType& client, size_t } template -bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { +typename ESP8266WebServerTemplate::ClientFuture ESP8266WebServerTemplate::_parseRequest(ClientType& client) { // Read the first line of HTTP request String req = client.readStringUntil('\r'); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("request: "); - DEBUG_OUTPUT.println(req); -#endif + DBGWS("request: %s\n", req.c_str()); client.readStringUntil('\n'); //reset header value for (int i = 0; i < _headerKeysCount; ++i) { - _currentHeaders[i].value =String(); + _currentHeaders[i].value.clear(); } // First line of HTTP request looks like "GET /path HTTP/1.1" @@ -79,10 +69,8 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { int addr_start = req.indexOf(' '); int addr_end = req.indexOf(' ', addr_start + 1); if (addr_start == -1 || addr_end == -1) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Invalid request"); -#endif - return false; + DBGWS("Invalid request\n"); + return CLIENT_MUST_STOP; } String methodStr = req.substring(0, addr_start); @@ -98,6 +86,13 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { _currentUri = url; _chunked = false; + if (_hook) + { + auto whatNow = _hook(methodStr, url, &client, mime::getContentType); + if (whatNow != CLIENT_REQUEST_CAN_CONTINUE) + return whatNow; + } + HTTPMethod method = HTTP_GET; if (methodStr == F("HEAD")) { method = HTTP_HEAD; @@ -117,14 +112,8 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { _keepAlive = _currentVersion > 0; // Keep the connection alive by default // if the protocol version is greater than HTTP 1.0 -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("method: "); - DEBUG_OUTPUT.print(methodStr); - DEBUG_OUTPUT.print(" url: "); - DEBUG_OUTPUT.print(url); - DEBUG_OUTPUT.print(" search: "); - DEBUG_OUTPUT.println(searchStr); -#endif + DBGWS("method: %s url: %s search: %s keepAlive=: %d\n", + methodStr.c_str(), url.c_str(), searchStr.c_str(), _keepAlive); //attach handler RequestHandlerType* handler; @@ -157,12 +146,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { headerValue.trim(); _collectHeader(headerName.c_str(),headerValue.c_str()); - #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("headerName: "); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print("headerValue: "); - DEBUG_OUTPUT.println(headerValue); - #endif + DBGWS("headerName: %s\nheaderValue: %s\n", headerName.c_str(), headerValue.c_str()); if (headerName.equalsIgnoreCase(FPSTR(Content_Type))){ using namespace mime; @@ -193,7 +177,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { ) ) { - return false; + return CLIENT_MUST_STOP; } if (isEncoded) { @@ -218,7 +202,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { } else { // isForm is true // here: content is not yet read (plainBuf is still empty) if (!_parseForm(client, boundaryStr, contentLength)) { - return false; + return CLIENT_MUST_STOP; } } } else { @@ -237,12 +221,7 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { headerValue = req.substring(headerDiv + 2); _collectHeader(headerName.c_str(),headerValue.c_str()); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print(F("headerName: ")); - DEBUG_OUTPUT.println(headerName); - DEBUG_OUTPUT.print(F("headerValue: ")); - DEBUG_OUTPUT.println(headerValue); -#endif + DBGWS("headerName: %s\nheaderValue: %s\n", headerName.c_str(), headerValue.c_str()); if (headerName.equalsIgnoreCase(F("Host"))){ _hostHeader = headerValue; @@ -255,19 +234,15 @@ bool ESP8266WebServerTemplate::_parseRequest(ClientType& client) { client.flush(); #ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print(F("Request: ")); - DEBUG_OUTPUT.println(url); - DEBUG_OUTPUT.print(F("Arguments: ")); - DEBUG_OUTPUT.println(searchStr); - - DEBUG_OUTPUT.println(F("final list of key/value pairs:")); + DBGWS("Request: %s\nArguments: %s\nfinal list of key/value pairs:\n", + url.c_str(), searchStr.c_str()); for (int i = 0; i < _currentArgCount; i++) - DEBUG_OUTPUT.printf(" key:'%s' value:'%s'\r\n", + DBGWS(" key:'%s' value:'%s'\r\n", _currentArgs[i].key.c_str(), _currentArgs[i].value.c_str()); #endif - return true; + return CLIENT_REQUEST_CAN_CONTINUE; } template @@ -316,10 +291,7 @@ void ESP8266WebServerTemplate::_parseArguments(const String& data) { template int ESP8266WebServerTemplate::_parseArgumentsPrivate(const String& data, std::function handler) { -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args: "); - DEBUG_OUTPUT.println(data); -#endif + DBGWS("args: %s\n", data.c_str()); size_t pos = 0; int arg_total = 0; @@ -357,11 +329,7 @@ int ESP8266WebServerTemplate::_parseArgumentsPrivate(const String& d break; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("args count: "); - DEBUG_OUTPUT.println(arg_total); -#endif - + DBGWS("args count: %d\n", (int)arg_total); return arg_total; } @@ -390,12 +358,7 @@ uint8_t ESP8266WebServerTemplate::_uploadReadByte(ClientType& client template bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const String& boundary, uint32_t len){ (void) len; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Parse Form: Boundary: "); - DEBUG_OUTPUT.print(boundary); - DEBUG_OUTPUT.print(" Length: "); - DEBUG_OUTPUT.println(len); -#endif + DBGWS("Parse Form: Boundary: '%s' Length: %d\n", boundary.c_str(), (int)len); String line; int retry = 0; do { @@ -429,18 +392,12 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const argFilename = argName.substring(nameStart+2, argName.length() - 1); argName = argName.substring(0, argName.indexOf('"')); argIsFile = true; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg FileName: "); - DEBUG_OUTPUT.println(argFilename); -#endif + DBGWS("PostArg FileName: %s\n", argFilename.c_str()); //use GET to set the filename if uploading using blob if (argFilename == F("blob") && hasArg(FPSTR(filename))) argFilename = arg(FPSTR(filename)); } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Name: "); - DEBUG_OUTPUT.println(argName); -#endif + DBGWS("PostArg Name: %s\n", argName.c_str()); using namespace mime; argType = FPSTR(mimeTable[txt].mimeType); line = client.readStringUntil('\r'); @@ -451,10 +408,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const client.readStringUntil('\r'); client.readStringUntil('\n'); } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Type: "); - DEBUG_OUTPUT.println(argType); -#endif + DBGWS("PostArg Type: %s\n", argType.c_str()); if (!argIsFile){ while(1){ line = client.readStringUntil('\r'); @@ -463,20 +417,14 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const if (argValue.length() > 0) argValue += '\n'; argValue += line; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("PostArg Value: "); - DEBUG_OUTPUT.println(argValue); - DEBUG_OUTPUT.println(); -#endif + DBGWS("PostArg Value: %s\n\n", argValue.c_str()); RequestArgument& arg = _postArgs[_postArgsLen++]; arg.key = argName; arg.value = argValue; if (line == ("--"+boundary+"--")){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif + DBGWS("Done Parsing POST\n"); break; } } else { @@ -488,12 +436,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const _currentUpload->totalSize = 0; _currentUpload->currentSize = 0; _currentUpload->contentLength = len; -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Start File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.println(_currentUpload->type); -#endif + DBGWS("Start File: %s Type: %s\n", _currentUpload->filename.c_str(), _currentUpload->type.c_str()); if(_currentHandler && _currentHandler->canUpload(_currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); _currentUpload->status = UPLOAD_FILE_WRITE; @@ -537,20 +480,14 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const _currentUpload->status = UPLOAD_FILE_END; if(_currentHandler && _currentHandler->canUpload(_currentUri)) _currentHandler->upload(*this, _currentUri, *_currentUpload); -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("End File: "); - DEBUG_OUTPUT.print(_currentUpload->filename); - DEBUG_OUTPUT.print(" Type: "); - DEBUG_OUTPUT.print(_currentUpload->type); - DEBUG_OUTPUT.print(" Size: "); - DEBUG_OUTPUT.println(_currentUpload->totalSize); -#endif + DBGWS("End File: %s Type: %s Size: %d\n", + _currentUpload->filename.c_str(), + _currentUpload->type.c_str(), + (int)_currentUpload->totalSize); line = client.readStringUntil(0x0D); client.readStringUntil(0x0A); if (line == "--"){ -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.println("Done Parsing POST"); -#endif + DBGWS("Done Parsing POST\n"); break; } continue; @@ -598,10 +535,7 @@ bool ESP8266WebServerTemplate::_parseForm(ClientType& client, const } return true; } -#ifdef DEBUG_ESP_HTTP_SERVER - DEBUG_OUTPUT.print("Error: line: "); - DEBUG_OUTPUT.println(line); -#endif + DBGWS("Error: line: %s\n", line.c_str()); return false; } From a67986915512c5304bd7c161cf0d9c65f66e0892 Mon Sep 17 00:00:00 2001 From: "Earle F. Philhower, III" Date: Tue, 28 Jul 2020 17:39:38 -0700 Subject: [PATCH 10/12] BREAKING - analogWriteRange 8-bit default (#7456) Matching standard Arduino cores, make the default analogWrite() take values from 0...255. Users can always use the analogWriteRange() call to change to a different setup. Add a `analogWriteResolution` which takes a number of bits and sets the range from 0...(1< 0) { + if ((range >= 15) && (range <= 65535)) { analogScale = range; } } +extern void __analogWriteResolution(int res) { + if ((res >= 4) && (res <= 16)) { + analogScale = (1 << res) - 1; + } +} + extern void __analogWriteFreq(uint32_t freq) { if (freq < 100) { analogFreq = 100; @@ -57,6 +63,10 @@ extern void __analogWrite(uint8_t pin, int val) { val = analogScale; } + // Per the Arduino docs at https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/ + // val: the duty cycle: between 0 (always off) and 255 (always on). + // So if val = 0 we have digitalWrite(LOW), if we have val==range we have digitalWrite(HIGH) + analogMap &= ~(1 << pin); uint32_t high = (analogPeriod * val) / analogScale; uint32_t low = analogPeriod - high; @@ -75,5 +85,6 @@ extern void __analogWrite(uint8_t pin, int val) { extern void analogWrite(uint8_t pin, int val) __attribute__((weak, alias("__analogWrite"))); extern void analogWriteFreq(uint32_t freq) __attribute__((weak, alias("__analogWriteFreq"))); extern void analogWriteRange(uint32_t range) __attribute__((weak, alias("__analogWriteRange"))); +extern void analogWriteResolution(int res) __attribute__((weak, alias("__analogWriteResolution"))); }; diff --git a/doc/reference.rst b/doc/reference.rst index db789128e6..6cb03d6928 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -102,9 +102,19 @@ Analog output ``analogWrite(pin, value)`` enables software PWM on the given pin. PWM may be used on pins 0 to 16. Call ``analogWrite(pin, 0)`` to disable PWM -on the pin. ``value`` may be in range from 0 to ``PWMRANGE``, which is -equal to 1023 by default. PWM range may be changed by calling -``analogWriteRange(new_range)``. +on the pin. + +``value`` may be in range from 0 to 255 (which is the Arduino default). +PWM range may be changed by calling ``analogWriteRange(new_range)`` or +``analogWriteResolution(bits)``. ``new_range`` may be from 15...65535 +or ``bits`` may be from 4...16. + +**NOTE:** The default ``analogWrite`` range was 1023 in releases before +3.0, but this lead to incompatibility with external libraries which +depended on the Arduino core default of 256. Existing applications which +rely on the prior 1023 value may add a call to ``analogWriteRange(1023)`` +to their ``setup()`` routine to retrurn to their old behavior. Applications +which already were calling ``analogWriteRange`` need no change. PWM frequency is 1kHz by default. Call ``analogWriteFreq(new_frequency)`` to change the frequency. Valid values @@ -113,7 +123,7 @@ are from 100Hz up to 40000Hz. The ESP doesn't have hardware PWM, so the implementation is by software. With one PWM output at 40KHz, the CPU is already rather loaded. The more PWM outputs used, and the higher their frequency, the closer you get to -the CPU limits, and the less CPU cycles are available for sketch execution. +the CPU limits, and the fewer CPU cycles are available for sketch execution. Timing and delays ----------------- From d5187790bd09f58c98603922fab9d2806388751e Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 30 Jul 2020 01:37:32 +1000 Subject: [PATCH 11/12] Mention OTA Update class blocks flash mode changes (#7321) Add mention that OTA Update class will block changes to flash mode bits if the image is uncompressed, and link to the recent discussion on this. Co-authored-by: Earle F. Philhower, III --- doc/ota_updates/readme.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/ota_updates/readme.rst b/doc/ota_updates/readme.rst index 35eb931507..6714d30961 100755 --- a/doc/ota_updates/readme.rst +++ b/doc/ota_updates/readme.rst @@ -669,6 +669,8 @@ Updater is in the Core and deals with writing the firmware to the flash, checkin **Note:** The bootloader command will be stored into the first 128 bytes of user RTC memory, then it will be retrieved by eboot on boot. That means that user data present there will be lost `(per discussion in #5330) `__. +**Note:** For uncompressed firmware images, the Updater will change the flash mode bits if they differ from the flash mode the device is currently running at. This ensures that the flash mode is not changed to an incompatible mode when the device is in a remote or hard to access area. Compressed images are not modified, thus changing the flash mode in this instance could result in damage to the ESP8266 and/or flash memory chip or your device no longer be accessible via OTA, and requiring re-flashing via a serial connection `(per discussion in #7307) `__. + Update process - memory view ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 1041a9d7523377cb67b3ce2b7cfb837c623ebd07 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Thu, 30 Jul 2020 01:26:56 +0200 Subject: [PATCH 12/12] webhook/http1.1: prevent from losing a new client while waiting (#7492) --- libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h index ce0d5bf2ea..218fd168af 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer-impl.h @@ -366,7 +366,7 @@ void ESP8266WebServerTemplate::handleClient() { break; case HC_WAIT_CLOSE: // Wait for client to close the connection - if (!_server.available() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) { + if (!_server.hasClient() && (millis() - _statusChange <= HTTP_MAX_CLOSE_WAIT)) { keepCurrentClient = true; callYield = true; if (_currentClient.available())