From 159b1638b283bdd5aa6dc69ffcc9f580961d120c Mon Sep 17 00:00:00 2001 From: Euripedes Rocha Date: Mon, 17 Oct 2022 12:21:52 +0200 Subject: [PATCH] Reorganize mqtt build structure - Integrate build definitions from idf - Changes CMakeLists to allow import - Added host test from idf - Added test code from idf --- CMakeLists.txt | 18 ++ components/mqtt/Kconfig => Kconfig | 7 + components/mqtt/CMakeLists.txt | 13 - components/mqtt/esp-mqtt | 1 - components/mqtt/host_test/mocks/config.yaml | 25 -- .../mocks/include/freertos/FreeRTOSConfig.h | 133 -------- .../mocks/include/freertos/portmacro.h | 177 ----------- .../host_test/mocks/include/machine/endian.h | 2 - components/mqtt/test/CMakeLists.txt | 9 - components/mqtt/test/Kconfig | 14 - components/mqtt/test/test_mqtt.c | 108 ------- components/mqtt/test/test_mqtt5.c | 151 ---------- .../mqtt/test/test_mqtt5_client_broker.c | 285 ------------------ .../mqtt/test/test_mqtt5_client_broker.h | 51 ---- .../mqtt/test/test_mqtt_client_broker.c | 227 -------------- .../mqtt/test/test_mqtt_client_broker.h | 50 --- components/mqtt/test/test_mqtt_connection.c | 144 --------- components/mqtt/test/test_mqtt_connection.h | 18 -- .../host_test => host_test}/CMakeLists.txt | 1 + .../mqtt/host_test => host_test}/README.md | 0 .../main/CMakeLists.txt | 0 .../main/test_mqtt_client.cpp | 5 + host_test/mocks/heap/CMakeLists.txt | 4 + host_test/mocks/heap/heap_mock.c | 11 + .../mocks/include/sys/queue.h | 0 .../sdkconfig.defaults | 0 idf_component.yml | 5 + mqtt_client.c | 5 + 28 files changed, 56 insertions(+), 1408 deletions(-) create mode 100644 CMakeLists.txt rename components/mqtt/Kconfig => Kconfig (96%) delete mode 100644 components/mqtt/CMakeLists.txt delete mode 160000 components/mqtt/esp-mqtt delete mode 100644 components/mqtt/host_test/mocks/config.yaml delete mode 100644 components/mqtt/host_test/mocks/include/freertos/FreeRTOSConfig.h delete mode 100644 components/mqtt/host_test/mocks/include/freertos/portmacro.h delete mode 100644 components/mqtt/host_test/mocks/include/machine/endian.h delete mode 100644 components/mqtt/test/CMakeLists.txt delete mode 100644 components/mqtt/test/Kconfig delete mode 100644 components/mqtt/test/test_mqtt.c delete mode 100644 components/mqtt/test/test_mqtt5.c delete mode 100644 components/mqtt/test/test_mqtt5_client_broker.c delete mode 100644 components/mqtt/test/test_mqtt5_client_broker.h delete mode 100644 components/mqtt/test/test_mqtt_client_broker.c delete mode 100644 components/mqtt/test/test_mqtt_client_broker.h delete mode 100644 components/mqtt/test/test_mqtt_connection.c delete mode 100644 components/mqtt/test/test_mqtt_connection.h rename {components/mqtt/host_test => host_test}/CMakeLists.txt (94%) rename {components/mqtt/host_test => host_test}/README.md (100%) rename {components/mqtt/host_test => host_test}/main/CMakeLists.txt (100%) rename {components/mqtt/host_test => host_test}/main/test_mqtt_client.cpp (97%) create mode 100644 host_test/mocks/heap/CMakeLists.txt create mode 100644 host_test/mocks/heap/heap_mock.c rename {components/mqtt/host_test => host_test}/mocks/include/sys/queue.h (100%) rename {components/mqtt/host_test => host_test}/sdkconfig.defaults (100%) create mode 100644 idf_component.yml diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1fce7fb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +set(srcs mqtt_client.c lib/mqtt_msg.c lib/mqtt_outbox.c lib/platform_esp32_idf.c) + +if(CONFIG_MQTT_PROTOCOL_5) + list(APPEND srcs lib/mqtt5_msg.c mqtt5_client.c) +endif() + +list(TRANSFORM srcs PREPEND ${CMAKE_CURRENT_LIST_DIR}/) +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/include + PRIV_INCLUDE_DIRS ${CMAKE_CURRENT_LIST_DIR}/lib/include + REQUIRES esp_event tcp_transport + PRIV_REQUIRES esp_timer http_parser esp_hw_support heap + KCONFIG ${CMAKE_CURRENT_LIST_DIR}/Kconfig + ) +target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") + + + diff --git a/components/mqtt/Kconfig b/Kconfig similarity index 96% rename from components/mqtt/Kconfig rename to Kconfig index 4db6e15..113bac7 100644 --- a/components/mqtt/Kconfig +++ b/Kconfig @@ -124,6 +124,13 @@ menu "ESP-MQTT Configurations" help MQTT task priority. Higher number denotes higher priority. + config MQTT_EVENT_QUEUE_SIZE + int "Number of queued events." + default 1 + depends on MQTT_USE_CUSTOM_CONFIG + help + A value higher than 1 enables multiple queued events. + config MQTT_TASK_CORE_SELECTION_ENABLED bool "Enable MQTT task core selection" help diff --git a/components/mqtt/CMakeLists.txt b/components/mqtt/CMakeLists.txt deleted file mode 100644 index 29aa349..0000000 --- a/components/mqtt/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -set(srcs esp-mqtt/mqtt_client.c esp-mqtt/lib/mqtt_msg.c esp-mqtt/lib/mqtt_outbox.c esp-mqtt/lib/platform_esp32_idf.c) - -if(CONFIG_MQTT_PROTOCOL_5) - list(APPEND srcs esp-mqtt/lib/mqtt5_msg.c esp-mqtt/mqtt5_client.c) -endif() - -idf_component_register(SRCS "${srcs}" - INCLUDE_DIRS esp-mqtt/include - PRIV_INCLUDE_DIRS "esp-mqtt/lib/include" - REQUIRES esp_event tcp_transport - PRIV_REQUIRES esp_timer http_parser esp_hw_support - ) -target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt deleted file mode 160000 index ae53d79..0000000 --- a/components/mqtt/esp-mqtt +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ae53d799da294f03ef65c33e88fa33648e638134 diff --git a/components/mqtt/host_test/mocks/config.yaml b/components/mqtt/host_test/mocks/config.yaml deleted file mode 100644 index cdaab2a..0000000 --- a/components/mqtt/host_test/mocks/config.yaml +++ /dev/null @@ -1,25 +0,0 @@ - :cmock: - :plugins: - - expect - - expect_any_args - - return_thru_ptr - - ignore - - array - - callback - :includes_h_pre_orig_header: - - local_FreeRTOS_config.h - - esp_attr.h - - FreeRTOS.h - - net/if.h - :strippables: - - '(?:__attribute__\s*\(+.*?\)+)' - - '(?:vQueueAddToRegistry\s*\(+.*?\)+)' - - '(?:vQueueUnregisterQueue\s*\(+.*?\)+)' - - '(?:pcQueueGetName\s*\(+.*?\)+)' - - '(?:xQueueTakeMutexRecursive\s*\(+.*?\)+)' - - '(?:xQueueGiveMutexRecursive\s*\(+.*?\)+)' - - '(?:vTaskSetThreadLocalStoragePointerAndDelCallback\s*\(+.*?\)+)' - - '(?:esp_log_writev\s*\(+.*?\)+)' - - '(?:esp_restart\s*\(+.*?\)+)' - - '(?:esp_system_abort\s*\(+.*?\)+)' - - PRIVILEGED_FUNCTION diff --git a/components/mqtt/host_test/mocks/include/freertos/FreeRTOSConfig.h b/components/mqtt/host_test/mocks/include/freertos/FreeRTOSConfig.h deleted file mode 100644 index 0492f81..0000000 --- a/components/mqtt/host_test/mocks/include/freertos/FreeRTOSConfig.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd. - All rights reserved - - VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. - - This file is part of the FreeRTOS distribution. - - FreeRTOS is free software; you can redistribute it and/or modify it under - the terms of the GNU General Public License (version 2) as published by the - Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. - - *************************************************************************** - >>! NOTE: The modification to the GPL is included to allow you to !<< - >>! distribute a combined work that includes FreeRTOS without being !<< - >>! obliged to provide the source code for proprietary components !<< - >>! outside of the FreeRTOS kernel. !<< - *************************************************************************** - - FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. Full license text is available on the following - link: http://www.freertos.org/a00114.html - - *************************************************************************** - * * - * FreeRTOS provides completely free yet professionally developed, * - * robust, strictly quality controlled, supported, and cross * - * platform software that is more than just the market leader, it * - * is the industry's de facto standard. * - * * - * Help yourself get started quickly while simultaneously helping * - * to support the FreeRTOS project by purchasing a FreeRTOS * - * tutorial book, reference manual, or both: * - * http://www.FreeRTOS.org/Documentation * - * * - *************************************************************************** - - http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading - the FAQ page "My application does not run, what could be wrong?". Have you - defined configASSERT()? - - http://www.FreeRTOS.org/support - In return for receiving this top quality - embedded software for free we request you assist our global community by - participating in the support forum. - - http://www.FreeRTOS.org/training - Investing in training allows your team to - be as productive as possible as early as possible. Now you can receive - FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers - Ltd, and the world's leading authority on the world's leading RTOS. - - http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, - including FreeRTOS+Trace - an indispensable productivity tool, a DOS - compatible FAT file system, and our tiny thread aware UDP/IP stack. - - http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. - Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. - - http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High - Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS - licenses offer ticketed support, indemnification and commercial middleware. - - http://www.SafeRTOS.com - High Integrity Systems also provide a safety - engineered and independently SIL3 certified version for use in safety and - mission critical applications that require provable dependability. - - 1 tab == 4 spaces! -*/ - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -#include "esp_attr.h" - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -#define configUSE_PREEMPTION 1 -#define configUSE_IDLE_HOOK 1 -#define configUSE_TICK_HOOK 1 -#define configTICK_RATE_HZ ((TickType_t)1000) -#define configMINIMAL_STACK_SIZE ((unsigned short)256) /* This can be made smaller if required. */ -#define configTOTAL_HEAP_SIZE ((size_t)(32 * 1024)) -#define configMAX_TASK_NAME_LEN (16) -#define configUSE_TRACE_FACILITY 1 -#define configUSE_16_BIT_TICKS 1 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_CO_ROUTINES 1 -#define configUSE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configUSE_ALTERNATIVE_API 0 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configCHECK_FOR_STACK_OVERFLOW 0 /* Do not use this option on the PC port. */ -#define configUSE_APPLICATION_TASK_TAG 1 -#define configQUEUE_REGISTRY_SIZE 0 - -#define configMAX_PRIORITIES (10) -#define configMAX_CO_ROUTINE_PRIORITIES (2) - -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ - -#define INCLUDE_vTaskPrioritySet 1 -#define INCLUDE_uxTaskPriorityGet 1 -#define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 1 -#define INCLUDE_vTaskSuspend 1 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 0 /* Do not use this option on the PC port. */ - -/* This demo makes use of one or more example stats formatting functions. These -format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within -FreeRTOS/Source/tasks.c for limitations. */ -#define configUSE_STATS_FORMATTING_FUNCTIONS 1 - -/* An example "task switched in" hook macro definition. */ -#define traceTASK_SWITCHED_IN() xTaskCallApplicationTaskHook(NULL, (void*)0xabcd) - -extern void vMainQueueSendPassed(void); -#define traceQUEUE_SEND(pxQueue) vMainQueueSendPassed() - -#endif /* FREERTOS_CONFIG_H */ diff --git a/components/mqtt/host_test/mocks/include/freertos/portmacro.h b/components/mqtt/host_test/mocks/include/freertos/portmacro.h deleted file mode 100644 index 23c3d6e..0000000 --- a/components/mqtt/host_test/mocks/include/freertos/portmacro.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * FreeRTOS Kernel V10.4.3 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ -#ifndef PORTMACRO_H -#define PORTMACRO_H - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __ASSEMBLER__ - -/*----------------------------------------------------------- - * Port specific definitions. - * - * The settings in this file configure FreeRTOS correctly for the - * given hardware and compiler. - * - * These settings should not be altered. - *----------------------------------------------------------- - */ - -/* Type definitions. */ -#define portCHAR uint8_t -#define portFLOAT float -#define portDOUBLE double -#define portLONG int32_t -#define portSHORT int16_t -#define portSTACK_TYPE uint8_t -#define portBASE_TYPE int -// interrupt module will mask interrupt with priority less than threshold -#define RVHAL_EXCM_LEVEL 4 - -typedef portSTACK_TYPE StackType_t; -typedef portBASE_TYPE BaseType_t; -typedef unsigned portBASE_TYPE UBaseType_t; - -#if (configUSE_16_BIT_TICKS == 1) -typedef uint16_t TickType_t; -#define portMAX_DELAY (TickType_t)0xffff -#else -typedef uint32_t TickType_t; -#define portMAX_DELAY (TickType_t)0xffffffffUL -#endif -/*------------------------------------------------------*/ - -/* Architecture specifics. */ -#define portSTACK_GROWTH (-1) -#define portTICK_PERIOD_MS ((TickType_t)(1000 / configTICK_RATE_HZ)) -#define portBYTE_ALIGNMENT 16 -/*-----------------------------------------------------------*/ - -#define portCRITICAL_NESTING_IN_TCB 0 - -/* - * Send an interrupt to another core in order to make the task running - * on it yield for a higher-priority task. - */ -void vPortYieldOtherCore(BaseType_t coreid); - -/* - Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack - watchpoint around. - */ -void vPortSetStackWatchpoint(void *pxStackStart); - -/* - * Returns true if the current core is in ISR context; low prio ISR, med prio ISR or timer tick ISR. High prio ISRs - * aren't detected here, but they normally cannot call C code, so that should not be an issue anyway. - */ -BaseType_t xPortInIsrContext(void); - -/* - * This function will be called in High prio ISRs. Returns true if the current core was in ISR context - * before calling into high prio ISR context. - */ -BaseType_t xPortInterruptedFromISRContext(void); - -/* "mux" data structure (spinlock) */ -typedef struct { - /* owner field values: - * 0 - Uninitialized (invalid) - * portMUX_FREE_VAL - Mux is free, can be locked by either CPU - * CORE_ID_REGVAL_PRO / CORE_ID_REGVAL_APP - Mux is locked to the particular core - * - * - * Any value other than portMUX_FREE_VAL, CORE_ID_REGVAL_PRO, CORE_ID_REGVAL_APP indicates corruption - */ - uint32_t owner; - /* count field: - * If mux is unlocked, count should be zero. - * If mux is locked, count is non-zero & represents the number of recursive locks on the mux. - */ - uint32_t count; -} portMUX_TYPE; - -#define portMUX_FREE_VAL SPINLOCK_FREE - -/* Special constants for vPortCPUAcquireMutexTimeout() */ -#define portMUX_NO_TIMEOUT SPINLOCK_WAIT_FOREVER /* When passed for 'timeout_cycles', spin forever if necessary */ -#define portMUX_TRY_LOCK SPINLOCK_NO_WAIT /* Try to acquire the spinlock a single time only */ - -// Keep this in sync with the portMUX_TYPE struct definition please. -#define portMUX_INITIALIZER_UNLOCKED \ - { .owner = portMUX_FREE_VAL, .count = 0, } - -/* Scheduler utilities. */ -extern void vPortYield(void); -extern void vPortYieldFromISR(void); - -#define portYIELD() vPortYield() -#define portYIELD_FROM_ISR() vPortYieldFromISR() - -/* Yielding within an API call (when interrupts are off), means the yield should be delayed - until interrupts are re-enabled. - To do this, we use the "cross-core" interrupt as a trigger to yield on this core when interrupts are re-enabled.This - is the same interrupt & code path which is used to trigger a yield between CPUs, although in this case the yield is - happening on the same CPU. -*/ -#define portYIELD_WITHIN_API() portYIELD() -/*-----------------------------------------------------------*/ - -/* Critical section management. */ -extern int vPortSetInterruptMask(void); -extern void vPortClearInterruptMask(int); - -extern void vPortEnterCritical(void); -extern void vPortExitCritical(void); - -/* Task function macros as described on the FreeRTOS.org WEB site. */ -#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void* pvParameters) -#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void* pvParameters) - -void vApplicationSleep(TickType_t xExpectedIdleTime); -#define portSUPPRESS_TICKS_AND_SLEEP(idleTime) vApplicationSleep(idleTime) - -#define portNOP() //__asm volatile ( " nop " ) - -#define portVALID_TCB_MEM(ptr) // esp_ptr_byte_accessible(ptr) -#define portVALID_STACK_MEM(ptr) // esp_ptr_byte_accessible(ptr) - -#endif //__ASSEMBLER__ - -#ifdef __cplusplus -} -#endif - -#endif /* PORTMACRO_H */ diff --git a/components/mqtt/host_test/mocks/include/machine/endian.h b/components/mqtt/host_test/mocks/include/machine/endian.h deleted file mode 100644 index 228316d..0000000 --- a/components/mqtt/host_test/mocks/include/machine/endian.h +++ /dev/null @@ -1,2 +0,0 @@ -#pragma once -#include_next diff --git a/components/mqtt/test/CMakeLists.txt b/components/mqtt/test/CMakeLists.txt deleted file mode 100644 index 616d362..0000000 --- a/components/mqtt/test/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(srcs test_mqtt_client_broker.c test_mqtt_connection.c test_mqtt.c) - -if(CONFIG_MQTT_PROTOCOL_5) - list(APPEND srcs test_mqtt5_client_broker.c test_mqtt5.c) -endif() - -idf_component_register(SRCS "${srcs}" - PRIV_REQUIRES cmock test_utils mqtt nvs_flash app_update esp_eth esp_netif) - target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format") diff --git a/components/mqtt/test/Kconfig b/components/mqtt/test/Kconfig deleted file mode 100644 index 30b2c10..0000000 --- a/components/mqtt/test/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -menu "ESP-MQTT Unit Test Config" - - config MQTT_TEST_BROKER_URI - string "URI of the test broker" - default "mqtt://mqtt.eclipseprojects.io" - help - URL of an mqtt broker which this test connects to. - - config MQTT5_TEST_BROKER_URI - string "URI of the test broker" - default "mqtt://mqtt.eclipseprojects.io" - help - URL of an mqtt broker which this test connects to. -endmenu diff --git a/components/mqtt/test/test_mqtt.c b/components/mqtt/test/test_mqtt.c deleted file mode 100644 index d997bce..0000000 --- a/components/mqtt/test/test_mqtt.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - * - * This test code is in the Public Domain (or CC0 licensed, at your option.) - * - * Unless required by applicable law or agreed to in writing, this - * software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - * CONDITIONS OF ANY KIND, either express or implied. - */ - -#include -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "unity.h" -#include "test_utils.h" -#include "memory_checks.h" -#include "mqtt_client.h" -#include "nvs_flash.h" -#include "esp_ota_ops.h" -#include "sdkconfig.h" -#include "test_mqtt_client_broker.h" -#include "test_mqtt_connection.h" -#include "esp_mac.h" - -static void test_leak_setup(const char * file, long line) -{ - uint8_t mac[6]; - struct timeval te; - gettimeofday(&te, NULL); // get current time - esp_read_mac(mac, ESP_MAC_WIFI_STA); - printf("%s:%ld: time=%jd.%lds, mac:" MACSTR "\n", file, line, (intmax_t)te.tv_sec, te.tv_usec, MAC2STR(mac)); - test_utils_record_free_mem(); -} - -TEST_CASE("mqtt init with invalid url", "[mqtt][leaks=0]") -{ - test_leak_setup(__FILE__, __LINE__); - const esp_mqtt_client_config_t mqtt_cfg = { - .broker.address.uri = "INVALID", - }; - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_EQUAL(NULL, client ); -} - -TEST_CASE("mqtt init and deinit", "[mqtt][leaks=0]") -{ - test_leak_setup(__FILE__, __LINE__); - const esp_mqtt_client_config_t mqtt_cfg = { - // no connection takes place, but the uri has to be valid for init() to succeed - .broker.address.uri = "mqtts://localhost:8883", - }; - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_NOT_EQUAL(NULL, client ); - esp_mqtt_client_destroy(client); -} - -static const char* this_bin_addr(void) -{ - spi_flash_mmap_handle_t out_handle; - const void *binary_address; - const esp_partition_t* partition = esp_ota_get_running_partition(); - esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &binary_address, &out_handle); - return binary_address; -} - -TEST_CASE("mqtt enqueue and destroy outbox", "[mqtt][leaks=0]") -{ - const char * bin_addr = this_bin_addr(); - test_leak_setup(__FILE__, __LINE__); - const int messages = 20; - const int size = 2000; - const esp_mqtt_client_config_t mqtt_cfg = { - // no connection takes place, but the uri has to be valid for init() to succeed - .broker.address.uri = "mqtts://localhost:8883", - }; - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_NOT_EQUAL(NULL, client ); - int bytes_before = esp_get_free_heap_size(); - for (int i=0; i -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "unity.h" -#include "test_utils.h" -#include "memory_checks.h" -#include "mqtt_client.h" -#include "nvs_flash.h" -#include "esp_ota_ops.h" -#include "sdkconfig.h" -#include "test_mqtt5_client_broker.h" -#include "test_mqtt_connection.h" -#include "esp_mac.h" - -static esp_mqtt5_user_property_item_t user_property_arr[3] = { - {"board", "esp32"}, - {"u", "user"}, - {"p", "password"} -}; - -static void test_leak_setup(const char * file, long line) -{ - uint8_t mac[6]; - struct timeval te; - gettimeofday(&te, NULL); // get current time - esp_read_mac(mac, ESP_MAC_WIFI_STA); - printf("%s:%ld: time=%ld.%lds, mac:" MACSTR "\n", file, line, te.tv_sec, te.tv_usec, MAC2STR(mac)); - test_utils_record_free_mem(); -} - -TEST_CASE("mqtt5 init with invalid url", "[mqtt5][leaks=0]") -{ - test_leak_setup(__FILE__, __LINE__); - const esp_mqtt_client_config_t mqtt5_cfg = { - .broker.address.uri = "INVALID", - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - TEST_ASSERT_EQUAL(NULL, client ); -} - -TEST_CASE("mqtt5 init and deinit", "[mqtt5][leaks=0]") -{ - test_leak_setup(__FILE__, __LINE__); - const esp_mqtt_client_config_t mqtt5_cfg = { - // no connection takes place, but the uri has to be valid for init() to succeed - .broker.address.uri = "mqtts://localhost:8883", - .session.protocol_ver = MQTT_PROTOCOL_V_5, - .credentials.username = "123", - .credentials.authentication.password = "456", - .session.last_will.topic = "/topic/will", - .session.last_will.msg = "i will leave", - .session.last_will.msg_len = 12, - .session.last_will.qos = 1, - .session.last_will.retain = true, - }; - esp_mqtt5_connection_property_config_t connect_property = { - .session_expiry_interval = 10, - .maximum_packet_size = 1024, - .receive_maximum = 65535, - .topic_alias_maximum = 2, - .request_resp_info = true, - .request_problem_info = true, - .will_delay_interval = 10, - .payload_format_indicator = true, - .message_expiry_interval = 10, - .content_type = "json", - .response_topic = "/test/response", - .correlation_data = "123456", - .correlation_data_len = 6, - }; - - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, 3); - esp_mqtt5_client_set_user_property(&connect_property.will_user_property, user_property_arr, 3); - esp_mqtt5_client_set_connect_property(client, &connect_property); - esp_mqtt5_client_delete_user_property(connect_property.user_property); - esp_mqtt5_client_delete_user_property(connect_property.will_user_property); - TEST_ASSERT_NOT_EQUAL(NULL, client ); - esp_mqtt_client_destroy(client); -} - -static const char* this_bin_addr(void) -{ - spi_flash_mmap_handle_t out_handle; - const void *binary_address; - const esp_partition_t* partition = esp_ota_get_running_partition(); - esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &binary_address, &out_handle); - return binary_address; -} - -TEST_CASE("mqtt5 enqueue and destroy outbox", "[mqtt5][leaks=0]") -{ - const char * bin_addr = this_bin_addr(); - test_leak_setup(__FILE__, __LINE__); - const int messages = 20; - const int size = 2000; - const esp_mqtt_client_config_t mqtt5_cfg = { - // no connection takes place, but the uri has to be valid for init() to succeed - .broker.address.uri = "mqtts://localhost:8883", - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - esp_mqtt5_publish_property_config_t publish_property = { - .payload_format_indicator = 1, - .message_expiry_interval = 1000, - .topic_alias = 0, - .response_topic = "/topic/test/response", - .correlation_data = "123456", - .correlation_data_len = 6, - .content_type = "json", - }; - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - TEST_ASSERT_NOT_EQUAL(NULL, client ); - int bytes_before = esp_get_free_heap_size(); - for (int i = 0; i < messages; i ++) { - esp_mqtt5_client_set_user_property(&publish_property.user_property, user_property_arr, 3); - esp_mqtt5_client_set_publish_property(client, &publish_property); - esp_mqtt_client_publish(client, "test", bin_addr, size, 1, 0); - esp_mqtt5_client_delete_user_property(publish_property.user_property); - publish_property.user_property = NULL; - } - int bytes_after = esp_get_free_heap_size(); - // check that outbox allocated all messages on heap - TEST_ASSERT_GREATER_OR_EQUAL(messages*size, bytes_before - bytes_after); - - esp_mqtt_client_destroy(client); -} - -#if SOC_EMAC_SUPPORTED -/** - * This test cases uses ethernet kit, so build and use it only if EMAC supported - */ -TEST_CASE("mqtt5 broker tests", "[mqtt5][test_env=UT_T2_Ethernet]") -{ - test_case_uses_tcpip(); - connect_test_fixture_setup(); - - RUN_MQTT5_BROKER_TEST(mqtt5_connect_disconnect); - RUN_MQTT5_BROKER_TEST(mqtt5_subscribe_publish); - RUN_MQTT5_BROKER_TEST(mqtt5_lwt_clean_disconnect); - RUN_MQTT5_BROKER_TEST(mqtt5_subscribe_payload); - - connect_test_fixture_teardown(); -} -#endif // SOC_EMAC_SUPPORTED diff --git a/components/mqtt/test/test_mqtt5_client_broker.c b/components/mqtt/test/test_mqtt5_client_broker.c deleted file mode 100644 index ced44e9..0000000 --- a/components/mqtt/test/test_mqtt5_client_broker.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "mqtt_client.h" -#include "esp_log.h" -#include "esp_mac.h" - -#define WAIT_FOR_EVENT(event) \ - TEST_ASSERT_TRUE(xEventGroupWaitBits(s_event_group, event, pdTRUE, pdTRUE, pdMS_TO_TICKS(COMMON_OPERATION_TIMEOUT)) & event); - -#define TEST_ASSERT_TRUE(condition) TEST_ASSERT_TRUE_LINE(condition, __LINE__) -#define TEST_ASSERT_TRUE_LINE(condition, line) \ - do { \ - if (!(condition)) { \ - ESP_LOGE("test_mqtt5_client_broker.c", \ - "Assertion failed in line %d", line); \ - return false; \ - } \ - } while(0) - - -static const int COMMON_OPERATION_TIMEOUT = 10000; -static const int CONNECT_BIT = BIT0; -static const int DISCONNECT_BIT = BIT1; -static const int DATA_BIT = BIT2; - -static EventGroupHandle_t s_event_group; - -static esp_mqtt5_user_property_item_t user_property_arr[3] = { - {"board", "esp32"}, - {"u", "user"}, - {"p", "password"} -}; - -static char* append_mac(const char* string) -{ - uint8_t mac[6]; - char *id_string = NULL; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - asprintf(&id_string, "%s_%02x%02X%02X", string, mac[3], mac[4], mac[5]); - return id_string; -} - -static void mqtt5_data_handler_qos(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_DATA) { - esp_mqtt_event_handle_t event = event_data; - int * qos = handler_args; - *qos = event->qos; - xEventGroupSetBits(s_event_group, DATA_BIT); - } -} - -static void mqtt5_data_handler_lwt(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_DATA) { - esp_mqtt_event_handle_t event = event_data; - ESP_LOGI("mqtt-lwt", "MQTT_EVENT_DATA"); - ESP_LOGI("mqtt-lwt", "TOPIC=%.*s", event->topic_len, event->topic); - ESP_LOGI("mqtt-lwt", "DATA=%.*s", event->data_len, event->data); - if (strncmp(event->data, "no-lwt", event->data_len) == 0) { - // no lwt, just to indicate the test has finished - xEventGroupSetBits(s_event_group, DATA_BIT); - } else { - // count up any potential lwt message - int * count = handler_args; - *count = *count + 1; - ESP_LOGE("mqtt5-lwt", "count=%d", *count); - } - } -} - -static void mqtt5_data_handler_subscribe(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_SUBSCRIBED) { - esp_mqtt_event_handle_t event = event_data; - ESP_LOGI("mqtt5-subscribe", "MQTT_EVENT_SUBSCRIBED, data size=%d", event->data_len); - int * sub_payload = handler_args; - if (event->data_len == 1) { - ESP_LOGI("mqtt5-subscribe", "DATA=%d", *(uint8_t*)event->data); - *sub_payload = *(uint8_t*)event->data; - } - xEventGroupSetBits(s_event_group, DATA_BIT); - } -} - - -static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - switch ((esp_mqtt_event_id_t)event_id) { - case MQTT_EVENT_CONNECTED: - xEventGroupSetBits(s_event_group, CONNECT_BIT); - break; - - case MQTT_EVENT_DISCONNECTED: - xEventGroupSetBits(s_event_group, DISCONNECT_BIT); - break; - default: - break; - } -} - -bool mqtt5_connect_disconnect(void) -{ - const esp_mqtt_client_config_t mqtt5_cfg = { - .broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI, - .network.disable_auto_reconnect = true, - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - esp_mqtt5_connection_property_config_t connect_property = { - .session_expiry_interval = 10, - .maximum_packet_size = 1024, - .receive_maximum = 65535, - .topic_alias_maximum = 2, - .request_resp_info = true, - .request_problem_info = true, - }; - esp_mqtt5_disconnect_property_config_t disconnect_property = { - .session_expiry_interval = 10, - .disconnect_reason = 0, - }; - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, 3)); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_connect_property(client, &connect_property)); - esp_mqtt5_client_delete_user_property(connect_property.user_property); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_user_property(&disconnect_property.user_property, user_property_arr, 3)); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_disconnect_property(client, &disconnect_property)); - esp_mqtt5_client_delete_user_property(disconnect_property.user_property); - esp_mqtt_client_disconnect(client); - WAIT_FOR_EVENT(DISCONNECT_BIT); - esp_mqtt_client_reconnect(client); - WAIT_FOR_EVENT(CONNECT_BIT); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - return true; -} - -bool mqtt5_subscribe_publish(void) -{ - const esp_mqtt_client_config_t mqtt5_cfg = { - .broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI, - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - esp_mqtt5_publish_property_config_t publish_property = { - .payload_format_indicator = 1, - .message_expiry_interval = 1000, - .topic_alias = 1, - .response_topic = "/topic/test/response", - .correlation_data = "123456", - .correlation_data_len = 6, - .content_type = "json", - }; - esp_mqtt5_subscribe_property_config_t subscribe_property = { - .subscribe_id = 25555, - .no_local_flag = false, - .retain_as_published_flag = true, - .retain_handle = 0, - }; - char* topic = append_mac("topic"); - TEST_ASSERT_TRUE(NULL != topic); - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - int qos = -1; - esp_mqtt_client_register_event(client, MQTT_EVENT_DATA, mqtt5_data_handler_qos, &qos); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_subscribe_property(client, &subscribe_property)); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 2) != -1); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_publish_property(client, &publish_property)); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client, topic, "message", 0, 2, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos == 2); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client, topic, "message", 0, 1, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos == 1); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - free(topic); - return true; -} - -bool mqtt5_lwt_clean_disconnect(void) -{ - char* lwt = append_mac("lwt"); - TEST_ASSERT_TRUE(lwt); - const esp_mqtt_client_config_t mqtt5_cfg1 = { - .broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI, - .credentials.set_null_client_id = true, - .session.last_will.topic = lwt, - .session.last_will.msg = "lwt_msg", - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - const esp_mqtt_client_config_t mqtt5_cfg2 = { - .broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI, - .credentials.set_null_client_id = true, - .session.last_will.topic = lwt, - .session.last_will.msg = "lwt_msg", - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - esp_mqtt5_connection_property_config_t connect_property = { - .will_delay_interval = 10, - .payload_format_indicator = true, - .message_expiry_interval = 10, - .content_type = "json", - .response_topic = "/test/response", - .correlation_data = "123456", - .correlation_data_len = 6, - }; - s_event_group = xEventGroupCreate(); - - esp_mqtt_client_handle_t client1 = esp_mqtt_client_init(&mqtt5_cfg1); - esp_mqtt_client_handle_t client2 = esp_mqtt_client_init(&mqtt5_cfg2); - TEST_ASSERT_TRUE(NULL != client1 && NULL != client2 ); - esp_mqtt_client_register_event(client1, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); - esp_mqtt_client_register_event(client2, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_connect_property(client1, &connect_property)); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_connect_property(client2, &connect_property)); - TEST_ASSERT_TRUE(esp_mqtt_client_start(client1) == ESP_OK); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_start(client2) == ESP_OK); - WAIT_FOR_EVENT(CONNECT_BIT); - int counter = 0; - esp_mqtt_client_register_event(client1, MQTT_EVENT_DATA, mqtt5_data_handler_lwt, &counter); - esp_mqtt_client_register_event(client2, MQTT_EVENT_DATA, mqtt5_data_handler_lwt, &counter); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client1, lwt, 0) != -1); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client2, lwt, 0) != -1); - esp_mqtt_client_disconnect(client1); - WAIT_FOR_EVENT(DISCONNECT_BIT); - esp_mqtt_client_reconnect(client1); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client1, lwt, 0) != -1); - esp_mqtt_client_stop(client2); - esp_mqtt_client_start(client2); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client2, lwt, 0) != -1); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client1, lwt, "no-lwt", 0, 0, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(counter == 0); - esp_mqtt_client_destroy(client1); - esp_mqtt_client_destroy(client2); - vEventGroupDelete(s_event_group); - free(lwt); - return true; -} - -bool mqtt5_subscribe_payload(void) -{ - const esp_mqtt_client_config_t mqtt5_cfg = { - .broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI, - .network.disable_auto_reconnect = true, - .session.protocol_ver = MQTT_PROTOCOL_V_5, - }; - char* topic = append_mac("topic"); - TEST_ASSERT_TRUE(NULL != topic); - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - int qos_payload = -1; - esp_mqtt_client_register_event(client, MQTT_EVENT_SUBSCRIBED, mqtt5_data_handler_subscribe, &qos_payload); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 2) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos_payload == 2); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos_payload == 0); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - free(topic); - return true; -} diff --git a/components/mqtt/test/test_mqtt5_client_broker.h b/components/mqtt/test/test_mqtt5_client_broker.h deleted file mode 100644 index 52b6ab8..0000000 --- a/components/mqtt/test/test_mqtt5_client_broker.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once -#include "esp_log.h" - -/** - * @brief MQTT5 client-broker tests are not implemented as separate test cases - * due to time consuming connection setup/teardown. - * This utility macro is used to run functional cases as MQTT tests - * and evaluate as separate assertions in one "mqtt5 broker tests" test case. - */ -#define RUN_MQTT5_BROKER_TEST(test_name) \ - do { \ - ESP_LOGI("mqtt5_test", "Running test:" #test_name "()"); \ - TEST_ASSERT_TRUE_MESSAGE(test_name(), "Mqtt5 test failed: " #test_name "() "); \ - ESP_LOGI("mqtt5_test", "Test:" #test_name "() passed "); \ - } while(0) - - -/** - * @brief This module contains mqtt5 test cases interacting the client with a (real) broker - */ - -/** - * @brief The client subscribes and publishes on the same topic - * and verifies the received published qos in the event - */ -bool mqtt5_subscribe_publish(void); - -/** - * @brief The client connects, disconnects and reconnects. - * Tests basic client state transitions - */ -bool mqtt5_connect_disconnect(void); - -/** - * @brief Two clients with defined lwt connect and subscribe to lwt topic. - * This test verifies that no lwt is send when each of the client disconnects. - * (we expect a clean disconnection, so no last-will being sent) - */ -bool mqtt5_lwt_clean_disconnect(void); - -/** - * @brief The client subscribes to a topic with certain qos - * and verifies the qos in SUBACK message from the broker. - */ -bool mqtt5_subscribe_payload(void); diff --git a/components/mqtt/test/test_mqtt_client_broker.c b/components/mqtt/test/test_mqtt_client_broker.c deleted file mode 100644 index 05fca43..0000000 --- a/components/mqtt/test/test_mqtt_client_broker.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "mqtt_client.h" -#include "esp_log.h" -#include "esp_mac.h" - -#define WAIT_FOR_EVENT(event) \ - TEST_ASSERT_TRUE(xEventGroupWaitBits(s_event_group, event, pdTRUE, pdTRUE, pdMS_TO_TICKS(COMMON_OPERATION_TIMEOUT)) & event); - -#define TEST_ASSERT_TRUE(condition) TEST_ASSERT_TRUE_LINE(condition, __LINE__) -#define TEST_ASSERT_TRUE_LINE(condition, line) \ - do { \ - if (!(condition)) { \ - ESP_LOGE("test_mqtt_client_broker.c", \ - "Assertion failed in line %d", line); \ - return false; \ - } \ - } while(0) - - -static const int COMMON_OPERATION_TIMEOUT = 10000; -static const int CONNECT_BIT = BIT0; -static const int DISCONNECT_BIT = BIT1; -static const int DATA_BIT = BIT2; - -static EventGroupHandle_t s_event_group; - -static char* append_mac(const char* string) -{ - uint8_t mac[6]; - char *id_string = NULL; - esp_read_mac(mac, ESP_MAC_WIFI_STA); - asprintf(&id_string, "%s_%02x%02X%02X", string, mac[3], mac[4], mac[5]); - return id_string; -} - -static void mqtt_data_handler_qos(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_DATA) { - esp_mqtt_event_handle_t event = event_data; - int * qos = handler_args; - *qos = event->qos; - xEventGroupSetBits(s_event_group, DATA_BIT); - } -} - -static void mqtt_data_handler_lwt(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_DATA) { - esp_mqtt_event_handle_t event = event_data; - ESP_LOGI("mqtt-lwt", "MQTT_EVENT_DATA"); - ESP_LOGI("mqtt-lwt", "TOPIC=%.*s", event->topic_len, event->topic); - ESP_LOGI("mqtt-lwt", "DATA=%.*s", event->data_len, event->data); - if (strncmp(event->data, "no-lwt", event->data_len) == 0) { - // no lwt, just to indicate the test has finished - xEventGroupSetBits(s_event_group, DATA_BIT); - } else { - // count up any potential lwt message - int * count = handler_args; - *count = *count + 1; - ESP_LOGE("mqtt-lwt", "count=%d", *count); - } - } -} - -static void mqtt_data_handler_subscribe(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - if (event_id == MQTT_EVENT_SUBSCRIBED) { - esp_mqtt_event_handle_t event = event_data; - ESP_LOGI("mqtt-subscribe", "MQTT_EVENT_SUBSCRIBED, data size=%d", event->data_len); - int * sub_payload = handler_args; - if (event->data_len == 1) { - ESP_LOGI("mqtt-subscribe", "DATA=%d", *(uint8_t*)event->data); - *sub_payload = *(uint8_t*)event->data; - } - xEventGroupSetBits(s_event_group, DATA_BIT); - } -} - - -static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) -{ - switch ((esp_mqtt_event_id_t)event_id) { - case MQTT_EVENT_CONNECTED: - xEventGroupSetBits(s_event_group, CONNECT_BIT); - break; - - case MQTT_EVENT_DISCONNECTED: - xEventGroupSetBits(s_event_group, DISCONNECT_BIT); - break; - default: - break; - } -} - -bool mqtt_connect_disconnect(void) -{ - const esp_mqtt_client_config_t mqtt_cfg = { - .broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI, - .network.disable_auto_reconnect = true, - }; - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - esp_mqtt_client_disconnect(client); - WAIT_FOR_EVENT(DISCONNECT_BIT); - esp_mqtt_client_reconnect(client); - WAIT_FOR_EVENT(CONNECT_BIT); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - return true; -} - -bool mqtt_subscribe_publish(void) -{ - const esp_mqtt_client_config_t mqtt_cfg = { - .broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI, - }; - char* topic = append_mac("topic"); - TEST_ASSERT_TRUE(NULL != topic); - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - int qos = -1; - esp_mqtt_client_register_event(client, MQTT_EVENT_DATA, mqtt_data_handler_qos, &qos); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 2) != -1); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client, topic, "message", 0, 2, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos == 2); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client, topic, "message", 0, 1, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos == 1); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - free(topic); - return true; -} - -bool mqtt_lwt_clean_disconnect(void) -{ - char* lwt = append_mac("lwt"); - TEST_ASSERT_TRUE(lwt); - const esp_mqtt_client_config_t mqtt_cfg1 = { - .broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI, - .credentials.set_null_client_id = true, - .session.last_will.topic = lwt, - .session.last_will.msg = "lwt_msg" - }; - const esp_mqtt_client_config_t mqtt_cfg2 = { - .broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI, - .credentials.set_null_client_id = true, - .session.last_will.topic = lwt, - .session.last_will.msg = "lwt_msg" - }; - s_event_group = xEventGroupCreate(); - - esp_mqtt_client_handle_t client1 = esp_mqtt_client_init(&mqtt_cfg1); - esp_mqtt_client_handle_t client2 = esp_mqtt_client_init(&mqtt_cfg2); - TEST_ASSERT_TRUE(NULL != client1 && NULL != client2 ); - esp_mqtt_client_register_event(client1, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - esp_mqtt_client_register_event(client2, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - TEST_ASSERT_TRUE(esp_mqtt_client_start(client1) == ESP_OK); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_start(client2) == ESP_OK); - WAIT_FOR_EVENT(CONNECT_BIT); - int counter = 0; - esp_mqtt_client_register_event(client1, MQTT_EVENT_DATA, mqtt_data_handler_lwt, &counter); - esp_mqtt_client_register_event(client2, MQTT_EVENT_DATA, mqtt_data_handler_lwt, &counter); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client1, lwt, 0) != -1); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client2, lwt, 0) != -1); - esp_mqtt_client_disconnect(client1); - WAIT_FOR_EVENT(DISCONNECT_BIT); - esp_mqtt_client_reconnect(client1); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client1, lwt, 0) != -1); - esp_mqtt_client_stop(client2); - esp_mqtt_client_start(client2); - WAIT_FOR_EVENT(CONNECT_BIT); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client2, lwt, 0) != -1); - TEST_ASSERT_TRUE(esp_mqtt_client_publish(client1, lwt, "no-lwt", 0, 0, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(counter == 0); - esp_mqtt_client_destroy(client1); - esp_mqtt_client_destroy(client2); - vEventGroupDelete(s_event_group); - free(lwt); - return true; -} - -bool mqtt_subscribe_payload(void) -{ - const esp_mqtt_client_config_t mqtt_cfg = { - .broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI, - .network.disable_auto_reconnect = true, - }; - char* topic = append_mac("topic"); - TEST_ASSERT_TRUE(NULL != topic); - s_event_group = xEventGroupCreate(); - esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); - TEST_ASSERT_TRUE(NULL != client ); - esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); - TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client)); - WAIT_FOR_EVENT(CONNECT_BIT); - int qos_payload = -1; - esp_mqtt_client_register_event(client, MQTT_EVENT_SUBSCRIBED, mqtt_data_handler_subscribe, &qos_payload); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 2) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos_payload == 2); - TEST_ASSERT_TRUE(esp_mqtt_client_subscribe(client, topic, 0) != -1); - WAIT_FOR_EVENT(DATA_BIT); - TEST_ASSERT_TRUE(qos_payload == 0); - esp_mqtt_client_destroy(client); - vEventGroupDelete(s_event_group); - free(topic); - return true; -} diff --git a/components/mqtt/test/test_mqtt_client_broker.h b/components/mqtt/test/test_mqtt_client_broker.h deleted file mode 100644 index 6bfd5d8..0000000 --- a/components/mqtt/test/test_mqtt_client_broker.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once -#include "esp_log.h" - -/** - * @brief MQTT client-broker tests are not implemented as separate test cases - * due to time consuming connection setup/teardown. - * This utility macro is used to run functional cases as MQTT tests - * and evaluate as separate assertions in one "mqtt broker tests" test case. - */ -#define RUN_MQTT_BROKER_TEST(test_name) \ - do { \ - ESP_LOGI("mqtt_test", "Running test:" #test_name "()"); \ - TEST_ASSERT_TRUE_MESSAGE(test_name(), "Mqtt test failed: " #test_name "() "); \ - ESP_LOGI("mqtt_test", "Test:" #test_name "() passed "); \ - } while(0) - - -/** - * @brief This module contains mqtt test cases interacting the client with a (real) broker - */ - -/** - * @brief The client subscribes and publishes on the same topic - * and verifies the received published qos in the event - */ -bool mqtt_subscribe_publish(void); - -/** - * @brief The client connects, disconnects and reconnects. - * Tests basic client state transitions - */ -bool mqtt_connect_disconnect(void); - -/** - * @brief Two clients with defined lwt connect and subscribe to lwt topic. - * This test verifies that no lwt is send when each of the client disconnects. - * (we expect a clean disconnection, so no last-will being sent) - */ -bool mqtt_lwt_clean_disconnect(void); - -/** - * @brief The client subscribes to a topic with certain qos - * and verifies the qos in SUBACK message from the broker. - */ -bool mqtt_subscribe_payload(void); diff --git a/components/mqtt/test/test_mqtt_connection.c b/components/mqtt/test/test_mqtt_connection.c deleted file mode 100644 index 0e82003..0000000 --- a/components/mqtt/test/test_mqtt_connection.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "unity.h" -#include "esp_event.h" -#include "esp_netif.h" -#include "esp_eth.h" -#include "esp_log.h" - - -#if SOC_EMAC_SUPPORTED -#define ETH_START_BIT BIT(0) -#define ETH_STOP_BIT BIT(1) -#define ETH_CONNECT_BIT BIT(2) -#define ETH_GOT_IP_BIT BIT(3) -#define ETH_STOP_TIMEOUT_MS (10000) -#define ETH_GET_IP_TIMEOUT_MS (60000) - - -static const char *TAG = "esp32_eth_test_fixture"; -static EventGroupHandle_t s_eth_event_group = NULL; -static esp_netif_t *s_eth_netif = NULL; -static esp_eth_mac_t *s_mac = NULL; -static esp_eth_phy_t *s_phy = NULL; -static esp_eth_handle_t s_eth_handle = NULL; -static esp_eth_netif_glue_handle_t s_eth_glue = NULL; - - -/** Event handler for Ethernet events */ -static void eth_event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg; - switch (event_id) { - case ETHERNET_EVENT_CONNECTED: - xEventGroupSetBits(eth_event_group, ETH_CONNECT_BIT); - ESP_LOGI(TAG, "Ethernet Link Up"); - break; - case ETHERNET_EVENT_DISCONNECTED: - ESP_LOGI(TAG, "Ethernet Link Down"); - break; - case ETHERNET_EVENT_START: - xEventGroupSetBits(eth_event_group, ETH_START_BIT); - ESP_LOGI(TAG, "Ethernet Started"); - break; - case ETHERNET_EVENT_STOP: - xEventGroupSetBits(eth_event_group, ETH_STOP_BIT); - ESP_LOGI(TAG, "Ethernet Stopped"); - break; - default: - break; - } -} - -/** Event handler for IP_EVENT_ETH_GOT_IP */ -static void got_ip_event_handler(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg; - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - const esp_netif_ip_info_t *ip_info = &event->ip_info; - ESP_LOGI(TAG, "Ethernet Got IP Address"); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - ESP_LOGI(TAG, "ETHIP:" IPSTR, IP2STR(&ip_info->ip)); - ESP_LOGI(TAG, "ETHMASK:" IPSTR, IP2STR(&ip_info->netmask)); - ESP_LOGI(TAG, "ETHGW:" IPSTR, IP2STR(&ip_info->gw)); - ESP_LOGI(TAG, "~~~~~~~~~~~"); - xEventGroupSetBits(eth_event_group, ETH_GOT_IP_BIT); -} - -static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_wait) -{ - int i = 0; - ms_to_wait += 100; - for (i = 0; i < ms_to_wait / 100; i++) { - vTaskDelay(pdMS_TO_TICKS(100)); - if (esp_eth_driver_uninstall(eth_hdl) == ESP_OK) { - break; - } - } - if (i < ms_to_wait / 10) { - return ESP_OK; - } else { - return ESP_FAIL; - } -} - - -void connect_test_fixture_setup(void) -{ - EventBits_t bits; - s_eth_event_group = xEventGroupCreate(); - TEST_ASSERT(s_eth_event_group != NULL); - TEST_ESP_OK(esp_event_loop_create_default()); - // create TCP/IP netif - esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH(); - s_eth_netif = esp_netif_new(&netif_cfg); - - eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); - s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); - eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); - s_phy = esp_eth_phy_new_ip101(&phy_config); - esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(s_mac, s_phy); - - // install Ethernet driver - TEST_ESP_OK(esp_eth_driver_install(ð_config, &s_eth_handle)); - // combine driver with netif - s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); - TEST_ESP_OK(esp_netif_attach(s_eth_netif, s_eth_glue)); - // register user defined event handers - TEST_ESP_OK(esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, ð_event_handler, s_eth_event_group)); - TEST_ESP_OK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &got_ip_event_handler, s_eth_event_group)); - // start Ethernet driver - TEST_ESP_OK(esp_eth_start(s_eth_handle)); - /* wait for IP lease */ - bits = xEventGroupWaitBits(s_eth_event_group, ETH_GOT_IP_BIT, true, true, pdMS_TO_TICKS(ETH_GET_IP_TIMEOUT_MS)); - TEST_ASSERT((bits & ETH_GOT_IP_BIT) == ETH_GOT_IP_BIT); -} - -void connect_test_fixture_teardown(void) -{ - EventBits_t bits; - // stop Ethernet driver - TEST_ESP_OK(esp_eth_stop(s_eth_handle)); - /* wait for connection stop */ - bits = xEventGroupWaitBits(s_eth_event_group, ETH_STOP_BIT, true, true, pdMS_TO_TICKS(ETH_STOP_TIMEOUT_MS)); - TEST_ASSERT((bits & ETH_STOP_BIT) == ETH_STOP_BIT); - TEST_ESP_OK(esp_eth_del_netif_glue(s_eth_glue)); - /* driver should be uninstalled within 2 seconds */ - TEST_ESP_OK(test_uninstall_driver(s_eth_handle, 2000)); - TEST_ESP_OK(s_phy->del(s_phy)); - TEST_ESP_OK(s_mac->del(s_mac)); - TEST_ESP_OK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, got_ip_event_handler)); - TEST_ESP_OK(esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, eth_event_handler)); - esp_netif_destroy(s_eth_netif); - TEST_ESP_OK(esp_event_loop_delete_default()); - vEventGroupDelete(s_eth_event_group); -} -#endif // SOC_EMAC_SUPPORTED diff --git a/components/mqtt/test/test_mqtt_connection.h b/components/mqtt/test/test_mqtt_connection.h deleted file mode 100644 index 5322ddf..0000000 --- a/components/mqtt/test/test_mqtt_connection.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ -#pragma once -#include "soc/soc_caps.h" - -/** - * Connection test fixture setup, so we expect the broker is available - * on network - */ -void connect_test_fixture_setup(void); - -/** - * Cleans up the connection - */ -void connect_test_fixture_teardown(void); diff --git a/components/mqtt/host_test/CMakeLists.txt b/host_test/CMakeLists.txt similarity index 94% rename from components/mqtt/host_test/CMakeLists.txt rename to host_test/CMakeLists.txt index d1c1ac6..db98733 100644 --- a/components/mqtt/host_test/CMakeLists.txt +++ b/host_test/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.16) include($ENV{IDF_PATH}/tools/cmake/project.cmake) set(COMPONENTS main) list(APPEND EXTRA_COMPONENT_DIRS + "mocks/heap/" "$ENV{IDF_PATH}/tools/mocks/esp_hw_support/" "$ENV{IDF_PATH}/tools/mocks/freertos/" "$ENV{IDF_PATH}/tools/mocks/esp_timer/" diff --git a/components/mqtt/host_test/README.md b/host_test/README.md similarity index 100% rename from components/mqtt/host_test/README.md rename to host_test/README.md diff --git a/components/mqtt/host_test/main/CMakeLists.txt b/host_test/main/CMakeLists.txt similarity index 100% rename from components/mqtt/host_test/main/CMakeLists.txt rename to host_test/main/CMakeLists.txt diff --git a/components/mqtt/host_test/main/test_mqtt_client.cpp b/host_test/main/test_mqtt_client.cpp similarity index 97% rename from components/mqtt/host_test/main/test_mqtt_client.cpp rename to host_test/main/test_mqtt_client.cpp index 8ebbf1e..37dd34e 100644 --- a/components/mqtt/host_test/main/test_mqtt_client.cpp +++ b/host_test/main/test_mqtt_client.cpp @@ -1,3 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #define CATCH_CONFIG_MAIN // This tells the catch header to generate a main #include "catch.hpp" diff --git a/host_test/mocks/heap/CMakeLists.txt b/host_test/mocks/heap/CMakeLists.txt new file mode 100644 index 0000000..0a0c8a6 --- /dev/null +++ b/host_test/mocks/heap/CMakeLists.txt @@ -0,0 +1,4 @@ +idf_component_get_property(original_heap_dir heap COMPONENT_OVERRIDEN_DIR) + +idf_component_register(SRCS heap_mock.c + INCLUDE_DIRS "${original_heap_dir}/include") diff --git a/host_test/mocks/heap/heap_mock.c b/host_test/mocks/heap/heap_mock.c new file mode 100644 index 0000000..6bc3b35 --- /dev/null +++ b/host_test/mocks/heap/heap_mock.c @@ -0,0 +1,11 @@ +#include "esp_heap_caps.h" +#include +#include + + + +void *heap_caps_calloc(size_t n, size_t size, uint32_t caps) { + (void)caps; + return calloc(n, size); + +} diff --git a/components/mqtt/host_test/mocks/include/sys/queue.h b/host_test/mocks/include/sys/queue.h similarity index 100% rename from components/mqtt/host_test/mocks/include/sys/queue.h rename to host_test/mocks/include/sys/queue.h diff --git a/components/mqtt/host_test/sdkconfig.defaults b/host_test/sdkconfig.defaults similarity index 100% rename from components/mqtt/host_test/sdkconfig.defaults rename to host_test/sdkconfig.defaults diff --git a/idf_component.yml b/idf_component.yml new file mode 100644 index 0000000..23cec31 --- /dev/null +++ b/idf_component.yml @@ -0,0 +1,5 @@ +version: "1.0.0" +description: esp-mqtt +dependencies: + idf: + version: ">=5.0" diff --git a/mqtt_client.c b/mqtt_client.c index d732d95..3a2563c 100644 --- a/mqtt_client.c +++ b/mqtt_client.c @@ -235,6 +235,10 @@ esp_mqtt_set_transport_failed: /* Checks if the user supplied config values are internally consistent */ static esp_err_t esp_mqtt_check_cfg_conflict(const mqtt_config_storage_t *cfg, const esp_mqtt_client_config_t *user_cfg) { + if(cfg == NULL || user_cfg == NULL) { + ESP_LOGE(TAG, "Invalid configuration"); + return ESP_ERR_INVALID_ARG; + } esp_err_t ret = ESP_OK; bool ssl_cfg_enabled = cfg->use_global_ca_store || cfg->cacert_buf || cfg->clientcert_buf || cfg->psk_hint_key || cfg->alpn_protos; @@ -517,6 +521,7 @@ esp_err_t esp_mqtt_set_config(esp_mqtt_client_handle_t client, const esp_mqtt_cl if (config->broker.address.transport) { free(client->config->scheme); + client->config->scheme = NULL; if (config->broker.address.transport == MQTT_TRANSPORT_OVER_TCP) { client->config->scheme = create_string(MQTT_OVER_TCP_SCHEME, strlen(MQTT_OVER_TCP_SCHEME)); ESP_MEM_CHECK(TAG, client->config->scheme, goto _mqtt_set_config_failed);