mirror of
https://github.com/espressif/esp-mqtt.git
synced 2025-10-01 17:41:37 +02:00
chore: Adds pre-commit checks and introduce conventional commits
This commit is contained in:
31
.ci/astyle-rules.yml
Normal file
31
.ci/astyle-rules.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
DEFAULT:
|
||||
options: >-
|
||||
--style=otbs
|
||||
--indent=spaces=4
|
||||
--break-blocks
|
||||
--pad-oper
|
||||
--pad-comma
|
||||
--pad-header
|
||||
--unpad-paren
|
||||
--delete-empty-lines
|
||||
--add-braces
|
||||
--align-pointer=name
|
||||
--align-reference=name
|
||||
--max-continuation-indent=120
|
||||
--keep-one-line-statements
|
||||
--break-after-logical
|
||||
include:
|
||||
- "*.c"
|
||||
- "*.h"
|
||||
- "*.cpp"
|
||||
- "*.hpp"
|
||||
|
||||
# Exclude mocked components and generated files
|
||||
mocks_and_generated:
|
||||
check: false
|
||||
include:
|
||||
- "build*/"
|
||||
- "components/mocks/"
|
||||
- "managed_components/"
|
||||
- "*.pb.h"
|
||||
- "*.pb.c"
|
46
.ci/check_copyright_config.yaml
Normal file
46
.ci/check_copyright_config.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
# don't modify this section!
|
||||
DEFAULT:
|
||||
perform_check: yes # should the check be performed?
|
||||
# Sections setting this to 'no' don't need to include any other options as they are ignored
|
||||
# When a file is using a section with the option set to 'no', no checks are performed.
|
||||
|
||||
# what licenses (or license expressions) are allowed for files in this section
|
||||
# when setting this option in a section, you need to list all the allowed licenses
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
license_for_new_files: Apache-2.0 # license to be used when inserting a new copyright notice
|
||||
new_notice_c: | # notice for new C, CPP, H, HPP and LD files
|
||||
/*
|
||||
* SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: {license}
|
||||
*/
|
||||
new_notice_python: | # notice for new python files
|
||||
# SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: {license}
|
||||
|
||||
# comment lines matching:
|
||||
# SPDX-FileCopyrightText: year[-year] Espressif Systems
|
||||
# or
|
||||
# SPDX-FileContributor: year[-year] Espressif Systems
|
||||
# are replaced with this template prefixed with the correct comment notation (# or // or *) and SPDX- notation
|
||||
espressif_copyright: "{years} Espressif Systems (Shanghai) CO LTD"
|
||||
examples_and_unit_tests:
|
||||
include:
|
||||
- "examples/"
|
||||
- "test/**"
|
||||
- "**/pytest_*.py"
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
- Unlicense
|
||||
- CC0-1.0
|
||||
license_for_new_files: Unlicense OR CC0-1.0
|
||||
|
||||
third_party_libs:
|
||||
include:
|
||||
- "lib/mqtt_msg.c"
|
||||
- "lib/include/mqtt_msg.h"
|
||||
- "test/host/mocks/include/sys/queue.h"
|
||||
allowed_licenses:
|
||||
- BSD-3-Clause
|
||||
- Apache-2.0
|
1
.github/workflows/build-and-target-test.yml
vendored
1
.github/workflows/build-and-target-test.yml
vendored
@@ -34,4 +34,3 @@ jobs:
|
||||
# target: ${{inputs.target}}
|
||||
# app_name: ${{inputs.app_name}}
|
||||
# app_path: ${{inputs.app_path}}
|
||||
|
||||
|
1
.github/workflows/test-examples.yml
vendored
1
.github/workflows/test-examples.yml
vendored
@@ -49,4 +49,3 @@ jobs:
|
||||
target: ${{matrix.target}}
|
||||
app_name: ${{matrix.example.name}}
|
||||
app_path: $IDF_PATH/examples/protocols/${{matrix.example.path}}
|
||||
|
||||
|
@@ -6,6 +6,7 @@
|
||||
tags:
|
||||
- build
|
||||
- internet
|
||||
timeout: 1h
|
||||
script:
|
||||
- pip install -U 'idf-ci<1'
|
||||
- idf-ci build run
|
||||
|
25
.gitlab/ci/pre-check.yml
Normal file
25
.gitlab/ci/pre-check.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
# Pre-check jobs for ESP-MQTT
|
||||
|
||||
.check_pre_commit_template:
|
||||
stage: pre_check
|
||||
image: "${CI_DOCKER_REGISTRY}/esp-idf-pre-commit:2"
|
||||
tags: [build, internet]
|
||||
variables:
|
||||
GIT_STRATEGY: fetch
|
||||
GIT_DEPTH: 1
|
||||
SUBMODULES_TO_FETCH: "all"
|
||||
script:
|
||||
- pre-commit install
|
||||
- pre-commit run --all-files
|
||||
cache:
|
||||
paths:
|
||||
- .cache/submodule_archives
|
||||
policy: pull
|
||||
|
||||
check_pre_commit:
|
||||
extends:
|
||||
- .check_pre_commit_template
|
||||
rules:
|
||||
- if: '$CI_COMMIT_REF_NAME == "master" && $CI_PIPELINE_SOURCE == "push"'
|
||||
when: never
|
||||
- when: on_success
|
76
.pre-commit-config.yaml
Normal file
76
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
minimum_pre_commit_version: 4.0.0 # Specifies the minimum version of pre-commit required for this configuration
|
||||
default_install_hook_types: [pre-commit,commit-msg] # Default hook types to install if not specified in individual hooks
|
||||
default_stages: [pre-commit]
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace # Removes trailing whitespaces from lines
|
||||
exclude: &whitespace_excludes |
|
||||
(?x)^(
|
||||
.+\.(md|rst|map|bin|drawio|elf)|
|
||||
.+\.log$|
|
||||
compile_commands\.json$|
|
||||
dependencies\.lock$|
|
||||
build.*/.*|
|
||||
__pycache__/.*
|
||||
)$
|
||||
- id: end-of-file-fixer # Ensures files end with a newline
|
||||
exclude: *whitespace_excludes
|
||||
- id: check-executables-have-shebangs # Checks executables have a proper shebang
|
||||
- id: mixed-line-ending # Detects mixed line endings (CRLF/LF)
|
||||
args: ['-f=lf'] # Forces files to use LF line endings
|
||||
- id: double-quote-string-fixer # Converts single quotes to double quotes in strings
|
||||
|
||||
- repo: https://github.com/espressif/check-copyright/
|
||||
rev: v1.1.1
|
||||
hooks:
|
||||
- id: check-copyright
|
||||
args: ['--config', '.ci/check_copyright_config.yaml']
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.11.5
|
||||
hooks:
|
||||
- id: ruff # Runs ruff linter (replaces flake8)
|
||||
args: ['--fix', '--exit-non-zero-on-fix']
|
||||
files: \.py$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.15.0
|
||||
hooks:
|
||||
- id: mypy # Runs mypy for Python type checking
|
||||
additional_dependencies: ['PyYAML', 'types-PyYAML']
|
||||
files: \.py$
|
||||
exclude: ^docs/.*/conf\.py$
|
||||
|
||||
- repo: https://github.com/espressif/conventional-precommit-linter
|
||||
rev: v1.10.0
|
||||
hooks:
|
||||
- id: conventional-precommit-linter # Lints commit messages for conventional format
|
||||
stages: [commit-msg]
|
||||
args:
|
||||
- --types=ci,docs,feat,fix,perf,refactor,chore
|
||||
- --scopes=mqtt,mqtt5,examples
|
||||
- --subject-min-length=10
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell # Code spell checker
|
||||
args: ["--write-changes"]
|
||||
additional_dependencies: [tomli]
|
||||
exclude: |
|
||||
(?x)^(
|
||||
.+\.(bin|elf|map)|
|
||||
build.*/.*|
|
||||
dependencies\.lock$|
|
||||
compile_commands\.json$|
|
||||
__pycache__/.*
|
||||
)$
|
||||
|
||||
- repo: https://github.com/espressif/astyle_py.git
|
||||
rev: v1.1.0
|
||||
hooks:
|
||||
- id: astyle_py
|
||||
args: ['--astyle-version=3.4.7', '--rules=.ci/astyle-rules.yml']
|
2
Kconfig
2
Kconfig
@@ -185,6 +185,6 @@ menu "ESP-MQTT Configurations"
|
||||
Set to true to have publish topic in all data events. This changes the behaviour
|
||||
when the message is bigger than the receive buffer size. The first event of the sequence
|
||||
always have the topic.
|
||||
Note: This will allocate memory to store the topic only in case of messge bigger than the buffer size.
|
||||
Note: This will allocate memory to store the topic only in case of message bigger than the buffer size.
|
||||
|
||||
endmenu
|
||||
|
@@ -1,3 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Common (non-language-specific) configuration for Sphinx
|
||||
@@ -6,6 +8,7 @@
|
||||
# type: ignore
|
||||
# pylint: disable=wildcard-import
|
||||
# pylint: disable=undefined-variable
|
||||
# ruff: noqa: F405
|
||||
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
@@ -15,7 +18,7 @@ from esp_docs.conf_docs import * # noqa: F403,F401
|
||||
# Only required when using ESP-IDF extensions that depend on IDF environment
|
||||
|
||||
|
||||
extensions += ['sphinx_copybutton',
|
||||
extensions += ['sphinx_copybutton', # noqa: F405
|
||||
# Needed as a trigger for running doxygen
|
||||
'esp_docs.esp_extensions.dummy_build_system',
|
||||
'esp_docs.esp_extensions.run_doxygen'
|
||||
@@ -25,8 +28,8 @@ extensions += ['sphinx_copybutton',
|
||||
github_repo = 'espressif/esp-mqtt'
|
||||
|
||||
# context used by sphinx_idf_theme
|
||||
html_context['github_user'] = 'espressif'
|
||||
html_context['github_repo'] = 'esp-mqtt'
|
||||
html_context['github_user'] = 'espressif' # noqa: F405
|
||||
html_context['github_repo'] = 'esp-mqtt' # noqa: F405
|
||||
|
||||
# Extra options required by sphinx_idf_theme
|
||||
project_slug = 'esp-mqtt'
|
||||
@@ -34,6 +37,3 @@ versions_url = './_static/mqtt_docs_versions.js'
|
||||
|
||||
idf_targets = [ 'esp32' ]
|
||||
languages = ['en']
|
||||
|
||||
|
||||
|
||||
|
@@ -1,3 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
|
@@ -1,3 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# English Language RTD & Sphinx config file
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -27,7 +27,6 @@
|
||||
|
||||
static const char *TAG = "MQTT_EXAMPLE";
|
||||
|
||||
|
||||
static void log_error_if_nonzero(const char *message, int error_code)
|
||||
{
|
||||
if (error_code != 0) {
|
||||
@@ -51,19 +50,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -73,27 +71,33 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -111,8 +115,10 @@ static void mqtt_app_start(void)
|
||||
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0) {
|
||||
int count = 0;
|
||||
printf("Please enter url of mqtt broker\n");
|
||||
|
||||
while (count < 128) {
|
||||
int c = fgetc(stdin);
|
||||
|
||||
if (c == '\n') {
|
||||
line[count] = '\0';
|
||||
break;
|
||||
@@ -120,27 +126,27 @@ static void mqtt_app_start(void)
|
||||
line[count] = c;
|
||||
++count;
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
mqtt_cfg.broker.address.uri = line;
|
||||
printf("Broker url: %s\n", line);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||
abort();
|
||||
}
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
|
||||
/*Let's enqueue a few messages to the outbox to see the allocations*/
|
||||
int msg_id;
|
||||
msg_id = esp_mqtt_client_enqueue(client, "/topic/qos1", "data_3", 0, 1, 0, true);
|
||||
ESP_LOGI(TAG, "Enqueued msg_id=%d", msg_id);
|
||||
msg_id = esp_mqtt_client_enqueue(client, "/topic/qos2", "QoS2 message", 0, 2, 0, true);
|
||||
ESP_LOGI(TAG, "Enqueued msg_id=%d", msg_id);
|
||||
|
||||
/* Now we start the client and it's possible to see the memory usage for the operations in the outbox. */
|
||||
esp_mqtt_client_start(client);
|
||||
}
|
||||
@@ -150,7 +156,6 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("MQTT_EXAMPLE", ESP_LOG_VERBOSE);
|
||||
@@ -158,16 +163,13 @@ void app_main(void)
|
||||
esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("custom_outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -24,9 +24,11 @@ constexpr auto TAG = "custom_outbox";
|
||||
* The trace resource class is created here as an example on how to build a custom memory resource
|
||||
* The class is only needed to show where we are allocating from and to track allocations and deallocations.
|
||||
*/
|
||||
class trace_resource : public std::pmr::memory_resource {
|
||||
class trace_resource : public std::pmr::memory_resource
|
||||
{
|
||||
public:
|
||||
explicit trace_resource(std::string resource_name, std::pmr::memory_resource *upstream_resource = std::pmr::get_default_resource()) : upstream{upstream_resource}, name{std::move(resource_name)} {}
|
||||
explicit trace_resource(std::string resource_name,
|
||||
std::pmr::memory_resource *upstream_resource = std::pmr::get_default_resource()) : upstream{upstream_resource}, name{std::move(resource_name)} {}
|
||||
[[nodiscard]] std::string_view get_name() const noexcept
|
||||
{
|
||||
return std::string_view(name);
|
||||
@@ -77,11 +79,14 @@ struct outbox_item {
|
||||
outbox_tick_t tick,
|
||||
pending_state_t pending_state,
|
||||
allocator_type alloc = {}
|
||||
) : message(std::move(message), alloc), id(msg_id), type(msg_type), qos(msg_qos), tick(tick), pending_state(pending_state) {}
|
||||
) : message(std::move(message), alloc), id(msg_id), type(msg_type), qos(msg_qos), tick(tick),
|
||||
pending_state(pending_state) {}
|
||||
|
||||
/*Copy and move constructors have an extra allocator parameter, for copy default and allocator aware are the same.*/
|
||||
outbox_item(const outbox_item &other, allocator_type alloc = {}) : message(other.message, alloc), id(other.id), type(other.type), qos(other.qos), tick(other.tick), pending_state(other.pending_state) {}
|
||||
outbox_item(outbox_item &&other, allocator_type alloc) noexcept : message(std::move(other.message), alloc), id(other.id), type(other.type), qos(other.qos), tick(other.tick), pending_state(other.pending_state)
|
||||
outbox_item(const outbox_item &other, allocator_type alloc = {}) : message(other.message, alloc), id(other.id),
|
||||
type(other.type), qos(other.qos), tick(other.tick), pending_state(other.pending_state) {}
|
||||
outbox_item(outbox_item &&other, allocator_type alloc) noexcept : message(std::move(other.message), alloc),
|
||||
id(other.id), type(other.type), qos(other.qos), tick(other.tick), pending_state(other.pending_state)
|
||||
{}
|
||||
|
||||
outbox_item(const outbox_item &) = default;
|
||||
@@ -175,6 +180,7 @@ struct outbox_t {
|
||||
total_size -= item.get_size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
@@ -228,7 +234,8 @@ struct outbox_t {
|
||||
QUEUED
|
||||
);
|
||||
total_size += item.get_size();
|
||||
ESP_LOGD(TAG, "ENQUEUE msgid=%d, msg_type=%d, len=%d, size=%" PRIu64, message->msg_id, message->msg_type, message->len + message->remaining_len, outbox_get_size(this));
|
||||
ESP_LOGD(TAG, "ENQUEUE msgid=%d, msg_type=%d, len=%d, size=%" PRIu64, message->msg_id, message->msg_type,
|
||||
message->len + message->remaining_len, outbox_get_size(this));
|
||||
return &item;
|
||||
} catch (const std::exception &e) {
|
||||
return nullptr;
|
||||
@@ -244,6 +251,7 @@ struct outbox_t {
|
||||
if (tick != nullptr) {
|
||||
*tick = item->get_tick();
|
||||
}
|
||||
|
||||
return &(*item);
|
||||
}
|
||||
return nullptr;
|
||||
@@ -260,6 +268,7 @@ private:
|
||||
queue.erase(to_erase);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
std::size_t total_size{};
|
||||
@@ -273,17 +282,17 @@ extern "C" {
|
||||
/* First we create a fixed size memory buffer to be used. */
|
||||
static constexpr auto work_memory_size = 16 * 1024;
|
||||
static std::array<std::byte, work_memory_size> resource_buffer{};
|
||||
|
||||
try {
|
||||
/*
|
||||
* Since the outbox is managed by a C API we can't rely on C++ automatic cleanup and smart pointers but, on production code it would be better to add the
|
||||
* memory resources to outbox_t, applying RAII principles, and make only outbox_item allocator aware. For the sake of the example we are keeping them
|
||||
* separated to explictly show the relations.
|
||||
* First we create the monotonic buffer and add null_memory_resource as upstream. This way if our working memory is exausted an exception is thrown.
|
||||
* separated to explicitly show the relations.
|
||||
* First we create the monotonic buffer and add null_memory_resource as upstream. This way if our working memory is exhausted an exception is thrown.
|
||||
*/
|
||||
auto *monotonic_resource = new std::pmr::monotonic_buffer_resource{resource_buffer.data(), resource_buffer.size(), std::pmr::null_memory_resource()};
|
||||
/*Here we add our custom trace wrapper type to trace allocations and deallocations*/
|
||||
auto *trace_monotonic = new trace_resource("Monotonic", monotonic_resource);
|
||||
|
||||
/* We compose monotonic buffer with pool resource, since the monotonic deallocate is a no-op and we need to remove messages to not go out of memory.*/
|
||||
auto *pool_resource = new std::pmr::unsynchronized_pool_resource{trace_monotonic};
|
||||
auto *trace_pool = new trace_resource("Pool", pool_resource);
|
||||
@@ -293,7 +302,6 @@ extern "C" {
|
||||
} catch (const std::exception &e) {
|
||||
ESP_LOGD(TAG, "Not enough memory to construct the outbox, review the resource_buffer size");
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,13 +326,13 @@ uint8_t *outbox_item_get_data(outbox_item_handle_t item, size_t *len, uint16_t
|
||||
if (item == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return item->get_data(len, msg_id, msg_type, qos);
|
||||
}
|
||||
|
||||
esp_err_t outbox_delete_item(outbox_handle_t outbox, outbox_item_handle_t item_to_delete)
|
||||
{
|
||||
return outbox->erase(item_to_delete);
|
||||
|
||||
}
|
||||
|
||||
esp_err_t outbox_delete(outbox_handle_t outbox, int msg_id, int msg_type)
|
||||
@@ -356,6 +364,7 @@ pending_state_t outbox_item_get_pending(outbox_item_handle_t item)
|
||||
if (item != nullptr) {
|
||||
return item->state();
|
||||
}
|
||||
|
||||
return QUEUED;
|
||||
}
|
||||
|
||||
@@ -384,7 +393,6 @@ void outbox_destroy(outbox_handle_t outbox)
|
||||
auto *pool_resource = static_cast<std::pmr::unsynchronized_pool_resource *>(trace_pool->upstream_resource());
|
||||
auto *trace_monotonic = static_cast<trace_resource *>(pool_resource->upstream_resource());
|
||||
auto *monotonic_resource = static_cast<std::pmr::monotonic_buffer_resource *>(trace_monotonic->upstream_resource());
|
||||
|
||||
delete monotonic_resource;
|
||||
delete trace_monotonic;
|
||||
delete pool_resource;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -26,10 +26,10 @@ static void log_error_if_nonzero(const char *message, int error_code)
|
||||
}
|
||||
|
||||
static esp_mqtt5_user_property_item_t user_property_arr[] = {
|
||||
{"board", "esp32"},
|
||||
{"u", "user"},
|
||||
{"p", "password"}
|
||||
};
|
||||
{"board", "esp32"},
|
||||
{"u", "user"},
|
||||
{"p", "password"}
|
||||
};
|
||||
|
||||
#define USE_PROPERTY_ARR_SIZE sizeof(user_property_arr)/sizeof(esp_mqtt5_user_property_item_t)
|
||||
|
||||
@@ -72,8 +72,10 @@ static void print_user_property(mqtt5_user_property_handle_t user_property)
|
||||
{
|
||||
if (user_property) {
|
||||
uint8_t count = esp_mqtt5_client_get_user_property_count(user_property);
|
||||
|
||||
if (count) {
|
||||
esp_mqtt5_user_property_item_t *item = malloc(count * sizeof(esp_mqtt5_user_property_item_t));
|
||||
|
||||
if (esp_mqtt5_client_get_user_property(user_property, item, &count) == ESP_OK) {
|
||||
for (int i = 0; i < count; i ++) {
|
||||
esp_mqtt5_user_property_item_t *t = &item[i];
|
||||
@@ -82,6 +84,7 @@ static void print_user_property(mqtt5_user_property_handle_t user_property)
|
||||
free((char *)t->value);
|
||||
}
|
||||
}
|
||||
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
@@ -103,8 +106,9 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
ESP_LOGD(TAG, "free heap size is %" PRIu32 ", minimum %" PRIu32, esp_get_free_heap_size(),
|
||||
esp_get_minimum_free_heap_size());
|
||||
|
||||
ESP_LOGD(TAG, "free heap size is %" PRIu32 ", minimum %" PRIu32, esp_get_free_heap_size(), esp_get_minimum_free_heap_size());
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
@@ -115,21 +119,18 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
esp_mqtt5_client_delete_user_property(publish_property.user_property);
|
||||
publish_property.user_property = NULL;
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
esp_mqtt5_client_set_user_property(&subscribe_property.user_property, user_property_arr, USE_PROPERTY_ARR_SIZE);
|
||||
esp_mqtt5_client_set_subscribe_property(client, &subscribe_property);
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
esp_mqtt5_client_delete_user_property(subscribe_property.user_property);
|
||||
subscribe_property.user_property = NULL;
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
esp_mqtt5_client_set_user_property(&subscribe1_property.user_property, user_property_arr, USE_PROPERTY_ARR_SIZE);
|
||||
esp_mqtt5_client_set_subscribe_property(client, &subscribe1_property);
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 2);
|
||||
esp_mqtt5_client_delete_user_property(subscribe1_property.user_property);
|
||||
subscribe1_property.user_property = NULL;
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
esp_mqtt5_client_set_user_property(&unsubscribe_property.user_property, user_property_arr, USE_PROPERTY_ARR_SIZE);
|
||||
esp_mqtt5_client_set_unsubscribe_property(client, &unsubscribe_property);
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos0");
|
||||
@@ -137,10 +138,12 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
esp_mqtt5_client_delete_user_property(unsubscribe_property.user_property);
|
||||
unsubscribe_property.user_property = NULL;
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
print_user_property(event->property->user_property);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, reason code=0x%02x ", event->msg_id, (uint8_t)*event->data);
|
||||
print_user_property(event->property->user_property);
|
||||
@@ -148,6 +151,7 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
print_user_property(event->property->user_property);
|
||||
@@ -157,10 +161,12 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
disconnect_property.user_property = NULL;
|
||||
esp_mqtt_client_disconnect(client);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
print_user_property(event->property->user_property);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
print_user_property(event->property->user_property);
|
||||
@@ -171,17 +177,21 @@ static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32
|
||||
ESP_LOGI(TAG, "TOPIC=%.*s", event->topic_len, event->topic);
|
||||
ESP_LOGI(TAG, "DATA=%.*s", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
print_user_property(event->property->user_property);
|
||||
ESP_LOGI(TAG, "MQTT5 return code is %d", event->error_handle->connect_return_code);
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -204,7 +214,6 @@ static void mqtt5_app_start(void)
|
||||
.correlation_data = "123456",
|
||||
.correlation_data_len = 6,
|
||||
};
|
||||
|
||||
esp_mqtt_client_config_t mqtt5_cfg = {
|
||||
.broker.address.uri = CONFIG_BROKER_URL,
|
||||
.session.protocol_ver = MQTT_PROTOCOL_V_5,
|
||||
@@ -217,15 +226,16 @@ static void mqtt5_app_start(void)
|
||||
.session.last_will.qos = 1,
|
||||
.session.last_will.retain = true,
|
||||
};
|
||||
|
||||
#if CONFIG_BROKER_URL_FROM_STDIN
|
||||
char line[128];
|
||||
|
||||
if (strcmp(mqtt5_cfg.uri, "FROM_STDIN") == 0) {
|
||||
int count = 0;
|
||||
printf("Please enter url of mqtt broker\n");
|
||||
|
||||
while (count < 128) {
|
||||
int c = fgetc(stdin);
|
||||
|
||||
if (c == '\n') {
|
||||
line[count] = '\0';
|
||||
break;
|
||||
@@ -233,29 +243,28 @@ static void mqtt5_app_start(void)
|
||||
line[count] = c;
|
||||
++count;
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
mqtt5_cfg.broker.address.uri = line;
|
||||
printf("Broker url: %s\n", line);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
|
||||
|
||||
/* Set connection properties and user properties */
|
||||
esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, USE_PROPERTY_ARR_SIZE);
|
||||
esp_mqtt5_client_set_user_property(&connect_property.will_user_property, user_property_arr, USE_PROPERTY_ARR_SIZE);
|
||||
esp_mqtt5_client_set_connect_property(client, &connect_property);
|
||||
|
||||
/* If you call esp_mqtt5_client_set_user_property to set user properties, DO NOT forget to delete them.
|
||||
* esp_mqtt5_client_set_connect_property will malloc buffer to store the user_property and you can delete it after
|
||||
*/
|
||||
esp_mqtt5_client_delete_user_property(connect_property.user_property);
|
||||
esp_mqtt5_client_delete_user_property(connect_property.will_user_property);
|
||||
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
|
||||
esp_mqtt_client_start(client);
|
||||
@@ -263,11 +272,9 @@ static void mqtt5_app_start(void)
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("mqtt_example", ESP_LOG_VERBOSE);
|
||||
@@ -275,16 +282,13 @@ void app_main(void)
|
||||
esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt5_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT over SSL Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -26,9 +31,9 @@
|
||||
|
||||
static const char *TAG = "mqtts_example";
|
||||
|
||||
|
||||
#if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n"
|
||||
CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
#else
|
||||
extern const uint8_t mqtt_eclipseprojects_io_pem_start[] asm("_binary_mqtt_eclipseprojects_io_pem_start");
|
||||
#endif
|
||||
@@ -66,18 +71,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -87,23 +92,30 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
|
||||
if (strncmp(event->data, "send binary please", event->data_len) == 0) {
|
||||
ESP_LOGI(TAG, "Sending the binary");
|
||||
send_binary(client);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
ESP_LOGI(TAG, "Last error code reported from esp-tls: 0x%x", event->error_handle->esp_tls_last_esp_err);
|
||||
ESP_LOGI(TAG, "Last tls stack error number: 0x%x", event->error_handle->esp_tls_stack_err);
|
||||
@@ -114,7 +126,9 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Unknown error type: 0x%x", event->error_handle->error_type);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -129,7 +143,6 @@ static void mqtt_app_start(void)
|
||||
.verification.certificate = (const char *)mqtt_eclipseprojects_io_pem_start
|
||||
},
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
@@ -142,7 +155,6 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
@@ -150,16 +162,13 @@ void app_main(void)
|
||||
esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ from threading import Thread
|
||||
import paho.mqtt.client as mqtt
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded import Dut # noqa: F401
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
event_client_connected = Event()
|
||||
|
@@ -2,14 +2,16 @@
|
||||
| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
|
||||
|
||||
# ESP-MQTT SSL Mutual Authentication with Digital Signature
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
Espressif's ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6, ESP32-H2 and ESP32-P4 MCU have a built-in Digital Signature (DS) Peripheral, which provides hardware acceleration for RSA signature. More details can be found at [Digital Signature with ESP-TLS](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/protocols/esp_tls.html#digital-signature-with-esp-tls).
|
||||
|
||||
This example connects to the broker test.mosquitto.org using ssl transport with client certificate(RSA) and as a demonstration subscribes/unsubscribes and sends a message on certain topic.The RSA signature operation required in the ssl connection is performed with help of the Digital Signature (DS) peripheral.
|
||||
(Please note that the public broker is maintained by the community so may not be always available, for details please visit http://test.mosquitto.org)
|
||||
(Please note that the public broker is maintained by the community so may not be always available, for details please visit <http://test.mosquitto.org>)
|
||||
|
||||
It uses ESP-MQTT library which implements mqtt client to connect to mqtt broker.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware Required
|
||||
@@ -21,9 +23,11 @@ This example can be executed on any of the supported ESP32 family board (which h
|
||||
#### 1) Selecting the target
|
||||
|
||||
Please select the supported target with the following command:
|
||||
|
||||
```
|
||||
idf.py set-target /* target */
|
||||
```
|
||||
|
||||
More details can be found at [Selecting the target](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system.html#selecting-the-target).
|
||||
|
||||
#### 2) Generate your client key and certificate
|
||||
@@ -46,15 +50,18 @@ Paste the generated CSR in the [Mosquitto test certificate signer](https://test.
|
||||
#### 3) Configure the DS peripheral
|
||||
|
||||
* i) Install the [esp_secure_cert configuration utility](https://github.com/espressif/esp_secure_cert_mgr/tree/main/tools#esp_secure_cert-configuration-tool) with following command:
|
||||
|
||||
```
|
||||
pip install esp-secure-cert-tool
|
||||
```
|
||||
|
||||
* ii) The DS peripheral can be configured by executing the following command:
|
||||
|
||||
```
|
||||
configure_esp_secure_cert.py -p /* Serial port */ --device-cert /* Device cert */ --private-key /* RSA priv key */ --target_chip /* target chip */ --configure_ds --skip_flash
|
||||
```
|
||||
This command shall generate a partition named `esp_secure_cert.bin` in the `esp_secure_cert_data` directory. This partition would be aumatically detected by the build system and flashed at appropriate offset when `idf.py flash` command is used. For this process, the command must be executed in the current folder only.
|
||||
|
||||
This command shall generate a partition named `esp_secure_cert.bin` in the `esp_secure_cert_data` directory. This partition would be automatically detected by the build system and flashed at appropriate offset when `idf.py flash` command is used. For this process, the command must be executed in the current folder only.
|
||||
|
||||
In the command USB COM port is nothing but the serial port to which the ESP chip is connected. see
|
||||
[check serial port](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/establish-serial-connection.html#check-port-on-windows) for more details.
|
||||
@@ -63,6 +70,7 @@ RSA private key is nothing but the client private key ( RSA ) generated in Step
|
||||
> Note: More details about the `esp-secure-cert-tool` utility can be found [here](https://github.com/espressif/esp_secure_cert_mgr/tree/main/tools).
|
||||
|
||||
#### 4) Connection configuration
|
||||
|
||||
* Open the project configuration menu (`idf.py menuconfig`)
|
||||
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details.
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT Mutual Authentication Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -51,19 +56,19 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
// your_context_t *context = event->context;
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -73,20 +78,25 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -97,14 +107,17 @@ static void mqtt_app_start(void)
|
||||
{
|
||||
/* The context is used by the DS peripheral, should not be freed */
|
||||
esp_ds_data_ctx_t *ds_data = esp_secure_cert_get_ds_ctx();
|
||||
|
||||
if (ds_data == NULL) {
|
||||
ESP_LOGE(TAG, "Error in reading DS data from NVS");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
char *device_cert = NULL;
|
||||
esp_err_t ret;
|
||||
uint32_t len;
|
||||
ret = esp_secure_cert_get_device_cert(&device_cert, &len);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to obtain the device certificate");
|
||||
vTaskDelete(NULL);
|
||||
@@ -113,7 +126,7 @@ static void mqtt_app_start(void)
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker = {
|
||||
.address.uri = "mqtts://test.mosquitto.org:8884",
|
||||
.verification.certificate = (const char *)server_cert_pem_start,
|
||||
.verification.certificate = (const char *)server_cert_pem_start,
|
||||
},
|
||||
.credentials = {
|
||||
.authentication = {
|
||||
@@ -123,7 +136,6 @@ static void mqtt_app_start(void)
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
@@ -135,22 +147,18 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT Mutual Authentication Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -61,18 +66,18 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -82,27 +87,33 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -111,17 +122,16 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
|
||||
static void mqtt_app_start(void)
|
||||
{
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtts://test.mosquitto.org:8884",
|
||||
.broker.verification.certificate = (const char *)server_cert_pem_start,
|
||||
.credentials = {
|
||||
.authentication = {
|
||||
.certificate = (const char *)client_cert_pem_start,
|
||||
.key = (const char *)client_key_pem_start,
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "mqtts://test.mosquitto.org:8884",
|
||||
.broker.verification.certificate = (const char *)server_cert_pem_start,
|
||||
.credentials = {
|
||||
.authentication = {
|
||||
.certificate = (const char *)client_cert_pem_start,
|
||||
.key = (const char *)client_key_pem_start,
|
||||
},
|
||||
}
|
||||
};
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
@@ -134,22 +144,18 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT over SSL Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -47,10 +52,10 @@ static const char *TAG = "mqtts_example";
|
||||
static const uint8_t s_key[] = { 0xBA, 0xD1, 0x23 };
|
||||
|
||||
static const psk_hint_key_t psk_hint_key = {
|
||||
.key = s_key,
|
||||
.key_size = sizeof(s_key),
|
||||
.hint = "hint"
|
||||
};
|
||||
.key = s_key,
|
||||
.key_size = sizeof(s_key),
|
||||
.hint = "hint"
|
||||
};
|
||||
|
||||
/*
|
||||
* @brief Event handler registered to receive MQTT events
|
||||
@@ -68,55 +73,58 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, return code=0x%02x ", event->msg_id, (uint8_t)*event->data);
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d, return code=0x%02x ", event->msg_id, (uint8_t)*event->data);
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mqtt_app_start(void)
|
||||
{
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = EXAMPLE_BROKER_URI,
|
||||
.broker.verification.psk_hint_key = &psk_hint_key,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
@@ -129,23 +137,19 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT (over TCP) Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -23,7 +28,6 @@
|
||||
|
||||
static const char *TAG = "mqtt_example";
|
||||
|
||||
|
||||
static void log_error_if_nonzero(const char *message, int error_code)
|
||||
{
|
||||
if (error_code != 0) {
|
||||
@@ -47,21 +51,20 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos1", "data_3", 0, 1, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -71,27 +74,33 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -109,8 +118,10 @@ static void mqtt_app_start(void)
|
||||
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0) {
|
||||
int count = 0;
|
||||
printf("Please enter url of mqtt broker\n");
|
||||
|
||||
while (count < 128) {
|
||||
int c = fgetc(stdin);
|
||||
|
||||
if (c == '\n') {
|
||||
line[count] = '\0';
|
||||
break;
|
||||
@@ -118,16 +129,18 @@ static void mqtt_app_start(void)
|
||||
line[count] = c;
|
||||
++count;
|
||||
}
|
||||
|
||||
vTaskDelay(10 / portTICK_PERIOD_MS);
|
||||
}
|
||||
|
||||
mqtt_cfg.broker.address.uri = line;
|
||||
printf("Broker url: %s\n", line);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
|
||||
abort();
|
||||
}
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
|
||||
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
@@ -139,7 +152,6 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("mqtt_example", ESP_LOG_VERBOSE);
|
||||
@@ -147,16 +159,13 @@ void app_main(void)
|
||||
esp_log_level_set("esp-tls", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT over Websockets Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -54,6 +59,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
@@ -61,13 +67,12 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -77,27 +82,33 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
|
||||
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
|
||||
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
|
||||
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -109,7 +120,6 @@ static void mqtt_app_start(void)
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = CONFIG_BROKER_URI,
|
||||
};
|
||||
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
@@ -121,7 +131,6 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("mqtt_example", ESP_LOG_VERBOSE);
|
||||
@@ -129,16 +138,13 @@ void app_main(void)
|
||||
esp_log_level_set("transport_ws", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT over Secure Websockets Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -31,9 +36,9 @@
|
||||
|
||||
static const char *TAG = "mqttwss_example";
|
||||
|
||||
|
||||
#if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n"
|
||||
CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
#else
|
||||
extern const uint8_t mqtt_eclipseprojects_io_pem_start[] asm("_binary_mqtt_eclipseprojects_io_pem_start");
|
||||
#endif
|
||||
@@ -43,19 +48,19 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
|
||||
{
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
|
||||
// your_context_t *context = event->context;
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos0", 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_subscribe(client, "/topic/qos1", 1);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
msg_id = esp_mqtt_client_unsubscribe(client, "/topic/qos1");
|
||||
ESP_LOGI(TAG, "sent unsubscribe successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -65,24 +70,30 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event)
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -99,12 +110,10 @@ static void mqtt_app_start(void)
|
||||
.broker.address.uri = CONFIG_BROKER_URI,
|
||||
.broker.verification.certificate = (const char *)mqtt_eclipseprojects_io_pem_start,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
|
||||
|
||||
esp_mqtt_client_start(client);
|
||||
}
|
||||
|
||||
@@ -113,23 +122,19 @@ void app_main(void)
|
||||
ESP_LOGI(TAG, "[APP] Startup..");
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %" PRIu32 " bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("mqtt_example", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport_base", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("transport", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.
|
||||
* Read "Establishing Wi-Fi or Ethernet Connection" section in
|
||||
* examples/protocols/README.md for more information about this function.
|
||||
*/
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
mqtt_app_start();
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ from threading import Thread
|
||||
import paho.mqtt.client as mqtt
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded import Dut # noqa: F401
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
event_client_connected = Event()
|
||||
@@ -49,7 +49,7 @@ def on_message(client, userdata, msg): # type: (mqtt.Client, tuple, mqtt.client
|
||||
|
||||
@pytest.mark.ethernet
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_examples_protocol_mqtt_wss(dut): # type: (Dut) -> None
|
||||
def test_examples_protocol_mqtt_wss(dut): # type: (Dut) -> None # type: ignore
|
||||
broker_url = ''
|
||||
broker_port = 0
|
||||
"""
|
||||
|
@@ -19,5 +19,3 @@ tags:
|
||||
dependencies:
|
||||
idf:
|
||||
version: ">=5.3"
|
||||
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -76,15 +76,18 @@ typedef struct {
|
||||
uint16_t topic_alias_maximum; /*!< The maximum topic alias that we support */
|
||||
bool request_resp_info; /*!< This value to request Server to return Response information */
|
||||
bool request_problem_info; /*!< This value to indicate whether the reason string or user properties are sent in case of failures */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
uint32_t will_delay_interval; /*!< The time interval that server delays publishing will message */
|
||||
uint32_t message_expiry_interval; /*!< The time interval that message expiry */
|
||||
bool payload_format_indicator; /*!< This value is to indicator will message payload format */
|
||||
const char *content_type; /*!< This value is to indicator will message content type, use a MIME content type string */
|
||||
const char
|
||||
*content_type; /*!< This value is to indicator will message content type, use a MIME content type string */
|
||||
const char *response_topic; /*!< Topic name for a response message */
|
||||
const char *correlation_data; /*!< Binary data for receiver to match the response message */
|
||||
uint16_t correlation_data_len; /*!< The length of correlation data */
|
||||
mqtt5_user_property_handle_t will_user_property; /*!< The handle for will message user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
mqtt5_user_property_handle_t
|
||||
will_user_property; /*!< The handle for will message user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_connection_property_config_t;
|
||||
|
||||
/**
|
||||
@@ -93,12 +96,14 @@ typedef struct {
|
||||
typedef struct {
|
||||
bool payload_format_indicator; /*!< This value is to indicator publish message payload format */
|
||||
uint32_t message_expiry_interval; /*!< The time interval that message expiry */
|
||||
uint16_t topic_alias; /*!< An interger value to identify the topic instead of using topic name string */
|
||||
uint16_t topic_alias; /*!< An integer value to identify the topic instead of using topic name string */
|
||||
const char *response_topic; /*!< Topic name for a response message */
|
||||
const char *correlation_data; /*!< Binary data for receiver to match the response message */
|
||||
uint16_t correlation_data_len; /*!< The length of correlation data */
|
||||
const char *content_type; /*!< This value is to indicator publish message content type, use a MIME content type string */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
const char
|
||||
*content_type; /*!< This value is to indicator publish message content type, use a MIME content type string */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_publish_property_config_t;
|
||||
|
||||
/**
|
||||
@@ -110,8 +115,10 @@ typedef struct {
|
||||
bool retain_as_published_flag; /*!< Subscription Option to keep the retain flag as published option */
|
||||
uint8_t retain_handle; /*!< Subscription Option to handle retain option */
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char *share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
const char
|
||||
*share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_subscribe_property_config_t;
|
||||
|
||||
/**
|
||||
@@ -119,8 +126,10 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char *share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
const char
|
||||
*share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_unsubscribe_property_config_t;
|
||||
|
||||
/**
|
||||
@@ -128,8 +137,9 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t session_expiry_interval; /*!< The interval time of session expiry */
|
||||
uint8_t disconnect_reason; /*!< The reason that connection disconnet, refer to mqtt5_error_reason_code */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
uint8_t disconnect_reason; /*!< The reason that connection disconnect, refer to mqtt5_error_reason_code */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_disconnect_property_config_t;
|
||||
|
||||
/**
|
||||
@@ -144,7 +154,8 @@ typedef struct {
|
||||
char *content_type; /*!< Content type of the message */
|
||||
int content_type_len; /*!< Content type length of the message */
|
||||
uint16_t subscribe_id; /*!< Subscription identifier of the message */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_delete_user_property to free the memory */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_delete_user_property to free the memory */
|
||||
} esp_mqtt5_event_property_t;
|
||||
|
||||
/**
|
||||
@@ -166,7 +177,8 @@ typedef struct {
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_connection_property_config_t *connect_property);
|
||||
esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_connection_property_config_t *connect_property);
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client publish property configuration
|
||||
@@ -181,7 +193,8 @@ esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_publish_property_config_t *property);
|
||||
esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_publish_property_config_t *property);
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client subscribe property configuration
|
||||
@@ -196,7 +209,8 @@ esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_subscribe_property_config_t *property);
|
||||
esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_subscribe_property_config_t *property);
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client unsubscribe property configuration
|
||||
@@ -211,7 +225,8 @@ esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t clie
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_unsubscribe_property_config_t *property);
|
||||
esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_unsubscribe_property_config_t *property);
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client disconnect property configuration
|
||||
@@ -227,7 +242,8 @@ esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t cl
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_disconnect_property_config_t *property);
|
||||
esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_disconnect_property_config_t *property);
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client user property configuration
|
||||
@@ -244,7 +260,8 @@ esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t cli
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property, esp_mqtt5_user_property_item_t item[], uint8_t item_num);
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property,
|
||||
esp_mqtt5_user_property_item_t item[], uint8_t item_num);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT5 client user property
|
||||
@@ -261,7 +278,8 @@ esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
* ESP_FAIL on fail
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_property, esp_mqtt5_user_property_item_t *item, uint8_t *item_num);
|
||||
esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_property,
|
||||
esp_mqtt5_user_property_item_t *item, uint8_t *item_num);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT5 client user property list count
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE', which is part of this source code package.
|
||||
@@ -215,7 +220,8 @@ typedef struct esp_mqtt_event_t {
|
||||
bool retain; /*!< Retained flag of the message associated with this event */
|
||||
int qos; /*!< QoS of the messages associated with this event */
|
||||
bool dup; /*!< dup flag of the message associated with this event */
|
||||
esp_mqtt_protocol_ver_t protocol_ver; /*!< MQTT protocol version used for connection, defaults to value from menuconfig*/
|
||||
esp_mqtt_protocol_ver_t
|
||||
protocol_ver; /*!< MQTT protocol version used for connection, defaults to value from menuconfig*/
|
||||
#ifdef CONFIG_MQTT_PROTOCOL_5
|
||||
esp_mqtt5_event_property_t *property; /*!< MQTT 5 property associated with this event */
|
||||
#endif
|
||||
@@ -260,7 +266,8 @@ typedef struct esp_mqtt_client_config_t {
|
||||
documentation for details. */
|
||||
esp_err_t (*crt_bundle_attach)(void *conf); /*!< Pointer to ESP x509 Certificate Bundle attach function for
|
||||
the usage of certificate bundles. Client only attach the bundle, the clean up must be done by the user. */
|
||||
const char *certificate; /*!< Certificate data, default is NULL. It's not copied nor freed by the client, user needs to clean up.*/
|
||||
const char
|
||||
*certificate; /*!< Certificate data, default is NULL. It's not copied nor freed by the client, user needs to clean up.*/
|
||||
size_t certificate_len; /*!< Length of the buffer pointed to by certificate. */
|
||||
const struct psk_key_hint *psk_hint_key; /*!< Pointer to PSK struct defined in esp_tls.h to enable PSK
|
||||
authentication (as alternative to certificate verification).
|
||||
@@ -343,7 +350,7 @@ typedef struct esp_mqtt_client_config_t {
|
||||
* Network related configuration
|
||||
*/
|
||||
struct network_t {
|
||||
int reconnect_timeout_ms; /*!< Reconnect to the broker after this value in miliseconds if auto reconnect is not
|
||||
int reconnect_timeout_ms; /*!< Reconnect to the broker after this value in milliseconds if auto reconnect is not
|
||||
disabled (defaults to 10s) */
|
||||
int timeout_ms; /*!< Abort network operation if it is not completed after this value, in milliseconds
|
||||
(defaults to 10s). */
|
||||
@@ -351,8 +358,9 @@ typedef struct esp_mqtt_client_config_t {
|
||||
bool disable_auto_reconnect; /*!< Client will reconnect to server (when errors/disconnect). Set
|
||||
`disable_auto_reconnect=true` to disable */
|
||||
esp_transport_keep_alive_t tcp_keep_alive_cfg; /*!< Transport keep-alive config*/
|
||||
esp_transport_handle_t transport; /*!< Custom transport handle to use, leave it NULL to allow MQTT client create or recreate its own. Warning: The transport should be valid during the client lifetime and is destroyed when esp_mqtt_client_destroy is called. */
|
||||
struct ifreq * if_name; /*!< The name of interface for data to go through. Use the default interface without setting */
|
||||
esp_transport_handle_t
|
||||
transport; /*!< Custom transport handle to use, leave it NULL to allow MQTT client create or recreate its own. Warning: The transport should be valid during the client lifetime and is destroyed when esp_mqtt_client_destroy is called. */
|
||||
struct ifreq *if_name; /*!< The name of interface for data to go through. Use the default interface without setting */
|
||||
} network; /*!< Network configuration */
|
||||
/**
|
||||
* Client task configuration
|
||||
@@ -364,7 +372,7 @@ typedef struct esp_mqtt_client_config_t {
|
||||
/**
|
||||
* Client buffer size configuration
|
||||
*
|
||||
* Client have two buffers for input and output respectivelly.
|
||||
* Client have two buffers for input and output respectively.
|
||||
*/
|
||||
struct buffer_t {
|
||||
int size; /*!< size of *MQTT* send/receive buffer*/
|
||||
@@ -614,7 +622,7 @@ esp_err_t esp_mqtt_client_destroy(esp_mqtt_client_handle_t client);
|
||||
* (i.e. on "before_connect" event
|
||||
*
|
||||
* Notes:
|
||||
* - When calling this function make sure to have all the intendend configurations
|
||||
* - When calling this function make sure to have all the intended configurations
|
||||
* set, otherwise default values are set.
|
||||
* @param client *MQTT* client handle
|
||||
*
|
||||
@@ -655,7 +663,8 @@ esp_err_t esp_mqtt_client_register_event(esp_mqtt_client_handle_t client,
|
||||
* ESP_ERR_INVALID_ARG on invalid event ID
|
||||
* ESP_OK on success
|
||||
*/
|
||||
esp_err_t esp_mqtt_client_unregister_event(esp_mqtt_client_handle_t client, esp_mqtt_event_id_t event, esp_event_handler_t event_handler);
|
||||
esp_err_t esp_mqtt_client_unregister_event(esp_mqtt_client_handle_t client, esp_mqtt_event_id_t event,
|
||||
esp_event_handler_t event_handler);
|
||||
|
||||
/**
|
||||
* @brief Get outbox size
|
||||
|
@@ -1,16 +1,8 @@
|
||||
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef _MQTT_SUPPORTED_FEATURES_H_
|
||||
#define _MQTT_SUPPORTED_FEATURES_H_
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,7 +48,8 @@ void esp_mqtt5_client_destory(esp_mqtt5_client_handle_t client);
|
||||
esp_err_t esp_mqtt5_client_publish_check(esp_mqtt5_client_handle_t client, int qos, int retain);
|
||||
esp_err_t esp_mqtt5_client_subscribe_check(esp_mqtt5_client_handle_t client, int qos);
|
||||
esp_err_t esp_mqtt5_create_default_config(esp_mqtt5_client_handle_t client);
|
||||
esp_err_t esp_mqtt5_get_publish_data(esp_mqtt5_client_handle_t client, uint8_t *msg_buf, size_t msg_read_len, char **msg_topic, size_t *msg_topic_len, char **msg_data, size_t *msg_data_len);
|
||||
esp_err_t esp_mqtt5_get_publish_data(esp_mqtt5_client_handle_t client, uint8_t *msg_buf, size_t msg_read_len,
|
||||
char **msg_topic, size_t *msg_topic_len, char **msg_data, size_t *msg_data_len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef MQTT5_MSG_H
|
||||
#define MQTT5_MSG_H
|
||||
#include <stdint.h>
|
||||
@@ -119,16 +124,26 @@ typedef struct {
|
||||
#define mqtt5_get_pubcomp_data mqtt5_get_puback_data
|
||||
|
||||
uint16_t mqtt5_get_id(uint8_t *buffer, size_t length);
|
||||
char *mqtt5_get_publish_property_payload(uint8_t *buffer, size_t buffer_length, char **msg_topic, size_t *msg_topic_len, esp_mqtt5_publish_resp_property_t *resp_property, uint16_t *property_len, size_t *payload_len, mqtt5_user_property_handle_t *user_property);
|
||||
char *mqtt5_get_publish_property_payload(uint8_t *buffer, size_t buffer_length, char **msg_topic, size_t *msg_topic_len,
|
||||
esp_mqtt5_publish_resp_property_t *resp_property, uint16_t *property_len, size_t *payload_len,
|
||||
mqtt5_user_property_handle_t *user_property);
|
||||
char *mqtt5_get_suback_data(uint8_t *buffer, size_t *length, mqtt5_user_property_handle_t *user_property);
|
||||
char *mqtt5_get_puback_data(uint8_t *buffer, size_t *length, mqtt5_user_property_handle_t *user_property);
|
||||
mqtt_message_t *mqtt5_msg_connect(mqtt_connection_t *connection, mqtt_connect_info_t *info, esp_mqtt5_connection_property_storage_t *property, esp_mqtt5_connection_will_property_storage_t *will_property);
|
||||
mqtt_message_t *mqtt5_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length, int qos, int retain, uint16_t *message_id, const esp_mqtt5_publish_property_config_t *property, const char *resp_info);
|
||||
esp_err_t mqtt5_msg_parse_connack_property(uint8_t *buffer, size_t buffer_len, mqtt_connect_info_t *connection_info, esp_mqtt5_connection_property_storage_t *connection_property, esp_mqtt5_connection_server_resp_property_t *resp_property, int *reason_code, uint8_t *ack_flag, mqtt5_user_property_handle_t *user_property);
|
||||
mqtt_message_t *mqtt5_msg_connect(mqtt_connection_t *connection, mqtt_connect_info_t *info,
|
||||
esp_mqtt5_connection_property_storage_t *property, esp_mqtt5_connection_will_property_storage_t *will_property);
|
||||
mqtt_message_t *mqtt5_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length,
|
||||
int qos, int retain, uint16_t *message_id, const esp_mqtt5_publish_property_config_t *property, const char *resp_info);
|
||||
esp_err_t mqtt5_msg_parse_connack_property(uint8_t *buffer, size_t buffer_len, mqtt_connect_info_t *connection_info,
|
||||
esp_mqtt5_connection_property_storage_t *connection_property,
|
||||
esp_mqtt5_connection_server_resp_property_t *resp_property, int *reason_code, uint8_t *ack_flag,
|
||||
mqtt5_user_property_handle_t *user_property);
|
||||
int mqtt5_msg_get_reason_code(uint8_t *buffer, size_t length);
|
||||
mqtt_message_t *mqtt5_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t *topic, int size, uint16_t *message_id, const esp_mqtt5_subscribe_property_config_t *property);
|
||||
mqtt_message_t *mqtt5_msg_unsubscribe(mqtt_connection_t *connection, const char *topic, uint16_t *message_id, const esp_mqtt5_unsubscribe_property_config_t *property);
|
||||
mqtt_message_t *mqtt5_msg_disconnect(mqtt_connection_t *connection, esp_mqtt5_disconnect_property_config_t *disconnect_property_info);
|
||||
mqtt_message_t *mqtt5_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t *topic, int size,
|
||||
uint16_t *message_id, const esp_mqtt5_subscribe_property_config_t *property);
|
||||
mqtt_message_t *mqtt5_msg_unsubscribe(mqtt_connection_t *connection, const char *topic, uint16_t *message_id,
|
||||
const esp_mqtt5_unsubscribe_property_config_t *property);
|
||||
mqtt_message_t *mqtt5_msg_disconnect(mqtt_connection_t *connection,
|
||||
esp_mqtt5_disconnect_property_config_t *disconnect_property_info);
|
||||
mqtt_message_t *mqtt5_msg_pubcomp(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt5_msg_pubrel(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt5_msg_pubrec(mqtt_connection_t *connection, uint16_t message_id);
|
||||
@@ -139,4 +154,3 @@ mqtt_message_t *mqtt5_msg_puback(mqtt_connection_t *connection, uint16_t message
|
||||
#endif
|
||||
|
||||
#endif /* MQTT5_MSG_H */
|
||||
|
||||
|
@@ -102,7 +102,7 @@ typedef struct {
|
||||
int message_retransmit_timeout;
|
||||
uint64_t outbox_limit;
|
||||
esp_transport_handle_t transport;
|
||||
struct ifreq * if_name;
|
||||
struct ifreq *if_name;
|
||||
esp_transport_keep_alive_t tcp_keep_alive_cfg;
|
||||
} mqtt_config_storage_t;
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE', which is part of this source code package.
|
||||
|
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2014 Stephen Robinson
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef MQTT_MSG_H
|
||||
#define MQTT_MSG_H
|
||||
#include <stdint.h>
|
||||
@@ -9,41 +15,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/* 7 6 5 4 3 2 1 0 */
|
||||
/*| --- Message Type---- | DUP Flag | QoS Level | Retain | */
|
||||
/* Remaining Length */
|
||||
|
||||
|
||||
enum mqtt_message_type {
|
||||
MQTT_MSG_TYPE_CONNECT = 1,
|
||||
MQTT_MSG_TYPE_CONNACK = 2,
|
||||
@@ -134,12 +109,14 @@ esp_err_t mqtt_msg_buffer_init(mqtt_connection_t *connection, int buffer_size);
|
||||
void mqtt_msg_buffer_destroy(mqtt_connection_t *connection);
|
||||
|
||||
mqtt_message_t *mqtt_msg_connect(mqtt_connection_t *connection, mqtt_connect_info_t *info);
|
||||
mqtt_message_t *mqtt_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length, int qos, int retain, uint16_t *message_id);
|
||||
mqtt_message_t *mqtt_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length,
|
||||
int qos, int retain, uint16_t *message_id);
|
||||
mqtt_message_t *mqtt_msg_puback(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt_msg_pubrec(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt_msg_pubrel(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt_msg_pubcomp(mqtt_connection_t *connection, uint16_t message_id);
|
||||
mqtt_message_t *mqtt_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t topic_list[], int size, uint16_t *message_id) __attribute__((nonnull));
|
||||
mqtt_message_t *mqtt_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t topic_list[], int size,
|
||||
uint16_t *message_id) __attribute__((nonnull));
|
||||
mqtt_message_t *mqtt_msg_unsubscribe(mqtt_connection_t *connection, const char *topic, uint16_t *message_id);
|
||||
mqtt_message_t *mqtt_msg_pingreq(mqtt_connection_t *connection);
|
||||
mqtt_message_t *mqtt_msg_pingresp(mqtt_connection_t *connection);
|
||||
@@ -149,4 +126,3 @@ mqtt_message_t *mqtt_msg_disconnect(mqtt_connection_t *connection);
|
||||
#endif
|
||||
|
||||
#endif /* MQTT_MSG_H */
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE', which is part of this source code package.
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE', which is part of this source code package.
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/*
|
||||
* This file is subject to the terms and conditions defined in
|
||||
* file 'LICENSE', which is part of this source code package.
|
||||
|
349
lib/mqtt5_msg.c
349
lib/mqtt5_msg.c
File diff suppressed because it is too large
Load Diff
@@ -1,33 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Stephen Robinson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
* SPDX-FileCopyrightText: 2014 Stephen Robinson
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_msg.h"
|
||||
@@ -56,7 +31,6 @@ static int append_string(mqtt_connection_t *connection, const char *string, int
|
||||
connection->buffer[connection->outbound_message.length++] = len & 0xff;
|
||||
memcpy(connection->buffer + connection->outbound_message.length, string, len);
|
||||
connection->outbound_message.length += len;
|
||||
|
||||
return len + 2;
|
||||
}
|
||||
|
||||
@@ -78,7 +52,6 @@ static uint16_t append_message_id(mqtt_connection_t *connection, uint16_t messag
|
||||
|
||||
connection->buffer[connection->outbound_message.length++] = message_id >> 8;
|
||||
connection->buffer[connection->outbound_message.length++] = message_id & 0xff;
|
||||
|
||||
return message_id;
|
||||
}
|
||||
|
||||
@@ -101,6 +74,7 @@ static mqtt_message_t *fini_message(mqtt_connection_t *connection, int type, int
|
||||
int total_length = message_length;
|
||||
int encoded_length = 0;
|
||||
uint8_t encoded_lens[4] = {0};
|
||||
|
||||
// Check if we have fragmented message and update total_len
|
||||
if (connection->outbound_message.fragmented_msg_total_length) {
|
||||
total_length = connection->outbound_message.fragmented_msg_total_length - MQTT_MAX_FIXED_HEADER_SIZE;
|
||||
@@ -108,12 +82,15 @@ static mqtt_message_t *fini_message(mqtt_connection_t *connection, int type, int
|
||||
|
||||
// Encode MQTT message length
|
||||
int len_bytes = 0; // size of encoded message length
|
||||
|
||||
do {
|
||||
encoded_length = total_length % 128;
|
||||
total_length /= 128;
|
||||
|
||||
if (total_length > 0) {
|
||||
encoded_length |= 0x80;
|
||||
}
|
||||
|
||||
encoded_lens[len_bytes] = encoded_length;
|
||||
len_bytes++;
|
||||
} while (total_length > 0);
|
||||
@@ -129,7 +106,8 @@ static mqtt_message_t *fini_message(mqtt_connection_t *connection, int type, int
|
||||
connection->outbound_message.data = connection->buffer + offs;
|
||||
connection->outbound_message.fragmented_msg_data_offset -= offs;
|
||||
// type byte
|
||||
connection->buffer[offs++] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
connection->buffer[offs++] = ((type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1);
|
||||
|
||||
// length bytes
|
||||
for (int j = 0; j < len_bytes; j++) {
|
||||
connection->buffer[offs++] = encoded_lens[j];
|
||||
@@ -145,12 +123,15 @@ size_t mqtt_get_total_length(const uint8_t *buffer, size_t length, int *fixed_si
|
||||
|
||||
for (i = 1; i < length; ++i) {
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
|
||||
if ((buffer[i] & 0x80) == 0) {
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
totlen += i;
|
||||
|
||||
if (fixed_size_len) {
|
||||
*fixed_size_len = i;
|
||||
}
|
||||
@@ -167,24 +148,27 @@ bool mqtt_header_complete(uint8_t *buffer, size_t buffer_length)
|
||||
if (i >= buffer_length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((buffer[i] & 0x80) == 0) {
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// i is now the length of the fixed header
|
||||
|
||||
if (i + 2 >= buffer_length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
i += topiclen;
|
||||
|
||||
if (mqtt_get_qos(buffer) > 0) {
|
||||
i += 2;
|
||||
}
|
||||
|
||||
// i is now the length of the fixed + variable header
|
||||
return buffer_length >= i;
|
||||
}
|
||||
@@ -204,6 +188,7 @@ char *mqtt_get_publish_topic(uint8_t *buffer, size_t *length)
|
||||
if (i + 2 >= *length) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
@@ -225,16 +210,19 @@ char *mqtt_get_publish_data(uint8_t *buffer, size_t *length)
|
||||
|
||||
for (i = 1; i < blength; ++i) {
|
||||
totlen += (buffer[i] & 0x7f) << (7 * (i - 1));
|
||||
|
||||
if ((buffer[i] & 0x80) == 0) {
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
totlen += i;
|
||||
|
||||
if (i + 2 >= blength) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
@@ -248,6 +236,7 @@ char *mqtt_get_publish_data(uint8_t *buffer, size_t *length)
|
||||
if (i + 2 >= blength) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
|
||||
@@ -260,6 +249,7 @@ char *mqtt_get_publish_data(uint8_t *buffer, size_t *length)
|
||||
} else {
|
||||
*length = blength - i;
|
||||
}
|
||||
|
||||
return (char *)(buffer + i);
|
||||
}
|
||||
|
||||
@@ -271,6 +261,7 @@ char *mqtt_get_suback_data(uint8_t *buffer, size_t *length)
|
||||
*length -= 4;
|
||||
return (char *)(buffer + 4);
|
||||
}
|
||||
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
@@ -296,18 +287,21 @@ uint16_t mqtt_get_id(uint8_t *buffer, size_t length)
|
||||
if (i + 2 >= length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
topiclen = buffer[i++] << 8;
|
||||
topiclen |= buffer[i++];
|
||||
|
||||
if (i + topiclen > length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
i += topiclen;
|
||||
|
||||
if (mqtt_get_qos(buffer) > 0) {
|
||||
if (i + 2 > length) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//i += 2;
|
||||
} else {
|
||||
return 0;
|
||||
@@ -315,6 +309,7 @@ uint16_t mqtt_get_id(uint8_t *buffer, size_t length)
|
||||
|
||||
return (buffer[i] << 8) | buffer[i + 1];
|
||||
}
|
||||
|
||||
case MQTT_MSG_TYPE_PUBACK:
|
||||
case MQTT_MSG_TYPE_PUBREC:
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
@@ -339,10 +334,9 @@ uint16_t mqtt_get_id(uint8_t *buffer, size_t length)
|
||||
|
||||
mqtt_message_t *mqtt_msg_connect(mqtt_connection_t *connection, mqtt_connect_info_t *info)
|
||||
{
|
||||
|
||||
set_message_header_size(connection);
|
||||
|
||||
int header_len;
|
||||
|
||||
if (info->protocol_ver == MQTT_PROTOCOL_V_3_1) {
|
||||
header_len = MQTT_3_1_VARIABLE_HEADER_SIZE;
|
||||
} else {
|
||||
@@ -352,9 +346,9 @@ mqtt_message_t *mqtt_msg_connect(mqtt_connection_t *connection, mqtt_connect_inf
|
||||
if (connection->outbound_message.length + header_len > connection->buffer_length) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
char *variable_header = (char *)(connection->buffer + connection->outbound_message.length);
|
||||
connection->outbound_message.length += header_len;
|
||||
|
||||
int header_idx = 0;
|
||||
variable_header[header_idx++] = 0; // Variable header length MSB
|
||||
|
||||
@@ -400,9 +394,11 @@ mqtt_message_t *mqtt_msg_connect(mqtt_connection_t *connection, mqtt_connect_inf
|
||||
}
|
||||
|
||||
variable_header[flags_offset] |= MQTT_CONNECT_FLAG_WILL;
|
||||
|
||||
if (info->will_retain) {
|
||||
variable_header[flags_offset] |= MQTT_CONNECT_FLAG_WILL_RETAIN;
|
||||
}
|
||||
|
||||
variable_header[flags_offset] |= (info->will_qos & 3) << 3;
|
||||
}
|
||||
|
||||
@@ -436,7 +432,8 @@ mqtt_message_t *mqtt_msg_connect(mqtt_connection_t *connection, mqtt_connect_inf
|
||||
return fini_message(connection, MQTT_MSG_TYPE_CONNECT, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length, int qos, int retain, uint16_t *message_id)
|
||||
mqtt_message_t *mqtt_msg_publish(mqtt_connection_t *connection, const char *topic, const char *data, int data_length,
|
||||
int qos, int retain, uint16_t *message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
@@ -464,55 +461,67 @@ mqtt_message_t *mqtt_msg_publish(mqtt_connection_t *connection, const char *topi
|
||||
if (connection->outbound_message.length + data_length > connection->buffer_length) {
|
||||
// Not enough size in buffer -> fragment this message
|
||||
connection->outbound_message.fragmented_msg_data_offset = connection->outbound_message.length;
|
||||
memcpy(connection->buffer + connection->outbound_message.length, data, connection->buffer_length - connection->outbound_message.length);
|
||||
memcpy(connection->buffer + connection->outbound_message.length, data,
|
||||
connection->buffer_length - connection->outbound_message.length);
|
||||
connection->outbound_message.length = connection->buffer_length;
|
||||
connection->outbound_message.fragmented_msg_total_length = data_length + connection->outbound_message.fragmented_msg_data_offset;
|
||||
connection->outbound_message.fragmented_msg_total_length = data_length +
|
||||
connection->outbound_message.fragmented_msg_data_offset;
|
||||
} else {
|
||||
memcpy(connection->buffer + connection->outbound_message.length, data, data_length);
|
||||
connection->outbound_message.length += data_length;
|
||||
connection->outbound_message.fragmented_msg_total_length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_puback(mqtt_connection_t *connection, uint16_t message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
if (append_message_id(connection, message_id) == 0) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBACK, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_pubrec(mqtt_connection_t *connection, uint16_t message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
if (append_message_id(connection, message_id) == 0) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREC, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_pubrel(mqtt_connection_t *connection, uint16_t message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
if (append_message_id(connection, message_id) == 0) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBREL, 0, 1, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_pubcomp(mqtt_connection_t *connection, uint16_t message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
if (append_message_id(connection, message_id) == 0) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
return fini_message(connection, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0);
|
||||
}
|
||||
|
||||
mqtt_message_t *mqtt_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t topic_list[], int size, uint16_t *message_id)
|
||||
mqtt_message_t *mqtt_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt_topic_t topic_list[], int size,
|
||||
uint16_t *message_id)
|
||||
{
|
||||
set_message_header_size(connection);
|
||||
|
||||
@@ -532,6 +541,7 @@ mqtt_message_t *mqtt_msg_subscribe(mqtt_connection_t *connection, const esp_mqtt
|
||||
if (connection->outbound_message.length + 1 > connection->buffer_length) {
|
||||
return fail_message(connection);
|
||||
}
|
||||
|
||||
connection->buffer[connection->outbound_message.length] = topic_list[topic_number].qos;
|
||||
connection->outbound_message.length ++;
|
||||
}
|
||||
@@ -587,6 +597,7 @@ int mqtt_has_valid_msg_hdr(uint8_t *buffer, size_t length)
|
||||
if (length < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (mqtt_get_type(buffer)) {
|
||||
case MQTT_MSG_TYPE_CONNECT:
|
||||
case MQTT_MSG_TYPE_CONNACK:
|
||||
@@ -599,10 +610,12 @@ int mqtt_has_valid_msg_hdr(uint8_t *buffer, size_t length)
|
||||
case MQTT_MSG_TYPE_PINGRESP:
|
||||
case MQTT_MSG_TYPE_DISCONNECT:
|
||||
return (buffer[0] & 0x0f) == 0; /* all flag bits are 0 */
|
||||
|
||||
case MQTT_MSG_TYPE_PUBREL:
|
||||
case MQTT_MSG_TYPE_SUBSCRIBE:
|
||||
case MQTT_MSG_TYPE_UNSUBSCRIBE:
|
||||
return (buffer[0] & 0x0f) == 0x02; /* only bit 1 is set */
|
||||
|
||||
case MQTT_MSG_TYPE_PUBLISH:
|
||||
qos = mqtt_get_qos(buffer);
|
||||
dup = mqtt_get_dup(buffer);
|
||||
@@ -611,6 +624,7 @@ int mqtt_has_valid_msg_hdr(uint8_t *buffer, size_t length)
|
||||
* dup flag must be set to 0 for all qos=0 messages [MQTT-3.3.1-2]
|
||||
*/
|
||||
return (qos < 3) && ((qos > 0) || (dup == 0));
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -620,9 +634,11 @@ esp_err_t mqtt_msg_buffer_init(mqtt_connection_t *connection, int buffer_size)
|
||||
{
|
||||
memset(&connection->outbound_message, 0, sizeof(mqtt_message_t));
|
||||
connection->buffer = (uint8_t *)calloc(buffer_size, sizeof(uint8_t));
|
||||
|
||||
if (!connection->buffer) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
connection->buffer_length = buffer_size;
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -633,5 +649,3 @@ void mqtt_msg_buffer_destroy(mqtt_connection_t *connection)
|
||||
free(connection->buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "mqtt_outbox.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
@@ -55,12 +60,15 @@ outbox_item_handle_t outbox_enqueue(outbox_handle_t outbox, outbox_message_handl
|
||||
return NULL;
|
||||
});
|
||||
memcpy(item->buffer, message->data, message->len);
|
||||
|
||||
if (message->remaining_data) {
|
||||
memcpy(item->buffer + message->len, message->remaining_data, message->remaining_len);
|
||||
}
|
||||
|
||||
STAILQ_INSERT_TAIL(outbox->list, item, next);
|
||||
outbox->size += item->len;
|
||||
ESP_LOGD(TAG, "ENQUEUE msgid=%d, msg_type=%d, len=%d, size=%"PRIu64, message->msg_id, message->msg_type, message->len + message->remaining_len, outbox_get_size(outbox));
|
||||
ESP_LOGD(TAG, "ENQUEUE msgid=%d, msg_type=%d, len=%d, size=%"PRIu64, message->msg_id, message->msg_type,
|
||||
message->len + message->remaining_len, outbox_get_size(outbox));
|
||||
return item;
|
||||
}
|
||||
|
||||
@@ -83,6 +91,7 @@ outbox_item_handle_t outbox_dequeue(outbox_handle_t outbox, pending_state_t pend
|
||||
if (tick) {
|
||||
*tick = item->tick;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
@@ -96,7 +105,8 @@ esp_err_t outbox_delete_item(outbox_handle_t outbox, outbox_item_handle_t item_t
|
||||
if (item == item_to_delete) {
|
||||
STAILQ_REMOVE(outbox->list, item, outbox_item, next);
|
||||
outbox->size -= item->len;
|
||||
ESP_LOGD(TAG, "DELETE_ITEM msgid=%d, msg_type=%d, remain size=%"PRIu64, item_to_delete->msg_id, item_to_delete->msg_type, outbox_get_size(outbox));
|
||||
ESP_LOGD(TAG, "DELETE_ITEM msgid=%d, msg_type=%d, remain size=%"PRIu64, item_to_delete->msg_id,
|
||||
item_to_delete->msg_type, outbox_get_size(outbox));
|
||||
free(item->buffer);
|
||||
free(item);
|
||||
return ESP_OK;
|
||||
@@ -114,6 +124,7 @@ uint8_t *outbox_item_get_data(outbox_item_handle_t item, size_t *len, uint16_t
|
||||
*qos = item->msg_qos;
|
||||
return (uint8_t *)item->buffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -129,7 +140,6 @@ esp_err_t outbox_delete(outbox_handle_t outbox, int msg_id, int msg_type)
|
||||
free(item);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -137,10 +147,12 @@ esp_err_t outbox_delete(outbox_handle_t outbox, int msg_id, int msg_type)
|
||||
esp_err_t outbox_set_pending(outbox_handle_t outbox, int msg_id, pending_state_t pending)
|
||||
{
|
||||
outbox_item_handle_t item = outbox_get(outbox, msg_id);
|
||||
|
||||
if (item) {
|
||||
item->pending = pending;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -149,16 +161,19 @@ pending_state_t outbox_item_get_pending(outbox_item_handle_t item)
|
||||
if (item) {
|
||||
return item->pending;
|
||||
}
|
||||
|
||||
return QUEUED;
|
||||
}
|
||||
|
||||
esp_err_t outbox_set_tick(outbox_handle_t outbox, int msg_id, outbox_tick_t tick)
|
||||
{
|
||||
outbox_item_handle_t item = outbox_get(outbox, msg_id);
|
||||
|
||||
if (item) {
|
||||
item->tick = tick;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -176,7 +191,6 @@ int outbox_delete_single_expired(outbox_handle_t outbox, outbox_tick_t current_t
|
||||
ESP_LOGD(TAG, "DELETE_SINGLE_EXPIRED msgid=%d, remain size=%"PRIu64, msg_id, outbox_get_size(outbox));
|
||||
return msg_id;
|
||||
}
|
||||
|
||||
}
|
||||
return msg_id;
|
||||
}
|
||||
@@ -194,7 +208,6 @@ int outbox_delete_expired(outbox_handle_t outbox, outbox_tick_t current_tick, ou
|
||||
free(item);
|
||||
deleted_items ++;
|
||||
}
|
||||
|
||||
}
|
||||
return deleted_items;
|
||||
}
|
||||
@@ -210,7 +223,8 @@ void outbox_delete_all_items(outbox_handle_t outbox)
|
||||
STAILQ_FOREACH_SAFE(item, outbox->list, next, tmp) {
|
||||
STAILQ_REMOVE(outbox->list, item, outbox_item, next);
|
||||
outbox->size -= item->len;
|
||||
ESP_LOGD(TAG, "DELETE_ALL_ITEMS msgid=%d, msg_type=%d, remain size=%"PRIu64, item->msg_id, item->msg_type, outbox_get_size(outbox));
|
||||
ESP_LOGD(TAG, "DELETE_ALL_ITEMS msgid=%d, msg_type=%d, remain size=%"PRIu64, item->msg_id, item->msg_type,
|
||||
outbox_get_size(outbox));
|
||||
free(item->buffer);
|
||||
free(item);
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef ESP_PLATFORM
|
||||
@@ -24,14 +29,14 @@ char *platform_create_id_string(void)
|
||||
{
|
||||
char *id_string = calloc(1, MAX_ID_STRING);
|
||||
ESP_MEM_CHECK(TAG, id_string, return NULL);
|
||||
#ifndef MAC_TYPE
|
||||
#ifndef MAC_TYPE
|
||||
ESP_LOGW(TAG, "Soc doesn't provide MAC, client could be disconnected in case of device with same name in the broker.");
|
||||
sprintf(id_string, "esp_mqtt_client_id");
|
||||
#else
|
||||
#else
|
||||
uint8_t mac[6];
|
||||
esp_read_mac(mac, MAC_TYPE);
|
||||
sprintf(id_string, "ESP32_%02x%02X%02X", mac[3], mac[4], mac[5]);
|
||||
#endif
|
||||
#endif
|
||||
return id_string;
|
||||
}
|
||||
|
||||
@@ -42,7 +47,7 @@ int platform_random(int max)
|
||||
|
||||
uint64_t platform_tick_get_ms(void)
|
||||
{
|
||||
return esp_timer_get_time()/(int64_t)1000;
|
||||
return esp_timer_get_time() / (int64_t)1000;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
204
mqtt5_client.c
204
mqtt5_client.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -11,14 +11,18 @@
|
||||
static const char *TAG = "mqtt5_client";
|
||||
|
||||
static void esp_mqtt5_print_error_code(esp_mqtt5_client_handle_t client, int code);
|
||||
static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias, char *topic, size_t topic_len);
|
||||
static char *esp_mqtt5_client_get_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias, size_t *topic_length);
|
||||
static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle,
|
||||
uint16_t topic_alias, char *topic, size_t topic_len);
|
||||
static char *esp_mqtt5_client_get_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias,
|
||||
size_t *topic_length);
|
||||
static void esp_mqtt5_client_delete_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle);
|
||||
static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_property_new, const mqtt5_user_property_handle_t user_property_old);
|
||||
static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_property_new,
|
||||
const mqtt5_user_property_handle_t user_property_old);
|
||||
|
||||
void esp_mqtt5_increment_packet_counter(esp_mqtt5_client_handle_t client)
|
||||
{
|
||||
bool msg_dup = mqtt5_get_dup(client->mqtt_state.connection.outbound_message.data);
|
||||
|
||||
if (msg_dup == false) {
|
||||
client->send_publish_packet_count ++;
|
||||
ESP_LOGD(TAG, "Sent (%d) qos > 0 publish packet without ack", client->send_publish_packet_count);
|
||||
@@ -36,9 +40,11 @@ void esp_mqtt5_decrement_packet_counter(esp_mqtt5_client_handle_t client)
|
||||
void esp_mqtt5_parse_pubcomp(esp_mqtt5_client_handle_t client)
|
||||
{
|
||||
if (client->mqtt_state.connection.information.protocol_ver == MQTT_PROTOCOL_V_5) {
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_PUBCOMP return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_read_len));
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_PUBCOMP return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer,
|
||||
client->mqtt_state.in_buffer_read_len));
|
||||
size_t msg_data_len = client->mqtt_state.in_buffer_read_len;
|
||||
client->event.data = mqtt5_get_pubcomp_data(client->mqtt_state.in_buffer, &msg_data_len, &client->event.property->user_property);
|
||||
client->event.data = mqtt5_get_pubcomp_data(client->mqtt_state.in_buffer, &msg_data_len,
|
||||
&client->event.property->user_property);
|
||||
client->event.data_len = msg_data_len;
|
||||
client->event.total_data_len = msg_data_len;
|
||||
client->event.current_data_offset = 0;
|
||||
@@ -48,9 +54,11 @@ void esp_mqtt5_parse_pubcomp(esp_mqtt5_client_handle_t client)
|
||||
void esp_mqtt5_parse_puback(esp_mqtt5_client_handle_t client)
|
||||
{
|
||||
if (client->mqtt_state.connection.information.protocol_ver == MQTT_PROTOCOL_V_5) {
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_PUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_read_len));
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_PUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer,
|
||||
client->mqtt_state.in_buffer_read_len));
|
||||
size_t msg_data_len = client->mqtt_state.in_buffer_read_len;
|
||||
client->event.data = mqtt5_get_puback_data(client->mqtt_state.in_buffer, &msg_data_len, &client->event.property->user_property);
|
||||
client->event.data = mqtt5_get_puback_data(client->mqtt_state.in_buffer, &msg_data_len,
|
||||
&client->event.property->user_property);
|
||||
client->event.data_len = msg_data_len;
|
||||
client->event.total_data_len = msg_data_len;
|
||||
client->event.current_data_offset = 0;
|
||||
@@ -60,9 +68,11 @@ void esp_mqtt5_parse_puback(esp_mqtt5_client_handle_t client)
|
||||
void esp_mqtt5_parse_unsuback(esp_mqtt5_client_handle_t client)
|
||||
{
|
||||
if (client->mqtt_state.connection.information.protocol_ver == MQTT_PROTOCOL_V_5) {
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_UNSUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_read_len));
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_UNSUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer,
|
||||
client->mqtt_state.in_buffer_read_len));
|
||||
size_t msg_data_len = client->mqtt_state.in_buffer_read_len;
|
||||
client->event.data = mqtt5_get_unsuback_data(client->mqtt_state.in_buffer, &msg_data_len, &client->event.property->user_property);
|
||||
client->event.data = mqtt5_get_unsuback_data(client->mqtt_state.in_buffer, &msg_data_len,
|
||||
&client->event.property->user_property);
|
||||
client->event.data_len = msg_data_len;
|
||||
client->event.total_data_len = msg_data_len;
|
||||
client->event.current_data_offset = 0;
|
||||
@@ -72,7 +82,8 @@ void esp_mqtt5_parse_unsuback(esp_mqtt5_client_handle_t client)
|
||||
void esp_mqtt5_parse_suback(esp_mqtt5_client_handle_t client)
|
||||
{
|
||||
if (client->mqtt_state.connection.information.protocol_ver == MQTT_PROTOCOL_V_5) {
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_SUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer, client->mqtt_state.in_buffer_read_len));
|
||||
ESP_LOGD(TAG, "MQTT_MSG_TYPE_SUBACK return code is %d", mqtt5_msg_get_reason_code(client->mqtt_state.in_buffer,
|
||||
client->mqtt_state.in_buffer_read_len));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,45 +100,56 @@ esp_err_t esp_mqtt5_parse_connack(esp_mqtt5_client_handle_t client, int *connect
|
||||
size_t len = client->mqtt_state.in_buffer_read_len;
|
||||
client->mqtt_state.in_buffer_read_len = 0;
|
||||
uint8_t ack_flag = 0;
|
||||
|
||||
if (mqtt5_msg_parse_connack_property(client->mqtt_state.in_buffer, len, &client->mqtt_state.
|
||||
connection.information, &client->mqtt5_config->connect_property_info, &client->mqtt5_config->server_resp_property_info, connect_rsp_code, &ack_flag, &client->event.property->user_property) != ESP_OK) {
|
||||
connection.information, &client->mqtt5_config->connect_property_info, &client->mqtt5_config->server_resp_property_info,
|
||||
connect_rsp_code, &ack_flag, &client->event.property->user_property) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to parse CONNACK packet");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (*connect_rsp_code == MQTT_CONNECTION_ACCEPTED) {
|
||||
ESP_LOGD(TAG, "Connected");
|
||||
client->event.session_present = ack_flag & 0x01;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_mqtt5_print_error_code(client, *connect_rsp_code);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_get_publish_data(esp_mqtt5_client_handle_t client, uint8_t *msg_buf, size_t msg_read_len, char **msg_topic, size_t *msg_topic_len, char **msg_data, size_t *msg_data_len)
|
||||
esp_err_t esp_mqtt5_get_publish_data(esp_mqtt5_client_handle_t client, uint8_t *msg_buf, size_t msg_read_len,
|
||||
char **msg_topic, size_t *msg_topic_len, char **msg_data, size_t *msg_data_len)
|
||||
{
|
||||
// get property
|
||||
uint16_t property_len = 0;
|
||||
esp_mqtt5_publish_resp_property_t property = {0};
|
||||
*msg_data = mqtt5_get_publish_property_payload(msg_buf, msg_read_len, msg_topic, msg_topic_len, &property, &property_len, msg_data_len, &client->event.property->user_property);
|
||||
if (*msg_data == NULL) {
|
||||
*msg_data = mqtt5_get_publish_property_payload(msg_buf, msg_read_len, msg_topic, msg_topic_len, &property,
|
||||
&property_len, msg_data_len, &client->event.property->user_property);
|
||||
|
||||
if (*msg_data == NULL) {
|
||||
ESP_LOGE(TAG, "%s: mqtt5_get_publish_property_payload() failed", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (property.topic_alias > client->mqtt5_config->connect_property_info.topic_alias_maximum) {
|
||||
ESP_LOGE(TAG, "%s: Broker response topic alias %d is over the max topic alias %d", __func__, property.topic_alias, client->mqtt5_config->connect_property_info.topic_alias_maximum);
|
||||
ESP_LOGE(TAG, "%s: Broker response topic alias %d is over the max topic alias %d", __func__, property.topic_alias,
|
||||
client->mqtt5_config->connect_property_info.topic_alias_maximum);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (property.topic_alias) {
|
||||
if (*msg_topic_len == 0) {
|
||||
*msg_topic = esp_mqtt5_client_get_topic_alias(client->mqtt5_config->peer_topic_alias, property.topic_alias, msg_topic_len);
|
||||
*msg_topic = esp_mqtt5_client_get_topic_alias(client->mqtt5_config->peer_topic_alias, property.topic_alias,
|
||||
msg_topic_len);
|
||||
|
||||
if (!*msg_topic) {
|
||||
ESP_LOGE(TAG, "%s: esp_mqtt5_client_get_topic_alias() failed", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
} else {
|
||||
if (esp_mqtt5_client_update_topic_alias(client->mqtt5_config->peer_topic_alias, property.topic_alias, *msg_topic, *msg_topic_len) != ESP_OK) {
|
||||
if (esp_mqtt5_client_update_topic_alias(client->mqtt5_config->peer_topic_alias, property.topic_alias, *msg_topic,
|
||||
*msg_topic_len) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "%s: esp_mqtt5_client_update_topic_alias() failed", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -159,6 +181,7 @@ esp_err_t esp_mqtt5_create_default_config(esp_mqtt5_client_handle_t client)
|
||||
client->mqtt5_config->server_resp_property_info.shared_subscribe_available = true;
|
||||
client->mqtt5_config->server_resp_property_info.receive_maximum = 65535;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -168,110 +191,145 @@ static void esp_mqtt5_print_error_code(esp_mqtt5_client_handle_t client, int cod
|
||||
case MQTT5_UNSPECIFIED_ERROR:
|
||||
ESP_LOGW(TAG, "Unspecified error");
|
||||
break;
|
||||
|
||||
case MQTT5_MALFORMED_PACKET:
|
||||
ESP_LOGW(TAG, "Malformed Packet");
|
||||
break;
|
||||
|
||||
case MQTT5_PROTOCOL_ERROR:
|
||||
ESP_LOGW(TAG, "Protocol Error");
|
||||
break;
|
||||
|
||||
case MQTT5_IMPLEMENT_SPECIFIC_ERROR:
|
||||
ESP_LOGW(TAG, "Implementation specific error");
|
||||
break;
|
||||
|
||||
case MQTT5_UNSUPPORTED_PROTOCOL_VER:
|
||||
ESP_LOGW(TAG, "Unsupported Protocol Version");
|
||||
break;
|
||||
|
||||
case MQTT5_INVALID_CLIENT_ID:
|
||||
ESP_LOGW(TAG, "Client Identifier not valid");
|
||||
break;
|
||||
|
||||
case MQTT5_BAD_USERNAME_OR_PWD:
|
||||
ESP_LOGW(TAG, "Bad User Name or Password");
|
||||
break;
|
||||
|
||||
case MQTT5_NOT_AUTHORIZED:
|
||||
ESP_LOGW(TAG, "Not authorized");
|
||||
break;
|
||||
|
||||
case MQTT5_SERVER_UNAVAILABLE:
|
||||
ESP_LOGW(TAG, "Server unavailable");
|
||||
break;
|
||||
|
||||
case MQTT5_SERVER_BUSY:
|
||||
ESP_LOGW(TAG, "Server busy");
|
||||
break;
|
||||
|
||||
case MQTT5_BANNED:
|
||||
ESP_LOGW(TAG, "Banned");
|
||||
break;
|
||||
|
||||
case MQTT5_SERVER_SHUTTING_DOWN:
|
||||
ESP_LOGW(TAG, "Server shutting down");
|
||||
break;
|
||||
|
||||
case MQTT5_BAD_AUTH_METHOD:
|
||||
ESP_LOGW(TAG, "Bad authentication method");
|
||||
break;
|
||||
|
||||
case MQTT5_KEEP_ALIVE_TIMEOUT:
|
||||
ESP_LOGW(TAG, "Keep Alive timeout");
|
||||
break;
|
||||
|
||||
case MQTT5_SESSION_TAKEN_OVER:
|
||||
ESP_LOGW(TAG, "Session taken over");
|
||||
break;
|
||||
|
||||
case MQTT5_TOPIC_FILTER_INVALID:
|
||||
ESP_LOGW(TAG, "Topic Filter invalid");
|
||||
break;
|
||||
|
||||
case MQTT5_TOPIC_NAME_INVALID:
|
||||
ESP_LOGW(TAG, "Topic Name invalid");
|
||||
break;
|
||||
|
||||
case MQTT5_PACKET_IDENTIFIER_IN_USE:
|
||||
ESP_LOGW(TAG, "Packet Identifier in use");
|
||||
break;
|
||||
|
||||
case MQTT5_PACKET_IDENTIFIER_NOT_FOUND:
|
||||
ESP_LOGW(TAG, "Packet Identifier not found");
|
||||
break;
|
||||
|
||||
case MQTT5_RECEIVE_MAXIMUM_EXCEEDED:
|
||||
ESP_LOGW(TAG, "Receive Maximum exceeded");
|
||||
break;
|
||||
|
||||
case MQTT5_TOPIC_ALIAS_INVALID:
|
||||
ESP_LOGW(TAG, "Topic Alias invalid");
|
||||
break;
|
||||
|
||||
case MQTT5_PACKET_TOO_LARGE:
|
||||
ESP_LOGW(TAG, "Packet too large");
|
||||
break;
|
||||
|
||||
case MQTT5_MESSAGE_RATE_TOO_HIGH:
|
||||
ESP_LOGW(TAG, "Message rate too high");
|
||||
break;
|
||||
|
||||
case MQTT5_QUOTA_EXCEEDED:
|
||||
ESP_LOGW(TAG, "Quota exceeded");
|
||||
break;
|
||||
|
||||
case MQTT5_ADMINISTRATIVE_ACTION:
|
||||
ESP_LOGW(TAG, "Administrative action");
|
||||
break;
|
||||
|
||||
case MQTT5_PAYLOAD_FORMAT_INVALID:
|
||||
ESP_LOGW(TAG, "Payload format invalid");
|
||||
break;
|
||||
|
||||
case MQTT5_RETAIN_NOT_SUPPORT:
|
||||
ESP_LOGW(TAG, "Retain not supported");
|
||||
break;
|
||||
|
||||
case MQTT5_QOS_NOT_SUPPORT:
|
||||
ESP_LOGW(TAG, "QoS not supported");
|
||||
break;
|
||||
|
||||
case MQTT5_USE_ANOTHER_SERVER:
|
||||
ESP_LOGW(TAG, "Use another server");
|
||||
break;
|
||||
|
||||
case MQTT5_SERVER_MOVED:
|
||||
ESP_LOGW(TAG, "Server moved");
|
||||
break;
|
||||
|
||||
case MQTT5_SHARED_SUBSCR_NOT_SUPPORTED:
|
||||
ESP_LOGW(TAG, "Shared Subscriptions not supported");
|
||||
break;
|
||||
|
||||
case MQTT5_CONNECTION_RATE_EXCEEDED:
|
||||
ESP_LOGW(TAG, "Connection rate exceeded");
|
||||
break;
|
||||
|
||||
case MQTT5_MAXIMUM_CONNECT_TIME:
|
||||
ESP_LOGW(TAG, "Maximum connect time");
|
||||
break;
|
||||
|
||||
case MQTT5_SUBSCRIBE_IDENTIFIER_NOT_SUPPORT:
|
||||
ESP_LOGW(TAG, "Subscription Identifiers not supported");
|
||||
break;
|
||||
|
||||
case MQTT5_WILDCARD_SUBSCRIBE_NOT_SUPPORT:
|
||||
ESP_LOGW(TAG, "Wildcard Subscriptions not supported");
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGW(TAG, "Connection refused, Unknow reason");
|
||||
ESP_LOGW(TAG, "Connection refused, Unknown reason");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -303,7 +361,8 @@ esp_err_t esp_mqtt5_client_publish_check(esp_mqtt5_client_handle_t client, int q
|
||||
|
||||
/* Flow control to check PUBLISH(No PUBACK or PUBCOMP received) packet sent count(Only record QoS1 and QoS2)*/
|
||||
if (client->send_publish_packet_count > client->mqtt5_config->server_resp_property_info.receive_maximum) {
|
||||
ESP_LOGE(TAG, "Client send more than %d QoS1 and QoS2 PUBLISH packet without no ack", client->mqtt5_config->server_resp_property_info.receive_maximum);
|
||||
ESP_LOGE(TAG, "Client send more than %d QoS1 and QoS2 PUBLISH packet without no ack",
|
||||
client->mqtt5_config->server_resp_property_info.receive_maximum);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
@@ -324,6 +383,7 @@ void esp_mqtt5_client_destory(esp_mqtt5_client_handle_t client)
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
free(client->mqtt5_config);
|
||||
}
|
||||
|
||||
free(client->event.property);
|
||||
}
|
||||
}
|
||||
@@ -341,7 +401,8 @@ static void esp_mqtt5_client_delete_topic_alias(mqtt5_topic_alias_handle_t topic
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias, char *topic, size_t topic_len)
|
||||
static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle,
|
||||
uint16_t topic_alias, char *topic, size_t topic_len)
|
||||
{
|
||||
mqtt5_topic_alias_item_t item;
|
||||
bool found = false;
|
||||
@@ -351,6 +412,7 @@ static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if ((item->topic_len != topic_len) || strncmp(topic, item->topic, topic_len)) {
|
||||
free(item->topic);
|
||||
@@ -372,10 +434,12 @@ static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t
|
||||
memcpy(item->topic, topic, topic_len);
|
||||
STAILQ_INSERT_TAIL(topic_alias_handle, item, next);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static char *esp_mqtt5_client_get_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias, size_t *topic_length)
|
||||
static char *esp_mqtt5_client_get_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle, uint16_t topic_alias,
|
||||
size_t *topic_length)
|
||||
{
|
||||
mqtt5_topic_alias_item_t item;
|
||||
STAILQ_FOREACH(item, topic_alias_handle, next) {
|
||||
@@ -388,7 +452,8 @@ static char *esp_mqtt5_client_get_topic_alias(mqtt5_topic_alias_handle_t topic_a
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_property_new, const mqtt5_user_property_handle_t user_property_old)
|
||||
static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_property_new,
|
||||
const mqtt5_user_property_handle_t user_property_old)
|
||||
{
|
||||
if (!user_property_new || !user_property_old) {
|
||||
ESP_LOGE(TAG, "Input is NULL");
|
||||
@@ -415,12 +480,14 @@ static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_publish_property_config_t *property)
|
||||
esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_publish_property_config_t *property)
|
||||
{
|
||||
if (!client) {
|
||||
ESP_LOGE(TAG, "Client was not initialized");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MQTT_API_LOCK(client);
|
||||
|
||||
/* Check protocol version */
|
||||
@@ -429,27 +496,33 @@ esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Check topic alias less than server maximum topic alias */
|
||||
if (property->topic_alias > client->mqtt5_config->server_resp_property_info.topic_alias_maximum) {
|
||||
ESP_LOGE(TAG, "Topic alias %d is bigger than server support %d", property->topic_alias, client->mqtt5_config->server_resp_property_info.topic_alias_maximum);
|
||||
ESP_LOGE(TAG, "Topic alias %d is bigger than server support %d", property->topic_alias,
|
||||
client->mqtt5_config->server_resp_property_info.topic_alias_maximum);
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
client->mqtt5_config->publish_property_info = property;
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_subscribe_property_config_t *property)
|
||||
esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_subscribe_property_config_t *property)
|
||||
{
|
||||
if (!client) {
|
||||
ESP_LOGE(TAG, "Client was not initialized");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (property->retain_handle > 2) {
|
||||
ESP_LOGE(TAG, "retain_handle only support 0, 1, 2");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MQTT_API_LOCK(client);
|
||||
|
||||
/* Check protocol version */
|
||||
@@ -458,6 +531,7 @@ esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t clie
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (property->is_share_subscribe) {
|
||||
if (property->no_local_flag) {
|
||||
// MQTT-3.8.3-4 not allow that No Local bit to 1 on a Shared Subscription
|
||||
@@ -465,28 +539,33 @@ esp_err_t esp_mqtt5_client_set_subscribe_property(esp_mqtt5_client_handle_t clie
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!client->mqtt5_config->server_resp_property_info.shared_subscribe_available) {
|
||||
ESP_LOGE(TAG, "MQTT broker not support shared subscribe");
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!property->share_name || !strlen(property->share_name)) {
|
||||
ESP_LOGE(TAG, "Share name can't be empty for shared subscribe");
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
client->mqtt5_config->subscribe_property_info = property;
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_unsubscribe_property_config_t *property)
|
||||
esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_unsubscribe_property_config_t *property)
|
||||
{
|
||||
if (!client) {
|
||||
ESP_LOGE(TAG, "Client was not initialized");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MQTT_API_LOCK(client);
|
||||
|
||||
/* Check protocol version */
|
||||
@@ -495,29 +574,34 @@ esp_err_t esp_mqtt5_client_set_unsubscribe_property(esp_mqtt5_client_handle_t cl
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (property->is_share_subscribe) {
|
||||
if (!client->mqtt5_config->server_resp_property_info.shared_subscribe_available) {
|
||||
ESP_LOGE(TAG, "MQTT broker not support shared subscribe");
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!property->share_name || !strlen(property->share_name)) {
|
||||
ESP_LOGE(TAG, "Share name can't be empty for shared subscribe");
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
client->mqtt5_config->unsubscribe_property_info = property;
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_disconnect_property_config_t *property)
|
||||
esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_disconnect_property_config_t *property)
|
||||
{
|
||||
if (!client) {
|
||||
ESP_LOGE(TAG, "Client was not initialized");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MQTT_API_LOCK(client);
|
||||
|
||||
/* Check protocol version */
|
||||
@@ -526,13 +610,16 @@ esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t cli
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (property) {
|
||||
if (property->session_expiry_interval) {
|
||||
client->mqtt5_config->disconnect_property_info.session_expiry_interval = property->session_expiry_interval;
|
||||
}
|
||||
|
||||
if (property->disconnect_reason) {
|
||||
client->mqtt5_config->disconnect_property_info.disconnect_reason = property->disconnect_reason;
|
||||
}
|
||||
|
||||
if (property->user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
client->mqtt5_config->disconnect_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
@@ -541,7 +628,9 @@ esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t cli
|
||||
return ESP_ERR_NO_MEM;
|
||||
});
|
||||
STAILQ_INIT(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->disconnect_property_info.user_property, property->user_property) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->disconnect_property_info.user_property,
|
||||
property->user_property) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_mqtt5_user_property_copy fail");
|
||||
free(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
client->mqtt5_config->disconnect_property_info.user_property = NULL;
|
||||
@@ -555,12 +644,14 @@ esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t cli
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client, const esp_mqtt5_connection_property_config_t *connect_property)
|
||||
esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client,
|
||||
const esp_mqtt5_connection_property_config_t *connect_property)
|
||||
{
|
||||
if (!client) {
|
||||
ESP_LOGE(TAG, "Client was not initialized");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
MQTT_API_LOCK(client);
|
||||
|
||||
/* Check protocol version */
|
||||
@@ -569,13 +660,16 @@ esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (connect_property) {
|
||||
if (connect_property->session_expiry_interval) {
|
||||
client->mqtt5_config->connect_property_info.session_expiry_interval = connect_property->session_expiry_interval;
|
||||
}
|
||||
|
||||
if (connect_property->maximum_packet_size) {
|
||||
if (connect_property->maximum_packet_size > client->mqtt_state.in_buffer_length) {
|
||||
ESP_LOGW(TAG, "Connect maximum_packet_size property is over buffer_size(%d), Please first change it", client->mqtt_state.in_buffer_length);
|
||||
ESP_LOGW(TAG, "Connect maximum_packet_size property is over buffer_size(%d), Please first change it",
|
||||
client->mqtt_state.in_buffer_length);
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_FAIL;
|
||||
} else {
|
||||
@@ -584,62 +678,82 @@ esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client
|
||||
} else {
|
||||
client->mqtt5_config->connect_property_info.maximum_packet_size = client->mqtt_state.in_buffer_length;
|
||||
}
|
||||
|
||||
if (connect_property->receive_maximum) {
|
||||
client->mqtt5_config->connect_property_info.receive_maximum = connect_property->receive_maximum;
|
||||
}
|
||||
|
||||
if (connect_property->topic_alias_maximum) {
|
||||
client->mqtt5_config->connect_property_info.topic_alias_maximum = connect_property->topic_alias_maximum;
|
||||
|
||||
if (!client->mqtt5_config->peer_topic_alias) {
|
||||
client->mqtt5_config->peer_topic_alias = calloc(1, sizeof(struct mqtt5_topic_alias_list_t));
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->peer_topic_alias, goto _mqtt_set_config_failed);
|
||||
STAILQ_INIT(client->mqtt5_config->peer_topic_alias);
|
||||
}
|
||||
}
|
||||
|
||||
if (connect_property->request_resp_info) {
|
||||
client->mqtt5_config->connect_property_info.request_resp_info = connect_property->request_resp_info;
|
||||
}
|
||||
|
||||
if (connect_property->request_problem_info) {
|
||||
client->mqtt5_config->connect_property_info.request_problem_info = connect_property->request_problem_info;
|
||||
}
|
||||
|
||||
if (connect_property->user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->connect_property_info.user_property);
|
||||
client->mqtt5_config->connect_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->connect_property_info.user_property, goto _mqtt_set_config_failed);
|
||||
STAILQ_INIT(client->mqtt5_config->connect_property_info.user_property);
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->connect_property_info.user_property, connect_property->user_property) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->connect_property_info.user_property,
|
||||
connect_property->user_property) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_mqtt5_user_property_copy fail");
|
||||
goto _mqtt_set_config_failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (connect_property->payload_format_indicator) {
|
||||
client->mqtt5_config->will_property_info.payload_format_indicator = connect_property->payload_format_indicator;
|
||||
}
|
||||
|
||||
if (connect_property->will_delay_interval) {
|
||||
client->mqtt5_config->will_property_info.will_delay_interval = connect_property->will_delay_interval;
|
||||
}
|
||||
|
||||
if (connect_property->message_expiry_interval) {
|
||||
client->mqtt5_config->will_property_info.message_expiry_interval = connect_property->message_expiry_interval;
|
||||
}
|
||||
ESP_MEM_CHECK(TAG, esp_mqtt_set_if_config(connect_property->content_type, &client->mqtt5_config->will_property_info.content_type), goto _mqtt_set_config_failed);
|
||||
ESP_MEM_CHECK(TAG, esp_mqtt_set_if_config(connect_property->response_topic, &client->mqtt5_config->will_property_info.response_topic), goto _mqtt_set_config_failed);
|
||||
|
||||
ESP_MEM_CHECK(TAG, esp_mqtt_set_if_config(connect_property->content_type,
|
||||
&client->mqtt5_config->will_property_info.content_type), goto _mqtt_set_config_failed);
|
||||
ESP_MEM_CHECK(TAG, esp_mqtt_set_if_config(connect_property->response_topic,
|
||||
&client->mqtt5_config->will_property_info.response_topic), goto _mqtt_set_config_failed);
|
||||
|
||||
if (connect_property->correlation_data && connect_property->correlation_data_len) {
|
||||
free(client->mqtt5_config->will_property_info.correlation_data);
|
||||
client->mqtt5_config->will_property_info.correlation_data = malloc(connect_property->correlation_data_len);
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->will_property_info.correlation_data, goto _mqtt_set_config_failed);
|
||||
memcpy(client->mqtt5_config->will_property_info.correlation_data, connect_property->correlation_data, connect_property->correlation_data_len);
|
||||
memcpy(client->mqtt5_config->will_property_info.correlation_data, connect_property->correlation_data,
|
||||
connect_property->correlation_data_len);
|
||||
client->mqtt5_config->will_property_info.correlation_data_len = connect_property->correlation_data_len;
|
||||
}
|
||||
|
||||
if (connect_property->will_user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->will_property_info.user_property);
|
||||
client->mqtt5_config->will_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->will_property_info.user_property, goto _mqtt_set_config_failed);
|
||||
STAILQ_INIT(client->mqtt5_config->will_property_info.user_property);
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->will_property_info.user_property, connect_property->will_user_property) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->will_property_info.user_property,
|
||||
connect_property->will_user_property) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "esp_mqtt5_user_property_copy fail");
|
||||
goto _mqtt_set_config_failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_OK;
|
||||
_mqtt_set_config_failed:
|
||||
@@ -648,7 +762,8 @@ _mqtt_set_config_failed:
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property, esp_mqtt5_user_property_item_t item[], uint8_t item_num)
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property,
|
||||
esp_mqtt5_user_property_item_t item[], uint8_t item_num)
|
||||
{
|
||||
if (!item_num || !item) {
|
||||
ESP_LOGE(TAG, "Input value is NULL");
|
||||
@@ -667,7 +782,6 @@ esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
ESP_MEM_CHECK(TAG, user_property_item, goto err);
|
||||
size_t key_len = strlen(item[i].key);
|
||||
size_t value_len = strlen(item[i].value);
|
||||
|
||||
user_property_item->key = calloc(1, key_len + 1);
|
||||
ESP_MEM_CHECK(TAG, user_property_item->key, {
|
||||
free(user_property_item);
|
||||
@@ -675,7 +789,6 @@ esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
});
|
||||
memcpy(user_property_item->key, item[i].key, key_len);
|
||||
user_property_item->key[key_len] = '\0';
|
||||
|
||||
user_property_item->value = calloc(1, value_len + 1);
|
||||
ESP_MEM_CHECK(TAG, user_property_item->value, {
|
||||
free(user_property_item->key);
|
||||
@@ -684,10 +797,10 @@ esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
});
|
||||
memcpy(user_property_item->value, item[i].value, value_len);
|
||||
user_property_item->value[value_len] = '\0';
|
||||
|
||||
STAILQ_INSERT_TAIL(*user_property, user_property_item, next);
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
@@ -695,9 +808,11 @@ err:
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_property, esp_mqtt5_user_property_item_t *item, uint8_t *item_num)
|
||||
esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_property,
|
||||
esp_mqtt5_user_property_item_t *item, uint8_t *item_num)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (user_property && item && *item_num) {
|
||||
mqtt5_user_property_item_t user_property_item;
|
||||
uint8_t num = *item_num;
|
||||
@@ -729,27 +844,33 @@ esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_p
|
||||
ESP_LOGE(TAG, "Input value is NULL or item_num is 0");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
for (j = 0; j < i; j ++) {
|
||||
if (item[j].key) {
|
||||
free((char *)item[j].key);
|
||||
}
|
||||
|
||||
if (item[j].value) {
|
||||
free((char *)item[j].value);
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
uint8_t esp_mqtt5_client_get_user_property_count(mqtt5_user_property_handle_t user_property)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
if (user_property) {
|
||||
mqtt5_user_property_item_t item;
|
||||
STAILQ_FOREACH(item, user_property, next) {
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -764,5 +885,6 @@ void esp_mqtt5_client_delete_user_property(mqtt5_user_property_handle_t user_pro
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
free(user_property);
|
||||
}
|
||||
|
596
mqtt_client.c
596
mqtt_client.c
File diff suppressed because it is too large
Load Diff
@@ -25,4 +25,3 @@ log_cli = True
|
||||
log_cli_level = INFO
|
||||
log_cli_format = %(asctime)s %(levelname)s %(message)s
|
||||
log_cli_date_format = %Y-%m-%d %H:%M:%S
|
||||
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
/* Build only example to check mqtt client API from C++
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "esp_eth.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#if SOC_EMAC_SUPPORTED
|
||||
#define ETH_START_BIT BIT(0)
|
||||
#define ETH_STOP_BIT BIT(1)
|
||||
@@ -20,7 +19,6 @@
|
||||
#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;
|
||||
@@ -29,30 +27,34 @@ 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +78,15 @@ static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_
|
||||
{
|
||||
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 {
|
||||
@@ -89,7 +94,6 @@ static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void connect_test_fixture_setup(void)
|
||||
{
|
||||
EventBits_t bits;
|
||||
@@ -99,14 +103,12 @@ void connect_test_fixture_setup(void)
|
||||
// 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
|
||||
|
@@ -2,4 +2,3 @@ dependencies:
|
||||
espressif/mqtt:
|
||||
version: "*"
|
||||
override_path: "../../../.."
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*
|
||||
@@ -23,12 +23,14 @@
|
||||
|
||||
TEST_GROUP(mqtt);
|
||||
|
||||
TEST_SETUP(mqtt){
|
||||
TEST_SETUP(mqtt)
|
||||
{
|
||||
test_utils_record_free_mem();
|
||||
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
|
||||
}
|
||||
|
||||
TEST_TEAR_DOWN(mqtt){
|
||||
TEST_TEAR_DOWN(mqtt)
|
||||
{
|
||||
test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL),
|
||||
test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL));
|
||||
}
|
||||
@@ -36,87 +38,85 @@ TEST_TEAR_DOWN(mqtt){
|
||||
TEST(mqtt, init_with_invalid_url)
|
||||
{
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = "INVALID",
|
||||
.broker.address.uri = "INVALID",
|
||||
};
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
TEST_ASSERT_EQUAL(NULL, client );
|
||||
TEST_ASSERT_EQUAL(NULL, client);
|
||||
}
|
||||
|
||||
TEST(mqtt, init_and_deinit)
|
||||
{
|
||||
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",
|
||||
// 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 );
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, client);
|
||||
esp_mqtt_client_destroy(client);
|
||||
}
|
||||
|
||||
static const char* this_bin_addr(void)
|
||||
static const char *this_bin_addr(void)
|
||||
{
|
||||
esp_partition_mmap_handle_t out_handle;
|
||||
const void *binary_address;
|
||||
const esp_partition_t* partition = esp_ota_get_running_partition();
|
||||
const esp_partition_t *partition = esp_ota_get_running_partition();
|
||||
esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &binary_address, &out_handle);
|
||||
return binary_address;
|
||||
}
|
||||
|
||||
TEST(mqtt, enqueue_and_destroy_outbox)
|
||||
{
|
||||
const char * bin_addr = this_bin_addr();
|
||||
|
||||
// Reseting leak detection since this_bin_addr adds to allocated memory.
|
||||
const char *bin_addr = this_bin_addr();
|
||||
// Resetting leak detection since this_bin_addr adds to allocated memory.
|
||||
test_utils_record_free_mem();
|
||||
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
|
||||
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",
|
||||
// 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 );
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, client);
|
||||
int bytes_before = esp_get_free_heap_size();
|
||||
for (int i=0; i<messages; ++i) {
|
||||
|
||||
for (int i = 0; i < messages; ++i) {
|
||||
esp_mqtt_client_publish(client, "test", bin_addr, size, 1, 0);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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
|
||||
* This test cases uses ethernet kit, so build and use it only if EMACS supported
|
||||
*/
|
||||
TEST(mqtt, broker_tests)
|
||||
{
|
||||
test_case_uses_tcpip();
|
||||
connect_test_fixture_setup();
|
||||
|
||||
RUN_MQTT_BROKER_TEST(mqtt_connect_disconnect);
|
||||
RUN_MQTT_BROKER_TEST(mqtt_subscribe_publish);
|
||||
RUN_MQTT_BROKER_TEST(mqtt_lwt_clean_disconnect);
|
||||
RUN_MQTT_BROKER_TEST(mqtt_subscribe_payload);
|
||||
|
||||
connect_test_fixture_teardown();
|
||||
}
|
||||
#endif // SOC_EMAC_SUPPORTED
|
||||
|
||||
|
||||
TEST_GROUP_RUNNER(mqtt) {
|
||||
RUN_TEST_CASE(mqtt, init_with_invalid_url);
|
||||
RUN_TEST_CASE(mqtt, init_and_deinit);
|
||||
RUN_TEST_CASE(mqtt, enqueue_and_destroy_outbox);
|
||||
|
||||
TEST_GROUP_RUNNER(mqtt)
|
||||
{
|
||||
RUN_TEST_CASE(mqtt, init_with_invalid_url);
|
||||
RUN_TEST_CASE(mqtt, init_and_deinit);
|
||||
RUN_TEST_CASE(mqtt, enqueue_and_destroy_outbox);
|
||||
#if SOC_EMAC_SUPPORTED
|
||||
RUN_TEST_CASE(mqtt, broker_tests);
|
||||
RUN_TEST_CASE(mqtt, broker_tests);
|
||||
#endif // SOC_EMAC_SUPPORTED
|
||||
}
|
||||
|
||||
void app_main(void){
|
||||
UNITY_MAIN(mqtt);
|
||||
void app_main(void)
|
||||
{
|
||||
UNITY_MAIN(mqtt);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -22,7 +22,6 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
static const int COMMON_OPERATION_TIMEOUT = 10000;
|
||||
static const int CONNECT_BIT = BIT0;
|
||||
static const int DISCONNECT_BIT = BIT1;
|
||||
@@ -30,7 +29,7 @@ static const int DATA_BIT = BIT2;
|
||||
|
||||
static EventGroupHandle_t s_event_group;
|
||||
|
||||
static char* append_mac(const char* string)
|
||||
static char *append_mac(const char *string)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
char *id_string = NULL;
|
||||
@@ -43,7 +42,7 @@ static void mqtt_data_handler_qos(void *handler_args, esp_event_base_t base, int
|
||||
{
|
||||
if (event_id == MQTT_EVENT_DATA) {
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
int * qos = handler_args;
|
||||
int *qos = handler_args;
|
||||
*qos = event->qos;
|
||||
xEventGroupSetBits(s_event_group, DATA_BIT);
|
||||
}
|
||||
@@ -56,12 +55,13 @@ static void mqtt_data_handler_lwt(void *handler_args, esp_event_base_t base, int
|
||||
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;
|
||||
int *count = handler_args;
|
||||
*count = *count + 1;
|
||||
ESP_LOGE("mqtt-lwt", "count=%d", *count);
|
||||
}
|
||||
@@ -73,40 +73,42 @@ static void mqtt_data_handler_subscribe(void *handler_args, esp_event_base_t bas
|
||||
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;
|
||||
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;
|
||||
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_CONNECTED:
|
||||
xEventGroupSetBits(s_event_group, CONNECT_BIT);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
|
||||
break;
|
||||
default:
|
||||
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,
|
||||
.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 );
|
||||
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);
|
||||
@@ -122,13 +124,13 @@ bool mqtt_connect_disconnect(void)
|
||||
bool mqtt_subscribe_publish(void)
|
||||
{
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
|
||||
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
|
||||
};
|
||||
char* topic = append_mac("topic");
|
||||
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 );
|
||||
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);
|
||||
@@ -149,25 +151,24 @@ bool mqtt_subscribe_publish(void)
|
||||
|
||||
bool mqtt_lwt_clean_disconnect(void)
|
||||
{
|
||||
char* lwt = append_mac("lwt");
|
||||
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"
|
||||
.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"
|
||||
.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 );
|
||||
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);
|
||||
@@ -201,14 +202,14 @@ bool mqtt_lwt_clean_disconnect(void)
|
||||
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,
|
||||
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
|
||||
.network.disable_auto_reconnect = true,
|
||||
};
|
||||
char* topic = append_mac("topic");
|
||||
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 );
|
||||
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);
|
||||
|
@@ -19,7 +19,6 @@
|
||||
ESP_LOGI("mqtt_test", "Test:" #test_name "() passed "); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This module contains mqtt test cases interacting the client with a (real) broker
|
||||
*/
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,7 +15,6 @@
|
||||
#include "test_mqtt_connection.h"
|
||||
#include "esp_partition.h"
|
||||
|
||||
|
||||
TEST_GROUP(mqtt5);
|
||||
|
||||
TEST_SETUP(mqtt5)
|
||||
@@ -43,7 +42,7 @@ TEST(mqtt5, init_with_invalid_url)
|
||||
.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_ASSERT_EQUAL(NULL, client);
|
||||
}
|
||||
|
||||
TEST(mqtt5, init_and_deinit)
|
||||
@@ -75,14 +74,13 @@ TEST(mqtt5, init_and_deinit)
|
||||
.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 );
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, client);
|
||||
esp_mqtt_client_destroy(client);
|
||||
}
|
||||
|
||||
@@ -98,7 +96,7 @@ static const char *this_bin_addr(void)
|
||||
TEST(mqtt5, enqueue_and_destroy_outbox)
|
||||
{
|
||||
const char *bin_addr = this_bin_addr();
|
||||
// Reseting leak detection since this_bin_addr adds to allocated memory.
|
||||
// Resetting leak detection since this_bin_addr adds to allocated memory.
|
||||
test_utils_record_free_mem();
|
||||
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
|
||||
const int messages = 20;
|
||||
@@ -118,8 +116,9 @@ TEST(mqtt5, enqueue_and_destroy_outbox)
|
||||
.content_type = "json",
|
||||
};
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, client );
|
||||
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);
|
||||
@@ -127,27 +126,25 @@ TEST(mqtt5, enqueue_and_destroy_outbox)
|
||||
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
|
||||
* This test cases uses ethernet kit, so build and use it only if EMACS supported
|
||||
*/
|
||||
TEST(mqtt5, broker_tests)
|
||||
{
|
||||
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
|
||||
@@ -158,14 +155,12 @@ TEST_GROUP_RUNNER(mqtt5)
|
||||
RUN_TEST_CASE(mqtt5, init_with_invalid_url);
|
||||
RUN_TEST_CASE(mqtt5, init_and_deinit);
|
||||
RUN_TEST_CASE(mqtt5, enqueue_and_destroy_outbox);
|
||||
|
||||
#if SOC_EMAC_SUPPORTED
|
||||
RUN_TEST_CASE(mqtt5, broker_tests);
|
||||
#endif // SOC_EMAC_SUPPORTED
|
||||
#endif //!DISABLED_FOR_TARGETS(ESP32H2)
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
UNITY_MAIN(mqtt5);
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -23,7 +23,6 @@
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
static const int COMMON_OPERATION_TIMEOUT = 10000;
|
||||
static const int CONNECT_BIT = BIT0;
|
||||
static const int DISCONNECT_BIT = BIT1;
|
||||
@@ -37,7 +36,7 @@ static esp_mqtt5_user_property_item_t user_property_arr[3] = {
|
||||
{"p", "password"}
|
||||
};
|
||||
|
||||
static char* append_mac(const char* string)
|
||||
static char *append_mac(const char *string)
|
||||
{
|
||||
uint8_t mac[6];
|
||||
char *id_string = NULL;
|
||||
@@ -50,7 +49,7 @@ static void mqtt5_data_handler_qos(void *handler_args, esp_event_base_t base, in
|
||||
{
|
||||
if (event_id == MQTT_EVENT_DATA) {
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
int * qos = handler_args;
|
||||
int *qos = handler_args;
|
||||
*qos = event->qos;
|
||||
xEventGroupSetBits(s_event_group, DATA_BIT);
|
||||
}
|
||||
@@ -63,12 +62,13 @@ static void mqtt5_data_handler_lwt(void *handler_args, esp_event_base_t base, in
|
||||
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;
|
||||
int *count = handler_args;
|
||||
*count = *count + 1;
|
||||
ESP_LOGE("mqtt5-lwt", "count=%d", *count);
|
||||
}
|
||||
@@ -80,37 +80,39 @@ static void mqtt5_data_handler_subscribe(void *handler_args, esp_event_base_t ba
|
||||
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;
|
||||
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;
|
||||
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_CONNECTED:
|
||||
xEventGroupSetBits(s_event_group, CONNECT_BIT);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
|
||||
break;
|
||||
default:
|
||||
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,
|
||||
.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,
|
||||
@@ -126,14 +128,15 @@ bool mqtt5_connect_disconnect(void)
|
||||
};
|
||||
s_event_group = xEventGroupCreate();
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
|
||||
TEST_ASSERT_TRUE(NULL != client );
|
||||
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_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);
|
||||
@@ -148,8 +151,8 @@ bool mqtt5_connect_disconnect(void)
|
||||
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,
|
||||
.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,
|
||||
@@ -166,11 +169,11 @@ bool mqtt5_subscribe_publish(void)
|
||||
.retain_as_published_flag = true,
|
||||
.retain_handle = 0,
|
||||
};
|
||||
char* topic = append_mac("topic");
|
||||
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 );
|
||||
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);
|
||||
@@ -193,21 +196,21 @@ bool mqtt5_subscribe_publish(void)
|
||||
|
||||
bool mqtt5_lwt_clean_disconnect(void)
|
||||
{
|
||||
char* lwt = append_mac("lwt");
|
||||
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,
|
||||
.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,
|
||||
.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,
|
||||
@@ -219,10 +222,9 @@ bool mqtt5_lwt_clean_disconnect(void)
|
||||
.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 );
|
||||
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));
|
||||
@@ -258,15 +260,15 @@ bool mqtt5_lwt_clean_disconnect(void)
|
||||
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,
|
||||
.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");
|
||||
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 );
|
||||
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);
|
||||
|
@@ -20,7 +20,6 @@
|
||||
ESP_LOGI("mqtt5_test", "Test:" #test_name "() passed "); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/**
|
||||
* @brief This module contains mqtt5 test cases interacting the client with a (real) broker
|
||||
*/
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT connect test
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -43,16 +48,21 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
(void)event_id;
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
ESP_LOGD(TAG, "Event: %d, Test case: %d", event->event_id, running_test_case);
|
||||
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_BEFORE_CONNECT:
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED: Test=%d", running_test_case);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_ERROR: Test=%d", running_test_case);
|
||||
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_ESP_TLS) {
|
||||
ESP_LOGI(TAG, "ESP-TLS ERROR: %s", esp_err_to_name(event->error_handle->esp_tls_last_esp_err));
|
||||
} else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
|
||||
@@ -60,7 +70,9 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Unknown error type: 0x%x", event->error_handle->error_type);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -69,7 +81,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
|
||||
static void connect_no_certs(esp_mqtt_client_handle_t client, const char *uri)
|
||||
{
|
||||
ESP_LOGI(TAG, "Runnning :CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT");
|
||||
ESP_LOGI(TAG, "Running :CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT");
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri
|
||||
};
|
||||
@@ -81,10 +93,10 @@ static void connect_with_client_key_password(esp_mqtt_client_handle_t client, co
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.verification.certificate = (const char *)ca_local_crt,
|
||||
.credentials.authentication.certificate = (const char *)client_pwd_crt,
|
||||
.credentials.authentication.key = (const char *)client_pwd_key,
|
||||
.credentials.authentication.key_password = "esp32",
|
||||
.credentials.authentication.key_password_len = 5
|
||||
.credentials.authentication.certificate = (const char *)client_pwd_crt,
|
||||
.credentials.authentication.key = (const char *)client_pwd_key,
|
||||
.credentials.authentication.key_password = "esp32",
|
||||
.credentials.authentication.key_password_len = 5
|
||||
};
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
@@ -94,9 +106,9 @@ static void connect_with_server_der_cert(esp_mqtt_client_handle_t client, const
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.verification.certificate = (const char *)ca_der_start,
|
||||
.broker.verification.certificate_len = ca_der_end - ca_der_start,
|
||||
.credentials.authentication.certificate = "NULL",
|
||||
.credentials.authentication.key = "NULL"
|
||||
.broker.verification.certificate_len = ca_der_end - ca_der_start,
|
||||
.credentials.authentication.certificate = "NULL",
|
||||
.credentials.authentication.key = "NULL"
|
||||
};
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
@@ -106,8 +118,8 @@ static void connect_with_wrong_server_cert(esp_mqtt_client_handle_t client, cons
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.verification.certificate = (const char *)client_pwd_crt,
|
||||
.credentials.authentication.certificate = "NULL",
|
||||
.credentials.authentication.key = "NULL"
|
||||
.credentials.authentication.certificate = "NULL",
|
||||
.credentials.authentication.key = "NULL"
|
||||
};
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
@@ -126,8 +138,8 @@ static void connect_with_server_client_certs(esp_mqtt_client_handle_t client, co
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.verification.certificate = (const char *)ca_local_crt,
|
||||
.credentials.authentication.certificate = (const char *)client_pwd_crt,
|
||||
.credentials.authentication.key = (const char *)client_no_pwd_key
|
||||
.credentials.authentication.certificate = (const char *)client_pwd_crt,
|
||||
.credentials.authentication.key = (const char *)client_no_pwd_key
|
||||
};
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
@@ -137,8 +149,8 @@ static void connect_with_invalid_client_certs(esp_mqtt_client_handle_t client, c
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
.broker.address.uri = uri,
|
||||
.broker.verification.certificate = (const char *)ca_local_crt,
|
||||
.credentials.authentication.certificate = (const char *)client_inv_crt,
|
||||
.credentials.authentication.key = (const char *)client_no_pwd_key
|
||||
.credentials.authentication.certificate = (const char *)client_inv_crt,
|
||||
.credentials.authentication.key = (const char *)client_no_pwd_key
|
||||
};
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
@@ -153,45 +165,57 @@ static void connect_with_alpn(esp_mqtt_client_handle_t client, const char *uri)
|
||||
esp_mqtt_set_config(client, &mqtt_cfg);
|
||||
}
|
||||
|
||||
void connect_setup(command_context_t * ctx) {
|
||||
void connect_setup(command_context_t *ctx)
|
||||
{
|
||||
esp_mqtt_client_register_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, ctx->data);
|
||||
}
|
||||
|
||||
void connect_teardown(command_context_t * ctx) {
|
||||
void connect_teardown(command_context_t *ctx)
|
||||
{
|
||||
esp_mqtt_client_unregister_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler);
|
||||
}
|
||||
void connection_test(command_context_t * ctx, const char *uri, int test_case)
|
||||
void connection_test(command_context_t *ctx, const char *uri, int test_case)
|
||||
{
|
||||
ESP_LOGI(TAG, "CASE:%d, connecting to %s", test_case, uri);
|
||||
running_test_case = test_case;
|
||||
|
||||
switch (test_case) {
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT:
|
||||
connect_no_certs(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT:
|
||||
connect_with_server_cert(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH:
|
||||
connect_with_server_client_certs(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT:
|
||||
connect_with_wrong_server_cert(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT:
|
||||
connect_with_server_der_cert(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD:
|
||||
connect_with_client_key_password(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT:
|
||||
connect_with_invalid_client_certs(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN:
|
||||
connect_with_alpn(ctx->mqtt_client, uri);
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unknown test case %d ", test_case);
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Test case:%d started", test_case);
|
||||
}
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT publish-connect test
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -36,15 +41,16 @@ publish_args_t publish_args;
|
||||
return 1; \
|
||||
}} while(0)
|
||||
|
||||
|
||||
static int do_free_heap(int argc, char **argv) {
|
||||
static int do_free_heap(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
ESP_LOGI(TAG, "Note free memory: %d bytes", esp_get_free_heap_size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_init(int argc, char **argv) {
|
||||
static int do_init(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||
@@ -52,75 +58,92 @@ static int do_init(int argc, char **argv) {
|
||||
.network.disable_auto_reconnect = true
|
||||
};
|
||||
command_context.mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
|
||||
if(!command_context.mqtt_client) {
|
||||
|
||||
if (!command_context.mqtt_client) {
|
||||
ESP_LOGE(TAG, "Failed to initialize client");
|
||||
return 1;
|
||||
}
|
||||
|
||||
publish_init_flags();
|
||||
ESP_LOGI(TAG, "Mqtt client initialized");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_start(int argc, char **argv) {
|
||||
static int do_start(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if(esp_mqtt_client_start(command_context.mqtt_client) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt_client_start(command_context.mqtt_client) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to start mqtt client task");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Mqtt client started");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_stop(int argc, char **argv) {
|
||||
static int do_stop(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if(esp_mqtt_client_stop(command_context.mqtt_client) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt_client_stop(command_context.mqtt_client) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to stop mqtt client task");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Mqtt client stopped");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_disconnect(int argc, char **argv) {
|
||||
static int do_disconnect(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if(esp_mqtt_client_disconnect(command_context.mqtt_client) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt_client_disconnect(command_context.mqtt_client) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to request disconnection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Mqtt client disconnected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_connect_setup(int argc, char **argv) {
|
||||
static int do_connect_setup(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
connect_setup(&command_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_connect_teardown(int argc, char **argv) {
|
||||
static int do_connect_teardown(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
connect_teardown(&command_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_reconnect(int argc, char **argv) {
|
||||
static int do_reconnect(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
if(esp_mqtt_client_reconnect(command_context.mqtt_client) != ESP_OK) {
|
||||
|
||||
if (esp_mqtt_client_reconnect(command_context.mqtt_client) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to request reconnection");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Mqtt client will reconnect");
|
||||
return 0;
|
||||
;
|
||||
}
|
||||
|
||||
static int do_destroy(int argc, char **argv) {
|
||||
static int do_destroy(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
esp_mqtt_client_destroy(command_context.mqtt_client);
|
||||
@@ -132,54 +155,62 @@ static int do_destroy(int argc, char **argv) {
|
||||
static int do_connect(int argc, char **argv)
|
||||
{
|
||||
int nerrors = arg_parse(argc, argv, (void **) &connection_args);
|
||||
|
||||
if (nerrors != 0) {
|
||||
arg_print_errors(stderr, connection_args.end, argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if(!command_context.mqtt_client) {
|
||||
|
||||
if (!command_context.mqtt_client) {
|
||||
ESP_LOGE(TAG, "MQTT client not initialized, call init first");
|
||||
return 1;
|
||||
}
|
||||
|
||||
connection_test(&command_context, *connection_args.uri->sval, *connection_args.test_case->ival);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_publish_setup(int argc, char **argv) {
|
||||
static int do_publish_setup(int argc, char **argv)
|
||||
{
|
||||
RETURN_ON_PARSE_ERROR(publish_setup_args);
|
||||
if(command_context.data) {
|
||||
|
||||
if (command_context.data) {
|
||||
free(command_context.data);
|
||||
}
|
||||
|
||||
command_context.data = calloc(1, sizeof(publish_context_t));
|
||||
((publish_context_t*)command_context.data)->pattern = strdup(*publish_setup_args.pattern->sval);
|
||||
((publish_context_t*)command_context.data)->pattern_repetitions = *publish_setup_args.pattern_repetitions->ival;
|
||||
((publish_context_t*)command_context.data)->subscribe_to = strdup(*publish_setup_args.subscribe_to->sval);
|
||||
((publish_context_t*)command_context.data)->publish_to = strdup(*publish_setup_args.publish_to->sval);
|
||||
((publish_context_t *)command_context.data)->pattern = strdup(*publish_setup_args.pattern->sval);
|
||||
((publish_context_t *)command_context.data)->pattern_repetitions = *publish_setup_args.pattern_repetitions->ival;
|
||||
((publish_context_t *)command_context.data)->subscribe_to = strdup(*publish_setup_args.subscribe_to->sval);
|
||||
((publish_context_t *)command_context.data)->publish_to = strdup(*publish_setup_args.publish_to->sval);
|
||||
publish_setup(&command_context, *publish_setup_args.transport->sval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_publish(int argc, char **argv) {
|
||||
static int do_publish(int argc, char **argv)
|
||||
{
|
||||
RETURN_ON_PARSE_ERROR(publish_args);
|
||||
publish_test(&command_context, publish_args.expected_to_publish->ival[0], publish_args.qos->ival[0], publish_args.enqueue->ival[0]);
|
||||
publish_test(&command_context, publish_args.expected_to_publish->ival[0], publish_args.qos->ival[0],
|
||||
publish_args.enqueue->ival[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_publish_report(int argc, char **argv) {
|
||||
static int do_publish_report(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
publish_context_t * ctx = command_context.data;
|
||||
ESP_LOGI(TAG,"Test Report : Messages received %d, %d expected", ctx->nr_of_msg_received, ctx->nr_of_msg_expected);
|
||||
|
||||
publish_context_t *ctx = command_context.data;
|
||||
ESP_LOGI(TAG, "Test Report : Messages received %d, %d expected", ctx->nr_of_msg_received, ctx->nr_of_msg_expected);
|
||||
return 0;
|
||||
}
|
||||
void register_common_commands(void) {
|
||||
void register_common_commands(void)
|
||||
{
|
||||
const esp_console_cmd_t init = {
|
||||
.command = "init",
|
||||
.help = "Run inition test\n",
|
||||
.hint = NULL,
|
||||
.func = &do_init,
|
||||
};
|
||||
|
||||
const esp_console_cmd_t start = {
|
||||
.command = "start",
|
||||
.help = "Run startion test\n",
|
||||
@@ -210,17 +241,19 @@ void register_common_commands(void) {
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&destroy));
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&free_heap));
|
||||
}
|
||||
void register_publish_commands(void) {
|
||||
publish_setup_args.transport = arg_str1(NULL,NULL,"<transport>", "Selected transport to test");
|
||||
publish_setup_args.publish_to = arg_str1(NULL,NULL,"<transport>", "Selected publish_to to publish");
|
||||
publish_setup_args.subscribe_to = arg_str1(NULL,NULL,"<transport>", "Selected subscribe_to to publish");
|
||||
publish_setup_args.pattern = arg_str1(NULL,NULL,"<pattern>", "Message pattern repeated to build big messages");
|
||||
publish_setup_args.pattern_repetitions = arg_int1(NULL,NULL,"<pattern repetitions>", "How many times the pattern is repeated");
|
||||
void register_publish_commands(void)
|
||||
{
|
||||
publish_setup_args.transport = arg_str1(NULL, NULL, "<transport>", "Selected transport to test");
|
||||
publish_setup_args.publish_to = arg_str1(NULL, NULL, "<transport>", "Selected publish_to to publish");
|
||||
publish_setup_args.subscribe_to = arg_str1(NULL, NULL, "<transport>", "Selected subscribe_to to publish");
|
||||
publish_setup_args.pattern = arg_str1(NULL, NULL, "<pattern>", "Message pattern repeated to build big messages");
|
||||
publish_setup_args.pattern_repetitions = arg_int1(NULL, NULL, "<pattern repetitions>",
|
||||
"How many times the pattern is repeated");
|
||||
publish_setup_args.end = arg_end(1);
|
||||
|
||||
publish_args.expected_to_publish = arg_int1(NULL,NULL,"<number of messages>", "How many times the pattern is repeated");
|
||||
publish_args.qos = arg_int1(NULL,NULL,"<qos>", "How many times the pattern is repeated");
|
||||
publish_args.enqueue = arg_int1(NULL,NULL,"<enqueue>", "How many times the pattern is repeated");
|
||||
publish_args.expected_to_publish = arg_int1(NULL, NULL, "<number of messages>",
|
||||
"How many times the pattern is repeated");
|
||||
publish_args.qos = arg_int1(NULL, NULL, "<qos>", "How many times the pattern is repeated");
|
||||
publish_args.enqueue = arg_int1(NULL, NULL, "<enqueue>", "How many times the pattern is repeated");
|
||||
publish_args.end = arg_end(1);
|
||||
const esp_console_cmd_t publish_setup = {
|
||||
.command = "publish_setup",
|
||||
@@ -229,7 +262,6 @@ void register_publish_commands(void) {
|
||||
.func = &do_publish_setup,
|
||||
.argtable = &publish_setup_args
|
||||
};
|
||||
|
||||
const esp_console_cmd_t publish = {
|
||||
.command = "publish",
|
||||
.help = "Run publish test\n",
|
||||
@@ -247,11 +279,11 @@ void register_publish_commands(void) {
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&publish));
|
||||
ESP_ERROR_CHECK(esp_console_cmd_register(&publish_report));
|
||||
}
|
||||
void register_connect_commands(void){
|
||||
connection_args.uri = arg_str1(NULL,NULL,"<broker uri>", "Broker address");
|
||||
connection_args.test_case = arg_int1(NULL, NULL, "<test case>","Selected test case");
|
||||
void register_connect_commands(void)
|
||||
{
|
||||
connection_args.uri = arg_str1(NULL, NULL, "<broker uri>", "Broker address");
|
||||
connection_args.test_case = arg_int1(NULL, NULL, "<test case>", "Selected test case");
|
||||
connection_args.end = arg_end(1);
|
||||
|
||||
const esp_console_cmd_t connect = {
|
||||
.command = "connect",
|
||||
.help = "Run connection test\n",
|
||||
@@ -259,7 +291,6 @@ void register_connect_commands(void){
|
||||
.func = &do_connect,
|
||||
.argtable = &connection_args
|
||||
};
|
||||
|
||||
const esp_console_cmd_t reconnect = {
|
||||
.command = "reconnect",
|
||||
.help = "Run reconnection test\n",
|
||||
@@ -292,7 +323,7 @@ void register_connect_commands(void){
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EXAMPLE_RUN_LOCAL_BROKER
|
||||
static void broker_task(void* ctx)
|
||||
static void broker_task(void *ctx)
|
||||
{
|
||||
// broker continues to run in this task
|
||||
struct mosq_broker_config config = { .host = CONFIG_EXAMPLE_BROKER_HOST, .port = CONFIG_EXAMPLE_BROKER_PORT };
|
||||
@@ -303,15 +334,12 @@ static void broker_task(void* ctx)
|
||||
void app_main(void)
|
||||
{
|
||||
static const size_t max_line = 256;
|
||||
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
|
||||
ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version());
|
||||
|
||||
esp_log_level_set("*", ESP_LOG_INFO);
|
||||
esp_log_level_set("wifi", ESP_LOG_ERROR);
|
||||
esp_log_level_set("mqtt_client", ESP_LOG_VERBOSE);
|
||||
esp_log_level_set("outbox", ESP_LOG_VERBOSE);
|
||||
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
@@ -327,7 +355,6 @@ void app_main(void)
|
||||
register_common_commands();
|
||||
register_connect_commands();
|
||||
register_publish_commands();
|
||||
|
||||
esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
|
||||
ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl));
|
||||
ESP_ERROR_CHECK(esp_console_start_repl(repl));
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@@ -11,7 +11,7 @@ typedef enum {NONE, TCP, SSL, WS, WSS} transport_t;
|
||||
|
||||
typedef struct {
|
||||
esp_mqtt_client_handle_t mqtt_client;
|
||||
void * data;
|
||||
void *data;
|
||||
} command_context_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -25,7 +25,7 @@ typedef struct {
|
||||
size_t expected_size;
|
||||
size_t nr_of_msg_received;
|
||||
size_t nr_of_msg_expected;
|
||||
char * received_data;
|
||||
char *received_data;
|
||||
} publish_context_t ;
|
||||
|
||||
typedef struct {
|
||||
@@ -51,9 +51,9 @@ typedef struct {
|
||||
} publish_setup_args_t;
|
||||
|
||||
void publish_init_flags(void);
|
||||
void publish_setup(command_context_t * ctx, char const * transport);
|
||||
void publish_teardown(command_context_t * ctx);
|
||||
void publish_test(command_context_t * ctx, int expect_to_publish, int qos, bool enqueue);
|
||||
void connection_test(command_context_t * ctx, const char *uri, int test_case);
|
||||
void connect_setup(command_context_t * ctx);
|
||||
void connect_teardown(command_context_t * ctx);
|
||||
void publish_setup(command_context_t *ctx, char const *transport);
|
||||
void publish_teardown(command_context_t *ctx);
|
||||
void publish_test(command_context_t *ctx, int expect_to_publish, int qos, bool enqueue);
|
||||
void connection_test(command_context_t *ctx, const char *uri, int test_case);
|
||||
void connect_setup(command_context_t *ctx);
|
||||
void connect_teardown(command_context_t *ctx);
|
||||
|
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/* MQTT publish test
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
@@ -27,7 +32,8 @@ static EventGroupHandle_t mqtt_event_group;
|
||||
const static int CONNECTED_BIT = BIT0;
|
||||
#define CLIENT_ID_SUFFIX_SIZE 12
|
||||
#if CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDDEN == 1
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n"
|
||||
CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
|
||||
#else
|
||||
extern const uint8_t mqtt_eclipseprojects_io_pem_start[] asm("_binary_mqtt_eclipseprojects_io_pem_start");
|
||||
#endif
|
||||
@@ -35,21 +41,23 @@ extern const uint8_t mqtt_eclipseprojects_io_pem_end[] asm("_binary_mqtt_eclip
|
||||
|
||||
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
publish_context_t * test_data = handler_args;
|
||||
publish_context_t *test_data = handler_args;
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
static int msg_id = 0;
|
||||
static int actual_len = 0;
|
||||
|
||||
switch (event->event_id) {
|
||||
case MQTT_EVENT_BEFORE_CONNECT:
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
|
||||
xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT);
|
||||
msg_id = esp_mqtt_client_subscribe(client, test_data->subscribe_to, test_data->qos);
|
||||
ESP_LOGI(TAG, "sent subscribe successful %s , msg_id=%d", test_data->subscribe_to, msg_id);
|
||||
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
break;
|
||||
@@ -57,58 +65,74 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGD(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
|
||||
ESP_LOGI(TAG, "TOPIC=%.*s", event->topic_len, event->topic);
|
||||
ESP_LOGI(TAG, "ID=%d, total_len=%d, data_len=%d, current_data_offset=%d", event->msg_id, event->total_data_len, event->data_len, event->current_data_offset);
|
||||
if (event->current_data_offset == 0) {
|
||||
actual_len = event->data_len;
|
||||
msg_id = event->msg_id;
|
||||
if (event->total_data_len != test_data->expected_size) {
|
||||
ESP_LOGE(TAG, "Incorrect message size: %d != %d", event->total_data_len, test_data->expected_size);
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
actual_len += event->data_len;
|
||||
// check consistency with msg_id across multiple data events for single msg
|
||||
if (msg_id != event->msg_id) {
|
||||
ESP_LOGE(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
if (event->current_data_offset + event->data_len > test_data->expected_size) {
|
||||
ESP_LOGE(TAG, "Buffer overflow detected: offset %d + data_len %d > buffer size %d", event->current_data_offset, event->data_len, test_data->expected_size);
|
||||
abort();
|
||||
}
|
||||
if (memcmp(test_data->expected + event->current_data_offset, event->data, event->data_len) != 0) {
|
||||
ESP_LOGE(TAG, "Data mismatch at offset %d: \n expected %.*s, \n got %.*s", event->current_data_offset, event->data_len, test_data->expected + event->current_data_offset, event->data_len, event->data);
|
||||
abort();
|
||||
}
|
||||
ESP_LOGI(TAG, "ID=%d, total_len=%d, data_len=%d, current_data_offset=%d", event->msg_id, event->total_data_len,
|
||||
event->data_len, event->current_data_offset);
|
||||
|
||||
if (event->current_data_offset == 0) {
|
||||
actual_len = event->data_len;
|
||||
msg_id = event->msg_id;
|
||||
|
||||
if (event->total_data_len != test_data->expected_size) {
|
||||
ESP_LOGE(TAG, "Incorrect message size: %d != %d", event->total_data_len, test_data->expected_size);
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
actual_len += event->data_len;
|
||||
|
||||
// check consistency with msg_id across multiple data events for single msg
|
||||
if (msg_id != event->msg_id) {
|
||||
ESP_LOGE(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
if (event->current_data_offset + event->data_len > test_data->expected_size) {
|
||||
ESP_LOGE(TAG, "Buffer overflow detected: offset %d + data_len %d > buffer size %d", event->current_data_offset,
|
||||
event->data_len, test_data->expected_size);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (memcmp(test_data->expected + event->current_data_offset, event->data, event->data_len) != 0) {
|
||||
ESP_LOGE(TAG, "Data mismatch at offset %d: \n expected %.*s, \n got %.*s", event->current_data_offset, event->data_len,
|
||||
test_data->expected + event->current_data_offset, event->data_len, event->data);
|
||||
abort();
|
||||
}
|
||||
|
||||
memcpy(test_data->received_data + event->current_data_offset, event->data, event->data_len);
|
||||
|
||||
if (actual_len == event->total_data_len) {
|
||||
if (0 == memcmp(test_data->received_data, test_data->expected, test_data->expected_size)) {
|
||||
memset(test_data->received_data, 0, test_data->expected_size);
|
||||
test_data->nr_of_msg_received++;
|
||||
|
||||
if (test_data->nr_of_msg_received == test_data->nr_of_msg_expected) {
|
||||
ESP_LOGI(TAG, "Correct pattern received exactly x times");
|
||||
ESP_LOGI(TAG, "Test finished correctly!");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "FAILED!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(test_data->received_data + event->current_data_offset, event->data, event->data_len);
|
||||
if (actual_len == event->total_data_len) {
|
||||
if (0 == memcmp(test_data->received_data, test_data->expected, test_data->expected_size)) {
|
||||
memset(test_data->received_data, 0, test_data->expected_size);
|
||||
test_data->nr_of_msg_received++;
|
||||
if (test_data->nr_of_msg_received == test_data->nr_of_msg_expected) {
|
||||
ESP_LOGI(TAG, "Correct pattern received exactly x times");
|
||||
ESP_LOGI(TAG, "Test finished correctly!");
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "FAILED!");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGE(TAG, "MQTT_EVENT_ERROR");
|
||||
break;
|
||||
|
||||
default:
|
||||
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
@@ -120,7 +144,7 @@ void test_init(void)
|
||||
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
|
||||
}
|
||||
|
||||
void pattern_setup(publish_context_t * test_data)
|
||||
void pattern_setup(publish_context_t *test_data)
|
||||
{
|
||||
int pattern_size = strlen(test_data->pattern);
|
||||
free(test_data->expected);
|
||||
@@ -129,17 +153,20 @@ void pattern_setup(publish_context_t * test_data)
|
||||
test_data->expected_size = (size_t)(pattern_size) * test_data->pattern_repetitions;
|
||||
test_data->expected = malloc(test_data->expected_size);
|
||||
test_data->received_data = malloc(test_data->expected_size);
|
||||
|
||||
for (int i = 0; i < test_data->pattern_repetitions; i++) {
|
||||
memcpy(test_data->expected + (ptrdiff_t)(i * pattern_size), test_data->pattern, pattern_size);
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "EXPECTED STRING %.*s, SIZE:%d", test_data->expected_size, test_data->expected, test_data->expected_size);
|
||||
}
|
||||
|
||||
static void configure_client(command_context_t * ctx, const char *transport)
|
||||
static void configure_client(command_context_t *ctx, const char *transport)
|
||||
{
|
||||
publish_context_t * test_data = ctx->data;
|
||||
publish_context_t *test_data = ctx->data;
|
||||
ESP_LOGI(TAG, "Configuration");
|
||||
transport_t selected_transport;
|
||||
|
||||
if (0 == strcmp(transport, "tcp")) {
|
||||
selected_transport = TCP;
|
||||
} else if (0 == strcmp(transport, "ssl")) {
|
||||
@@ -153,34 +180,40 @@ static void configure_client(command_context_t * ctx, const char *transport)
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
if (selected_transport != test_data->selected_transport) {
|
||||
test_data->selected_transport = selected_transport;
|
||||
esp_mqtt_client_config_t config = {0};
|
||||
|
||||
switch (selected_transport) {
|
||||
case NONE:
|
||||
break;
|
||||
|
||||
case TCP:
|
||||
ESP_LOGI(TAG, "[TCP transport] Startup..");
|
||||
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_TCP_URI;
|
||||
break;
|
||||
|
||||
case SSL:
|
||||
ESP_LOGI(TAG, "[SSL transport] Startup..");
|
||||
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_SSL_URI;
|
||||
break;
|
||||
|
||||
case WS:
|
||||
ESP_LOGI(TAG, "[WS transport] Startup..");
|
||||
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_WS_URI;
|
||||
break;
|
||||
|
||||
case WSS:
|
||||
ESP_LOGI(TAG, "[WSS transport] Startup..");
|
||||
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_WSS_URI;
|
||||
break;
|
||||
}
|
||||
|
||||
if (selected_transport == SSL || selected_transport == WSS) {
|
||||
ESP_LOGI(TAG, "Set certificate");
|
||||
config.broker.verification.certificate = (const char *)mqtt_eclipseprojects_io_pem_start;
|
||||
}
|
||||
|
||||
// Generate a random client id for each iteration
|
||||
char client_id[CLIENT_ID_SUFFIX_SIZE] = {0};
|
||||
snprintf(client_id, sizeof(client_id), "esp32-%08X", esp_random());
|
||||
@@ -189,41 +222,47 @@ static void configure_client(command_context_t * ctx, const char *transport)
|
||||
}
|
||||
}
|
||||
|
||||
void publish_init_flags(void) {
|
||||
void publish_init_flags(void)
|
||||
{
|
||||
mqtt_event_group = xEventGroupCreate();
|
||||
}
|
||||
|
||||
void publish_setup(command_context_t * ctx, char const * const transport) {
|
||||
void publish_setup(command_context_t *ctx, char const *const transport)
|
||||
{
|
||||
xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);
|
||||
publish_context_t * data = (publish_context_t*)ctx->data;
|
||||
publish_context_t *data = (publish_context_t *)ctx->data;
|
||||
pattern_setup(data);
|
||||
configure_client(ctx, transport);
|
||||
esp_mqtt_client_register_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, data);
|
||||
}
|
||||
|
||||
void publish_teardown(command_context_t * ctx)
|
||||
void publish_teardown(command_context_t *ctx)
|
||||
{
|
||||
esp_mqtt_client_unregister_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler);
|
||||
}
|
||||
|
||||
void publish_test(command_context_t * ctx, int expect_to_publish, int qos, bool enqueue)
|
||||
void publish_test(command_context_t *ctx, int expect_to_publish, int qos, bool enqueue)
|
||||
{
|
||||
publish_context_t * data = (publish_context_t*)ctx->data;
|
||||
publish_context_t *data = (publish_context_t *)ctx->data;
|
||||
data->nr_of_msg_expected = expect_to_publish;
|
||||
ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d", data->pattern, data->pattern_repetitions, data->nr_of_msg_expected);
|
||||
|
||||
ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d", data->pattern, data->pattern_repetitions,
|
||||
data->nr_of_msg_expected);
|
||||
xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
|
||||
|
||||
for (int i = 0; i < data->nr_of_msg_expected; i++) {
|
||||
int msg_id;
|
||||
|
||||
if (enqueue) {
|
||||
msg_id = esp_mqtt_client_enqueue(ctx->mqtt_client, data->publish_to, data->expected, data->expected_size, qos, 0, true);
|
||||
} else {
|
||||
msg_id = esp_mqtt_client_publish(ctx->mqtt_client, data->publish_to, data->expected, data->expected_size, qos, 0);
|
||||
if(msg_id < 0) {
|
||||
|
||||
if (msg_id < 0) {
|
||||
ESP_LOGE(TAG, "Failed to publish");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Publishing msg_id=%d", msg_id);
|
||||
}
|
||||
}
|
||||
|
@@ -181,8 +181,8 @@ def connect_dut(dut: Dut, uri: str, case_id: int) -> Any:
|
||||
def run_cases(dut: Dut, uri: str, cases: Dict[str, int]) -> None:
|
||||
try:
|
||||
dut.write('init')
|
||||
dut.write(f'start')
|
||||
dut.write(f'disconnect')
|
||||
dut.write('start')
|
||||
dut.write('disconnect')
|
||||
for case in [
|
||||
'EXAMPLE_CONNECT_CASE_NO_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_CERT',
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -25,7 +25,7 @@ extern "C" {
|
||||
#include "Mockqueue.h"
|
||||
#include "Mocktask.h"
|
||||
#if __has_include ("Mockidf_additions.h")
|
||||
/* Some functions were moved from "task.h" to "idf_additions.h" */
|
||||
/* Some functions were moved from "task.h" to "idf_additions.h" */
|
||||
#include "Mockidf_additions.h"
|
||||
#endif
|
||||
#include "Mockesp_timer.h"
|
||||
@@ -49,7 +49,8 @@ auto random_string(std::size_t n)
|
||||
return str;
|
||||
}
|
||||
|
||||
using unique_mqtt_client = std::unique_ptr < std::remove_pointer_t<esp_mqtt_client_handle_t>, decltype([](esp_mqtt_client_handle_t client)
|
||||
using unique_mqtt_client = std::unique_ptr < std::remove_pointer_t<esp_mqtt_client_handle_t>,
|
||||
decltype([](esp_mqtt_client_handle_t client)
|
||||
{
|
||||
esp_mqtt_client_destroy(client);
|
||||
}) >;
|
||||
@@ -118,15 +119,15 @@ SCENARIO("MQTT Client Operation")
|
||||
REQUIRE(res == ESP_FAIL);
|
||||
}
|
||||
}
|
||||
SECTION("User set interface to use"){
|
||||
SECTION("User set interface to use") {
|
||||
http_parser_parse_url_ExpectAnyArgsAndReturn(0);
|
||||
http_parser_parse_url_ReturnThruPtr_u(&ret_uri);
|
||||
struct ifreq if_name = {};
|
||||
strncpy(if_name.ifr_name, "custom", IFNAMSIZ - 1);
|
||||
if_name.ifr_name[IFNAMSIZ - 1] = '\0';;
|
||||
config.network.if_name = &if_name;
|
||||
SECTION("Client is not started"){
|
||||
REQUIRE(esp_mqtt_set_config(client.get(), &config)== ESP_OK);
|
||||
SECTION("Client is not started") {
|
||||
REQUIRE(esp_mqtt_set_config(client.get(), &config) == ESP_OK);
|
||||
}
|
||||
}
|
||||
SECTION("After Start Client Is Cleanly destroyed") {
|
||||
@@ -143,15 +144,14 @@ SCENARIO("MQTT Client Operation")
|
||||
auto password = random_string(10);
|
||||
auto lw_topic = random_string(10);
|
||||
auto lw_msg = random_string(10);
|
||||
|
||||
config.broker = {.address = {
|
||||
.hostname = host.data(),
|
||||
.path = path.data()
|
||||
.path = path.data()
|
||||
}
|
||||
};
|
||||
config.credentials = {
|
||||
.username = username.data(),
|
||||
.client_id = client_id.data(),
|
||||
.client_id = client_id.data(),
|
||||
.authentication = {
|
||||
.password = password.data()
|
||||
}
|
||||
@@ -159,13 +159,11 @@ SCENARIO("MQTT Client Operation")
|
||||
config.session = {
|
||||
.last_will {
|
||||
.topic = lw_topic.data(),
|
||||
.msg = lw_msg.data()
|
||||
.msg = lw_msg.data()
|
||||
}
|
||||
};
|
||||
auto client = unique_mqtt_client{esp_mqtt_client_init(&config)};
|
||||
REQUIRE(client != nullptr);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user