From da1277265af8592a97b3aec64d43effa3e24b09e Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Wed, 16 Oct 2024 14:18:08 +0200 Subject: [PATCH 01/14] Fix naming of method. Closes #230. --- src/ThingsBoard.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ThingsBoard.h b/src/ThingsBoard.h index c8b6b775..79433ac2 100644 --- a/src/ThingsBoard.h +++ b/src/ThingsBoard.h @@ -462,7 +462,7 @@ class ThingsBoardSized { /// See https://thingsboard.io/docs/user-guide/telemetry/ for more information /// @param json String containing our json key value pairs we want to attempt to send /// @return Whether sending the data was successful or not - bool sendTelemtryString(char const * json) { + bool sendTelemetryString(char const * json) { return Send_Json_String(TELEMETRY_TOPIC, json); } From 75e2a088c90f6a35251f4287e0298464163f393b Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:56:07 +0200 Subject: [PATCH 02/14] Fix compilation issues and warnings for Arduino boards --- examples/0002-arduino_rpc/0002-arduino_rpc.ino | 2 +- src/Helper.h | 1 - src/ThingsBoard.h | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/0002-arduino_rpc/0002-arduino_rpc.ino b/examples/0002-arduino_rpc/0002-arduino_rpc.ino index 80e7029b..f6851001 100644 --- a/examples/0002-arduino_rpc/0002-arduino_rpc.ino +++ b/examples/0002-arduino_rpc/0002-arduino_rpc.ino @@ -53,7 +53,7 @@ WiFiEspClient espClient; Arduino_MQTT_Client mqttClient(espClient); // Initialize used apis Server_Side_RPC rpc; -const IAPI_Implementation* apis[1U] = { +IAPI_Implementation* apis[1U] = { &rpc }; // Initialize ThingsBoard instance with the maximum needed buffer size diff --git a/src/Helper.h b/src/Helper.h index 6fff6249..79ebf404 100644 --- a/src/Helper.h +++ b/src/Helper.h @@ -96,7 +96,6 @@ class Helper { // to keep compatibility with code that supports the STL we allow InputIterators, therefore we have to implement the size calculation the more inneficient O(n) way instead. // This allows the edge case where an end-user uses this method themselves in the code with their own implemented list data type. size_t size = 0U; - auto it = first; for (auto it = first; it != last; ++it, ++size) {} return size; #endif // THINGSBOARD_ENABLE_STL diff --git a/src/ThingsBoard.h b/src/ThingsBoard.h index 79433ac2..4a42628c 100644 --- a/src/ThingsBoard.h +++ b/src/ThingsBoard.h @@ -869,7 +869,7 @@ class ThingsBoardSized { static size_t * staticGetRequestID() { if (m_subscribedInstance == nullptr) { - return false; + return nullptr; } return m_subscribedInstance->getRequestID(); } From b29634b44bcaedb0680cdbc1053eef13099a3c3a Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 18 Oct 2024 22:42:45 +0200 Subject: [PATCH 03/14] Bump version number --- CMakeLists.txt | 2 +- docs/Doxyfile | 2 +- idf_component.yml | 2 +- library.json | 2 +- library.properties | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08d7f323..77bded85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,4 +37,4 @@ if(ESP_PLATFORM) return() endif() -project(ThingsBoardClientSDK VERSION 0.14.0) +project(ThingsBoardClientSDK VERSION 0.14.1) diff --git a/docs/Doxyfile b/docs/Doxyfile index 6a019bd7..0c7beed8 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "ThingsBoard Client SDK" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.14.0 +PROJECT_NUMBER = 0.14.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/idf_component.yml b/idf_component.yml index da4f0697..a5344fe9 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.14.0" +version: "0.14.1" description: Provides access to ThingsBoard platform over the MQTT protocol or alternatively over HTTP/S. url: https://github.com/thingsboard/thingsboard-client-sdk dependencies: diff --git a/library.json b/library.json index 3459b29c..66e232c5 100644 --- a/library.json +++ b/library.json @@ -9,7 +9,7 @@ "dependencies": { "bblanchon/ArduinoJson": "^6.21.5" }, - "version": "0.14.0", + "version": "0.14.1", "examples": "examples/*/*.ino", "frameworks": "*", "license": "MIT" diff --git a/library.properties b/library.properties index 46a09119..008d6739 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ # See https://arduino.github.io/arduino-cli/0.35/library-specification/#libraryproperties-file-format for more information on the formatting name=ThingsBoard -version=0.14.0 +version=0.14.1 author=ThingsBoard Team maintainer=ThingsBoard Team sentence=ThingsBoard library for Arduino. From 2144e9afb3e4b259a74b7ffc9ade28f54db57de3 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Sun, 20 Oct 2024 15:37:49 +0200 Subject: [PATCH 04/14] Optimize away println in Logger Impl --- README.md | 8 ++++---- src/Attribute_Request.h | 10 +++++----- src/Client_Side_RPC.h | 4 ++-- src/DefaultLogger.h | 16 +++++++--------- src/Espressif_Updater.h | 4 ++-- src/OTA_Firmware_Update.h | 28 ++++++++++++++-------------- src/OTA_Handler.h | 20 ++++++++++---------- src/Server_Side_RPC.h | 6 +++--- src/ThingsBoard.h | 22 +++++++++++----------- src/ThingsBoardHttp.h | 14 +++++++------- 10 files changed, 65 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 075c4a72..0a9a7b6a 100644 --- a/README.md +++ b/README.md @@ -670,10 +670,10 @@ class CustomLogger { public: template static int printfln(char const * format, Args const &... args) { - return 0; - } - - static int println(char const * message) { + // Check if variadic template contains any actual additional arguments that should be inserted into format message + if (constexpr sizeof...(Args) == 0U) { + return 0; + } return 0; } }; diff --git a/src/Attribute_Request.h b/src/Attribute_Request.h index 6ba3225f..fc8155c0 100644 --- a/src/Attribute_Request.h +++ b/src/Attribute_Request.h @@ -106,7 +106,7 @@ class Attribute_Request : public IAPI_Implementation { char const * attribute_response_key = attribute_request.Get_Attribute_Key(); if (attribute_response_key == nullptr) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(ATT_KEY_NOT_FOUND); + Logger::printfln(ATT_KEY_NOT_FOUND); #endif // THINGSBOARD_ENABLE_DEBUG goto delete_callback; } @@ -182,13 +182,13 @@ class Attribute_Request : public IAPI_Implementation { // Check if any sharedKeys were requested if (attributes.empty()) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(NO_KEYS_TO_REQUEST); + Logger::printfln(NO_KEYS_TO_REQUEST); #endif // THINGSBOARD_ENABLE_DEBUG return false; } else if (attribute_request_key == nullptr || attribute_response_key == nullptr) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(ATT_KEY_NOT_FOUND); + Logger::printfln(ATT_KEY_NOT_FOUND); #endif // THINGSBOARD_ENABLE_DEBUG return false; } @@ -227,7 +227,7 @@ class Attribute_Request : public IAPI_Implementation { for (const auto & att : attributes) { if (Helper::stringIsNullorEmpty(att)) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(ATT_KEY_IS_NULL); + Logger::printfln(ATT_KEY_IS_NULL); #endif // THINGSBOARD_ENABLE_DEBUG continue; } @@ -245,7 +245,7 @@ class Attribute_Request : public IAPI_Implementation { size_t * p_request_id = m_get_request_id_callback.Call_Callback(); if (p_request_id == nullptr) { - Logger::println(REQUEST_ID_NULL); + Logger::printfln(REQUEST_ID_NULL); return false; } auto & request_id = *p_request_id; diff --git a/src/Client_Side_RPC.h b/src/Client_Side_RPC.h index 1bb3287d..33c7d52b 100644 --- a/src/Client_Side_RPC.h +++ b/src/Client_Side_RPC.h @@ -49,7 +49,7 @@ class Client_Side_RPC : public IAPI_Implementation { char const * method_name = callback.Get_Name(); if (Helper::stringIsNullorEmpty(method_name)) { - Logger::println(CLIENT_RPC_METHOD_NULL); + Logger::printfln(CLIENT_RPC_METHOD_NULL); return false; } RPC_Request_Callback * registered_callback = nullptr; @@ -90,7 +90,7 @@ class Client_Side_RPC : public IAPI_Implementation { size_t * p_request_id = m_get_request_id_callback.Call_Callback(); if (p_request_id == nullptr) { - Logger::println(REQUEST_ID_NULL); + Logger::printfln(REQUEST_ID_NULL); return false; } auto & request_id = *p_request_id; diff --git a/src/DefaultLogger.h b/src/DefaultLogger.h index ef68f070..ccdab528 100644 --- a/src/DefaultLogger.h +++ b/src/DefaultLogger.h @@ -13,7 +13,8 @@ char constexpr LOG_MESSAGE_FORMAT[] = "[TB] %s\n"; /// @brief Default logger class used by the ThingsBoard class to log messages into the console output class DefaultLogger { public: - /// @brief Prints the given format message containing format specifiers (subsequences beginning with %) as well as a new line character at the end of the message + /// @brief Prints the given format message containing format specifiers (subsequences beginning with %) as well as a new line character at the end of the message. + /// If no additional arguments are given it simply prints the given format messsage /// @tparam ...Args Additional arguments formatted and inserted in the resulting string replacing their respective specifiers. /// See https://cplusplus.com/reference/cstdio/printf/ for more information on the possible format specifiers and the corresponding argument type /// @param format Formatting message that the given arguments will be inserted into @@ -21,19 +22,16 @@ class DefaultLogger { /// @return Either the written amount of characters or an error indicator (being a negative number) if one occured template static int printfln(char const * format, Args const &... args) { + // Check if variadic template contains any actual additional arguments that should be inserted into format message + if (constexpr sizeof...(Args) == 0U) { + return printf(LOG_MESSAGE_FORMAT, format); + } int const size = Helper::detectSize(format, args...); char arguments[size] = {}; int const written_characters = snprintf(arguments, size, format, args...); // Written characters is expected to be one less, because of the null termination character bool const result = (written_characters == (size - 1)); - return println(result ? arguments : FAILED_MESSAGE); - } - - /// @brief Prints the given message containing a new line character at the end of the message, but no format specifiers (subsequences beginning with %) - /// @param message Message that should be simply printed to the console, without any additional arguments, use peintfln() for that - /// @return Either the written amount of characters or an error indicator (being a negative number) if one occured - static int println(char const * message) { - return printf(LOG_MESSAGE_FORMAT, message); + return printf(LOG_MESSAGE_FORMAT, result ? arguments : FAILED_MESSAGE); } }; diff --git a/src/Espressif_Updater.h b/src/Espressif_Updater.h index 50ff98ad..cb1e354d 100644 --- a/src/Espressif_Updater.h +++ b/src/Espressif_Updater.h @@ -30,14 +30,14 @@ class Espressif_Updater : public IUpdater { esp_partition_t const * configured = esp_ota_get_boot_partition(); if (configured != running) { - Logger::println(INVALID_OTA_PARTIION); + Logger::printfln(INVALID_OTA_PARTIION); return false; } esp_partition_t const * update_partition = esp_ota_get_next_update_partition(nullptr); if (update_partition == nullptr) { - Logger::println(MISSING_OTA_APP); + Logger::printfln(MISSING_OTA_APP); return false; } diff --git a/src/OTA_Firmware_Update.h b/src/OTA_Firmware_Update.h index c365871f..a215b7cf 100644 --- a/src/OTA_Firmware_Update.h +++ b/src/OTA_Firmware_Update.h @@ -91,7 +91,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { /// @return Whether subscribing the given callback was successful or not bool Start_Firmware_Update(OTA_Update_Callback const & callback) { if (!Prepare_Firmware_Settings(callback)) { - Logger::println(RESETTING_FAILED); + Logger::printfln(RESETTING_FAILED); return false; } @@ -129,7 +129,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { /// @return Whether subscribing the given callback was successful or not bool Subscribe_Firmware_Update(OTA_Update_Callback const & callback) { if (!Prepare_Firmware_Settings(callback)) { - Logger::println(RESETTING_FAILED); + Logger::printfln(RESETTING_FAILED); return false; } @@ -245,7 +245,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { size_t * p_request_id = m_get_request_id_callback.Call_Callback(); if (p_request_id == nullptr) { - Logger::println(REQUEST_ID_NULL); + Logger::printfln(REQUEST_ID_NULL); return false; } auto & request_id = *p_request_id; @@ -262,7 +262,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { if (!m_subscribe_topic_callback.Call_Callback(FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC)) { char message[JSON_STRING_SIZE(strlen(SUBSCRIBE_TOPIC_FAILED)) + JSON_STRING_SIZE(strlen(FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC))] = {}; (void)snprintf(message, sizeof(message), SUBSCRIBE_TOPIC_FAILED, FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC); - Logger::println(message); + Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); return false; } @@ -306,7 +306,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { /// @brief Handler if the firmware shared attribute request times out without getting a response. /// Is used to signal that the update could not be started, because the current firmware information could not be fetched void Request_Timeout() { - Logger::println(NO_FW_REQUEST_RESPONSE); + Logger::printfln(NO_FW_REQUEST_RESPONSE); Firmware_Send_State(FW_STATE_FAILED, NO_FW_REQUEST_RESPONSE); } @@ -316,7 +316,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { void Firmware_Shared_Attribute_Received(JsonObjectConst const & data) { // Check if firmware is available for our device if (!data.containsKey(FW_VER_KEY) || !data.containsKey(FW_TITLE_KEY) || !data.containsKey(FW_CHKS_KEY) || !data.containsKey(FW_CHKS_ALGO_KEY) || !data.containsKey(FW_SIZE_KEY)) { - Logger::println(NO_FW); + Logger::printfln(NO_FW); Firmware_Send_State(FW_STATE_FAILED, NO_FW); return; } @@ -331,7 +331,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { char const * curr_fw_version = m_fw_callback.Get_Firmware_Version(); if (fw_title == nullptr || fw_version == nullptr || curr_fw_title == nullptr || curr_fw_version == nullptr || fw_algorithm == nullptr || fw_checksum == nullptr) { - Logger::println(EMPTY_FW); + Logger::printfln(EMPTY_FW); Firmware_Send_State(FW_STATE_FAILED, EMPTY_FW); return; } @@ -346,7 +346,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { else if (strncmp(curr_fw_title, fw_title, strlen(curr_fw_title)) != 0) { char message[JSON_STRING_SIZE(strlen(FW_NOT_FOR_US)) + JSON_STRING_SIZE(strlen(fw_title)) + JSON_STRING_SIZE(strlen(curr_fw_title))] = {}; (void)snprintf(message, sizeof(message), FW_NOT_FOR_US, fw_title, curr_fw_title); - Logger::println(message); + Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); return; } @@ -368,7 +368,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { else { char message[JSON_STRING_SIZE(strlen(FW_CHKS_ALGO_NOT_SUPPORTED)) + JSON_STRING_SIZE(strlen(fw_algorithm))] = {}; (void)snprintf(message, sizeof(message), FW_CHKS_ALGO_NOT_SUPPORTED, fw_algorithm); - Logger::println(message); + Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); return; } @@ -381,12 +381,12 @@ class OTA_Firmware_Update : public IAPI_Implementation { } #if THINGSBOARD_ENABLE_DEBUG - Logger::println(PAGE_BREAK); - Logger::println(NEW_FW); + Logger::printfln(PAGE_BREAK); + Logger::printfln(NEW_FW); char firmware[JSON_STRING_SIZE(strlen(FROM_TOO)) + JSON_STRING_SIZE(strlen(curr_fw_version)) + JSON_STRING_SIZE(strlen(fw_version))] = {}; (void)snprintf(firmware, sizeof(firmware), FROM_TOO, curr_fw_version, fw_version); - Logger::println(firmware); - Logger::println(DOWNLOADING_FW); + Logger::printfln(firmware); + Logger::printfln(DOWNLOADING_FW); #endif // THINGSBOARD_ENABLE_DEBUG // Calculate the number of chuncks we need to request, @@ -399,7 +399,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { // Increase size of receive buffer if (m_changed_buffer_size && !m_set_buffer_size_callback.Call_Callback(chunk_size + 50U)) { - Logger::println(NOT_ENOUGH_RAM); + Logger::printfln(NOT_ENOUGH_RAM); Firmware_Send_State(FW_STATE_FAILED, NOT_ENOUGH_RAM); m_fw_callback.Call_Callback(false); return; diff --git a/src/OTA_Handler.h b/src/OTA_Handler.h index ae503f76..2176ae15 100644 --- a/src/OTA_Handler.h +++ b/src/OTA_Handler.h @@ -92,7 +92,7 @@ class OTA_Handler { void Stop_Firmware_Update() { m_watchdog.detach(); m_fw_updater->reset(); - Logger::println(FW_UPDATE_ABORTED); + Logger::printfln(FW_UPDATE_ABORTED); Handle_Failure(OTA_Failure_Response::RETRY_NOTHING, FW_UPDATE_ABORTED); m_fw_callback = nullptr; } @@ -121,7 +121,7 @@ class OTA_Handler { if (current_chunk == 0U) { // Initialize Flash if (!m_fw_updater->begin(m_fw_size)) { - Logger::println(ERROR_UPDATE_BEGIN); + Logger::printfln(ERROR_UPDATE_BEGIN); return Handle_Failure(OTA_Failure_Response::RETRY_UPDATE, ERROR_UPDATE_BEGIN); } } @@ -131,7 +131,7 @@ class OTA_Handler { if (written_bytes != total_bytes) { char message[Helper::detectSize(ERROR_UPDATE_WRITE, written_bytes, total_bytes)] = {}; (void)snprintf(message, sizeof(message), ERROR_UPDATE_WRITE, written_bytes, total_bytes); - Logger::println(message); + Logger::printfln(message); return Handle_Failure(OTA_Failure_Response::RETRY_UPDATE, message); } @@ -145,7 +145,7 @@ class OTA_Handler { // Ensure to check if the update was cancelled during the progress callback, // if it was the callback variable was reset and there is no need to request the next firmware packet if (m_fw_callback == nullptr) { - Logger::println(OTA_CB_IS_NULL); + Logger::printfln(OTA_CB_IS_NULL); return Handle_Failure(OTA_Failure_Response::RETRY_NOTHING, OTA_CB_IS_NULL); } @@ -201,7 +201,7 @@ class OTA_Handler { } if (!m_publish_callback.Call_Callback(m_fw_callback->Get_Request_ID(), m_requested_chunks)) { - Logger::println(UNABLE_TO_REQUEST_CHUNCKS); + Logger::printfln(UNABLE_TO_REQUEST_CHUNCKS); } // Watchdog gets started no matter if publishing request was successful or not in hopes, @@ -225,21 +225,21 @@ class OTA_Handler { if (strncmp(m_fw_checksum, calculated_checksum, strlen(m_fw_checksum)) != 0) { char message[Helper::detectSize(CHECKSUM_VERIFICATION_FAILED, calculated_checksum, m_fw_checksum)] = {}; (void)snprintf(message, sizeof(message), CHECKSUM_VERIFICATION_FAILED, calculated_checksum, m_fw_checksum); - Logger::println(message); + Logger::printfln(message); return Handle_Failure(OTA_Failure_Response::RETRY_UPDATE, message); } #if THINGSBOARD_ENABLE_DEBUG - Logger::println(CHECKSUM_VERIFICATION_SUCCESS); + Logger::printfln(CHECKSUM_VERIFICATION_SUCCESS); #endif // THINGSBOARD_ENABLE_DEBUG if (!m_fw_updater->end()) { - Logger::println(ERROR_UPDATE_END); + Logger::printfln(ERROR_UPDATE_END); return Handle_Failure(OTA_Failure_Response::RETRY_UPDATE, ERROR_UPDATE_END); } #if THINGSBOARD_ENABLE_DEBUG - Logger::println(FW_UPDATE_SUCCESS); + Logger::printfln(FW_UPDATE_SUCCESS); #endif // THINGSBOARD_ENABLE_DEBUG (void)m_send_fw_state_callback.Call_Callback(FW_STATE_UPDATING, ""); @@ -286,7 +286,7 @@ class OTA_Handler { uint64_t const & timeout = m_fw_callback->Get_Timeout(); char message[Helper::detectSize(CHUNK_REQUEST_TIMED_OUT, m_requested_chunks, timeout)] = {}; (void)snprintf(message, sizeof(message), CHUNK_REQUEST_TIMED_OUT, m_requested_chunks, timeout); - Logger::println(message); + Logger::printfln(message); Handle_Failure(OTA_Failure_Response::RETRY_CHUNK, message); } diff --git a/src/Server_Side_RPC.h b/src/Server_Side_RPC.h index bbf866ed..5da04c35 100644 --- a/src/Server_Side_RPC.h +++ b/src/Server_Side_RPC.h @@ -112,7 +112,7 @@ class Server_Side_RPC : public IAPI_Implementation { void Process_Json_Response(char const * topic, JsonDocument const & data) override { if (!data.containsKey(RPC_METHOD_KEY)) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(SERVER_RPC_METHOD_NULL); + Logger::printfln(SERVER_RPC_METHOD_NULL); #endif // THINGSBOARD_ENABLE_DEBUG return; } @@ -134,7 +134,7 @@ class Server_Side_RPC : public IAPI_Implementation { #endif // THINGSBOARD_ENABLE_STL #if THINGSBOARD_ENABLE_DEBUG if (!data.containsKey(RPC_PARAMS_KEY)) { - Logger::println(NO_RPC_PARAMS_PASSED); + Logger::printfln(NO_RPC_PARAMS_PASSED); } #endif // THINGSBOARD_ENABLE_DEBUG @@ -154,7 +154,7 @@ class Server_Side_RPC : public IAPI_Implementation { if (json_buffer.isNull()) { #if THINGSBOARD_ENABLE_DEBUG - Logger::println(RPC_RESPONSE_NULL); + Logger::printfln(RPC_RESPONSE_NULL); #endif // THINGSBOARD_ENABLE_DEBUG return; } diff --git a/src/ThingsBoard.h b/src/ThingsBoard.h index 4a42628c..83f6787f 100644 --- a/src/ThingsBoard.h +++ b/src/ThingsBoard.h @@ -200,7 +200,7 @@ class ThingsBoardSized { bool setBufferSize(uint16_t buffer_size) { bool const result = m_client.set_buffer_size(buffer_size); if (!result) { - Logger::println(UNABLE_TO_ALLOCATE_BUFFER); + Logger::printfln(UNABLE_TO_ALLOCATE_BUFFER); } return result; } @@ -277,13 +277,13 @@ class ThingsBoardSized { // Check if allocating needed memory failed when trying to create the JsonDocument, // if it did the isNull() method will return true. See https://arduinojson.org/v6/api/jsonvariant/isnull/ for more information if (source.isNull()) { - Logger::println(UNABLE_TO_ALLOCATE_JSON); + Logger::printfln(UNABLE_TO_ALLOCATE_JSON); return false; } // Check if inserting any of the internal values failed because the JsonDocument was too small, // if it did the overflowed() method will return true. See https://arduinojson.org/v6/api/jsondocument/overflowed/ for more information if (source.overflowed()) { - Logger::println(JSON_SIZE_TO_SMALL); + Logger::printfln(JSON_SIZE_TO_SMALL); return false; } bool result = false; @@ -304,7 +304,7 @@ class ThingsBoardSized { if (json_size > getMaximumStackSize()) { char* json = new char[json_size](); if (serializeJson(source, json, json_size) < json_size - 1) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); } else { result = Send_Json_String(topic, json); @@ -317,7 +317,7 @@ class ThingsBoardSized { else { char json[json_size] = {}; if (serializeJson(source, json, json_size) < json_size - 1) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); return result; } result = Send_Json_String(topic, json); @@ -542,13 +542,13 @@ class ThingsBoardSized { /// @return Whether sending the data was successful or not bool Serialize_Json(char const * topic, JsonDocument const & source, size_t const & json_size) { if (!m_client.begin_publish(topic, json_size)) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); return false; } BufferingPrint buffered_print(m_client, getBufferingSize()); size_t const bytes_serialized = serializeJson(source, buffered_print); if (bytes_serialized < json_size) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); return false; } buffered_print.flush(); @@ -608,7 +608,7 @@ class ThingsBoardSized { bool connectToHost(char const * access_token, char const * client_id, char const * password) { bool const connection_result = m_client.connect(client_id, access_token, password); if (!connection_result) { - Logger::println(CONNECT_FAILED); + Logger::printfln(CONNECT_FAILED); } return connection_result; } @@ -643,7 +643,7 @@ class ThingsBoardSized { StaticJsonDocument json_buffer; if (!t.SerializeKeyValue(json_buffer)) { - Logger::println(UNABLE_TO_SERIALIZE); + Logger::printfln(UNABLE_TO_SERIALIZE); return false; } return telemetry ? sendTelemetryJson(json_buffer, Helper::Measure_Json(json_buffer)) : sendAttributeJson(json_buffer, Helper::Measure_Json(json_buffer)); @@ -681,14 +681,14 @@ class ThingsBoardSized { #if THINGSBOARD_ENABLE_STL if (std::any_of(first, last, [&json_buffer](Telemetry const & data) { return !data.SerializeKeyValue(json_buffer); })) { - Logger::println(UNABLE_TO_SERIALIZE); + Logger::printfln(UNABLE_TO_SERIALIZE); return false; } #else for (auto it = first; it != last; ++it) { auto const & data = *it; if (!data.SerializeKeyValue(json_buffer)) { - Logger::println(UNABLE_TO_SERIALIZE); + Logger::printfln(UNABLE_TO_SERIALIZE); return false; } } diff --git a/src/ThingsBoardHttp.h b/src/ThingsBoardHttp.h index 6a14105e..9c66cba2 100644 --- a/src/ThingsBoardHttp.h +++ b/src/ThingsBoardHttp.h @@ -52,7 +52,7 @@ class ThingsBoardHttpSized { { m_client.set_keep_alive(keep_alive); if (m_client.connect(host, port) != 0) { - Logger::println(CONNECT_FAILED); + Logger::printfln(CONNECT_FAILED); } } @@ -72,20 +72,20 @@ class ThingsBoardHttpSized { // Check if allocating needed memory failed when trying to create the JsonDocument, // if it did the isNull() method will return true. See https://arduinojson.org/v6/api/jsonvariant/isnull/ for more information if (source.isNull()) { - Logger::println(UNABLE_TO_ALLOCATE_JSON); + Logger::printfln(UNABLE_TO_ALLOCATE_JSON); return false; } // Check if inserting any of the internal values failed because the JsonDocument was too small, // if it did the overflowed() method will return true. See https://arduinojson.org/v6/api/jsondocument/overflowed/ for more information if (source.overflowed()) { - Logger::println(JSON_SIZE_TO_SMALL); + Logger::printfln(JSON_SIZE_TO_SMALL); return false; } bool result = false; if (getMaximumStackSize() < json_size) { char * json = new char[json_size](); if (serializeJson(source, json, json_size) < json_size - 1) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); } else { result = Send_Json_String(topic, json); @@ -98,7 +98,7 @@ class ThingsBoardHttpSized { else { char json[json_size] = {}; if (serializeJson(source, json, json_size) < json_size - 1) { - Logger::println(UNABLE_TO_SERIALIZE_JSON); + Logger::printfln(UNABLE_TO_SERIALIZE_JSON); return result; } result = Send_Json_String(topic, json); @@ -335,14 +335,14 @@ class ThingsBoardHttpSized { #if THINGSBOARD_ENABLE_STL if (std::any_of(first, last, [&json_buffer](Telemetry const & data) { return !data.SerializeKeyValue(json_buffer); })) { - Logger::println(UNABLE_TO_SERIALIZE); + Logger::printfln(UNABLE_TO_SERIALIZE); return false; } #else for (auto it = first; it != last; ++it) { auto const & data = *it; if (!data.SerializeKeyValue(json_buffer)) { - Logger::println(UNABLE_TO_SERIALIZE); + Logger::printfln(UNABLE_TO_SERIALIZE); return false; } } From 04484a4987b5a2245f171d56247dd649f803a5e4 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Sun, 20 Oct 2024 15:48:23 +0200 Subject: [PATCH 05/14] Fix usage of if constexpr for non C++20 boards --- README.md | 4 ---- src/DefaultLogger.h | 24 ++++++++++++++++-------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0a9a7b6a..950015db 100644 --- a/README.md +++ b/README.md @@ -670,10 +670,6 @@ class CustomLogger { public: template static int printfln(char const * format, Args const &... args) { - // Check if variadic template contains any actual additional arguments that should be inserted into format message - if (constexpr sizeof...(Args) == 0U) { - return 0; - } return 0; } }; diff --git a/src/DefaultLogger.h b/src/DefaultLogger.h index ccdab528..a51d12ad 100644 --- a/src/DefaultLogger.h +++ b/src/DefaultLogger.h @@ -22,16 +22,24 @@ class DefaultLogger { /// @return Either the written amount of characters or an error indicator (being a negative number) if one occured template static int printfln(char const * format, Args const &... args) { - // Check if variadic template contains any actual additional arguments that should be inserted into format message - if (constexpr sizeof...(Args) == 0U) { + // Check if variadic template contains any actual additional arguments that should be inserted into format message. + // If it does, use constexpr if statement for C++20 supported devices to optimize away the branch instruction at compile time + // or alternatively runtime for devices that do not support C++20 +#if THINGSBOARD_ENABLE_CXX20 + if constexpr (sizeof...(Args) == 0U) { +#else + if (sizeof...(Args) == 0U) { +#endif // THINGSBOARD_ENABLE_CXX20 return printf(LOG_MESSAGE_FORMAT, format); } - int const size = Helper::detectSize(format, args...); - char arguments[size] = {}; - int const written_characters = snprintf(arguments, size, format, args...); - // Written characters is expected to be one less, because of the null termination character - bool const result = (written_characters == (size - 1)); - return printf(LOG_MESSAGE_FORMAT, result ? arguments : FAILED_MESSAGE); + else { + int const size = Helper::detectSize(format, args...); + char arguments[size] = {}; + int const written_characters = snprintf(arguments, size, format, args...); + // Written characters is expected to be one less, because of the null termination character + bool const result = (written_characters == (size - 1)); + return printf(LOG_MESSAGE_FORMAT, result ? arguments : FAILED_MESSAGE); + } } }; From ba8e0a9a4b683b1fa11c70bb63991ba9dffd890e Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:28:05 +0100 Subject: [PATCH 06/14] Add new example to ESP32 workflow --- .github/workflows/esp32-compile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/esp32-compile.yml b/.github/workflows/esp32-compile.yml index 8a9d4b28..fe843277 100644 --- a/.github/workflows/esp32-compile.yml +++ b/.github/workflows/esp32-compile.yml @@ -71,6 +71,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino + - examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' From 5df7d3c9632a4ef3abbc1da21efdc4409fc3efb3 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:28:46 +0100 Subject: [PATCH 07/14] Add new example to ESP8266 workflow --- .github/workflows/esp8266-compile.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/esp8266-compile.yml b/.github/workflows/esp8266-compile.yml index bf1705da..f072c428 100644 --- a/.github/workflows/esp8266-compile.yml +++ b/.github/workflows/esp8266-compile.yml @@ -70,6 +70,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino + - examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' From cb4e0e59da6b9c3b788821a2febf2c59c55881ce Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:39:01 +0100 Subject: [PATCH 08/14] Rename file and fix issues --- .github/workflows/esp32-compile.yml | 2 +- .github/workflows/esp8266-compile.yml | 2 +- .../0019_esp8266_esp32_send_attributes.ino | 5 ++--- .../README.md | 0 4 files changed, 4 insertions(+), 5 deletions(-) rename examples/{0019_esp8266_esp32_send_attributes => 0019-esp8266_esp32_send_attributes}/0019_esp8266_esp32_send_attributes.ino (99%) rename examples/{0019_esp8266_esp32_send_attributes => 0019-esp8266_esp32_send_attributes}/README.md (100%) diff --git a/.github/workflows/esp32-compile.yml b/.github/workflows/esp32-compile.yml index fe843277..69df085a 100644 --- a/.github/workflows/esp32-compile.yml +++ b/.github/workflows/esp32-compile.yml @@ -71,7 +71,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino - - examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino + - examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' diff --git a/.github/workflows/esp8266-compile.yml b/.github/workflows/esp8266-compile.yml index f072c428..3fc4dae2 100644 --- a/.github/workflows/esp8266-compile.yml +++ b/.github/workflows/esp8266-compile.yml @@ -70,7 +70,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino - - examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino + - examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' diff --git a/examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino b/examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino similarity index 99% rename from examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino rename to examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino index b72508e3..cfe0c9e5 100644 --- a/examples/0019_esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino +++ b/examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino @@ -224,11 +224,10 @@ void loop() { { ACTIVE_KEY, true }, }; - Telemetry* begin = data; - Telemetry* end = data + ATTRIBUTES_SIZE; + Telemetry* begin = attributes; + Telemetry* end = attributes + ATTRIBUTES_SIZE; tb.sendAttributes(begin, end); - #if !USING_HTTPS tb.loop(); #endif diff --git a/examples/0019_esp8266_esp32_send_attributes/README.md b/examples/0019-esp8266_esp32_send_attributes/README.md similarity index 100% rename from examples/0019_esp8266_esp32_send_attributes/README.md rename to examples/0019-esp8266_esp32_send_attributes/README.md From 4c417df07759af0c3373459516076cae1ab3cdb4 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:37:11 +0100 Subject: [PATCH 09/14] Fix missing file error --- .github/workflows/esp32-compile.yml | 2 +- .github/workflows/esp8266-compile.yml | 2 +- ...nd_attributes.ino => 0019-esp8266_esp32_send_attributes.ino} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename examples/0019-esp8266_esp32_send_attributes/{0019_esp8266_esp32_send_attributes.ino => 0019-esp8266_esp32_send_attributes.ino} (100%) diff --git a/.github/workflows/esp32-compile.yml b/.github/workflows/esp32-compile.yml index 69df085a..ed157c17 100644 --- a/.github/workflows/esp32-compile.yml +++ b/.github/workflows/esp32-compile.yml @@ -71,7 +71,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino - - examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino + - examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' diff --git a/.github/workflows/esp8266-compile.yml b/.github/workflows/esp8266-compile.yml index 3fc4dae2..54735cb3 100644 --- a/.github/workflows/esp8266-compile.yml +++ b/.github/workflows/esp8266-compile.yml @@ -70,7 +70,7 @@ jobs: - examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino - examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino - examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino - - examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino + - examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}/${{ env.SKETCHES_REPORTS_NAME }} enable-warnings-report: 'true' diff --git a/examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino b/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino similarity index 100% rename from examples/0019-esp8266_esp32_send_attributes/0019_esp8266_esp32_send_attributes.ino rename to examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino From 2ca0e1bcadfedac077c6d3a1ba83ab9ac015942b Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Fri, 15 Nov 2024 13:20:17 +0100 Subject: [PATCH 10/14] Fix missing dynamic ifdef in example --- .../0019-esp8266_esp32_send_attributes.ino | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino b/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino index cfe0c9e5..d9ca0947 100644 --- a/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino +++ b/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino @@ -226,7 +226,11 @@ void loop() { Telemetry* begin = attributes; Telemetry* end = attributes + ATTRIBUTES_SIZE; +#if THINGSBOARD_ENABLE_DYNAMIC + tb.sendAttributes(begin, end); +#else tb.sendAttributes(begin, end); +#endif // THINGSBOARD_ENABLE_DYNAMIC #if !USING_HTTPS tb.loop(); From 8ffed01b5979dfdd325b07570edd49116eaffe66 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:47:58 +0100 Subject: [PATCH 11/14] Fix #237 with topic copy and remove JSON_STRING_SIZE usage --- src/Espressif_MQTT_Client.h | 9 +++++++-- src/Helper.h | 2 +- src/OTA_Firmware_Update.h | 8 ++++---- src/Provision.h | 2 +- src/Shared_Attribute_Update.h | 2 +- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Espressif_MQTT_Client.h b/src/Espressif_MQTT_Client.h index aa6b6a01..ba821b9b 100644 --- a/src/Espressif_MQTT_Client.h +++ b/src/Espressif_MQTT_Client.h @@ -416,15 +416,20 @@ class Espressif_MQTT_Client : public IMQTT_Client { case esp_mqtt_event_id_t::MQTT_EVENT_DISCONNECTED: m_connected = false; break; - case esp_mqtt_event_id_t::MQTT_EVENT_DATA: + case esp_mqtt_event_id_t::MQTT_EVENT_DATA: { // Check wheter the given message has not bee received completly, but instead would be received in multiple chunks, // if it were we discard the message because receiving a message over multiple chunks is currently not supported if (event->data_len != event->total_data_len) { Logger::printfln(MQTT_DATA_EXCEEDS_BUFFER, event->total_data_len, get_buffer_size()); break; } - m_received_data_callback.Call_Callback(event->topic, reinterpret_cast(event->data), event->data_len); + // Topic is not null terminated, to fix this issue we copy the topic string. + // This overhead is acceptable, because we nearly always copy only a few bytes (around 20), meaning the overhead is insignificant. + char topic[event->topic_len + 1] = {}; + strncpy(topic, event->topic, event->topic_len); + m_received_data_callback.Call_Callback(topic, reinterpret_cast(event->data), event->data_len); break; + } default: // Nothing to do break; diff --git a/src/Helper.h b/src/Helper.h index 79ebf404..460520bc 100644 --- a/src/Helper.h +++ b/src/Helper.h @@ -63,7 +63,7 @@ class Helper { /// @return Total size required for the string that would be produced by serializeJson + 1 byte for the string null terminator template static size_t Measure_Json(TSource const & source) { - return JSON_STRING_SIZE(measureJson(source)); + return measureJson(source) + 1; } /// @brief Removes the element with the given index, which allows to use data containers that do not have a random-access iterator. diff --git a/src/OTA_Firmware_Update.h b/src/OTA_Firmware_Update.h index a215b7cf..97fd6ebb 100644 --- a/src/OTA_Firmware_Update.h +++ b/src/OTA_Firmware_Update.h @@ -260,7 +260,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { /// @return Whether subscribing to the firmware response topic was successful or not bool Firmware_OTA_Subscribe() { if (!m_subscribe_topic_callback.Call_Callback(FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC)) { - char message[JSON_STRING_SIZE(strlen(SUBSCRIBE_TOPIC_FAILED)) + JSON_STRING_SIZE(strlen(FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC))] = {}; + char message[strlen(SUBSCRIBE_TOPIC_FAILED) + strlen(FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC) + 2] = {}; (void)snprintf(message, sizeof(message), SUBSCRIBE_TOPIC_FAILED, FIRMWARE_RESPONSE_SUBSCRIBE_TOPIC); Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); @@ -344,7 +344,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { // If firmware title is not the same, we do not initiate an update, because we expect the binary to be for another type of device // and downloading it on this device could possibly cause hardware issues or even destroy the device else if (strncmp(curr_fw_title, fw_title, strlen(curr_fw_title)) != 0) { - char message[JSON_STRING_SIZE(strlen(FW_NOT_FOR_US)) + JSON_STRING_SIZE(strlen(fw_title)) + JSON_STRING_SIZE(strlen(curr_fw_title))] = {}; + char message[strlen(FW_NOT_FOR_US) + strlen(fw_title) + strlen(curr_fw_title) + 3] = {}; (void)snprintf(message, sizeof(message), FW_NOT_FOR_US, fw_title, curr_fw_title); Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); @@ -366,7 +366,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { fw_checksum_algorithm = mbedtls_md_type_t::MBEDTLS_MD_SHA512; } else { - char message[JSON_STRING_SIZE(strlen(FW_CHKS_ALGO_NOT_SUPPORTED)) + JSON_STRING_SIZE(strlen(fw_algorithm))] = {}; + char message[strlen(FW_CHKS_ALGO_NOT_SUPPORTED) + strlen(fw_algorithm) + 2] = {}; (void)snprintf(message, sizeof(message), FW_CHKS_ALGO_NOT_SUPPORTED, fw_algorithm); Logger::printfln(message); Firmware_Send_State(FW_STATE_FAILED, message); @@ -383,7 +383,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { #if THINGSBOARD_ENABLE_DEBUG Logger::printfln(PAGE_BREAK); Logger::printfln(NEW_FW); - char firmware[JSON_STRING_SIZE(strlen(FROM_TOO)) + JSON_STRING_SIZE(strlen(curr_fw_version)) + JSON_STRING_SIZE(strlen(fw_version))] = {}; + char firmware[strlen(FROM_TOO) + strlen(curr_fw_version) + strlen(fw_version) + 3] = {}; (void)snprintf(firmware, sizeof(firmware), FROM_TOO, curr_fw_version, fw_version); Logger::printfln(firmware); Logger::printfln(DOWNLOADING_FW); diff --git a/src/Provision.h b/src/Provision.h index 8b8f132e..8ba142c3 100644 --- a/src/Provision.h +++ b/src/Provision.h @@ -108,7 +108,7 @@ class Provision : public IAPI_Implementation { } bool Compare_Response_Topic(char const * topic) const override { - return strncmp(PROV_RESPONSE_TOPIC, topic, JSON_STRING_SIZE(strlen(PROV_RESPONSE_TOPIC))) == 0; + return strncmp(PROV_RESPONSE_TOPIC, topic, strlen(PROV_RESPONSE_TOPIC) + 1) == 0; } bool Unsubscribe() override { diff --git a/src/Shared_Attribute_Update.h b/src/Shared_Attribute_Update.h index 64be34e8..76b5a34f 100644 --- a/src/Shared_Attribute_Update.h +++ b/src/Shared_Attribute_Update.h @@ -161,7 +161,7 @@ class Shared_Attribute_Update : public IAPI_Implementation { } bool Compare_Response_Topic(char const * topic) const override { - return strncmp(ATTRIBUTE_TOPIC, topic, JSON_STRING_SIZE(strlen(ATTRIBUTE_TOPIC))) == 0; + return strncmp(ATTRIBUTE_TOPIC, topic, strlen(ATTRIBUTE_TOPIC) + 1) == 0; } bool Unsubscribe() override { From ec2719421cef3eadb7348fa8596b051311274c87 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:46:07 +0100 Subject: [PATCH 12/14] Adjust sdk to breaking api changes in PubSubClient --- README.md | 2 +- .../0000-arduino_send_telemetry.ino | 7 +- .../0001-arduino_send_batch.ino | 7 +- .../0002-arduino_rpc/0002-arduino_rpc.ino | 8 +- .../0003-esp8266_esp32_send_data.ino | 5 +- .../0004-arduino-sim900_send_telemetry.ino | 5 +- ..._esp32_process_shared_attribute_update.ino | 5 +- .../0007-esp8266_esp32_claim_device.ino | 5 +- .../0008-esp8266_esp32_provision_device.ino | 5 +- .../0009-esp8266_esp32_process_OTA_MQTT.ino | 5 +- .../0010-esp8266_esp32_rpc.ino | 5 +- .../0011-esp8266_esp32_subscribe_OTA_MQTT.ino | 5 +- ...esp8266_esp32_request_shared_attribute.ino | 5 +- .../0013-esp8266_esp32_request_rpc.ino | 5 +- .../main/0014-espressif_esp32_send_data.cpp | 5 +- .../0015-espressif_esp32_process_OTA_MQTT.cpp | 5 +- .../main/0016-espressif_esp32_rpc.cpp | 5 +- ..._esp32_process_shared_attribute_update.cpp | 5 +- .../0018-espressif_esp32_provision_device.cpp | 5 +- .../0019-esp8266_esp32_send_attributes.ino | 5 +- src/Arduino_MQTT_Client.cpp | 12 +- src/Arduino_MQTT_Client.h | 6 +- src/Attribute_Request.h | 2 +- src/Client_Side_RPC.h | 2 +- src/Espressif_MQTT_Client.h | 20 +++- src/IAPI_Implementation.h | 5 +- src/IMQTT_Client.h | 23 ++-- src/OTA_Firmware_Update.h | 19 ++-- src/Provision.h | 2 +- src/Server_Side_RPC.h | 2 +- src/Shared_Attribute_Update.h | 2 +- src/ThingsBoard.h | 106 ++++++++++-------- 32 files changed, 181 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index 950015db..5eff0ec4 100644 --- a/README.md +++ b/README.md @@ -401,7 +401,7 @@ class Custom_API_Implementation : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { // Nothing to do } }; diff --git a/examples/0000-arduino_send_telemetry/0000-arduino_send_telemetry.ino b/examples/0000-arduino_send_telemetry/0000-arduino_send_telemetry.ino index 74282f37..ee94d59a 100644 --- a/examples/0000-arduino_send_telemetry/0000-arduino_send_telemetry.ino +++ b/examples/0000-arduino_send_telemetry/0000-arduino_send_telemetry.ino @@ -28,7 +28,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -46,8 +47,8 @@ SoftwareSerial soft(2U, 3U); // RX, TX WiFiEspClient espClient; // Initalize the Mqtt client instance Arduino_MQTT_Client mqttClient(espClient); -// Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE); +// Initialize ThingsBoard instance with the maximum needed buffer sizes +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE); /// @brief Initalizes WiFi connection, diff --git a/examples/0001-arduino_send_batch/0001-arduino_send_batch.ino b/examples/0001-arduino_send_batch/0001-arduino_send_batch.ino index abdb22d2..4aa0c062 100644 --- a/examples/0001-arduino_send_batch/0001-arduino_send_batch.ino +++ b/examples/0001-arduino_send_batch/0001-arduino_send_batch.ino @@ -28,7 +28,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -49,8 +50,8 @@ SoftwareSerial soft(2U, 3U); // RX, TX WiFiEspClient espClient; // Initalize the Mqtt client instance Arduino_MQTT_Client mqttClient(espClient); -// Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE); +// Initialize ThingsBoard instance with the maximum needed buffer sizes +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE); /// @brief Initalizes WiFi connection, diff --git a/examples/0002-arduino_rpc/0002-arduino_rpc.ino b/examples/0002-arduino_rpc/0002-arduino_rpc.ino index f6851001..d93e7ad3 100644 --- a/examples/0002-arduino_rpc/0002-arduino_rpc.ino +++ b/examples/0002-arduino_rpc/0002-arduino_rpc.ino @@ -29,7 +29,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -56,8 +57,9 @@ Server_Side_RPC rpc; IAPI_Implementation* apis[1U] = { &rpc }; -// Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis + 0U, apis + 1U); +// Initialize ThingsBoard instance with the maximum needed buffer sizes +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis + 0U, apis + 1U); + // Statuses for subscribing to rpc bool subscribed = false; diff --git a/examples/0003-esp8266_esp32_send_data/0003-esp8266_esp32_send_data.ino b/examples/0003-esp8266_esp32_send_data/0003-esp8266_esp32_send_data.ino index c31cf1c8..b46974c6 100644 --- a/examples/0003-esp8266_esp32_send_data/0003-esp8266_esp32_send_data.ino +++ b/examples/0003-esp8266_esp32_send_data/0003-esp8266_esp32_send_data.ino @@ -70,7 +70,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -136,7 +137,7 @@ Arduino_MQTT_Client mqttClient(espClient); // Initialize used apis const std::array apis = {}; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); #endif diff --git a/examples/0004-arduino-sim900_send_telemetry/0004-arduino-sim900_send_telemetry.ino b/examples/0004-arduino-sim900_send_telemetry/0004-arduino-sim900_send_telemetry.ino index b3eb5551..4dd95228 100644 --- a/examples/0004-arduino-sim900_send_telemetry/0004-arduino-sim900_send_telemetry.ino +++ b/examples/0004-arduino-sim900_send_telemetry/0004-arduino-sim900_send_telemetry.ino @@ -41,7 +41,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -65,7 +66,7 @@ TinyGsmClient client(modem); Arduino_MQTT_Client mqttClient(client); // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE); // Set to true, if modem is connected bool modemConnected = false; diff --git a/examples/0006-esp8266_esp32_process_shared_attribute_update/0006-esp8266_esp32_process_shared_attribute_update.ino b/examples/0006-esp8266_esp32_process_shared_attribute_update/0006-esp8266_esp32_process_shared_attribute_update.ino index c3c628dd..68090197 100644 --- a/examples/0006-esp8266_esp32_process_shared_attribute_update/0006-esp8266_esp32_process_shared_attribute_update.ino +++ b/examples/0006-esp8266_esp32_process_shared_attribute_update/0006-esp8266_esp32_process_shared_attribute_update.ino @@ -39,7 +39,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -110,7 +111,7 @@ const std::array apis = { &shared_update }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Statuses for subscribing to shared attributes bool subscribed = false; diff --git a/examples/0007-esp8266_esp32_claim_device/0007-esp8266_esp32_claim_device.ino b/examples/0007-esp8266_esp32_claim_device/0007-esp8266_esp32_claim_device.ino index 9eaf6163..60d1e593 100644 --- a/examples/0007-esp8266_esp32_claim_device/0007-esp8266_esp32_claim_device.ino +++ b/examples/0007-esp8266_esp32_claim_device/0007-esp8266_esp32_claim_device.ino @@ -43,7 +43,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -108,7 +109,7 @@ WiFiClient espClient; // Initalize the Mqtt client instance Arduino_MQTT_Client mqttClient(espClient); // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE); // Statuses for claiming bool claimingRequestSent = false; diff --git a/examples/0008-esp8266_esp32_provision_device/0008-esp8266_esp32_provision_device.ino b/examples/0008-esp8266_esp32_provision_device/0008-esp8266_esp32_provision_device.ino index 5b3acd39..83fb8f5b 100644 --- a/examples/0008-esp8266_esp32_provision_device/0008-esp8266_esp32_provision_device.ino +++ b/examples/0008-esp8266_esp32_provision_device/0008-esp8266_esp32_provision_device.ino @@ -39,7 +39,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -120,7 +121,7 @@ const std::array apis = { &prov }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); uint32_t previous_processing_time = 0U; diff --git a/examples/0009-esp8266_esp32_process_OTA_MQTT/0009-esp8266_esp32_process_OTA_MQTT.ino b/examples/0009-esp8266_esp32_process_OTA_MQTT/0009-esp8266_esp32_process_OTA_MQTT.ino index 7717edc5..a5f45526 100644 --- a/examples/0009-esp8266_esp32_process_OTA_MQTT/0009-esp8266_esp32_process_OTA_MQTT.ino +++ b/examples/0009-esp8266_esp32_process_OTA_MQTT/0009-esp8266_esp32_process_OTA_MQTT.ino @@ -68,7 +68,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 512U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 512U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 512U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -127,7 +128,7 @@ const std::array apis = { &ota }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Initalize the Updater client instance used to flash binary to flash memory #ifdef ESP8266 Arduino_ESP8266_Updater updater; diff --git a/examples/0010-esp8266_esp32_rpc/0010-esp8266_esp32_rpc.ino b/examples/0010-esp8266_esp32_rpc/0010-esp8266_esp32_rpc.ino index f2dc26b4..11bedec3 100644 --- a/examples/0010-esp8266_esp32_rpc/0010-esp8266_esp32_rpc.ino +++ b/examples/0010-esp8266_esp32_rpc/0010-esp8266_esp32_rpc.ino @@ -39,7 +39,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; // Baud rate for the debugging serial connection. // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -106,7 +107,7 @@ const std::array apis = { &rpc }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Statuses for subscribing to rpc bool subscribed = false; diff --git a/examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino b/examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino index 4f4b0aba..1a211453 100644 --- a/examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino +++ b/examples/0011-esp8266_esp32_subscribe_OTA_MQTT/0011-esp8266_esp32_subscribe_OTA_MQTT.ino @@ -63,7 +63,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 512U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 512U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 512U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -122,7 +123,7 @@ const std::array apis = { &ota }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Initalize the Updater client instance used to flash binary to flash memory #ifdef ESP8266 Arduino_ESP8266_Updater updater; diff --git a/examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino b/examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino index 14aebeac..1f384f66 100644 --- a/examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino +++ b/examples/0012-esp8266_esp32_request_shared_attribute/0012-esp8266_esp32_request_shared_attribute.ino @@ -39,7 +39,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -111,7 +112,7 @@ const std::array apis = { &attr_request }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Statuses for requesting of attributes bool requestedClient = false; diff --git a/examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino b/examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino index f1c0261f..430a1da4 100644 --- a/examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino +++ b/examples/0013-esp8266_esp32_request_rpc/0013-esp8266_esp32_request_rpc.ino @@ -39,7 +39,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; // Baud rate for the debugging serial connection. // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -103,7 +104,7 @@ const std::array apis = { &rpc_request }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Statuses for subscribing to rpc bool subscribed = false; diff --git a/examples/0014-espressif_esp32_send_data/main/0014-espressif_esp32_send_data.cpp b/examples/0014-espressif_esp32_send_data/main/0014-espressif_esp32_send_data.cpp index 5559c6aa..c8c21484 100644 --- a/examples/0014-espressif_esp32_send_data/main/0014-espressif_esp32_send_data.cpp +++ b/examples/0014-espressif_esp32_send_data/main/0014-espressif_esp32_send_data.cpp @@ -38,7 +38,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; #if ENCRYPTED // See https://comodosslstore.com/resources/what-is-a-root-ca-certificate-and-how-do-i-download-it/ @@ -85,7 +86,7 @@ constexpr char HUMIDITY_KEY[] = "humidity"; // Initalize the Mqtt client instance Espressif_MQTT_Client<> mqttClient; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE); // Status for successfully connecting to the given WiFi bool wifi_connected = false; diff --git a/examples/0015-espressif_esp32_process_OTA_MQTT/main/0015-espressif_esp32_process_OTA_MQTT.cpp b/examples/0015-espressif_esp32_process_OTA_MQTT/main/0015-espressif_esp32_process_OTA_MQTT.cpp index 83565465..ed32077c 100644 --- a/examples/0015-espressif_esp32_process_OTA_MQTT/main/0015-espressif_esp32_process_OTA_MQTT.cpp +++ b/examples/0015-espressif_esp32_process_OTA_MQTT/main/0015-espressif_esp32_process_OTA_MQTT.cpp @@ -57,7 +57,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // and a little bit more for the topic we received the message on. // This has to be done at least until the issue https://github.com/espressif/esp-mqtt/issues/267 has been fixed in the esp-mqtt client, // or if an older version of the esp-mqtt client is used that does not include the possible fixes to the aforementioned issue yet. -constexpr uint16_t MAX_MESSAGE_SIZE = FIRMWARE_PACKET_SIZE + 50U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = FIRMWARE_PACKET_SIZE + 50U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = FIRMWARE_PACKET_SIZE + 50U; #if ENCRYPTED // See https://comodosslstore.com/resources/what-is-a-root-ca-certificate-and-how-do-i-download-it/ @@ -108,7 +109,7 @@ const std::array apis = { &ota }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Initalize the Updater client instance used to flash binary to flash memory SDCard_Updater<> updater(UPDAT_FILE_PATH); diff --git a/examples/0016-espressif_esp32_rpc/main/0016-espressif_esp32_rpc.cpp b/examples/0016-espressif_esp32_rpc/main/0016-espressif_esp32_rpc.cpp index 2108f7b1..a804d24d 100644 --- a/examples/0016-espressif_esp32_rpc/main/0016-espressif_esp32_rpc.cpp +++ b/examples/0016-espressif_esp32_rpc/main/0016-espressif_esp32_rpc.cpp @@ -37,7 +37,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; #if ENCRYPTED // See https://comodosslstore.com/resources/what-is-a-root-ca-certificate-and-how-do-i-download-it/ @@ -94,7 +95,7 @@ const std::array apis = { &rpc }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Status for successfully connecting to the given WiFi bool wifi_connected = false; diff --git a/examples/0017-espressif_esp32_process_shared_attribute_update/main/0017-espressif_esp32_process_shared_attribute_update.cpp b/examples/0017-espressif_esp32_process_shared_attribute_update/main/0017-espressif_esp32_process_shared_attribute_update.cpp index 04593c29..f4232e0b 100644 --- a/examples/0017-espressif_esp32_process_shared_attribute_update/main/0017-espressif_esp32_process_shared_attribute_update.cpp +++ b/examples/0017-espressif_esp32_process_shared_attribute_update/main/0017-espressif_esp32_process_shared_attribute_update.cpp @@ -37,7 +37,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Maximum amount of attributs we can request or subscribe, has to be set both in the ThingsBoard template list and Attribute_Request_Callback template list // and should be the same as the amount of variables in the passed array. If it is less not all variables will be requested or subscribed @@ -96,7 +97,7 @@ const std::array apis = { &shared_update }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); // Status for successfully connecting to the given WiFi bool wifi_connected = false; diff --git a/examples/0018-espressif_esp32_provision_device/main/0018-espressif_esp32_provision_device.cpp b/examples/0018-espressif_esp32_provision_device/main/0018-espressif_esp32_provision_device.cpp index 8f8aac11..f5914b72 100644 --- a/examples/0018-espressif_esp32_provision_device/main/0018-espressif_esp32_provision_device.cpp +++ b/examples/0018-espressif_esp32_provision_device/main/0018-espressif_esp32_provision_device.cpp @@ -42,7 +42,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 256U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 256U; #if ENCRYPTED // See https://comodosslstore.com/resources/what-is-a-root-ca-certificate-and-how-do-i-download-it/ @@ -113,7 +114,7 @@ const std::array apis = { &prov }; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); uint32_t previous_processing_time = 0U; diff --git a/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino b/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino index d9ca0947..939751cb 100644 --- a/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino +++ b/examples/0019-esp8266_esp32_send_attributes/0019-esp8266_esp32_send_attributes.ino @@ -70,7 +70,8 @@ constexpr uint16_t THINGSBOARD_PORT = 1883U; // Maximum size packets will ever be sent or received by the underlying MQTT client, // if the size is to small messages might not be sent or received messages will be discarded -constexpr uint16_t MAX_MESSAGE_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_SEND_SIZE = 128U; +constexpr uint16_t MAX_MESSAGE_RECEIVE_SIZE = 128U; // Baud rate for the debugging serial connection // If the Serial output is mangled, ensure to change the monitor speed accordingly to this variable @@ -137,7 +138,7 @@ Arduino_MQTT_Client mqttClient(espClient); // Initialize used apis const std::array apis = {}; // Initialize ThingsBoard instance with the maximum needed buffer size -ThingsBoard tb(mqttClient, MAX_MESSAGE_SIZE, Default_Max_Stack_Size, apis); +ThingsBoard tb(mqttClient, MAX_MESSAGE_RECEIVE_SIZE, MAX_MESSAGE_SEND_SIZE, Default_Max_Stack_Size, apis); #endif diff --git a/src/Arduino_MQTT_Client.cpp b/src/Arduino_MQTT_Client.cpp index 8bc92df4..3afc7988 100644 --- a/src/Arduino_MQTT_Client.cpp +++ b/src/Arduino_MQTT_Client.cpp @@ -22,12 +22,16 @@ void Arduino_MQTT_Client::set_connect_callback(Callback::function callback m_connected_callback.Set_Callback(callback); } -bool Arduino_MQTT_Client::set_buffer_size(uint16_t buffer_size) { - return m_mqtt_client.setBufferSize(buffer_size); +bool Arduino_MQTT_Client::set_buffer_size(uint16_t receive_buffer_size, uint16_t send_buffer_size) { + return m_mqtt_client.setBufferSize(receive_buffer_size, send_buffer_size); } -uint16_t Arduino_MQTT_Client::get_buffer_size() { - return m_mqtt_client.getBufferSize(); +uint16_t Arduino_MQTT_Client::get_receive_buffer_size() { + return m_mqtt_client.getReceiveBufferSize(); +} + +uint16_t Arduino_MQTT_Client::get_send_buffer_size() { + return m_mqtt_client.getSendBufferSize(); } void Arduino_MQTT_Client::set_server(char const * domain, uint16_t port) { diff --git a/src/Arduino_MQTT_Client.h b/src/Arduino_MQTT_Client.h index 5de9ea3b..b1d5356a 100644 --- a/src/Arduino_MQTT_Client.h +++ b/src/Arduino_MQTT_Client.h @@ -31,9 +31,11 @@ class Arduino_MQTT_Client : public IMQTT_Client { void set_connect_callback(Callback::function callback) override; - bool set_buffer_size(uint16_t buffer_size) override; + bool set_buffer_size(uint16_t receive_buffer_size, uint16_t send_buffer_size) override; - uint16_t get_buffer_size() override; + uint16_t get_receive_buffer_size() override; + + uint16_t get_send_buffer_size() override; void set_server(char const * domain, uint16_t port) override; diff --git a/src/Attribute_Request.h b/src/Attribute_Request.h index fc8155c0..3b3137d3 100644 --- a/src/Attribute_Request.h +++ b/src/Attribute_Request.h @@ -158,7 +158,7 @@ class Attribute_Request : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_send_json_callback.Set_Callback(send_json_callback); m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); diff --git a/src/Client_Side_RPC.h b/src/Client_Side_RPC.h index 33c7d52b..f16eb8a5 100644 --- a/src/Client_Side_RPC.h +++ b/src/Client_Side_RPC.h @@ -170,7 +170,7 @@ class Client_Side_RPC : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_send_json_callback.Set_Callback(send_json_callback); m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); diff --git a/src/Espressif_MQTT_Client.h b/src/Espressif_MQTT_Client.h index ba821b9b..f9db1f9e 100644 --- a/src/Espressif_MQTT_Client.h +++ b/src/Espressif_MQTT_Client.h @@ -218,11 +218,13 @@ class Espressif_MQTT_Client : public IMQTT_Client { m_connected_callback.Set_Callback(callback); } - bool set_buffer_size(uint16_t buffer_size) override { + bool set_buffer_size(uint16_t receive_buffer_size, uint16_t send_buffer_size) override { #if ESP_IDF_VERSION_MAJOR < 5 - m_mqtt_configuration.buffer_size = buffer_size; + m_mqtt_configuration.buffer_size = receive_buffer_size; + m_mqtt_configuration.out_buffer_size = send_buffer_size; #else - m_mqtt_configuration.buffer.size = buffer_size; + m_mqtt_configuration.buffer.size = receive_buffer_size; + m_mqtt_configuration.buffer.out_size = send_buffer_size; #endif // ESP_IDF_VERSION_MAJOR < 5 // Calls esp_mqtt_set_config(), which should adjust the underlying mqtt client to the changed values. @@ -234,7 +236,7 @@ class Espressif_MQTT_Client : public IMQTT_Client { return update_configuration(); } - uint16_t get_buffer_size() override { + uint16_t get_receive_buffer_size() override { #if ESP_IDF_VERSION_MAJOR < 5 return m_mqtt_configuration.buffer_size; #else @@ -242,6 +244,14 @@ class Espressif_MQTT_Client : public IMQTT_Client { #endif // ESP_IDF_VERSION_MAJOR < 5 } + uint16_t get_send_buffer_size() override { +#if ESP_IDF_VERSION_MAJOR < 5 + return m_mqtt_configuration.out_buffer_size; +#else + return m_mqtt_configuration.buffer.out_size; +#endif // ESP_IDF_VERSION_MAJOR < 5 + } + void set_server(char const * domain, uint16_t port) override { #if ESP_IDF_VERSION_MAJOR < 5 m_mqtt_configuration.host = domain; @@ -420,7 +430,7 @@ class Espressif_MQTT_Client : public IMQTT_Client { // Check wheter the given message has not bee received completly, but instead would be received in multiple chunks, // if it were we discard the message because receiving a message over multiple chunks is currently not supported if (event->data_len != event->total_data_len) { - Logger::printfln(MQTT_DATA_EXCEEDS_BUFFER, event->total_data_len, get_buffer_size()); + Logger::printfln(MQTT_DATA_EXCEEDS_BUFFER, event->total_data_len, get_receive_buffer_size()); break; } // Topic is not null terminated, to fix this issue we copy the topic string. diff --git a/src/IAPI_Implementation.h b/src/IAPI_Implementation.h index 0a6c40e9..74228f20 100644 --- a/src/IAPI_Implementation.h +++ b/src/IAPI_Implementation.h @@ -94,10 +94,11 @@ class IAPI_Implementation { /// @param send_json_string_callback Method which allows to send arbitrary JSON string payload, points to Send_Json_String per default /// @param subscribe_topic_callback Method which allows to subscribe to arbitrary topics, points to m_client.subscribe per default /// @param unsubscribe_topic_callback Method which allows to unsubscribe from arbitrary topics, points to m_client.unsubscribe per default - /// @param get_size_callback Method which allows to get the current underlying size of the buffer, points to m_client.get_buffer_size per default + /// @param get_receive_size_callback Method which allows to get the current underlying receive size of the buffer, points to m_client.get_receive_buffer_size per default + /// @param get_send_size_callback Method which allows to get the current underlying send size of the buffer, points to m_client.get_send_buffer_size per default /// @param set_buffer_size_callback Method which allows to set the current underlying size of the buffer, points to m_client.set_buffer_size per default /// @param get_request_id_callback Method which allows to get the current request id as a mutable reference, points to getRequestID per default - virtual void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) = 0; + virtual void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) = 0; }; #endif // IAPI_Implementation_h diff --git a/src/IMQTT_Client.h b/src/IMQTT_Client.h index 467f3cc2..0182c3b8 100644 --- a/src/IMQTT_Client.h +++ b/src/IMQTT_Client.h @@ -44,15 +44,24 @@ class IMQTT_Client { /// @brief Changes the size of the buffer for sent and received MQTT messages, /// using a bigger value than uint16_t for passing the buffer size does not make any sense because the maximum message size received /// or sent by MQTT can never be bigger than 64K, because it relies on TCP and the TCP size limit also uses a uint16_t internally for the size parameter - /// @param buffer_size Maximum amount of data that can be either received or sent via MQTT at once, - /// expected behaviour is that, if bigger packets are received they are discarded and a warning is printed to the console - /// and if we attempt to send data that is bigger, it will simply not be sent and a message is printed to the console instead - /// @return Whether allocating the needed memory for the given buffer_size was successful or not - virtual bool set_buffer_size(uint16_t buffer_size) = 0; + /// @param receive_buffer_size Maximum amount of data that can be received via MQTT at once, + /// expected behaviour is that, if bigger packets are received they are discarded and a warning is printed to the console. + /// Should be big enough to hold the biggest response that is expected to be ever received by the device at once. + /// @param send_buffer_size Maximum amount of data that can be sent via MQTT at once, + /// expected behaviour is that, if we attempt to send data that is bigger, it will simply not be sent and a message is printed to the console instead. + /// Should be big enough to hold the biggest request that is expected to be ever sent by the device at once. + /// Alternatively it is possible if THINGSBOARD_ENABLE_STREAM_UTILS is enabled, requires using the Arduino framework and simply installing StreamUtils (https://github.com/bblanchon/ArduinoStreamUtils) library, + /// to only set the value of this paramter to the same value as the buffering_size passed to the constructor + enough memory to hold the topic and MQTT Header ~= 20 bytes + /// @return Whether allocating the needed memory for the given buffer sizes was successful or not + virtual bool set_buffer_size(uint16_t receive_buffer_size, uint16_t send_buffer_size) = 0; + + /// @brief Gets the previously set size of the internal buffer size for sent MQTT data + /// @return Internal size of the buffer + virtual uint16_t get_receive_buffer_size() = 0; - /// @brief Gets the previously set size of the internal buffer size for sent and received MQTT + /// @brief Gets the previously set size of the internal buffer size for received MQTT data /// @return Internal size of the buffer - virtual uint16_t get_buffer_size() = 0; + virtual uint16_t get_send_buffer_size() = 0; /// @brief Configures the server and port that the client should connect to MQTT over, /// should be called atleast once before calling connect() so it is clear which server to connect too diff --git a/src/OTA_Firmware_Update.h b/src/OTA_Firmware_Update.h index 97fd6ebb..e8095e6b 100644 --- a/src/OTA_Firmware_Update.h +++ b/src/OTA_Firmware_Update.h @@ -58,7 +58,8 @@ class OTA_Firmware_Update : public IAPI_Implementation { , m_send_json_string_callback() , m_subscribe_topic_callback() , m_unsubscribe_topic_callback() - , m_get_size_callback() + , m_get_receive_size_callback() + , m_get_send_size_callback() , m_set_buffer_size_callback() , m_get_request_id_callback() , m_fw_callback() @@ -216,13 +217,14 @@ class OTA_Firmware_Update : public IAPI_Implementation { m_subscribe_api_callback.Call_Callback(m_fw_attribute_request); } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_subscribe_api_callback.Set_Callback(subscribe_api_callback); m_send_json_callback.Set_Callback(send_json_callback); m_send_json_string_callback.Set_Callback(send_json_string_callback); m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); - m_get_size_callback.Set_Callback(get_size_callback); + m_get_receive_size_callback.Set_Callback(get_receive_size_callback); + m_get_send_size_callback.Set_Callback(get_send_size_callback); m_set_buffer_size_callback.Set_Callback(set_buffer_size_callback); m_get_request_id_callback.Set_Callback(get_request_id_callback); } @@ -277,7 +279,7 @@ class OTA_Firmware_Update : public IAPI_Implementation { // to allow to receive ota chunck packets that might be much bigger than the normal // buffer size would allow, therefore we return to the previous value to decrease overall memory usage if (m_changed_buffer_size) { - (void)m_set_buffer_size_callback.Call_Callback(m_previous_buffer_size); + (void)m_set_buffer_size_callback.Call_Callback(m_previous_buffer_size, m_get_send_size_callback.Call_Callback()); } // Reset now not needed private member variables m_fw_callback = OTA_Update_Callback(); @@ -394,11 +396,11 @@ class OTA_Firmware_Update : public IAPI_Implementation { const uint16_t& chunk_size = m_fw_callback.Get_Chunk_Size(); // Get the previous buffer size and cache it so the previous settings can be restored. - m_previous_buffer_size = m_get_size_callback.Call_Callback(); + m_previous_buffer_size = m_get_receive_size_callback.Call_Callback(); m_changed_buffer_size = m_previous_buffer_size < (chunk_size + 50U); // Increase size of receive buffer - if (m_changed_buffer_size && !m_set_buffer_size_callback.Call_Callback(chunk_size + 50U)) { + if (m_changed_buffer_size && !m_set_buffer_size_callback.Call_Callback(chunk_size + 50U, m_get_send_size_callback.Call_Callback())) { Logger::printfln(NOT_ENOUGH_RAM); Firmware_Send_State(FW_STATE_FAILED, NOT_ENOUGH_RAM); m_fw_callback.Call_Callback(false); @@ -455,8 +457,9 @@ class OTA_Firmware_Update : public IAPI_Implementation { Callback m_send_json_string_callback = {}; // Send json string callback Callback m_subscribe_topic_callback = {}; // Subscribe mqtt topic client callback Callback m_unsubscribe_topic_callback = {}; // Unubscribe mqtt topic client callback - Callback m_get_size_callback = {}; // Get client buffer size callback - Callback m_set_buffer_size_callback = {}; // Set client buffer size callback + Callback m_get_receive_size_callback = {}; // Get client receive buffer size callback + Callback m_get_send_size_callback = {}; // Get client send buffer size callback + Callback m_set_buffer_size_callback = {}; // Set client buffer size callback Callback m_get_request_id_callback = {}; // Get internal request id callback OTA_Update_Callback m_fw_callback = {}; // OTA update response callback diff --git a/src/Provision.h b/src/Provision.h index 8ba142c3..ed028eab 100644 --- a/src/Provision.h +++ b/src/Provision.h @@ -129,7 +129,7 @@ class Provision : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_send_json_callback.Set_Callback(send_json_callback); m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); diff --git a/src/Server_Side_RPC.h b/src/Server_Side_RPC.h index 5da04c35..3f3c2003 100644 --- a/src/Server_Side_RPC.h +++ b/src/Server_Side_RPC.h @@ -197,7 +197,7 @@ class Server_Side_RPC : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_send_json_callback.Set_Callback(send_json_callback); m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); diff --git a/src/Shared_Attribute_Update.h b/src/Shared_Attribute_Update.h index 76b5a34f..89b3ec66 100644 --- a/src/Shared_Attribute_Update.h +++ b/src/Shared_Attribute_Update.h @@ -186,7 +186,7 @@ class Shared_Attribute_Update : public IAPI_Implementation { // Nothing to do } - void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { + void Set_Client_Callbacks(Callback::function subscribe_api_callback, Callback::function send_json_callback, Callback::function send_json_string_callback, Callback::function subscribe_topic_callback, Callback::function unsubscribe_topic_callback, Callback::function get_receive_size_callback, Callback::function get_send_size_callback, Callback::function set_buffer_size_callback, Callback::function get_request_id_callback) override { m_subscribe_topic_callback.Set_Callback(subscribe_topic_callback); m_unsubscribe_topic_callback.Set_Callback(unsubscribe_topic_callback); } diff --git a/src/ThingsBoard.h b/src/ThingsBoard.h index 83f6787f..1862d151 100644 --- a/src/ThingsBoard.h +++ b/src/ThingsBoard.h @@ -18,7 +18,7 @@ uint16_t constexpr DEFAULT_MQTT_PORT = 1883U; char constexpr PROV_ACCESS_TOKEN[] = "provision"; // Log messages. char constexpr UNABLE_TO_DE_SERIALIZE_JSON[] = "Unable to de-serialize received json data with error (DeserializationError::%s)"; -char constexpr INVALID_BUFFER_SIZE[] = "Buffer size (%u) to small for the given payloads size (%u), increase with setBufferSize accordingly or set THINGSBOARD_ENABLE_STREAM_UTILS to 1 before including ThingsBoard"; +char constexpr INVALID_BUFFER_SIZE[] = "Send buffer size (%u) to small for the given payloads size (%u), increase with setBufferSize accordingly or install the StreamUtils library"; char constexpr UNABLE_TO_ALLOCATE_BUFFER[] = "Allocating memory for the internal MQTT buffer failed"; char constexpr MAX_ENDPOINTS_AMOUNT_TEMPLATE_NAME[] = "MaxEndpointsAmount"; #if THINGSBOARD_ENABLE_DYNAMIC @@ -71,18 +71,14 @@ class ThingsBoardSized { /// and to the end of the data container (last element + 1) and then every element between those iteratos will be copied, in the same order as in the original data container /// @tparam ...Args Holds the multiple arguments that will simply be forwarded to the Array or Vector (THINGSBOARD_ENABLE_DYNAMIC) constructor and therefore allow to use every overloaded vector constructor without having to implement them /// @param client MQTT Client implementation that should be used to establish the connection to ThingsBoard - /// @param buffer_size Maximum amount of data that can be either received or sent to ThingsBoard at once, if bigger packets are received they are discarded - /// and if we attempt to send data that is bigger, it will not be sent, the internal value can be changed later at any time with the setBufferSize() method - /// alternatively setting THINGSBOARD_ENABLE_STREAM_UTILS to 1 allows to send arbitrary size payloads if that is done the internal buffer of the MQTT Client implementation - /// can be theoretically set to only be as big as the biggest message we should every receive from ThingsBoard, - /// this will mean though that all messages are sent over the StreamUtils library as long as they are bigger than the internal buffer, + /// @param receive_buffer_size Maximum amount of data that can be received by this device at once, if bigger packets are received they are discarded and the update lost instead, default = Default_Payload_Size (64) + /// @param send_buffer_size Maximum amount of data that can be sent from this device at once. If we attempt to send data that is bigger, it will not be sent instead. + /// Alternatively setting THINGSBOARD_ENABLE_STREAM_UTILS to 1 allows to send arbitrary size payloads if that is done the internal buffer of the MQTT Client implementation + /// can be theoretically set the value as big as the buffering_size passed to the constructor + enough memory to hold the topic and MQTT Header ~= 20 bytes. + /// This will mean though that all messages are sent over the StreamUtils library as long as they are bigger than the internal buffer, /// which needs more time than sending a message directly but has the advantage of requiring less memory. - /// So if that is a problem on the board it might be useful to enable the THINGSBOARD_ENABLE_STREAM_UTILS option - /// and decrease the internal buffer size of the mqtt client to what is needed to receive all MQTT messages, - /// that size can vary but if all ThingsBoard features are used a buffer size of 256 bytes should suffice for receiving most responses. - /// If the aforementioned feature is not enabled the buffer size might need to be much bigger though, - /// but in that case if a message was too big to be sent the user will be informed with a message to the Logger. - /// The aforementioned options can only be enabled if Arduino is used to build this library, because the StreamUtils library requires it, default = Default_Payload_Size (64) + /// So if the available heap memory is a problem on the board it might be useful to enable the THINGSBOARD_ENABLE_STREAM_UTILS option. + /// This can be done by simply using Arduino as the framework and installing the StreamUtils (https://github.com/bblanchon/ArduinoStreamUtils) library, default = Default_Payload_Size (64) /// @param max_stack_size Maximum amount of bytes we want to allocate on the stack, default = Default_Max_Stack_Size (1024) /// @param ...args Arguments that will be forwarded into the overloaded Array or Vector (THINGSBOARD_ENABLE_DYNAMIC) constructor template @@ -95,7 +91,7 @@ class ThingsBoardSized { /// especially because attempting to allocate too much memory, will cause the allocation to fail, which is checked. But if the failure of that heap allocation is subscribed for example with the heap_caps_register_failed_alloc_callback method on the ESP32, /// then that subscribed callback will be called and could theoretically restart the device. To circumvent that we can simply set the size of this variable to a value that should never be exceeded by a non malicious json payload, received by attribute requests, shared attribute updates, server-side or client-side rpc. /// If this safety feature is not required, because the heap allocation failure callback is not subscribed, then the value of the variable can simply be kept as 0, which means we will not check the received payload for its size before the allocation happens, default = Default_Max_Response_Size (0) - ThingsBoardSized(IMQTT_Client & client, uint16_t buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & buffering_size = Default_Buffering_Size, size_t const & max_response_size = Default_Max_Response_Size, Args const &... args) + ThingsBoardSized(IMQTT_Client & client, uint16_t receive_buffer_size = Default_Payload_Size, uint16_t send_buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & buffering_size = Default_Buffering_Size, size_t const & max_response_size = Default_Max_Response_Size, Args const &... args) #else /// @param max_response_size Maximum amount of bytes allocated for the interal JsonDocument structure that holds the received payload. /// Size is calculated automatically from certain characters in the received payload (',', '{', '[') but if we receive a malicious payload that contains these symbols in a string {"example":",,,,,,..."}. @@ -103,14 +99,14 @@ class ThingsBoardSized { /// especially because attempting to allocate too much memory, will cause the allocation to fail, which is checked. But if the failure of that heap allocation is subscribed for example with the heap_caps_register_failed_alloc_callback method on the ESP32, /// then that subscribed callback will be called and could theoretically restart the device. To circumvent that we can simply set the size of this variable to a value that should never be exceeded by a non malicious json payload, received by attribute requests, shared attribute updates, server-side or client-side rpc. /// If this safety feature is not required, because the heap allocation failure callback is not subscribed, then the value of the variable can simply be kept as 0, which means we will not check the received payload for its size before the allocation happens, default = Default_Max_Response_Size (0) - ThingsBoardSized(IMQTT_Client & client, uint16_t buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & max_response_size = Default_Max_Response_Size, Args const &... args) + ThingsBoardSized(IMQTT_Client & client, uint16_t receive_buffer_size = Default_Payload_Size, uint16_t send_buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & max_response_size = Default_Max_Response_Size, Args const &... args) #endif // THINGSBOARD_ENABLE_STREAM_UTILS #else #if THINGSBOARD_ENABLE_STREAM_UTILS /// @param buffering_size Amount of bytes allocated to speed up serialization, default = Default_Buffering_Size (64) - ThingsBoardSized(IMQTT_Client & client, uint16_t buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & buffering_size = Default_Buffering_Size, Args const &... args) + ThingsBoardSized(IMQTT_Client & client, uint16_t receive_buffer_size = Default_Payload_Size, uint16_t send_buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, size_t const & buffering_size = Default_Buffering_Size, Args const &... args) #else - ThingsBoardSized(IMQTT_Client & client, uint16_t buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, Args const &... args) + ThingsBoardSized(IMQTT_Client & client, uint16_t receive_buffer_size = Default_Payload_Size, uint16_t send_buffer_size = Default_Payload_Size, size_t const & max_stack_size = Default_Max_Stack_Size, Args const &... args) #endif // THINGSBOARD_ENABLE_STREAM_UTILS #endif // THINGSBOARD_ENABLE_DYNAMIC : m_client(client) @@ -128,13 +124,13 @@ class ThingsBoardSized { continue; } #if THINGSBOARD_ENABLE_STL - api->Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getRequestID, this)); + api->Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientReceiveBufferSize, this), std::bind(&ThingsBoardSized::getClientSendBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::getRequestID, this)); #else - api->Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); + api->Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientReceiveBufferSize, ThingsBoardSized::staticGetClientSendBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); #endif // THINGSBOARD_ENABLE_STL api->Initialize(); } - (void)setBufferSize(buffer_size); + (void)setBufferSize(receive_buffer_size, send_buffer_size); // Initialize callback. #if THINGSBOARD_ENABLE_STL m_client.set_data_callback(std::bind(&ThingsBoardSized::onMQTTMessage, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -183,22 +179,21 @@ class ThingsBoardSized { } #endif // THINGSBOARD_ENABLE_DYNAMIC - /// @brief Sets the size of the buffer for the underlying network client that will be used to establish the connection to ThingsBoard - /// @param buffer_size Maximum amount of data that can be either received or sent to ThingsBoard at once, if bigger packets are received they are discarded - /// and if we attempt to send data that is bigger, it will not be sent, the internal value can be changed later at any time with the setBufferSize() method - /// alternatively setting THINGSBOARD_ENABLE_STREAM_UTILS to 1 allows to send arbitrary size payloads if that is done the internal buffer of the MQTT Client implementation - /// can be theoretically set to only be as big as the biggest message we should every receive from ThingsBoard, - /// this will mean though that all messages are sent over the StreamUtils library as long as they are bigger than the internal buffer, + /// @brief Sets the size of the buffer for the underlying network client that will be used to establish the connection to ThingsBoard. + /// The internal values can be changed later again, at any time with the setBufferSize() method. Is split into two arguments, because it allows seperating the buffer that received data from the one that sends data. + /// This makes it possible to optimize the memory used and to handle received data without copying it, while sending data in between. + /// Meaning it is possible to read the values in callback functions even after you send more data from this device. + /// @param receive_buffer_size Maximum amount of data that can be received by this device at once, if bigger packets are received they are discarded and the update lost instead + /// @param send_buffer_size Maximum amount of data that can be sent from this device at once. If we attempt to send data that is bigger, it will not be sent instead. + /// Alternatively setting THINGSBOARD_ENABLE_STREAM_UTILS to 1 allows to send arbitrary size payloads if that is done the internal buffer of the MQTT Client implementation + /// can be theoretically set the value as big as the buffering_size passed to the constructor + enough memory to hold the topic and MQTT Header ~= 20 bytes. + /// This will mean though that all messages are sent over the StreamUtils library as long as they are bigger than the internal buffer, /// which needs more time than sending a message directly but has the advantage of requiring less memory. - /// So if that is a problem on the board it might be useful to enable the THINGSBOARD_ENABLE_STREAM_UTILS option - /// and decrease the internal buffer size of the mqtt client to what is needed to receive all MQTT messages, - /// that size can vary but if all ThingsBoard features are used a buffer size of 256 bytes should suffice for receiving most responses. - /// If the aforementioned feature is not enabled the buffer size might need to be much bigger though, - /// but in that case if a message was too big to be sent the user will be informed with a message to the logger implementation. - /// The aforementioned options can only be enabled if Arduino is used to build this library, because the StreamUtils library requires it - /// @return Whether allocating the needed memory for the given buffer size was successful or not - bool setBufferSize(uint16_t buffer_size) { - bool const result = m_client.set_buffer_size(buffer_size); + /// So if the available heap memory is a problem on the board it might be useful to enable the THINGSBOARD_ENABLE_STREAM_UTILS option. + /// This can be done by simply using Arduino as the framework and installing the StreamUtils (https://github.com/bblanchon/ArduinoStreamUtils) library + /// @return Whether allocating the needed memory for the given buffer sizes was successful or not + bool setBufferSize(uint16_t receive_buffer_size, uint16_t send_buffer_size) { + bool const result = m_client.set_buffer_size(receive_buffer_size, send_buffer_size); if (!result) { Logger::printfln(UNABLE_TO_ALLOCATE_BUFFER); } @@ -335,11 +330,11 @@ class ThingsBoardSized { return false; } - uint16_t currentBufferSize = m_client.get_buffer_size(); + uint16_t current_send_buffer_size = m_client.get_send_buffer_size(); size_t const json_size = strlen(json); - if (currentBufferSize < json_size) { - Logger::printfln(INVALID_BUFFER_SIZE, currentBufferSize, json_size); + if (current_send_buffer_size < json_size) { + Logger::printfln(INVALID_BUFFER_SIZE, current_send_buffer_size, json_size); return false; } @@ -360,9 +355,9 @@ class ThingsBoardSized { } #endif // !THINGSBOARD_ENABLE_DYNAMIC #if THINGSBOARD_ENABLE_STL - api.Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getRequestID, this)); + api.Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientReceiveBufferSize, this), std::bind(&ThingsBoardSized::getClientSendBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::getRequestID, this)); #else - api.Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); + api.Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientReceiveBufferSize, ThingsBoardSized::staticGetClientSendBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); #endif // THINGSBOARD_ENABLE_STL api.Initialize(); m_api_implementations.push_back(&api); @@ -391,9 +386,9 @@ class ThingsBoardSized { continue; } #if THINGSBOARD_ENABLE_STL - api->Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getRequestID, this)); + api->Set_Client_Callbacks(std::bind(&ThingsBoardSized::Subscribe_API_Implementation, this, std::placeholders::_1), std::bind(&ThingsBoardSized::Send_Json, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3), std::bind(&ThingsBoardSized::Send_Json_String, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::clientSubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::clientUnsubscribe, this, std::placeholders::_1), std::bind(&ThingsBoardSized::getClientReceiveBufferSize, this), std::bind(&ThingsBoardSized::getClientSendBufferSize, this), std::bind(&ThingsBoardSized::setBufferSize, this, std::placeholders::_1, std::placeholders::_2), std::bind(&ThingsBoardSized::getRequestID, this)); #else - api->Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); + api->Set_Client_Callbacks(ThingsBoardSized::staticSubscribeImplementation, ThingsBoardSized::staticSendJson, ThingsBoardSized::staticSendJsonString, ThingsBoardSized::staticClientSubscribe, ThingsBoardSized::staticClientUnsubscribe, ThingsBoardSized::staticGetClientReceiveBufferSize, ThingsBoardSized::staticGetClientSendBufferSize, ThingsBoardSized::staticSetBufferSize, ThingsBoardSized::staticGetRequestID); #endif // THINGSBOARD_ENABLE_STL api->Initialize(); } @@ -562,10 +557,16 @@ class ThingsBoardSized { return m_max_stack; } - /// @brief Returns the current buffer size of the underlying client interface - /// @return Current internal buffer size - uint16_t getClientBufferSize() { - return m_client.get_buffer_size(); + /// @brief Returns the current receive buffer size of the underlying client interface + /// @return Current internal send buffer size + uint16_t getClientReceiveBufferSize() { + return m_client.get_receive_buffer_size(); + } + + /// @brief Returns the current send buffer size of the underlying client interface + /// @return Current internal receive buffer size + uint16_t getClientSendBufferSize() { + return m_client.get_send_buffer_size(); } /// @brief Subscribes the given topic with the underlying client interface @@ -874,18 +875,25 @@ class ThingsBoardSized { return m_subscribedInstance->getRequestID(); } - static uint16_t staticGetClientBufferSize() { + static uint16_t staticGetClientReceiveBufferSize() { + if (m_subscribedInstance == nullptr) { + return 0U; + } + return m_subscribedInstance->getClientReceiveBufferSize(); + } + + static uint16_t staticGetClientSendBufferSize() { if (m_subscribedInstance == nullptr) { return 0U; } - return m_subscribedInstance->getClientBufferSize(); + return m_subscribedInstance->getClientSendBufferSize(); } - static bool staticSetBufferSize(uint16_t buffer_size) { + static bool staticSetBufferSize(uint16_t receive_buffer_size, uint16_t send_buffer_size) { if (m_subscribedInstance == nullptr) { return false; } - return m_subscribedInstance->setBufferSize(buffer_size); + return m_subscribedInstance->setBufferSize(receive_buffer_size, send_buffer_size); } // PubSub client cannot call a instanced method when message arrives on subscribed topic. From a04f72e83dea64bbe3a8500b6ea5c303b6ce9a6f Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Tue, 10 Dec 2024 09:45:34 +0100 Subject: [PATCH 13/14] Adjust readme to breaking API changes --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 5eff0ec4..4908a898 100644 --- a/README.md +++ b/README.md @@ -130,10 +130,10 @@ If the device is causing problems that are not already described in more detail The buffer size for the serialized JSON is fixed to 64 bytes. The SDK will not send data if the size of it is bigger than the configured internal buffer size. Respective logs in the `"Serial Monitor"` window will indicate the condition: ``` -[TB] Buffer size (64) to small for the given payloads size (83), increase with setBufferSize accordingly or set THINGSBOARD_ENABLE_STREAM_UTILS to 1 before including ThingsBoard +[TB] Send buffer size (64) to small for the given payloads size (83), increase with setBufferSize accordingly or install the StreamUtils library ``` -If that's the case, the buffer size for serialization should be increased. To do so, `setBufferSize()` method can be used or the `bufferSize` passed to the constructor can be increased as illustrated below: +If that's the case, the buffer size for serialization should be increased. To do so, `setBufferSize()` method can be used or the `send_buffer_size` passed to the constructor can be increased as illustrated below: ```cpp // Initialize underlying client, used to establish a connection @@ -146,11 +146,11 @@ Arduino_MQTT_Client mqttClient(espClient); // ThingsBoard tb(mqttClient); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128); +ThingsBoardSized<32> tb(mqttClient, 128, 128); void setup() { // Increase internal buffer size after inital creation. - tb.setBufferSize(128); + tb.setBufferSize(128, 128); } ``` @@ -204,7 +204,7 @@ Arduino_MQTT_Client mqttClient(espClient); // ThingsBoard tb(mqttClient); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128); +ThingsBoardSized<32> tb(mqttClient, 128, 128); ``` Alternatively to remove the need for the `MaxResponse`template argument in the constructor template list and to ensure the size the buffer should have is always enough to hold received messages, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This makes the library use the [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) instead of the default [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/). Be aware though as this places the json structure onto the heap. @@ -238,10 +238,10 @@ const std::array apis = { }; // The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object -// ThingsBoard tb(mqttClient, Default_Payload, apis); +// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128, apis); +ThingsBoardSized<32> tb(mqttClient, 128, 128, apis); ``` Alternatively, to remove the need for the `MaxSubscriptions` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will replace the internal implementation with a growing vector instead, meaning all the subscribed callback data will reside on the heap instead. @@ -273,10 +273,10 @@ const std::array apis = { }; // The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object -// ThingsBoard tb(mqttClient, Default_Payload, apis); +// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128, apis); +ThingsBoardSized<32> tb(mqttClient, 128, 128, apis); ``` Alternatively, to remove the need for the `MaxAttributes` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will replace the internal implementation with a growing vector instead, meaning all the subscribed attribute data will reside on the heap instead. @@ -308,10 +308,10 @@ const std::array apis = { }; // The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object -// ThingsBoard tb(mqttClient, Default_Payload, apis); +// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128, apis); +ThingsBoardSized<32> tb(mqttClient, 128, 128, apis); ``` Alternatively, to remove the need for the `MaxRPC` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This will instead expect an additional parameter response size in the `RPC_Callback` constructor argument list, which shows the internal size the [`JsonDocument`](https://arduinojson.org/v6/api/jsondocument/) needs to have to contain the response. Use `JSON_OBJECT_SIZE()` and pass the amount of key value pair to calculate the estimated size. See https://arduinojson.org/v6/assistant/ for more information. @@ -341,10 +341,10 @@ const std::array apis = { }; // The SDK setup with 64 bytes for JSON payload and 8 fields for JSON object -// ThingsBoard tb(mqttClient, Default_Payload, apis); +// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128, apis); +ThingsBoardSized<32> tb(mqttClient, 128, 128, apis); ``` Alternatively, to remove the need for the `MaxRequestRPC` template argument in the constructor template list, see the [Dynamic ThingsBoard section](https://github.com/thingsboard/thingsboard-client-sdk?tab=readme-ov-file#dynamic-thingsboard-usage) section. This makes the library use the [`DynamicJsonDocument`](https://arduinojson.org/v6/api/dynamicjsondocument/) instead of the default [`StaticJsonDocument`](https://arduinojson.org/v6/api/staticjsondocument/). Be aware though as this copies the requests onto the heap. @@ -425,10 +425,10 @@ const std::array apis = { }; // The SDK setup with 64 bytes for JSON payload, 8 fields for JSON object and maximal 7 API endpoints subscribed at once -// ThingsBoard tb(mqttClient, Default_Payload, apis); +// ThingsBoard tb(mqttClient, Default_Payload, Default_Payload, apis); // The SDK setup with 128 bytes for JSON payload and 8 fields for JSON object and maximal 10 API endpoints subscribed at once -ThingsBoardSized<8, 10> tb(mqttClient, 128, apis); +ThingsBoardSized<8, 10> tb(mqttClient, 128, 128, apis); // Optional alternative way to subscribe the Custom API ater the class instance has already been created // tb.Subscribe_IAPI_Implementation(custom_api); @@ -652,7 +652,7 @@ Custom_MQTT_Client mqttClient(espClient); // ThingsBoard tb(mqttClient); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32> tb(mqttClient, 128); +ThingsBoardSized<32> tb(mqttClient, 128, 128); ``` ### Custom Logger Instance @@ -688,7 +688,7 @@ Arduino_MQTT_Client mqttClient(espClient); // ThingsBoard tb(mqttClient); // The SDK setup with 128 bytes for JSON payload and 32 fields for JSON object -ThingsBoardSized<32, Default_Response_Amount, CustomLogger> tb(mqttClient, 128); +ThingsBoardSized<32, Default_Response_Amount, CustomLogger> tb(mqttClient, 128, 128); ``` ## Have a question or proposal? From 10fd06f78fccc366a0340455d9fd01861cad9008 Mon Sep 17 00:00:00 2001 From: MathewHDYT <48954742+MathewHDYT@users.noreply.github.com> Date: Tue, 10 Dec 2024 10:09:39 +0100 Subject: [PATCH 14/14] Bump version and inlucde required dependencies --- CMakeLists.txt | 2 +- README.md | 4 ++-- docs/Doxyfile | 2 +- idf_component.yml | 2 +- library.json | 26 ++++++++++++++++++++++---- library.properties | 4 ++-- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 77bded85..4d012d5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,4 +37,4 @@ if(ESP_PLATFORM) return() endif() -project(ThingsBoardClientSDK VERSION 0.14.1) +project(ThingsBoardClientSDK VERSION 0.15.0) diff --git a/README.md b/README.md index 4908a898..a488b5db 100644 --- a/README.md +++ b/README.md @@ -76,10 +76,10 @@ Following dependencies are installed automatically or must be installed, too: **Installed automatically:** - [ArduinoJSON](https://github.com/bblanchon/ArduinoJson) — needed for dealing with the `JSON` payload that is sent to and received by `ThingsBoard`. _Please Note:_ you must use `v6.x.x` of this library as `v7.x.x` is not yet supported. Please see [this issue](https://github.com/thingsboard/thingsboard-client-sdk/issues/186#issuecomment-1877641466) for details as to why. + - [MQTT PubSub Client](https://github.com/thingsboard/pubsubclient) — for interacting with `MQTT`, when using the `Arduino_MQTT_Client` instance as an argument to `ThingsBoard`. Only installed if this library is used over `Arduino IDE` or `PlatformIO` with the Arduino framework. + - [Arduino Http Client](https://github.com/arduino-libraries/ArduinoHttpClient) — for interacting with `HTTP/S` when using the `Arduino_HTTP_Client` instance as an argument to `ThingsBoardHttp`. Only installed if this library is used over `Arduino IDE` or `PlatformIO` with the Arduino framework. **Needs to be installed manually:** - - [MQTT PubSub Client](https://github.com/thingsboard/pubsubclient) — for interacting with `MQTT`, when using the `Arduino_MQTT_Client` instance as an argument to `ThingsBoard`. - - [Arduino Http Client](https://github.com/arduino-libraries/ArduinoHttpClient) — for interacting with `HTTP/S` when using the `Arduino_HTTP_Client` instance as an argument to `ThingsBoardHttp`. - [MbedTLS Library](https://github.com/Seeed-Studio/Seeed_Arduino_mbedtls) — needed to create hashes for the OTA update for non `Espressif` boards. - [Arduino Timer](https://github.com/contrem/arduino-timer) - needed to create non-blocking callback timers for non `Espressif` boards. - [WiFiEsp Client](https://github.com/bportaluri/WiFiEsp) — needed when using a `Arduino Uno` with a `ESP8266`. diff --git a/docs/Doxyfile b/docs/Doxyfile index 0c7beed8..7d9828e8 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = "ThingsBoard Client SDK" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.14.1 +PROJECT_NUMBER = 0.15.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/idf_component.yml b/idf_component.yml index a5344fe9..4314af47 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -1,4 +1,4 @@ -version: "0.14.1" +version: "0.15.0" description: Provides access to ThingsBoard platform over the MQTT protocol or alternatively over HTTP/S. url: https://github.com/thingsboard/thingsboard-client-sdk dependencies: diff --git a/library.json b/library.json index 66e232c5..c8ae2b25 100644 --- a/library.json +++ b/library.json @@ -6,10 +6,28 @@ "type": "git", "url": "https://github.com/thingsboard/thingsboard-client-sdk" }, - "dependencies": { - "bblanchon/ArduinoJson": "^6.21.5" - }, - "version": "0.14.1", + "dependencies": + [ + { + "owner": "bblanchon", + "name": "ArduinoJson", + "version": "^6.21.5" + }, + { + "owner": "thingsboard", + "name": "TBPubSubClient", + "version": "^2.11.0", + "frameworks": ["arduino"] + }, + { + "owner": "arduino-libraries", + "name": "ArduinoHttpClient", + "version": "^0.6.1", + "frameworks": ["arduino"] + }, + "Update" + ], + "version": "0.15.0", "examples": "examples/*/*.ino", "frameworks": "*", "license": "MIT" diff --git a/library.properties b/library.properties index 008d6739..9454738c 100644 --- a/library.properties +++ b/library.properties @@ -1,6 +1,6 @@ # See https://arduino.github.io/arduino-cli/0.35/library-specification/#libraryproperties-file-format for more information on the formatting name=ThingsBoard -version=0.14.1 +version=0.15.0 author=ThingsBoard Team maintainer=ThingsBoard Team sentence=ThingsBoard library for Arduino. @@ -9,4 +9,4 @@ category=Communication url=https://github.com/thingsboard/thingsboard-client-sdk architectures=* includes=ThingsBoard.h -depends=ArduinoJson (=6.21.5) +depends=ArduinoJson (=6.21.5), TBPubSubClient (>=2.11.0), ArduinoHttpClient (>=0.6.1)