Compare commits

..

45 Commits

Author SHA1 Message Date
7dc87d28b2 Merge pull request #717 from david-cermak/feat/asio_sync_upstream
[asio]: Drop esp-asio patches in favor of sock-utils
2025-01-24 13:49:53 +01:00
ac6a388cdd bump(asio): 1.28.0 -> 1.32.0
1.32.0
Features
- Upgrade asio to 1.32 (9bdd429c)
- Drop esp/asio patches in favor of sock-utils (27435b7f)
Bug Fixes
- Fix chat example to print only the message body (76aaea08)
- Make asio enable if_nametoindex to fix linking (5db32cce)
- Re-applie refs to common comps idf_component.yml (9fe44a45)
- Reference common component from IDF (74fc228c)
- Revert referencing protocol_examples_common from IDF (f9e0281a)
- reference protocol_examples_common from IDF (09abb18b)
- specify override_path in example manifest files (1d8923cf)
Updated
- docs(asio): Updates asio docs (ce9337d3)
2025-01-24 12:40:45 +01:00
76aaea08d2 fix(asio): Fix chat example to print only the message body 2025-01-24 12:37:39 +01:00
5db32cce30 fix(asio): Make asio enable if_nametoindex to fix linking 2025-01-24 12:37:39 +01:00
9bdd429c7c feat(asio): Upgrade asio to 1.32 2025-01-24 10:47:54 +01:00
6f7c52cc3f fix(asio): Add tests for IDF-v5.4 2025-01-24 10:47:54 +01:00
27435b7f34 feat(asio): Drop esp/asio patches in favor of sock-utils 2025-01-24 10:47:54 +01:00
813331f003 Merge pull request #743 from david-cermak/fix/modem_ci
[modem]: Fix deprecated CI download action
2025-01-24 08:27:37 +01:00
4eda7d472f fix(modem): Fix deprecated download action 2025-01-23 19:15:28 +01:00
163029c0b6 Merge pull request #742 from david-cermak/bump/mdns_1.5.1
[mdns]: Bump 1.5.0 -> 1.5.1
2025-01-23 15:32:49 +01:00
96eae25096 bump(mdns): 1.5.0 -> 1.5.1
1.5.1
Bug Fixes
- Fix incorrect memory free for mdns browse (4451a8c5)
2025-01-23 09:00:01 +01:00
ebec8eff63 Merge pull request #740 from gytxxsy/fix/fix_wrong_mem_free_of_mdns_browse
[mdns]: fix incorrect memory free for mdns browse
2025-01-23 08:58:05 +01:00
4451a8c5ad fix(mdns): Fix incorrect memory free for mdns browse 2025-01-23 09:08:25 +08:00
6d19aabb02 Merge pull request #721 from david-cermak/feat/mosq_target_tests
[mosq]: Add IDF MQTT stress tests to mosquitto CI
2025-01-21 12:55:49 +01:00
9162de1150 fix(mosq): Remove temp modification of IDF files 2025-01-21 12:27:09 +01:00
dbd164dd91 fix(mosq): Add a note about stack size 2025-01-21 12:27:09 +01:00
90d663ad01 feat(mosq): Add IDF MQTT stress tests to mosquitto CI 2025-01-21 12:27:09 +01:00
a83f1b6787 Merge pull request #736 from david-cermak/bump/mdns_1.4.4
[mdns]: Bump 1.4.3 -> 1.5.0
2025-01-21 10:56:48 +01:00
84caca465d bump(mdns): 1.4.3 -> 1.5.0
1.5.0
Features
- supported removal of subtype when updating service (4ad88e29)
Bug Fixes
- Fix zero-sized VLA clang-tidy warnings (196198ec)
- Remove dead store to arg variable shared (e838bf03)
- Fix name mangling not to use strcpy() (99b54ac3)
- Fix potential null derefernce in _mdns_execute_action() (f5be2f41)
- Fix AFL test mock per espressif/esp-idf@a5bc08fb55 (3d8835cf)
- Fixed potential out-of-bound interface error (24f55ce9)
- Fixed incorrect error conversion (8f8516cc)
- Fixed potential overflow when allocating txt data (75a8e864)
- Move MDNS_NAME_BUF_LEN to public headers (907087c0, #724)
- Cleanup includes in mdns.c (68a9e148, #725)
- Allow advertizing service with port==0 (827ea65f)
- Fixed complier warning if MDNS_MAX_SERVICES==0 (95377216, #611)
2025-01-20 17:57:07 +01:00
8f81478fff Merge pull request #735 from david-cermak/fix/docs_build
[common]: Fix esp-docs dependencies
2025-01-20 14:50:32 +01:00
ae5a8ceeda fix(mosq): Run mosquitto version check only on labeled job or push 2025-01-20 12:56:02 +01:00
774bab22ea fix(common): Update esp-docs dependencies to fix docs-build job 2025-01-20 12:52:52 +01:00
265e38d684 Merge pull request #731 from tanyanquan/feat/update_subtype_removal
feat(mdns): supported removal of subtype when updating service (IDFGH-14413)
2025-01-20 09:48:27 +01:00
93f772171c Merge pull request #732 from david-cermak/fix/mdns_clangtiy_warns
[mdns]: Fixes clang-tidy warnings
2025-01-20 09:47:56 +01:00
4ad88e297f feat(mdns): supported removal of subtype when updating service 2025-01-16 10:56:54 +08:00
196198ecc9 fix(mdns): Fix zero-sized VLA clang-tidy warnings
and some minor leaks in creation of browse results
2025-01-15 14:23:34 +01:00
e838bf03f4 fix(mdns): Remove dead store to arg variable shared
Fixing: warning: Value stored to 'shared' is never read [clang-analyzer-deadcode.DeadStores]
2025-01-15 14:23:34 +01:00
99b54ac384 fix(mdns): Fix name mangling not to use strcpy()
Since it was flagged by clang-tidy as insecture API
2025-01-15 14:23:34 +01:00
f5be2f4115 fix(mdns): Fix potential null derefernce in _mdns_execute_action()
We did check for null-deref before checking 'a->type', but contol
continues and passes potential null-ptr to the processing function
_mdns_execute_action()
Fixed by asserting action != NULL, since it is an invalid state which
should never happen.
2025-01-15 14:21:59 +01:00
9b74256b51 Merge pull request #730 from david-cermak/fix/mdns_minor
[mdns]: Fixed some minor bugs
2025-01-15 12:27:05 +01:00
3d8835cfb9 fix(mdns): Fix AFL test mock per espressif/esp-idf@a5bc08fb55 2025-01-15 11:42:34 +01:00
24f55ce9b4 fix(mdns): Fixed potential out-of-bound interface error
invalid mdns_if was handled for enabling/announcing pcbs,
but not for the consequent browsing

Closes coverity isssue: 470162 Out-of-bounds access
2025-01-15 10:46:15 +01:00
8f8516cc3f fix(mdns): Fixed incorrect error conversion
Mixing esp_err_t (int) with err_t (uint8_t) from lwip.

Closes coverity isssue: 470139 Overflowed return value
2025-01-15 10:46:15 +01:00
75a8e8640a fix(mdns): Fixed potential overflow when allocating txt data
Closes coverity warning: 470092 Overflowed integer argument
2025-01-15 10:46:15 +01:00
907087c09b fix(mdns): Move MDNS_NAME_BUF_LEN to public headers
Since it's used by public API as maximum length of user buffer

Closes https://github.com/espressif/esp-protocols/issues/724
2025-01-15 10:46:10 +01:00
68a9e14898 fix(mdns): Cleanup includes in mdns.c
Closes https://github.com/espressif/esp-protocols/issues/725
2025-01-15 10:44:12 +01:00
827ea65fd5 fix(mdns): Allow advertizing service with port==0
Closes https://github.com/espressif/esp-idf/issues/14335
2025-01-15 10:44:12 +01:00
9537721600 fix(mdns): Fixed complier warning if MDNS_MAX_SERVICES==0
Closes https://github.com/espressif/esp-protocols/issues/611
2025-01-15 10:44:07 +01:00
4394f845fc Merge pull request #728 from david-cermak/bump/mdns_1.4.3
[mdns]: bump: 1.4.2 -> 1.4.3
2025-01-08 10:24:01 +01:00
9b0ba6060f bump(mdns): 1.4.2 -> 1.4.3
1.4.3
Features
- support zero item when update subtype (5bd82c01)
2025-01-08 09:42:38 +01:00
7c6a3098af Merge pull request #726 from zwx1995esp/feature/support_update_zero_item_of_subtype_for_mdns
feat(mdns): support zero item when update subtype (IDFGH-14369)
2025-01-07 18:40:25 +01:00
f3f3e23bec Merge pull request #727 from david-cermak/fix/sockutls_gai_error
fix(sockutls): Fix gai_strerror() impl to return const string
2025-01-07 15:59:24 +01:00
9ed835ba3f bump(sockutls): 0.2.1 -> 0.2.2
0.2.2
Bug Fixes
- Fix gai_strerror() impl to return const string (f12a2056)
2025-01-07 14:06:42 +01:00
f12a205657 fix(sockutls): Fix gai_strerror() impl to return const string
Previous gai_strerror() returned numeric representation of the code,
but used TLS storage, which might cause issues with stack sizes on all
tasks in the system. Alternatively we can leave the storage to static
only (which wouldn't be thread-safe) or we could one-time allocate and
never free (which is wrong).
This option uses hardcoded strings for common error codes used in lwip.
The disadvantage is that we might need to update the impl in the future
when lwip adds more codes.
2025-01-07 14:06:00 +01:00
zwx
5bd82c01a5 feat(mdns): support zero item when update subtype 2025-01-07 10:28:02 +08:00
34 changed files with 484 additions and 100 deletions

View File

@ -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

View File

@ -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

View File

@ -75,6 +75,7 @@ jobs:
done
check_consistency:
if: contains(github.event.pull_request.labels.*.name, 'mosquitto') || github.event_name == 'push'
name: Checks that API docs and versions are consistent
runs-on: ubuntu-latest
steps:
@ -100,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
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -7,3 +7,5 @@ repository: https://github.com/espressif/esp-protocols.git
dependencies:
idf:
version: ">=5.0"
espressif/sock_utils:
version: "^0.1"

View 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"

View File

@ -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_

View File

@ -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"

View File

@ -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"

View 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);
}
}

View File

@ -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.4.2
version: 1.5.1
version_files:
- idf_component.yml

View File

@ -1,5 +1,38 @@
# Changelog
## [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
- supported removal of subtype when updating service ([4ad88e29](https://github.com/espressif/esp-protocols/commit/4ad88e29))
### Bug Fixes
- Fix zero-sized VLA clang-tidy warnings ([196198ec](https://github.com/espressif/esp-protocols/commit/196198ec))
- Remove dead store to arg variable shared ([e838bf03](https://github.com/espressif/esp-protocols/commit/e838bf03))
- Fix name mangling not to use strcpy() ([99b54ac3](https://github.com/espressif/esp-protocols/commit/99b54ac3))
- Fix potential null derefernce in _mdns_execute_action() ([f5be2f41](https://github.com/espressif/esp-protocols/commit/f5be2f41))
- Fix AFL test mock per espressif/esp-idf@a5bc08fb55c ([3d8835cf](https://github.com/espressif/esp-protocols/commit/3d8835cf))
- Fixed potential out-of-bound interface error ([24f55ce9](https://github.com/espressif/esp-protocols/commit/24f55ce9))
- Fixed incorrect error conversion ([8f8516cc](https://github.com/espressif/esp-protocols/commit/8f8516cc))
- Fixed potential overflow when allocating txt data ([75a8e864](https://github.com/espressif/esp-protocols/commit/75a8e864))
- Move MDNS_NAME_BUF_LEN to public headers ([907087c0](https://github.com/espressif/esp-protocols/commit/907087c0), [#724](https://github.com/espressif/esp-protocols/issues/724))
- Cleanup includes in mdns.c ([68a9e148](https://github.com/espressif/esp-protocols/commit/68a9e148), [#725](https://github.com/espressif/esp-protocols/issues/725))
- Allow advertizing service with port==0 ([827ea65f](https://github.com/espressif/esp-protocols/commit/827ea65f))
- Fixed complier warning if MDNS_MAX_SERVICES==0 ([95377216](https://github.com/espressif/esp-protocols/commit/95377216), [#611](https://github.com/espressif/esp-protocols/issues/611))
## [1.4.3](https://github.com/espressif/esp-protocols/commits/mdns-v1.4.3)
### Features
- support zero item when update subtype ([5bd82c01](https://github.com/espressif/esp-protocols/commit/5bd82c01))
## [1.4.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.4.2)
### Features

View File

@ -1,4 +1,4 @@
version: "1.4.2"
version: "1.5.1"
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"

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -10,6 +10,7 @@
extern "C" {
#endif
#include "sdkconfig.h"
#include <esp_netif.h>
#define MDNS_TYPE_A 0x0001
@ -21,6 +22,13 @@ extern "C" {
#define MDNS_TYPE_NSEC 0x002F
#define MDNS_TYPE_ANY 0x00FF
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
#define MDNS_NAME_MAX_LEN (64+4) // Need to account for IPv6 reverse queries (64 char address + ".ip6" )
#else
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
#endif
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
/**
* @brief Asynchronous query handle
*/
@ -615,6 +623,8 @@ esp_err_t mdns_service_subtype_add_multiple_items_for_host(const char *instance_
* @param subtype the pointer of subtype array to add.
* @param num_items number of items in subtype array
*
* @note If `num_items` is 0, then remove all subtypes.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error

View File

@ -1,23 +1,21 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_random.h"
#include "esp_check.h"
#include "mdns.h"
#include "mdns_private.h"
#include "mdns_networking.h"
#include "esp_log.h"
#include "esp_random.h"
#include "esp_check.h"
static void _mdns_browse_item_free(mdns_browse_t *browse);
static esp_err_t _mdns_send_browse_action(mdns_action_type_t type, mdns_browse_t *browse);
@ -255,12 +253,13 @@ static char *_mdns_mangle_name(char *in)
}
sprintf(ret, "%s-2", in);
} else {
ret = malloc(strlen(in) + 2); //one extra byte in case 9-10 or 99-100 etc
size_t in_len = strlen(in);
ret = malloc(in_len + 2); //one extra byte in case 9-10 or 99-100 etc
if (ret == NULL) {
HOOK_MALLOC_FAILED;
return NULL;
}
strcpy(ret, in);
memcpy(ret, in, in_len);
int baseLen = p - in; //length of 'bla' in 'bla-123'
//overwrite suffix with new suffix
sprintf(ret + baseLen, "-%d", suffix + 1);
@ -334,6 +333,9 @@ static mdns_host_item_t *mdns_get_host_item(const char *hostname)
static bool _mdns_can_add_more_services(void)
{
#if MDNS_MAX_SERVICES == 0
return false;
#else
mdns_srv_item_t *s = _mdns_server->services;
uint16_t service_num = 0;
while (s) {
@ -343,8 +345,8 @@ static bool _mdns_can_add_more_services(void)
return false;
}
}
return true;
#endif
}
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t *packet)
@ -1810,7 +1812,6 @@ static bool _mdns_create_answer_from_service(mdns_tx_packet_t *packet, mdns_serv
return false;
}
} else if (question->type == MDNS_TYPE_SDPTR) {
shared = true;
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_SDPTR, service, NULL, false, false)) {
return false;
}
@ -2354,6 +2355,11 @@ static void _mdns_restart_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol
srv_count++;
a = a->next;
}
if (srv_count == 0) {
// proble only IP
_mdns_init_pcb_probe(tcpip_if, ip_protocol, NULL, 0, true);
return;
}
mdns_srv_item_t *services[srv_count];
size_t i = 0;
a = _mdns_server->services;
@ -2383,6 +2389,53 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
}
}
/**
* @brief Send bye for particular subtypes
*/
static void _mdns_send_bye_subtype(mdns_srv_item_t *service, const char *instance_name, mdns_subtype_t *remove_subtypes)
{
uint8_t i, j;
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
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);
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);
return;
}
static uint8_t pkt[MDNS_MAX_PACKET_SIZE];
uint16_t index = MDNS_HEAD_LEN;
memset(pkt, 0, MDNS_HEAD_LEN);
mdns_out_answer_t *a;
uint8_t count;
_mdns_set_u16(pkt, MDNS_HEAD_FLAGS_OFFSET, packet->flags);
_mdns_set_u16(pkt, MDNS_HEAD_ID_OFFSET, packet->id);
count = 0;
a = packet->answers;
while (a) {
if (a->type == MDNS_TYPE_PTR && a->service) {
const mdns_subtype_t *current_subtype = remove_subtypes;
while (current_subtype) {
count += (_mdns_append_subtype_ptr_record(pkt, &index, instance_name, current_subtype->subtype, a->service->service, a->service->proto, a->flush, a->bye) > 0);
current_subtype = current_subtype->next;
}
}
a = a->next;
}
_mdns_set_u16(pkt, MDNS_HEAD_ANSWERS_OFFSET, count);
_mdns_udp_pcb_write(packet->tcpip_if, packet->ip_protocol, &packet->dst, packet->port, pkt, index);
_mdns_free_tx_packet(packet);
}
}
}
}
/**
* @brief Send announcement on particular PCB
*/
@ -2554,6 +2607,10 @@ static void _mdns_restart_all_pcbs(void)
srv_count++;
a = a->next;
}
if (srv_count == 0) {
_mdns_probe_all_pcbs(NULL, 0, true, true);
return;
}
mdns_srv_item_t *services[srv_count];
size_t l = 0;
a = _mdns_server->services;
@ -2794,14 +2851,20 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
}
}
static void _mdns_free_subtype(mdns_subtype_t *subtype)
{
while (subtype) {
mdns_subtype_t *next = subtype->next;
free((char *)subtype->subtype);
free(subtype);
subtype = next;
}
}
static void _mdns_free_service_subtype(mdns_service_t *service)
{
while (service->subtype) {
mdns_subtype_t *next = service->subtype->next;
free((char *)service->subtype->subtype);
free(service->subtype);
service->subtype = next;
}
_mdns_free_subtype(service->subtype);
service->subtype = NULL;
}
/**
@ -2897,11 +2960,12 @@ static int _mdns_check_srv_collision(mdns_service_t *service, uint16_t priority,
static int _mdns_check_txt_collision(mdns_service_t *service, const uint8_t *data, size_t len)
{
size_t data_len = 0;
if (len == 1 && service->txt) {
if (len <= 1 && service->txt) { // len==0 means incorrect packet (and handled by the packet parser)
// but handled here again to fix clang-tidy warning on VLA "uint8_t our[0];"
return -1;//we win
} else if (len > 1 && !service->txt) {
return 1;//they win
} else if (len == 1 && !service->txt) {
} else if (len <= 1 && !service->txt) {
return 0;//same
}
@ -3485,8 +3549,9 @@ static void _mdns_result_txt_create(const uint8_t *data, size_t len, mdns_txt_it
uint16_t i = 0, y;
size_t partLen = 0;
int num_items = _mdns_txt_items_count_get(data, len);
if (num_items < 0) {
return;//error
if (num_items < 0 || num_items > SIZE_MAX / sizeof(mdns_txt_item_t)) {
// Error: num_items is incorrect (or too large to allocate)
return;
}
if (!num_items) {
@ -3786,7 +3851,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
mdns_class &= 0x7FFF;
content = data_ptr + data_len;
if (content > (data + len)) {
if (content > (data + len) || data_len == 0) {
goto clear_rx_packet;
}
@ -4233,6 +4298,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
} else {
free(out_sync_browse);
}
out_sync_browse = NULL;
}
clear_rx_packet:
@ -4269,15 +4335,10 @@ clear_rx_packet:
free(record);
}
free(parsed_packet);
if (browse_result_instance) {
free(browse_result_instance);
}
if (browse_result_service) {
free(browse_result_service);
}
if (browse_result_proto) {
free(browse_result_proto);
}
free(browse_result_instance);
free(browse_result_service);
free(browse_result_proto);
free(out_sync_browse);
}
/**
@ -4477,10 +4538,11 @@ void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base,
case IP_EVENT_GOT_IP6: {
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *) event_data;
mdns_if_t mdns_if = _mdns_get_if_from_esp_netif(event->esp_netif);
if (mdns_if < MDNS_MAX_INTERFACES) {
post_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
post_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4);
if (mdns_if >= MDNS_MAX_INTERFACES) {
return;
}
post_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
post_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4);
mdns_browse_t *browse = _mdns_server->browse;
while (browse) {
_mdns_browse_send(browse, mdns_if);
@ -5343,7 +5405,8 @@ static void _mdns_service_task(void *pvParameters)
for (;;) {
if (_mdns_server && _mdns_server->action_queue) {
if (xQueueReceive(_mdns_server->action_queue, &a, portMAX_DELAY) == pdTRUE) {
if (a && a->type == ACTION_TASK_STOP) {
assert(a);
if (a->type == ACTION_TASK_STOP) {
break;
}
MDNS_SERVICE_LOCK();
@ -5892,7 +5955,7 @@ esp_err_t mdns_instance_name_set(const char *instance)
esp_err_t mdns_service_add_for_host(const char *instance, const char *service, const char *proto, const char *host,
uint16_t port, mdns_txt_item_t txt[], size_t num_items)
{
if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || !port || !_mdns_server->hostname) {
if (!_mdns_server || _str_null_or_empty(service) || _str_null_or_empty(proto) || !_mdns_server->hostname) {
return ESP_ERR_INVALID_ARG;
}
@ -5901,7 +5964,8 @@ esp_err_t mdns_service_add_for_host(const char *instance, const char *service, c
const char *hostname = host ? host : _mdns_server->hostname;
mdns_service_t *s = NULL;
ESP_GOTO_ON_FALSE(_mdns_can_add_more_services(), ESP_ERR_NO_MEM, err, TAG, "Cannot add more services");
ESP_GOTO_ON_FALSE(_mdns_can_add_more_services(), ESP_ERR_NO_MEM, err, TAG,
"Cannot add more services, please increase CONFIG_MDNS_MAX_SERVICES (%d)", CONFIG_MDNS_MAX_SERVICES);
mdns_srv_item_t *item = _mdns_get_service_item_instance(instance, service, proto, hostname);
ESP_GOTO_ON_FALSE(!item, ESP_ERR_INVALID_ARG, err, TAG, "Service already exists");
@ -6347,11 +6411,23 @@ esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const
ret = _mdns_service_subtype_remove_for_host(s, subtype);
ESP_GOTO_ON_ERROR(ret, err, TAG, "Failed to remove the subtype: %s", subtype);
// TODO: Need to transmit a sendbye message for the removed subtype.
// TODO: Need to remove this subtype answer from the scheduled answer list.
// Transmit a sendbye message for the removed subtype.
mdns_subtype_t *remove_subtypes = (mdns_subtype_t *)malloc(sizeof(mdns_subtype_t));
ESP_GOTO_ON_FALSE(remove_subtypes, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
remove_subtypes->subtype = strdup(subtype);
ESP_GOTO_ON_FALSE(remove_subtypes->subtype, ESP_ERR_NO_MEM, out_of_mem, TAG, "Out of memory");
remove_subtypes->next = NULL;
_mdns_send_bye_subtype(s, instance_name, remove_subtypes);
_mdns_free_subtype(remove_subtypes);
err:
MDNS_SERVICE_UNLOCK();
return ret;
out_of_mem:
HOOK_MALLOC_FAILED;
free(remove_subtypes);
MDNS_SERVICE_UNLOCK();
return ret;
}
static esp_err_t _mdns_service_subtype_add_for_host(mdns_srv_item_t *service, const char *subtype)
@ -6423,19 +6499,75 @@ esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const cha
return mdns_service_subtype_add_multiple_items_for_host(instance_name, service_type, proto, hostname, _subtype, 1);
}
static mdns_subtype_t *_mdns_service_find_subtype_needed_sendbye(mdns_service_t *service, mdns_subtype_item_t subtype[],
uint8_t num_items)
{
if (!service) {
return NULL;
}
mdns_subtype_t *current = service->subtype;
mdns_subtype_t *prev = NULL;
mdns_subtype_t *prev_goodbye = NULL;
mdns_subtype_t *out_goodbye_subtype = NULL;
while (current) {
bool subtype_in_update = false;
for (int i = 0; i < num_items; i++) {
if (strcmp(subtype[i].subtype, current->subtype) == 0) {
subtype_in_update = true;
break;
}
}
if (!subtype_in_update) {
// Remove from original list
if (prev) {
prev->next = current->next;
} else {
service->subtype = current->next;
}
mdns_subtype_t *to_move = current;
current = current->next;
// Add to goodbye list
to_move->next = NULL;
if (prev_goodbye) {
prev_goodbye->next = to_move;
} else {
out_goodbye_subtype = to_move;
}
prev_goodbye = to_move;
} else {
prev = current;
current = current->next;
}
}
return out_goodbye_subtype;
}
esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instance_name, const char *service_type, const char *proto,
const char *hostname, mdns_subtype_item_t subtype[], uint8_t num_items)
{
MDNS_SERVICE_LOCK();
esp_err_t ret = ESP_OK;
int cur_index = 0;
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service_type) && !_str_null_or_empty(proto) &&
(num_items > 0), ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
ESP_GOTO_ON_FALSE(_mdns_server && _mdns_server->services && !_str_null_or_empty(service_type) && !_str_null_or_empty(proto),
ESP_ERR_INVALID_ARG, err, TAG, "Invalid state or arguments");
mdns_srv_item_t *s = _mdns_get_service_item_instance(instance_name, service_type, proto, hostname);
ESP_GOTO_ON_FALSE(s, ESP_ERR_NOT_FOUND, err, TAG, "Service doesn't exist");
// TODO: find subtype needs to say sendbye
mdns_subtype_t *goodbye_subtype = _mdns_service_find_subtype_needed_sendbye(s->service, subtype, num_items);
if (goodbye_subtype) {
_mdns_send_bye_subtype(s, instance_name, goodbye_subtype);
}
_mdns_free_subtype(goodbye_subtype);
_mdns_free_service_subtype(s->service);
for (; cur_index < num_items; cur_index++) {
@ -6450,8 +6582,9 @@ esp_err_t mdns_service_subtype_update_multiple_items_for_host(const char *instan
goto exit;
}
}
_mdns_announce_all_pcbs(&s, 1, false);
if (num_items) {
_mdns_announce_all_pcbs(&s, 1, false);
}
err:
if (ret == ESP_ERR_NO_MEM) {
for (int idx = 0; idx < cur_index; idx++) {

View File

@ -288,7 +288,7 @@ typedef struct {
static err_t _mdns_pcb_init_api(struct tcpip_api_call_data *api_call_msg)
{
mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg;
msg->err = _udp_pcb_init(msg->tcpip_if, msg->ip_protocol);
msg->err = _udp_pcb_init(msg->tcpip_if, msg->ip_protocol) == ESP_OK ? ERR_OK : ERR_IF;
return msg->err;
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -103,12 +103,6 @@
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
#define MDNS_ACTION_QUEUE_LEN CONFIG_MDNS_ACTION_QUEUE_LEN // Maximum actions pending to the server
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
#define MDNS_NAME_MAX_LEN (64+4) // Need to account for IPv6 reverse queries (64 char address + ".ip6" )
#else
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
#endif
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
#define MDNS_HEAD_LEN 12

View File

@ -117,6 +117,10 @@ void esp_log_write(esp_log_level_t level, const char *tag, const char *format, .
{
}
void esp_log(esp_log_config_t config, const char *tag, const char *format, ...)
{
}
uint32_t esp_log_timestamp(void)
{
return 0;

View File

@ -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

View 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.

View 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')

View File

@ -3,6 +3,6 @@ commitizen:
bump_message: 'bump(sockutls): $current_version -> $new_version'
pre_bump_hooks: python ../../ci/changelog.py sock_utils
tag_format: sock_utils-v$version
version: 0.2.1
version: 0.2.2
version_files:
- idf_component.yml

View File

@ -1,5 +1,11 @@
# Changelog
## [0.2.2](https://github.com/espressif/esp-protocols/commits/sock_utils-v0.2.2)
### Bug Fixes
- Fix gai_strerror() impl to return const string ([f12a2056](https://github.com/espressif/esp-protocols/commit/f12a2056))
## [0.2.1](https://github.com/espressif/esp-protocols/commits/sock_utils-v0.2.1)
### Bug Fixes

View File

@ -1,4 +1,4 @@
version: 0.2.1
version: 0.2.2
description: The component provides helper implementation of common system/socket utilities
url: https://github.com/espressif/esp-protocols/tree/master/components/sock_utils
dependencies:

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,13 +18,14 @@ extern "C" {
#endif
/**
* @brief Returns a numeric string representing of `getaddrinfo()` error code.
* @brief Returns a string representing of `getaddrinfo()` error code.
*
* @param[in] ecode Error code returned by `getaddrinfo()`.
* @param[in] errcode Error code returned by `getaddrinfo()`.
*
* @return A pointer to a string describing the error.
* @return A pointer to a string containing the error code, for example "EAI_NONAME"
* for EAI_NONAME error type.
*/
const char *gai_strerror(int ecode);
const char *gai_strerror(int errcode);
#ifdef __cplusplus
}

View File

@ -1,17 +1,36 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "gai_strerror.h"
#include "lwip/netdb.h"
_Thread_local char gai_strerror_string[32];
#define HANDLE_GAI_ERROR(code) \
case code: return #code;
const char *gai_strerror(int ecode)
const char *gai_strerror(int errcode)
{
if (snprintf(gai_strerror_string, sizeof(gai_strerror_string), "EAI error:%d", ecode) < 0) {
return "gai_strerror() failed";
switch (errcode) {
/* lwip defined DNS codes */
HANDLE_GAI_ERROR(EAI_BADFLAGS)
HANDLE_GAI_ERROR(EAI_FAIL)
HANDLE_GAI_ERROR(EAI_FAMILY)
HANDLE_GAI_ERROR(EAI_MEMORY)
HANDLE_GAI_ERROR(EAI_NONAME)
HANDLE_GAI_ERROR(EAI_SERVICE)
/* other error codes optionally defined in platform/newlib or toolchain */
#ifdef EAI_AGAIN
HANDLE_GAI_ERROR(EAI_AGAIN)
#endif
#ifdef EAI_SOCKTYPE
HANDLE_GAI_ERROR(EAI_SOCKTYPE)
#endif
#ifdef EAI_SYSTEM
HANDLE_GAI_ERROR(EAI_SYSTEM)
#endif
default:
return "Unknown error";
}
return gai_strerror_string;
}

View File

@ -1,8 +1 @@
sphinxcontrib-applehelp==1.0.4
sphinxcontrib_devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-qthelp==1.0.3
breathe==4.35
recommonmark==0.7.1
esp-docs==1.7.1
esp-docs>=2.0.0