From fd50e95e9e5bedb372c9621869996adb6926a035 Mon Sep 17 00:00:00 2001 From: Max Prokhorov Date: Tue, 18 Feb 2020 12:14:07 +0300 Subject: [PATCH] Thingspeak: tweak SecureClient connection (#2144) - continue #2140 , use the correct implementation for http requests not confuse code readers with our parsing - fix data sender data duplication, run build test - add note that this is actually really RAM heavy, some connection failures are not easily distinguishable from any code errors and are simply OOM. also - fix arduinoota prototype error when building without it (... ino2cpp, again) - add comment about 160mhz into the platformio.ini --- code/espurna/config/general.h | 3 ++ code/espurna/ota.h | 2 +- code/espurna/thingspeak.h | 2 ++ code/espurna/thinkspeak.ino | 65 ++++++++++++++--------------------- code/platformio.ini | 4 +++ 5 files changed, 36 insertions(+), 40 deletions(-) diff --git a/code/espurna/config/general.h b/code/espurna/config/general.h index bb0851ee..4cdc5d79 100644 --- a/code/espurna/config/general.h +++ b/code/espurna/config/general.h @@ -1420,6 +1420,9 @@ // so you should compile it with WEB_SUPPORT to 0. // When THINGSPEAK_USE_ASYNC is 1, requires EspAsyncTCP to be built with ASYNC_TCP_SSL_ENABLED=1 and ESP8266 Arduino Core >= 2.4.0. // When THINGSPEAK_USE_ASYNC is 0, requires Arduino Core >= 2.6.0 and SECURE_CLIENT_BEARSSL +// +// WARNING: Thingspeak servers do not support MFLN right now, connection requires at least 30KB of free RAM. +// Also see MQTT comments above. #ifndef THINGSPEAK_USE_SSL #define THINGSPEAK_USE_SSL 0 // Use secure connection diff --git a/code/espurna/ota.h b/code/espurna/ota.h index 6c89aeef..cf09b5e7 100644 --- a/code/espurna/ota.h +++ b/code/espurna/ota.h @@ -7,10 +7,10 @@ OTA MODULE #pragma once #include +#include #if OTA_ARDUINOOTA_SUPPORT -#include void arduinoOtaSetup(); #endif // OTA_ARDUINOOTA_SUPPORT == 1 diff --git a/code/espurna/thingspeak.h b/code/espurna/thingspeak.h index 14aed294..98be11a0 100644 --- a/code/espurna/thingspeak.h +++ b/code/espurna/thingspeak.h @@ -12,6 +12,8 @@ Copyright (C) 2019 by Xose PĂ©rez #if THINGSPEAK_USE_ASYNC #include +#else +#include #endif constexpr const size_t tspkDataBufferSize = 256; diff --git a/code/espurna/thinkspeak.ino b/code/espurna/thinkspeak.ino index 08900f4b..3d73c84c 100644 --- a/code/espurna/thinkspeak.ino +++ b/code/espurna/thinkspeak.ino @@ -205,13 +205,7 @@ void _tspkInitClient(const String& _url) { unsigned int code = (p) ? atoi(&p[4]) : 0; DEBUG_MSG_P(PSTR("[THINGSPEAK] Response value: %u\n"), code); - if ((0 == code) && _tspk_tries) { - _tspk_flush = true; - DEBUG_MSG_P(PSTR("[THINGSPEAK] Re-enqueuing %u more time(s)\n"), _tspk_tries); - } else { - _tspkClearQueue(); - } - + _tspkRetry(code); client->close(true); _tspk_client_state = tspk_state_t::NONE; @@ -293,45 +287,29 @@ SecureClientConfig _tspk_sc_config { #endif // THINGSPEAK_USE_SSL && SECURE_CLIENT_BEARSSL -void _tspkPost(WiFiClient* client, const URL& url) { - - if (!client->connect(url.host.c_str(), url.port)) { - DEBUG_MSG_P(PSTR("[THINGSPEAK] Connection failed\n")); - return; - } +void _tspkPost(WiFiClient& client, const URL& url, bool https) { - DEBUG_MSG_P(PSTR("[THINGSPEAK] Connected to %s:%u\n"), url.host.c_str(), url.port); DEBUG_MSG_P(PSTR("[THINGSPEAK] POST %s?%s\n"), url.path.c_str(), _tspk_data.c_str()); - char headers[strlen_P(THINGSPEAK_REQUEST_TEMPLATE) + url.path.length() + url.host.length() + 1]; - snprintf_P(headers, sizeof(headers), - THINGSPEAK_REQUEST_TEMPLATE, - url.path.c_str(), - url.host.c_str(), - _tspk_data.length() - ); - - client->print(headers); - client->print(_tspk_data); - - nice_delay(100); + HTTPClient http; + http.begin(client, url.host, url.port, url.path, https); - const auto response = client->readString(); - int pos = response.indexOf("\r\n\r\n"); + http.addHeader("User-agent", "ESPurna"); + http.addHeader("Content-Type", "application/x-www-form-urlencoded"); - unsigned int code = (pos > 0) ? response.substring(pos + 4).toInt() : 0; - DEBUG_MSG_P(PSTR("[THINGSPEAK] Response value: %u\n"), code); + const auto http_code = http.POST(_tspk_data); + int value = 0; - client->stop(); - - _tspk_last_flush = millis(); - if ((0 == code) && _tspk_tries) { - _tspk_flush = true; - DEBUG_MSG_P(PSTR("[THINGSPEAK] Re-enqueuing %u more time(s)\n"), _tspk_tries); + if (http_code == 200) { + value = http.getString().toInt(); + DEBUG_MSG_P(PSTR("[THINGSPEAK] Response value: %u\n"), value); } else { - _tspkClearQueue(); + DEBUG_MSG_P(PSTR("[THINGSPEAK] Response HTTP code: %d\n"), http_code); } + _tspkRetry(value); + _tspk_data = ""; + } void _tspkPost(const String& address) { @@ -351,14 +329,14 @@ void _tspkPost(const String& address) { return; } - _tspkPost(&client->get(), url); + _tspkPost(client->get(), url, true); return; } #endif if (url.protocol == "http") { auto client = std::make_unique(); - _tspkPost(client.get(), url); + _tspkPost(*client.get(), url, false); return; } @@ -385,6 +363,15 @@ void _tspkClearQueue() { } } +void _tspkRetry(int code) { + if ((0 == code) && _tspk_tries) { + _tspk_flush = true; + DEBUG_MSG_P(PSTR("[THINGSPEAK] Re-enqueuing %u more time(s)\n"), _tspk_tries); + } else { + _tspkClearQueue(); + } +} + void _tspkFlush() { if (!_tspk_flush) return; diff --git a/code/platformio.ini b/code/platformio.ini index 115bfaa2..d58180fa 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -61,6 +61,9 @@ debug_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP # -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY = v2 Lower Memory # -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH = v2 Higher Bandwidth # +# BearSSL performance: +# When building with -DSECURE_CLIENT=SECURE_CLIENT_BEARSSL, please add `board_build.f_cpu = 160000000` to the environment configuration +# # BearSSL ciphers: # When building on core >= 2.5, you can add the build flag -DBEARSSL_SSL_BASIC in order to build BearSSL with a limited set of ciphers: # TLS_RSA_WITH_AES_128_CBC_SHA256 / AES128-SHA256 @@ -285,6 +288,7 @@ src_build_flags = [env:nodemcu-lolin-secure-client] platform = ${common.platform_latest} board = ${common.board_4m} +board_build.f_cpu = 160000000 build_flags = ${common.build_flags_4m1m} -DDEBUG_FAUXMO=Serial