mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-03 21:56:40 +02:00
Compare commits
35 Commits
mdns-v1.5.
...
websocket-
Author | SHA1 | Date | |
---|---|---|---|
85a8dac42d | |||
39866116f5 | |||
7740b591b6 | |||
b57979d967 | |||
42674b49f9 | |||
e069ae7762 | |||
44d476fc50 | |||
55385ec312 | |||
a3c2bbed9e | |||
84c47c37f1 | |||
e7273c46ec | |||
2e7d240abd | |||
d4a004b5b4 | |||
9046af8f8d | |||
eeeb9006eb | |||
b167aa315f | |||
72ba24470d | |||
7dc87d28b2 | |||
ac6a388cdd | |||
76aaea08d2 | |||
5db32cce30 | |||
9bdd429c7c | |||
6f7c52cc3f | |||
27435b7f34 | |||
813331f003 | |||
bd23c233a4 | |||
4eda7d472f | |||
163029c0b6 | |||
96eae25096 | |||
ebec8eff63 | |||
4451a8c5ad | |||
6d19aabb02 | |||
9162de1150 | |||
dbd164dd91 | |||
90d663ad01 |
@ -13,7 +13,7 @@ jobs:
|
||||
name: Build
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3"]
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4"]
|
||||
idf_target: ["esp32", "esp32s2"]
|
||||
example: ["asio_chat", "async_request", "socks4", "ssl_client_server", "tcp_echo_server", "udp_echo_server"]
|
||||
runs-on: ubuntu-22.04
|
||||
@ -64,7 +64,7 @@ jobs:
|
||||
name: Target tests
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest", "release-v5.0", "release-v5.2", "release-v5.3"]
|
||||
idf_ver: ["latest", "release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4"]
|
||||
idf_target: ["esp32"]
|
||||
example: ["asio_chat", "tcp_echo_server", "udp_echo_server", "ssl_client_server"]
|
||||
needs: build_asio
|
||||
|
4
.github/workflows/modem__target-test.yml
vendored
4
.github/workflows/modem__target-test.yml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
idf.py set-target ${{ matrix.idf_target }}
|
||||
idf.py build
|
||||
$GITHUB_WORKSPACE/ci/clean_build_artifacts.sh ${GITHUB_WORKSPACE}/${TEST_DIR}/build
|
||||
- uses: actions/upload-artifact@v3
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
|
||||
path: ${{ env.TEST_DIR }}/build
|
||||
@ -75,7 +75,7 @@ jobs:
|
||||
run: |
|
||||
sudo rm -fr $GITHUB_WORKSPACE && mkdir $GITHUB_WORKSPACE
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/download-artifact@v3
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: modem_target_bin_${{ matrix.idf_target }}_${{ matrix.idf_ver }}_${{ matrix.test.app }}
|
||||
path: ${{ env.TEST_DIR }}/build
|
||||
|
74
.github/workflows/mosq__build.yml
vendored
74
.github/workflows/mosq__build.yml
vendored
@ -101,3 +101,77 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
echo "Versions are consistent: $CONFIG_VERSION"
|
||||
|
||||
build_idf_tests_with_mosq:
|
||||
name: Build IDF tests
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
idf_target: ["esp32"]
|
||||
test: [ { app: publish, path: "tools/test_apps/protocols/mqtt/publish_connect_test" }]
|
||||
runs-on: ubuntu-20.04
|
||||
container: espressif/idf:${{ matrix.idf_ver }}
|
||||
env:
|
||||
TARGET_TEST_DIR: build_esp32_local_broker
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Build ${{ matrix.test.app }} with IDF-${{ matrix.idf_ver }} for ${{ matrix.idf_target }}
|
||||
shell: bash
|
||||
run: |
|
||||
. ${IDF_PATH}/export.sh
|
||||
pip install idf-component-manager idf-build-apps --upgrade
|
||||
export MOSQUITTO_PATH=`pwd`/components/mosquitto
|
||||
# to use the actual version of mosquitto
|
||||
sed -i '/espressif\/mosquitto:/a \ \ \ \ override_path: "${MOSQUITTO_PATH}"' ${IDF_PATH}/${{matrix.test.path}}/main/idf_component.yml
|
||||
export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function"
|
||||
export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes"
|
||||
export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}"
|
||||
cd ${IDF_PATH}/${{matrix.test.path}}
|
||||
idf-build-apps find --config sdkconfig.ci.local_broker -vv --target ${{ matrix.idf_target }} --build-dir=${TARGET_TEST_DIR}
|
||||
idf-build-apps build --config sdkconfig.ci.local_broker -vv --target ${{ matrix.idf_target }} --build-dir=${TARGET_TEST_DIR}
|
||||
${GITHUB_WORKSPACE}/ci/clean_build_artifacts.sh `pwd`/${TARGET_TEST_DIR}
|
||||
# to replace mqtt test configs with specific mosquitto markers
|
||||
python ${MOSQUITTO_PATH}/test/replace_decorators.py pytest_mqtt_publish_app.py ${TARGET_TEST_DIR}/pytest_mosquitto.py
|
||||
zip -qur ${GITHUB_WORKSPACE}/artifacts.zip ${TARGET_TEST_DIR}
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: mosq_publish_esp32_${{ matrix.idf_ver }}
|
||||
path: artifacts.zip
|
||||
if-no-files-found: error
|
||||
|
||||
test_idf_ci_with_mosq:
|
||||
# Skip running on forks since it won't have access to secrets
|
||||
if: |
|
||||
github.repository == 'espressif/esp-protocols' &&
|
||||
( contains(github.event.pull_request.labels.*.name, 'mosquitto') || github.event_name == 'push' )
|
||||
name: Mosquitto IDF target tests
|
||||
needs: build_idf_tests_with_mosq
|
||||
strategy:
|
||||
matrix:
|
||||
idf_ver: ["latest"]
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- ESP32-ETHERNET-KIT
|
||||
env:
|
||||
TEST_DIR: examples
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: mosq_publish_esp32_${{ matrix.idf_ver }}
|
||||
path: ${{ env.TEST_DIR }}/ci/
|
||||
- name: Run Test
|
||||
working-directory: ${{ env.TEST_DIR }}
|
||||
run: |
|
||||
python -m pip install pytest-embedded-serial-esp pytest-embedded-idf pytest-rerunfailures pytest-timeout pytest-ignore-test-results "paho-mqtt<2"
|
||||
unzip ci/artifacts.zip -d ci
|
||||
for dir in `ls -d ci/build_*`; do
|
||||
rm -rf build sdkconfig.defaults
|
||||
mv $dir build
|
||||
mv build/*.py .
|
||||
# Run only "test_mosquitto" marked tests
|
||||
python -m pytest --log-cli-level DEBUG --junit-xml=./results_esp32_${{ matrix.idf_ver }}_${dir#"ci/build_"}.xml --target=esp32 -m test_mosquitto
|
||||
done
|
||||
|
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -1,6 +1,6 @@
|
||||
[submodule "components/asio/asio"]
|
||||
path = components/asio/asio
|
||||
url = https://github.com/espressif/asio
|
||||
url = https://github.com/chriskohlhoff/asio
|
||||
[submodule "components/mosquitto/mosquitto"]
|
||||
path = components/mosquitto/mosquitto
|
||||
url = https://github.com/eclipse/mosquitto
|
||||
|
@ -1,7 +1,8 @@
|
||||
---
|
||||
commitizen:
|
||||
bump_message: 'bump(asio): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py asio
|
||||
tag_format: asio-v$version
|
||||
version: 1.28.0~0
|
||||
version: 1.32.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,26 @@
|
||||
# Changelog
|
||||
|
||||
## [1.32.0](https://github.com/espressif/esp-protocols/commits/asio-v1.32.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Upgrade asio to 1.32 ([9bdd429c](https://github.com/espressif/esp-protocols/commit/9bdd429c))
|
||||
- Drop esp/asio patches in favor of sock-utils ([27435b7f](https://github.com/espressif/esp-protocols/commit/27435b7f))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix chat example to print only the message body ([76aaea08](https://github.com/espressif/esp-protocols/commit/76aaea08))
|
||||
- Make asio enable if_nametoindex to fix linking ([5db32cce](https://github.com/espressif/esp-protocols/commit/5db32cce))
|
||||
- Re-applie refs to common comps idf_component.yml ([9fe44a45](https://github.com/espressif/esp-protocols/commit/9fe44a45))
|
||||
- Reference common component from IDF ([74fc228c](https://github.com/espressif/esp-protocols/commit/74fc228c))
|
||||
- Revert referencing protocol_examples_common from IDF ([f9e0281a](https://github.com/espressif/esp-protocols/commit/f9e0281a))
|
||||
- reference protocol_examples_common from IDF ([09abb18b](https://github.com/espressif/esp-protocols/commit/09abb18b))
|
||||
- specify override_path in example manifest files ([1d8923cf](https://github.com/espressif/esp-protocols/commit/1d8923cf))
|
||||
|
||||
### Updated
|
||||
|
||||
- docs(asio): Updates asio docs ([ce9337d3](https://github.com/espressif/esp-protocols/commit/ce9337d3))
|
||||
|
||||
## [1.28.2~0](https://github.com/espressif/esp-protocols/commits/asio-1.28.2_0)
|
||||
|
||||
### Bug Fixes
|
||||
|
@ -6,8 +6,8 @@ if(NOT CONFIG_LWIP_IPV6 AND NOT CMAKE_BUILD_EARLY_EXPANSION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(asio_sources "asio/asio/src/asio.cpp")
|
||||
set(asio_requires lwip)
|
||||
set(asio_sources "asio/asio/src/asio.cpp" "port/src/asio_stub.cpp")
|
||||
set(asio_requires lwip sock_utils)
|
||||
|
||||
if(CONFIG_ASIO_SSL_SUPPORT)
|
||||
list(APPEND asio_sources
|
||||
@ -18,7 +18,7 @@ if(CONFIG_ASIO_SSL_SUPPORT)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${asio_sources}
|
||||
INCLUDE_DIRS "asio/asio/include" "port/include"
|
||||
INCLUDE_DIRS "port/include" "asio/asio/include"
|
||||
PRIV_INCLUDE_DIRS ${asio_priv_includes}
|
||||
PRIV_REQUIRES ${asio_requires})
|
||||
|
||||
@ -30,6 +30,7 @@ target_compile_definitions(${COMPONENT_LIB} PUBLIC SA_RESTART=0x01
|
||||
ASIO_STANDALONE
|
||||
ASIO_HAS_PTHREADS
|
||||
OPENSSL_NO_ENGINE
|
||||
ASIO_DETAIL_IMPL_POSIX_EVENT_IPP # this replaces asio's posix_event constructor
|
||||
)
|
||||
|
||||
if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS)
|
||||
|
@ -1,6 +1,15 @@
|
||||
menu "ESP-ASIO"
|
||||
visible if LWIP_IPV6
|
||||
|
||||
config ASIO_IS_ENABLED
|
||||
# Invisible option that is enabled if ASIO is added to the IDF components.
|
||||
# This is used to "select" LWIP_NETIF_API option
|
||||
# which enables if_indextoname() and if_nametoindex() functions
|
||||
# (these are optionally used in asio)
|
||||
bool
|
||||
default "y"
|
||||
select LWIP_NETIF_API
|
||||
|
||||
config ASIO_SSL_SUPPORT
|
||||
bool "Enable SSL/TLS support of ASIO"
|
||||
default n
|
||||
|
Submodule components/asio/asio updated: a2e0f70d61...03ae834edb
@ -120,7 +120,7 @@ private:
|
||||
asio::buffer(read_msg_.body(), read_msg_.body_length()),
|
||||
[this, self](std::error_code ec, std::size_t /*length*/) {
|
||||
if (!ec) {
|
||||
ESP_LOGD("asio-chat:", "%s", read_msg_.body());
|
||||
ESP_LOGD("asio-chat", "%.*s", read_msg_.body_length(), read_msg_.body());
|
||||
room_.deliver(read_msg_);
|
||||
do_read_header();
|
||||
} else {
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.28.2~0"
|
||||
version: "1.32.0"
|
||||
description: Cross-platform C++ library for network and I/O programming
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/asio
|
||||
issues: https://github.com/espressif/esp-protocols/issues
|
||||
@ -7,3 +7,5 @@ repository: https://github.com/espressif/esp-protocols.git
|
||||
dependencies:
|
||||
idf:
|
||||
version: ">=5.0"
|
||||
espressif/sock_utils:
|
||||
version: "^0.1"
|
||||
|
11
components/asio/port/include/asio/detail/config.hpp
Normal file
11
components/asio/port/include/asio/detail/config.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "sys/socket.h"
|
||||
#include "socketpair.h"
|
||||
|
||||
#include_next "asio/detail/config.hpp"
|
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef _ESP_ASIO_CONFIG_H_
|
||||
#define _ESP_ASIO_CONFIG_H_
|
||||
|
||||
#define ASIO_SSL_DETAIL_OPENSSL_TYPES_HPP
|
||||
#include "openssl_stub.hpp"
|
||||
|
||||
#endif // _ESP_ASIO_CONFIG_H_
|
@ -8,7 +8,7 @@
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
#include "openssl_stub.hpp"
|
||||
#include "asio/ssl/detail/openssl_types.hpp"
|
||||
#include <cstring>
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
#include "asio/error.hpp"
|
||||
|
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
#include "asio/detail/config.hpp"
|
||||
#include "openssl_stub.hpp"
|
||||
#include "asio/ssl/detail/openssl_types.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/ssl/detail/engine.hpp"
|
||||
|
36
components/asio/port/src/asio_stub.cpp
Normal file
36
components/asio/port/src/asio_stub.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||
//
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
//
|
||||
// SPDX-FileContributor: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
//
|
||||
#include "asio/detail/posix_event.hpp"
|
||||
#include "asio/detail/throw_error.hpp"
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <unistd.h>
|
||||
#include <climits>
|
||||
|
||||
namespace asio::detail {
|
||||
// This replaces asio's posix_event constructor
|
||||
// since the default POSIX version uses pthread_condattr_t operations (init, setclock, destroy),
|
||||
// which are not available on all IDF versions (some are defined in compilers' headers, others in
|
||||
// pthread library, but they typically return `ENOSYS` which causes trouble in the event wrapper)
|
||||
// IMPORTANT: Check implementation of posix_event() when upgrading upstream asio in order not to
|
||||
// miss any initialization step.
|
||||
posix_event::posix_event()
|
||||
: state_(0)
|
||||
{
|
||||
int error = ::pthread_cond_init(&cond_, nullptr);
|
||||
asio::error_code ec(error, asio::error::get_system_category());
|
||||
asio::detail::throw_error(ec, "event");
|
||||
}
|
||||
} // namespace asio::detail
|
||||
|
||||
extern "C" int pause (void)
|
||||
{
|
||||
while (true) {
|
||||
::sleep(UINT_MAX);
|
||||
}
|
||||
}
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(websocket): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py esp_websocket_client
|
||||
tag_format: websocket-v$version
|
||||
version: 1.3.0
|
||||
version: 1.4.0
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## [1.4.0](https://github.com/espressif/esp-protocols/commits/websocket-v1.4.0)
|
||||
|
||||
### Features
|
||||
|
||||
- Support DS peripheral for mutual TLS ([55385ec3](https://github.com/espressif/esp-protocols/commit/55385ec3))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- wait for task on destroy ([42674b49](https://github.com/espressif/esp-protocols/commit/42674b49))
|
||||
- Fix pytest to verify client correctly ([9046af8f](https://github.com/espressif/esp-protocols/commit/9046af8f))
|
||||
- propagate error type ([eeeb9006](https://github.com/espressif/esp-protocols/commit/eeeb9006))
|
||||
- fix example buffer leak ([5219c39d](https://github.com/espressif/esp-protocols/commit/5219c39d))
|
||||
|
||||
### Updated
|
||||
|
||||
- chore(websocket): align structure members ([beb6e57e](https://github.com/espressif/esp-protocols/commit/beb6e57e))
|
||||
- chore(websocket): remove unused client variable ([15d3a01e](https://github.com/espressif/esp-protocols/commit/15d3a01e))
|
||||
|
||||
## [1.3.0](https://github.com/espressif/esp-protocols/commits/websocket-v1.3.0)
|
||||
|
||||
### Features
|
||||
|
@ -93,6 +93,9 @@ typedef struct {
|
||||
size_t client_cert_len;
|
||||
const char *client_key;
|
||||
size_t client_key_len;
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
void *client_ds_data;
|
||||
#endif
|
||||
bool use_global_ca_store;
|
||||
bool skip_cert_common_name_check;
|
||||
const char *cert_common_name;
|
||||
@ -234,9 +237,9 @@ static esp_err_t esp_websocket_client_abort_connection(esp_websocket_client_hand
|
||||
} else {
|
||||
client->reconnect_tick_ms = _tick_get_ms();
|
||||
ESP_LOGI(TAG, "Reconnect after %d ms", client->wait_timeout_ms);
|
||||
client->error_handle.error_type = error_type;
|
||||
client->state = WEBSOCKET_STATE_WAIT_TIMEOUT;
|
||||
}
|
||||
client->error_handle.error_type = error_type;
|
||||
esp_websocket_client_dispatch_event(client, WEBSOCKET_EVENT_DISCONNECTED, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -446,6 +449,21 @@ static void destroy_and_free_resources(esp_websocket_client_handle_t client)
|
||||
client = NULL;
|
||||
}
|
||||
|
||||
static esp_err_t stop_wait_task(esp_websocket_client_handle_t client)
|
||||
{
|
||||
/* A running client cannot be stopped from the websocket task/event handler */
|
||||
TaskHandle_t running_task = xTaskGetCurrentTaskHandle();
|
||||
if (running_task == client->task_handle) {
|
||||
ESP_LOGE(TAG, "Client cannot be stopped from websocket task");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
client->run = false;
|
||||
xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY);
|
||||
client->state = WEBSOCKET_STATE_UNKNOW;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t set_websocket_transport_optional_settings(esp_websocket_client_handle_t client, const char *scheme)
|
||||
{
|
||||
esp_transport_handle_t trans = esp_transport_list_get_transport(client->transport_list, scheme);
|
||||
@ -531,6 +549,10 @@ static esp_err_t esp_websocket_client_create_transport(esp_websocket_client_hand
|
||||
} else {
|
||||
esp_transport_ssl_set_client_key_data_der(ssl, client->config->client_key, client->config->client_key_len);
|
||||
}
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
} else if (client->config->client_ds_data) {
|
||||
esp_transport_ssl_set_ds_data(ssl, client->config->client_ds_data);
|
||||
#endif
|
||||
}
|
||||
if (client->config->crt_bundle_attach) {
|
||||
#ifdef CONFIG_MBEDTLS_CERTIFICATE_BUNDLE
|
||||
@ -696,6 +718,9 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
|
||||
client->config->client_cert_len = config->client_cert_len;
|
||||
client->config->client_key = config->client_key;
|
||||
client->config->client_key_len = config->client_key_len;
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
client->config->client_ds_data = config->client_ds_data;
|
||||
#endif
|
||||
client->config->skip_cert_common_name_check = config->skip_cert_common_name_check;
|
||||
client->config->cert_common_name = config->cert_common_name;
|
||||
client->config->crt_bundle_attach = config->crt_bundle_attach;
|
||||
@ -744,6 +769,7 @@ esp_websocket_client_handle_t esp_websocket_client_init(const esp_websocket_clie
|
||||
ESP_WS_CLIENT_MEM_CHECK(TAG, client->status_bits, {
|
||||
goto _websocket_init_fail;
|
||||
});
|
||||
xEventGroupSetBits(client->status_bits, STOPPED_BIT);
|
||||
|
||||
client->buffer_size = buffer_size;
|
||||
return client;
|
||||
@ -758,9 +784,11 @@ esp_err_t esp_websocket_client_destroy(esp_websocket_client_handle_t client)
|
||||
if (client == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (client->run) {
|
||||
esp_websocket_client_stop(client);
|
||||
|
||||
if (client->status_bits && (STOPPED_BIT & xEventGroupGetBits(client->status_bits)) == 0) {
|
||||
stop_wait_task(client);
|
||||
}
|
||||
|
||||
destroy_and_free_resources(client);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -1149,23 +1177,13 @@ esp_err_t esp_websocket_client_stop(esp_websocket_client_handle_t client)
|
||||
if (client == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (!client->run) {
|
||||
|
||||
if (xEventGroupGetBits(client->status_bits) & STOPPED_BIT) {
|
||||
ESP_LOGW(TAG, "Client was not started");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* A running client cannot be stopped from the websocket task/event handler */
|
||||
TaskHandle_t running_task = xTaskGetCurrentTaskHandle();
|
||||
if (running_task == client->task_handle) {
|
||||
ESP_LOGE(TAG, "Client cannot be stopped from websocket task");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
client->run = false;
|
||||
xEventGroupWaitBits(client->status_bits, STOPPED_BIT, false, true, portMAX_DELAY);
|
||||
client->state = WEBSOCKET_STATE_UNKNOW;
|
||||
return ESP_OK;
|
||||
return stop_wait_task(client);
|
||||
}
|
||||
|
||||
static int esp_websocket_client_send_close(esp_websocket_client_handle_t client, int code, const char *additional_data, int total_len, TickType_t timeout)
|
||||
|
@ -55,7 +55,7 @@ class Websocket(object):
|
||||
ssl_context.load_cert_chain(certfile='main/certs/server/server_cert.pem', keyfile='main/certs/server/server_key.pem')
|
||||
if self.client_verify is True:
|
||||
ssl_context.load_verify_locations(cafile='main/certs/ca_cert.pem')
|
||||
ssl_context.verify = ssl.CERT_REQUIRED
|
||||
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
||||
ssl_context.check_hostname = False
|
||||
self.server = SimpleSSLWebSocketServer('', self.port, WebsocketTestEcho, ssl_context=ssl_context)
|
||||
else:
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
description: WebSocket protocol client for ESP-IDF
|
||||
url: https://github.com/espressif/esp-protocols/tree/master/components/esp_websocket_client
|
||||
dependencies:
|
||||
|
@ -108,10 +108,13 @@ typedef struct {
|
||||
int buffer_size; /*!< Websocket buffer size */
|
||||
const char *cert_pem; /*!< Pointer to certificate data in PEM or DER format for server verify (with SSL), default is NULL, not required to verify the server. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in cert_len. */
|
||||
size_t cert_len; /*!< Length of the buffer pointed to by cert_pem. May be 0 for null-terminated pem */
|
||||
const char *client_cert; /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */
|
||||
const char *client_cert; /*!< Pointer to certificate data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_key` or `client_ds_data` (if supported) has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_cert_len. */
|
||||
size_t client_cert_len; /*!< Length of the buffer pointed to by client_cert. May be 0 for null-terminated pem */
|
||||
const char *client_key; /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */
|
||||
const char *client_key; /*!< Pointer to private key data in PEM or DER format for SSL mutual authentication, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided and `client_ds_data` (if supported) gets ignored. PEM-format must have a terminating NULL-character. DER-format requires the length to be passed in client_key_len */
|
||||
size_t client_key_len; /*!< Length of the buffer pointed to by client_key_pem. May be 0 for null-terminated pem */
|
||||
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
|
||||
void *client_ds_data; /*!< Pointer to the encrypted private key data for SSL mutual authentication using the DS peripheral, default is NULL, not required if mutual authentication is not needed. If it is not NULL, also `client_cert` has to be provided. It is ignored if `client_key` is provided */
|
||||
#endif
|
||||
esp_websocket_transport_t transport; /*!< Websocket transport type, see `esp_websocket_transport_t */
|
||||
const char *subprotocol; /*!< Websocket subprotocol */
|
||||
const char *user_agent; /*!< Websocket user-agent */
|
||||
|
@ -3,6 +3,6 @@ commitizen:
|
||||
bump_message: 'bump(mdns): $current_version -> $new_version'
|
||||
pre_bump_hooks: python ../../ci/changelog.py mdns
|
||||
tag_format: mdns-v$version
|
||||
version: 1.5.0
|
||||
version: 1.5.2
|
||||
version_files:
|
||||
- idf_component.yml
|
||||
|
@ -1,5 +1,18 @@
|
||||
# Changelog
|
||||
|
||||
## [1.5.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.5.2)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix potential NULL deref when sending sub-buy ([e7273c46](https://github.com/espressif/esp-protocols/commit/e7273c46))
|
||||
- Fix _mdns_append_fqdn excessive stack usage ([bd23c233](https://github.com/espressif/esp-protocols/commit/bd23c233))
|
||||
|
||||
## [1.5.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.5.1)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fix incorrect memory free for mdns browse ([4451a8c5](https://github.com/espressif/esp-protocols/commit/4451a8c5))
|
||||
|
||||
## [1.5.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.5.0)
|
||||
|
||||
### Features
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: "1.5.0"
|
||||
version: "1.5.2"
|
||||
description: "Multicast UDP service used to provide local network service and host discovery."
|
||||
url: "https://github.com/espressif/esp-protocols/tree/master/components/mdns"
|
||||
issues: "https://github.com/espressif/esp-protocols/issues"
|
||||
|
@ -751,12 +751,12 @@ static uint16_t _mdns_append_fqdn(uint8_t *packet, uint16_t *index, const char *
|
||||
//empty string so terminate
|
||||
return _mdns_append_u8(packet, index, 0);
|
||||
}
|
||||
mdns_name_t name;
|
||||
static char buf[MDNS_NAME_BUF_LEN];
|
||||
uint8_t len = strlen(strings[0]);
|
||||
//try to find first the string length in the packet (if it exists)
|
||||
uint8_t *len_location = (uint8_t *)memchr(packet, (char)len, *index);
|
||||
while (len_location) {
|
||||
mdns_name_t name;
|
||||
//check if the string after len_location is the string that we are looking for
|
||||
if (memcmp(len_location + 1, strings[0], len)) { //not continuing with our string
|
||||
search_next:
|
||||
@ -2399,6 +2399,9 @@ static void _mdns_send_bye_subtype(mdns_srv_item_t *service, const char *instanc
|
||||
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||
if (mdns_is_netif_ready(i, j)) {
|
||||
mdns_tx_packet_t *packet = _mdns_alloc_packet_default((mdns_if_t)i, (mdns_ip_protocol_t)j);
|
||||
if (packet == NULL) {
|
||||
return;
|
||||
}
|
||||
packet->flags = MDNS_FLAGS_QR_AUTHORITATIVE;
|
||||
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, service->service, NULL, true, true)) {
|
||||
_mdns_free_tx_packet(packet);
|
||||
@ -4298,6 +4301,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
|
||||
} else {
|
||||
free(out_sync_browse);
|
||||
}
|
||||
out_sync_browse = NULL;
|
||||
}
|
||||
|
||||
clear_rx_packet:
|
||||
|
@ -20,7 +20,7 @@ mosq_broker_run(&config);
|
||||
|
||||
## Memory Footprint Considerations
|
||||
|
||||
The broker primarily uses the heap for internal data, with minimal use of static/BSS memory. It consumes approximately 60 kB of program memory.
|
||||
The broker primarily uses the heap for internal data, with minimal use of static/BSS memory. It consumes approximately 60 kB of program memory and minimum 5kB of stack size.
|
||||
|
||||
- **Initial Memory Usage**: ~2 kB of heap on startup
|
||||
- **Per Client Memory Usage**: ~4 kB of heap for each connected client
|
||||
|
5
components/mosquitto/test/README.md
Normal file
5
components/mosquitto/test/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# ESP32 mosquitto tests
|
||||
|
||||
Mosquitto component doesn't have any tests yet, but we upcycle IDF mqtt tests and run them with the current version of mosquitto.
|
||||
For that we need to update the IDF test project's `idf_component.yml` file to reference this actual version of mosquitto.
|
||||
We also need to update some pytest decorators to run only relevant test cases. See the [replacement](./replace_decorators.py) script.
|
42
components/mosquitto/test/replace_decorators.py
Normal file
42
components/mosquitto/test/replace_decorators.py
Normal file
@ -0,0 +1,42 @@
|
||||
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
# This script replaces the `@pytest` decorators in the test files
|
||||
# based on the value of the `config` parameter in the `@pytest` decorator.
|
||||
# to reuse mqtt test cases for mosquitto broker.
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
def replace_decorators(in_file: str, out_file: str) -> None:
|
||||
with open(in_file, 'r') as file:
|
||||
content = file.read()
|
||||
|
||||
# we replace config decorators to differentiate between local mosquitto based tests
|
||||
pattern = r"@pytest\.mark\.parametrize\(\s*'config'\s*,\s*\[\s*'(.*?)'\s*\]\s*,.*\)"
|
||||
|
||||
def replacement(match):
|
||||
config_value = match.group(1)
|
||||
if config_value == 'local_broker':
|
||||
return '@pytest.mark.test_mosquitto'
|
||||
else:
|
||||
return '@pytest.mark.test_mqtt'
|
||||
|
||||
# Replace occurrences
|
||||
updated_content = re.sub(pattern, replacement, content)
|
||||
|
||||
with open(out_file, 'w') as file:
|
||||
file.write(updated_content)
|
||||
|
||||
|
||||
# Main function to handle arguments
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 3:
|
||||
print('Usage: python replace_decorators.py <in_file> <out_file>')
|
||||
sys.exit(1)
|
||||
|
||||
in_file = sys.argv[1]
|
||||
out_file = sys.argv[2]
|
||||
replace_decorators(in_file, out_file)
|
||||
print(f'Replacements completed')
|
@ -66,13 +66,43 @@ Configuration:
|
||||
.. note:: If you want to verify the server, then you need to provide a certificate in PEM format, and provide to ``cert_pem`` in :cpp:type:`websocket_client_config_t`. If no certficate is provided then the TLS connection will default to not requiring verification.
|
||||
|
||||
PEM certificate for this example could be extracted from an openssl `s_client` command connecting to websocket.org.
|
||||
In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root or intermediate root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used).
|
||||
```
|
||||
echo "" | openssl s_client -showcerts -connect websocket.org:443 | sed -n "1,/Root/d; /BEGIN/,/END/p" | openssl x509 -outform PEM >websocket_org.pem
|
||||
```
|
||||
In case a host operating system has `openssl` and `sed` packages installed, one could execute the following command to download and save the root or intermediate root certificate to a file (Note for Windows users: Both Linux like environment or Windows native packages may be used). ::
|
||||
|
||||
echo "" | openssl s_client -showcerts -connect websocket.org:443 \
|
||||
| sed -n "1,/Root/d; /BEGIN/,/END/p" \
|
||||
| openssl x509 -outform PEM \
|
||||
> websocket_org.pem
|
||||
|
||||
This command will extract the second certificate in the chain and save it as a pem-file.
|
||||
|
||||
Mutual TLS with DS Peripheral
|
||||
"""""""""""""""""""""""""""""
|
||||
|
||||
To leverage the Digital Signature (DS) peripheral on supported targets, use `esp_secure_cert_mgr <https://github.com/espressif/esp_secure_cert_mgr/>`_ to flash an encrypted client certificate. In your project, add the dependency: ::
|
||||
|
||||
idf.py add-dependency esp_secure_cert_mgr
|
||||
|
||||
Set ``client_cert`` and ``client_ds_data`` in the config struct:
|
||||
|
||||
.. code:: c
|
||||
|
||||
char *client_cert = NULL;
|
||||
uint32_t client_cert_len = 0;
|
||||
esp_err_t err = esp_secure_cert_get_device_cert(&client_cert, &client_cert_len);
|
||||
assert(err == ESP_OK);
|
||||
|
||||
esp_ds_data_ctx_t *ds_data = esp_secure_cert_get_ds_ctx();
|
||||
assert(ds_data != NULL);
|
||||
|
||||
esp_websocket_client_config_t config = {
|
||||
.uri = "wss://echo.websocket.org",
|
||||
.cert_pem = (const char *)websocket_org_pem_start,
|
||||
.client_cert = client_cert,
|
||||
.client_ds_data = ds_data,
|
||||
};
|
||||
|
||||
.. note:: ``client_cert`` provided by `esp_secure_cert_mgr` is a null-terminated PEM; so ``client_cert_len`` (DER format) should not be set.
|
||||
|
||||
Subprotocol
|
||||
^^^^^^^^^^^
|
||||
|
||||
@ -91,14 +121,14 @@ For more options on :cpp:type:`esp_websocket_client_config_t`, please refer to A
|
||||
|
||||
Events
|
||||
------
|
||||
* `WEBSOCKET_EVENT_BEGIN': The client thread is running.
|
||||
* `WEBSOCKET_EVENT_BEGIN`: The client thread is running.
|
||||
* `WEBSOCKET_EVENT_BEFORE_CONNECT`: The client is about to connect.
|
||||
* `WEBSOCKET_EVENT_CONNECTED`: The client has successfully established a connection to the server. The client is now ready to send and receive data. Contains no event data.
|
||||
* `WEBSOCKET_EVENT_DATA`: The client has successfully received and parsed a WebSocket frame. The event data contains a pointer to the payload data, the length of the payload data as well as the opcode of the received frame. A message may be fragmented into multiple events if the length exceeds the buffer size. This event will also be posted for non-payload frames, e.g. pong or connection close frames.
|
||||
* `WEBSOCKET_EVENT_ERROR`: The client has experienced an error. Examples include transport write or read failures.
|
||||
* `WEBSOCKET_EVENT_DISCONNECTED`: The client has aborted the connection due to the transport layer failing to read data, e.g. because the server is unavailable. Contains no event data.
|
||||
* `WEBSOCKET_EVENT_CLOSED`: The connection has been closed cleanly.
|
||||
* `WEBSOCKET_EVENT_FINISH': The client thread is about to exit.
|
||||
* `WEBSOCKET_EVENT_FINISH`: The client thread is about to exit.
|
||||
|
||||
If the client handle is needed in the event handler it can be accessed through the pointer passed to the event handler:
|
||||
|
||||
|
Reference in New Issue
Block a user