managed components purge

This commit is contained in:
Thaddeus Hughes
2026-03-12 08:53:01 -05:00
parent 35b7074e81
commit 18faa5b83d
294 changed files with 19 additions and 59603 deletions

View File

@@ -1 +0,0 @@
--ignore-dir=build

View File

@@ -1,17 +0,0 @@
--align-reference=name
--attach-classes
--attach-classes
--attach-namespaces
--convert-tabs
--exclude=build
--exclude=common
--exclude=managed_components
--ignore-exclude-errors
--indent-switches
--indent=spaces=4
--keep-one-line-statements
--max-continuation-indent=120
--pad-header
--pad-oper
--style=allman
--unpad-paren

View File

@@ -1,66 +0,0 @@
---
Language: Cpp
BasedOnStyle: WebKit
AlignConsecutiveMacros: true
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Always
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ColumnLimit: 200
CompactNamespaces: true
Cpp11BracedListStyle: false
FixNamespaceComments: true
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never

View File

@@ -1 +0,0 @@
689853bb8993434f9556af0f2816e808bf77b5d22100144b21f3519993daf237

View File

@@ -1,28 +0,0 @@
---
name: esp_idf_lib_helpers
description: Common support library for esp-idf-lib
version: 1.4.0
groups:
- common
code_owners:
- trombik
- UncleRus
depends:
- freertos
thread_safe: n/a
targets:
- esp32
- esp8266
- esp32s2
- esp32c3
- esp32s3
- esp32c2
- esp32c6
- esp32h2
- esp32p4
- esp32c5
- esp32c61
license: ISC
copyrights:
- name: trombik
year: 2019

View File

@@ -1,12 +0,0 @@
examples/**/sdkconfig
examples/**/sdkconfig.old
examples/**/build/
examples/**/dependencies.lock
examples/**/managed_components/
docs/_*/
docs/**/*.log
*.swp
*.bak
*.orig
build/
.vscode/

View File

@@ -1,3 +0,0 @@
[submodule "common"]
path = common
url = https://github.com/esp-idf-lib/common.git

View File

@@ -1,12 +0,0 @@
idf_component_register(
INCLUDE_DIRS .
REQUIRES freertos
)
# include common cmake file for components
set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake)
if(EXISTS ${ESP_IDF_LIB_CMAKE})
include(${ESP_IDF_LIB_CMAKE})
else()
message(WARNING "${ESP_IDF_LIB_CMAKE} not found")
endif()

View File

@@ -1,13 +0,0 @@
Copyright (c) 2019 Tomoyuki Sakurai <y@trombik.org>
Permission to use, copy, modify, and distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -1,30 +0,0 @@
# esp-idf-lib/esp_idf_lib_helpers
[![Build examples](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build.yml)
[![Build docs](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//build-docs.yml)
[![Validation](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/esp_idf_lib_helpers/actions/workflows//validate-component.yml)
Common support library for esp-idf-lib.
* [Documentation](https://esp-idf-lib.github.io/esp_idf_lib_helpers/)
* [Repository](https://github.com/esp-idf-lib/esp_idf_lib_helpers)
* [Issues](https://github.com/esp-idf-lib/esp_idf_lib_helpers/issues)
* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions)
* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/esp_idf_lib_helpers)
## Installation
```sh
idf.py add-dependency esp-idf-lib/esp_idf_lib_helpers
```
## Support
For questions and discussions about the component, please use
[Discussions](https://github.com/esp-idf-lib/core/discussions)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).
## Contributing
Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env ruby
require "pathname"
require "yaml"
# A simple CLI to get values in .eil.yml
key = ARGV.shift
project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent
eil_file = project_root / ".eil.yml"
doc = YAML.safe_load(File.read eil_file)
case key
when "copyright_string"
puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ")
else
puts doc[key]
end

View File

@@ -1,36 +0,0 @@
# Set common build flags but enable them only when the build is in our CI,
# making them optional. The idea is, fail when compiled in our CI but just
# warn in any other cases. Code that compiles with one toolchain warning-free
# may not do so with another toolchain, which creates a project dependency on
# specific toolchain vendors and versions.
#
# Define flags that may cause failures here.
if (DEFINED ENV{ESP_IDF_LIB_CI})
set(ESP_IDF_LIB_CI_FLAGS
-Werror=unused-variable
-Werror=unused-function
-Werror=write-strings
-Werror
)
endif()
# Set common build flags. Mandatory.
#
# Define flags that do not cause failures here.
set(ESP_IDF_LIB_FLAGS
-Wextra
-Wwrite-strings
-Wunused-variable
-Wunused-function
-Wreturn-type
)
# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not
# set the flags.
get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE)
if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY")
target_compile_options(${COMPONENT_LIB} PRIVATE
${ESP_IDF_LIB_FLAGS}
${ESP_IDF_LIB_CI_FLAGS}
)
endif()

View File

@@ -1,8 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = .
ifdef CONFIG_IDF_TARGET_ESP8266
COMPONENT_DEPENDS = esp8266 freertos
else
COMPONENT_DEPENDS = freertos
endif

View File

@@ -1,101 +0,0 @@
/*
* Copyright (c) 2019 Tomoyuki Sakurai <y@trombik.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if !defined(__ESP_IDF_LIB_HELPERS__H__)
#define __ESP_IDF_LIB_HELPERS__H__
/* XXX this header file does not need to include freertos/FreeRTOS.h.
* but without it, ESP8266 RTOS SDK does not include `sdkconfig.h` in correct
* order. as this header depends on sdkconfig.h, sdkconfig.h must be included
* first. however, the SDK includes this header first, then includes
* `sdkconfig.h` when freertos/FreeRTOS.h is not explicitly included. an
* evidence can be found in `build/${COMPONENT}/${COMPONENT}.d` in a failed
* build.
*/
#include <freertos/FreeRTOS.h>
#include <esp_idf_version.h>
#if !defined(ESP_IDF_VERSION) || !defined(ESP_IDF_VERSION_VAL)
#error Unknown ESP-IDF/ESP8266 RTOS SDK version
#endif
/* Minimal supported version for ESP32, ESP32S2 */
#define HELPER_ESP32_MIN_VER ESP_IDF_VERSION_VAL(3, 3, 5)
/* Minimal supported version for ESP8266 */
#define HELPER_ESP8266_MIN_VER ESP_IDF_VERSION_VAL(3, 3, 0)
/* HELPER_TARGET_IS_ESP32
* 1 when the target is esp32
*/
#if defined(CONFIG_IDF_TARGET_ESP32) \
|| defined(CONFIG_IDF_TARGET_ESP32S2) \
|| defined(CONFIG_IDF_TARGET_ESP32S3) \
|| defined(CONFIG_IDF_TARGET_ESP32C2) \
|| defined(CONFIG_IDF_TARGET_ESP32C3) \
|| defined(CONFIG_IDF_TARGET_ESP32C5) \
|| defined(CONFIG_IDF_TARGET_ESP32C6) \
|| defined(CONFIG_IDF_TARGET_ESP32P4) \
|| defined(CONFIG_IDF_TARGET_ESP32C61) \
|| defined(CONFIG_IDF_TARGET_ESP32H2)
#define HELPER_TARGET_IS_ESP32 (1)
/* HELPER_TARGET_IS_ESP8266
* 1 when the target is esp8266
*/
#elif defined(CONFIG_IDF_TARGET_ESP8266)
#define HELPER_TARGET_IS_ESP8266 (1)
#else
#error BUG: cannot determine the target
#endif
#if HELPER_TARGET_IS_ESP32 && ESP_IDF_VERSION < HELPER_ESP32_MIN_VER
#error Unsupported ESP-IDF version. Please update!
#endif
#if HELPER_TARGET_IS_ESP8266 && ESP_IDF_VERSION < HELPER_ESP8266_MIN_VER
#error Unsupported ESP8266 RTOS SDK version. Please update!
#endif
/* HELPER_SPI_HOST_DEFAULT
*
* The default SPI_HOST for spi_host_device_t
*/
#if CONFIG_IDF_TARGET_ESP32
#define HELPER_SPI_HOST_DEFAULT SPI1_HOST
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define HELPER_SPI_HOST_DEFAULT SPI2_HOST
#elif CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61
#define HELPER_SPI_HOST_DEFAULT SPI1_HOST
#elif CONFIG_IDF_TARGET_ESP32H2
#define HELPER_SPI_HOST_DEFAULT SPI1_HOST
#elif CONFIG_IDF_TARGET_ESP32P4
#define HELPER_SPI_HOST_DEFAULT SPI1_HOST
#endif
/* show the actual values for debugging */
#if DEBUG
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32C3))
#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32H2))
#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32S2))
#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP32))
#pragma message(VAR_NAME_VALUE(CONFIG_IDF_TARGET_ESP8266))
#pragma message(VAR_NAME_VALUE(ESP_IDF_VERSION_MAJOR))
#endif
#endif

View File

@@ -1,27 +0,0 @@
#if CONFIG_IDF_TARGET_ESP32
#include <esp32/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32C2
#include <esp32c2/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32C3
#include <esp32c3/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32C5
#include <esp32c5/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32C6
#include <esp32c6/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32C61
#include <esp32c61/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32H2
#include <esp32h2/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32H4
#include <esp32h4/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32S2
#include <esp32s2/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32S3
#include <esp32s3/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP32P4
#include <esp32p4/rom/ets_sys.h>
#elif CONFIG_IDF_TARGET_ESP8266
#include <rom/ets_sys.h>
#else
#error "ets_sys: Unknown target"
#endif

View File

@@ -1,5 +0,0 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(example_example)

View File

@@ -1,5 +0,0 @@
#V := 1
PROJECT_NAME := example_example
include $(IDF_PATH)/make/project.mk

View File

@@ -1,16 +0,0 @@
# Example application for `example` component
## What the example does
The example does nothing but waits in a loop.
## Configuration
No configuration is available.
## Notes
This is an example application of `example`. It is intended as an example
application for new component.
The code under `main` should conform the code style.

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -1 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = .

View File

@@ -1,5 +0,0 @@
dependencies:
esp-idf-lib/esp_idf_lib_helpers:
version: '*'
description: default
version: 1.0.0

View File

@@ -1,39 +0,0 @@
/*
* Copyright (c) YYYY YOUR NAME HERE <user@your.dom.ain>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <esp_log.h>
#include <esp_idf_lib_helpers.h>
#include "my_local_header.h"
static char *tag = "main";
void app_main()
{
ESP_LOGI(tag, "An example log");
#if HELPER_TARGET_IS_ESP32
ESP_LOGI(tag, "the target is ESP32");
#else
ESP_LOGI(tag, "the target is not ESP32");
#endif
while (1)
{
vTaskDelay(pdMS_TO_TICKS(1000));
}
}

View File

@@ -1,20 +0,0 @@
/*
* Copyright (c) YYYY YOUR NAME HERE <user@your.dom.ain>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#if !defined(__MY_LOCAL_HEADER__H__)
#define __MY_LOCAL_HEADER__H__
#endif

View File

@@ -1 +0,0 @@
# add required non-default option for the example if any

View File

@@ -1,29 +0,0 @@
dependencies: {}
description: Common support library for esp-idf-lib
discussion: https://github.com/esp-idf-lib/core/discussions
documentation: https://esp-idf-lib.github.io/esp_idf_lib_helpers/
files:
exclude:
- docs/**/*
issues: https://github.com/esp-idf-lib/esp_idf_lib_helpers/issues
license: ISC
maintainers:
- Tomoyuki Sakurai (@trombik) <y@trombik.org>
- Ruslan V. Uss (@UncleRus) <unclerus@gmail.com>
repository: git://github.com/esp-idf-lib/esp_idf_lib_helpers.git
repository_info:
commit_sha: 918d82cafb1f00fd86f1ad8571271cb3e910588b
path: .
targets:
- esp32
- esp32c2
- esp32c3
- esp32c5
- esp32c6
- esp32c61
- esp32h2
- esp32p4
- esp32s2
- esp32s3
url: https://github.com/esp-idf-lib/core
version: 1.4.0

View File

@@ -1 +0,0 @@
--ignore-dir=build

View File

@@ -1,17 +0,0 @@
--align-reference=name
--attach-classes
--attach-classes
--attach-namespaces
--convert-tabs
--exclude=build
--exclude=common
--exclude=managed_components
--ignore-exclude-errors
--indent-switches
--indent=spaces=4
--keep-one-line-statements
--max-continuation-indent=120
--pad-header
--pad-oper
--style=allman
--unpad-paren

View File

@@ -1,66 +0,0 @@
---
Language: Cpp
BasedOnStyle: WebKit
AlignConsecutiveMacros: true
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Always
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ColumnLimit: 200
CompactNamespaces: true
Cpp11BracedListStyle: false
FixNamespaceComments: true
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never

View File

@@ -1 +0,0 @@
4f3838b2e68ab2b77fd43737139fa97dd0243b46af7b4a04588c67ff6b275ba1

View File

@@ -1,32 +0,0 @@
name: i2cdev
description: ESP-IDF I2C master thread-safe utilities
version: 2.1.0
groups:
- common
code_owners:
- UncleRus
- quinkq
- trombik
depends:
- driver
- freertos
- esp_idf_lib_helpers
thread_safe: yes
targets:
- esp32
- esp8266
- esp32s2
- esp32c3
- esp32s3
- esp32c2
- esp32c6
- esp32h2
- esp32p4
- esp32c5
- esp32c61
license: MIT
copyrights:
- name: UncleRus
year: 2018
- name: quinkq
year: 2025

View File

@@ -1,12 +0,0 @@
examples/**/sdkconfig
examples/**/sdkconfig.old
examples/**/build/
examples/**/dependencies.lock
examples/**/managed_components/
docs/_*/
docs/**/*.log
*.swp
*.bak
*.orig
build/
.vscode/

View File

@@ -1,3 +0,0 @@
[submodule "common"]
path = common
url = https://github.com/esp-idf-lib/common.git

View File

@@ -1,50 +0,0 @@
# ESP-IDF CMake component for i2cdev library
if(${IDF_VERSION_MAJOR} STREQUAL 5 AND ${IDF_VERSION_MINOR} LESS 3)
# Use driver component as esp_driver_gpio is not available before 5.3
set(req driver freertos log esp_timer)
else()
set(req esp_driver_gpio esp_driver_i2c freertos esp_idf_lib_helpers)
endif()
# ESP-IDF version detection for automatic driver selection
# Check for manual override via Kconfig
if(CONFIG_I2CDEV_USE_LEGACY_DRIVER)
set(USE_LEGACY_DRIVER TRUE)
message(STATUS "i2cdev: Manual override - using legacy driver (CONFIG_I2CDEV_USE_LEGACY_DRIVER=y)")
elseif(NOT DEFINED IDF_VERSION_MAJOR)
# In case older ESP-IDF versions that don't define IDF_VERSION_MAJOR
set(USE_LEGACY_DRIVER TRUE)
message(STATUS "i2cdev: IDF_VERSION_MAJOR not defined, using legacy driver")
elseif(IDF_VERSION_MAJOR LESS 5)
set(USE_LEGACY_DRIVER TRUE)
message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.x detected, using legacy driver")
elseif(IDF_VERSION_MAJOR EQUAL 5 AND IDF_VERSION_MINOR LESS 3)
set(USE_LEGACY_DRIVER TRUE)
message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR} detected, using legacy driver")
else()
set(USE_LEGACY_DRIVER FALSE)
message(STATUS "i2cdev: ESP-IDF v${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR} detected, using new i2c_master driver")
endif()
# Conditionally set the source file based on version detection or Kconfig override
if(USE_LEGACY_DRIVER)
set(SRCS "i2cdev_legacy.c")
message(STATUS "i2cdev: Compiling with legacy I2C driver (i2cdev_legacy.c)")
else()
set(SRCS "i2cdev.c")
message(STATUS "i2cdev: Compiling with new I2C master driver (i2cdev.c)")
endif()
# Register the component
idf_component_register(SRCS ${SRCS}
INCLUDE_DIRS "."
REQUIRES ${req})
# include common cmake file for components
set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake)
if(EXISTS ${ESP_IDF_LIB_CMAKE})
include(${ESP_IDF_LIB_CMAKE})
else()
message(WARNING "${ESP_IDF_LIB_CMAKE} not found")
endif()

View File

@@ -1,65 +0,0 @@
menu "I2C Device Library"
config I2CDEV_USE_LEGACY_DRIVER
bool "Use Legacy I2C Driver API"
default n
help
Select this option to use the older ESP-IDF I2C driver API (driver/i2c.h)
instead of the newer driver API (driver/i2c_master.h).
This is automatically determined by the build system based on your ESP-IDF version.
For ESP-IDF versions prior to v5.3, the legacy driver will be used automatically.
You can manually override this setting if needed.
config I2CDEV_AUTO_ENABLE_PULLUPS
bool "Automatically enable internal I2C pullups when not configured"
default n
depends on !IDF_TARGET_ESP8266
help
When enabled, internal pullup resistors are automatically enabled
when both sda_pullup_en and scl_pullup_en are false (default state).
Useful for development and prototyping. Disable for production
systems with external pullups to avoid interference.
Considerations:
- May increase power consumption slightly
- Could interfere with carefully tuned external pullups
- Not recommended for battery-powered applications
Note: This option only affects the modern i2cdev driver (ESP32 family).
Legacy driver behavior is unchanged for compatibility.
config I2CDEV_DEFAULT_SDA_PIN
int "Default I2C SDA pin"
default 21
help
Default SDA pin for I2C devices.
config I2CDEV_DEFAULT_SCL_PIN
int "Default I2C SCL pin"
default 22
help
Default SCL pin for I2C devices.
config I2CDEV_MAX_DEVICES_PER_PORT
int "Maximum number of devices per I2C port"
default 8
help
Maximum number of devices that can be registered on a single I2C port.
config I2CDEV_TIMEOUT
int "I2C transaction timeout, milliseconds"
default 1000
range 10 5000
config I2CDEV_NOLOCK
bool "Disable the use of mutexes"
default n
help
Attention! After enabling this option, all I2C device
drivers will become non-thread safe.
Use this option if you need to access your I2C devices
from interrupt handlers.
endmenu

View File

@@ -1,19 +0,0 @@
config EXAMPLE_I2C_MASTER_SCL
int "SCL GPIO Number"
default 5 if IDF_TARGET_ESP8266
default 6 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 4 if IDF_TARGET_ESP32H2
default 4 if IDF_TARGET_ESP32P4
help
GPIO number for I2C Master clock line.
config EXAMPLE_I2C_MASTER_SDA
int "SDA GPIO Number"
default 4 if IDF_TARGET_ESP8266
default 5 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 3 if IDF_TARGET_ESP32H2
default 3 if IDF_TARGET_ESP32P4
help
GPIO number for I2C Master data line.

View File

@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2018 Ruslan V. Uss (https://github.com/UncleRus)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,30 +0,0 @@
# esp-idf-lib/i2cdev
[![Build examples](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build.yml)
[![Build docs](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//build-docs.yml)
[![Validation](https://github.com/esp-idf-lib/i2cdev/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/i2cdev/actions/workflows//validate-component.yml)
ESP-IDF I2C master thread-safe utilities.
* [Documentation](https://esp-idf-lib.github.io/i2cdev/)
* [Repository](https://github.com/esp-idf-lib/i2cdev)
* [Issues](https://github.com/esp-idf-lib/i2cdev/issues)
* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions)
* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/i2cdev)
## Installation
```sh
idf.py add-dependency esp-idf-lib/i2cdev
```
## Support
For questions and discussions about the component, please use
[Discussions](https://github.com/esp-idf-lib/core/discussions)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).
## Contributing
Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env ruby
require "pathname"
require "yaml"
# A simple CLI to get values in .eil.yml
key = ARGV.shift
project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent
eil_file = project_root / ".eil.yml"
doc = YAML.safe_load(File.read eil_file)
case key
when "copyright_string"
puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ")
else
puts doc[key]
end

View File

@@ -1,36 +0,0 @@
# Set common build flags but enable them only when the build is in our CI,
# making them optional. The idea is, fail when compiled in our CI but just
# warn in any other cases. Code that compiles with one toolchain warning-free
# may not do so with another toolchain, which creates a project dependency on
# specific toolchain vendors and versions.
#
# Define flags that may cause failures here.
if (DEFINED ENV{ESP_IDF_LIB_CI})
set(ESP_IDF_LIB_CI_FLAGS
-Werror=unused-variable
-Werror=unused-function
-Werror=write-strings
-Werror
)
endif()
# Set common build flags. Mandatory.
#
# Define flags that do not cause failures here.
set(ESP_IDF_LIB_FLAGS
-Wextra
-Wwrite-strings
-Wunused-variable
-Wunused-function
-Wreturn-type
)
# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not
# set the flags.
get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE)
if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY")
target_compile_options(${COMPONENT_LIB} PRIVATE
${ESP_IDF_LIB_FLAGS}
${ESP_IDF_LIB_CI_FLAGS}
)
endif()

View File

@@ -1,29 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = .
ifdef CONFIG_IDF_TARGET_ESP8266
COMPONENT_DEPENDS = esp8266 freertos esp_idf_lib_helpers
# ESP8266 RTOS SDK auto-detects all .c files, so use COMPONENT_OBJS to override
# This prevents both i2cdev.c and i2cdev_legacy.c from being compiled
COMPONENT_OBJS := i2cdev_legacy.o
COMPONENT_SRCDIRS := .
else
COMPONENT_DEPENDS = driver freertos esp_idf_lib_helpers
# For ESP32 family, check for manual override first
ifdef CONFIG_I2CDEV_USE_LEGACY_DRIVER
COMPONENT_SRCS = i2cdev_legacy.c
else
# Check if version variables are available, fallback to legacy if not
ifdef IDF_VERSION_MAJOR
ifeq ($(shell test $(IDF_VERSION_MAJOR) -lt 5 && echo 1),1)
COMPONENT_SRCS = i2cdev_legacy.c
else ifeq ($(shell test $(IDF_VERSION_MAJOR) -eq 5 -a $(IDF_VERSION_MINOR) -lt 3 && echo 1),1)
COMPONENT_SRCS = i2cdev_legacy.c
else
COMPONENT_SRCS = i2cdev.c
endif
else
# Version variables not available - fallback to legacy driver for safety
COMPONENT_SRCS = i2cdev_legacy.c
endif
endif
endif

View File

@@ -1,7 +0,0 @@
# The following four lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(i2c_scanner)

View File

@@ -1,5 +0,0 @@
#V := 1
PROJECT_NAME := i2c_scanner
include $(IDF_PATH)/make/project.mk

View File

@@ -1,31 +0,0 @@
# I2C bus scanner
## What it does
This example scans the i2c bus in a loop and prints out a table with the addresses of the found i2c devices.
## Wiring
Connect `SCL` and `SDA` pins to the following pins with appropriate pull-up
resistors.
| Name | Description | Defaults |
|------|-------------|----------|
| `CONFIG_EXAMPLE_I2C_MASTER_SCL` | GPIO number for `SCL` | "5" for `esp8266`, "6" for `esp32c3`, "19" for `esp32`, `esp32s2`, and `esp32s3` |
| `CONFIG_EXAMPLE_I2C_MASTER_SDA` | GPIO number for `SDA` | "4" for `esp8266`, "5" for `esp32c3`, "18" for `esp32`, `esp32s2`, and `esp32s3` |
## Example output
Three devices found on a bus: 0x38, 0x60 and 0x77
```
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- 38 -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: 60 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- 77
```

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -1,7 +0,0 @@
menu "I2C scanner configuration"
config EXAMPLE_I2C_CLOCK_HZ
int "I2C clock frequency, Hz"
default 100000
rsource "../../../Kconfig.i2c"
endmenu

View File

@@ -1 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = . include/

View File

@@ -1,7 +0,0 @@
dependencies:
esp-idf-lib/esp_idf_lib_helpers:
version: '*'
esp-idf-lib/i2cdev:
version: '*'
description: default
version: 1.0.0

View File

@@ -1,43 +0,0 @@
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <i2cdev.h>
#include <stdio.h>
void task(void *ignore)
{
i2c_dev_t dev = { 0 };
dev.cfg.sda_io_num = CONFIG_EXAMPLE_I2C_MASTER_SDA;
dev.cfg.scl_io_num = CONFIG_EXAMPLE_I2C_MASTER_SCL;
#if HELPER_TARGET_IS_ESP32
dev.cfg.master.clk_speed = CONFIG_EXAMPLE_I2C_CLOCK_HZ; // 100kHz
#endif
while (1)
{
esp_err_t res;
printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n");
printf("00: ");
for (uint8_t addr = 3; addr < 0x78; addr++)
{
if (addr % 16 == 0)
printf("\n%.2x:", addr);
dev.addr = addr;
res = i2c_dev_probe(&dev, I2C_DEV_WRITE);
if (res == 0)
printf(" %.2x", addr);
else
printf(" --");
}
printf("\n\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main()
{
// Init i2cdev library
ESP_ERROR_CHECK(i2cdev_init());
// Start task
xTaskCreate(task, "i2c_scanner", configMINIMAL_STACK_SIZE * 3, NULL, 5, NULL);
}

View File

@@ -1,897 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ruslan V. Uss <unclerus@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* @file i2cdev.c
*
* ESP-IDF I2C master thread-safe functions for communication with I2C slave
*
* Copyright (C) 2018 Ruslan V. Uss <unclerus@gmail.com>
* Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API
*
* MIT Licensed as described in the file LICENSE
*/
#include "i2cdev.h"
#include <driver/i2c_master.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <inttypes.h>
#include <string.h>
static const char *TAG = "i2cdev";
// Fallback definition for platforms without 10-bit address support
#ifndef I2C_ADDR_BIT_LEN_10
#define I2C_ADDR_BIT_LEN_10 1
#endif
#define I2C_DEFAULT_FREQ_HZ 400000
#define I2C_MAX_RETRIES 3
#define I2C_RETRY_BASE_DELAY_MS 20
#define I2CDEV_MAX_STACK_ALLOC_SIZE 32 // Stack allocation threshold to avoid heap fragmentation for small buffers
typedef struct
{
SemaphoreHandle_t lock; // Mutex for exclusive access to this port's state
i2c_master_bus_handle_t bus_handle; // Handle to the initialized I2C master bus
bool installed; // Flag indicating if the bus for this port has been installed
uint32_t ref_count; // Number of devices currently active on this bus port
int sda_pin_current; // Actual SDA pin the bus was initialized with
int scl_pin_current; // Actual SCL pin the bus was initialized with
} i2c_port_state_t;
static i2c_port_state_t i2c_ports[I2C_NUM_MAX] = { 0 };
static i2c_dev_t *active_devices[I2C_NUM_MAX][CONFIG_I2CDEV_MAX_DEVICES_PER_PORT] = { { NULL } };
// Helper to register a device
static esp_err_t register_device(i2c_dev_t *dev)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
int port = dev->port;
if (port >= I2C_NUM_MAX)
return ESP_ERR_INVALID_ARG;
// Note: Port mutex should be held by caller
for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++)
{
if (active_devices[port][i] == NULL)
{
active_devices[port][i] = dev;
ESP_LOGV(TAG, "[0x%02x at %d] Registered device in slot %d", dev->addr, port, i);
return ESP_OK;
}
}
ESP_LOGE(TAG, "[0x%02x at %d] No free slots to register device - limit reached", dev->addr, port);
return ESP_ERR_NO_MEM;
}
// Helper to deregister a device
static void deregister_device(i2c_dev_t *dev)
{
if (!dev)
return;
int port = dev->port;
if (port >= I2C_NUM_MAX)
return;
for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++)
{
if (active_devices[port][i] == dev)
{
active_devices[port][i] = NULL;
ESP_LOGV(TAG, "[0x%02x at %d] Deregistered device from slot %d", dev->addr, port, i);
return;
}
}
}
esp_err_t i2cdev_init(void)
{
ESP_LOGV(TAG, "Initializing I2C subsystem...");
memset(active_devices, 0, sizeof(active_devices));
for (int i = 0; i < I2C_NUM_MAX; i++)
{
if (!i2c_ports[i].lock)
{
i2c_ports[i].lock = xSemaphoreCreateMutex();
if (!i2c_ports[i].lock)
{
ESP_LOGE(TAG, "Could not create port mutex %d", i);
return ESP_ERR_NO_MEM;
}
ESP_LOGV(TAG, "Created port mutex %d", i);
}
i2c_ports[i].installed = false;
i2c_ports[i].ref_count = 0;
i2c_ports[i].bus_handle = NULL;
i2c_ports[i].sda_pin_current = -1;
i2c_ports[i].scl_pin_current = -1;
}
ESP_LOGV(TAG, "I2C subsystem initialized.");
return ESP_OK;
}
esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Creating device mutex...", dev->addr, dev->port);
if (dev->mutex)
{
ESP_LOGW(TAG, "[0x%02x at %d] device mutex already exists (Handle: %p)", dev->addr, dev->port, dev->mutex);
return ESP_OK; // Already created
}
dev->mutex = xSemaphoreCreateMutex();
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not create device mutex", dev->addr, dev->port);
return ESP_ERR_NO_MEM; // Use ESP_ERR_NO_MEM for memory allocation failures
}
ESP_LOGV(TAG, "[0x%02x at %d] Device mutex created (Handle: %p)", dev->addr, dev->port, dev->mutex);
// Register the device for cleanup tracking (under port mutex for consistency)
if (dev->port < I2C_NUM_MAX && i2c_ports[dev->port].lock)
{
if (xSemaphoreTake(i2c_ports[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE)
{
esp_err_t reg_res = register_device(dev);
if (reg_res != ESP_OK)
{
ESP_LOGW(TAG, "[0x%02x at %d] Failed to register device: %s - device will work but cleanup tracking disabled", dev->addr, dev->port, esp_err_to_name(reg_res));
// Continue - device can still function without registration tracking
}
else
{
ESP_LOGV(TAG, "[0x%02x at %d] Device registered successfully for cleanup tracking", dev->addr, dev->port);
}
xSemaphoreGive(i2c_ports[dev->port].lock);
}
else
{
ESP_LOGW(TAG, "[0x%02x at %d] Could not take port mutex for device registration", dev->addr, dev->port);
// Continue - device can still function without registration tracking
}
}
// Set default address bit length if not explicitly set
if (dev->addr_bit_len != I2C_ADDR_BIT_LEN_7 && dev->addr_bit_len != I2C_ADDR_BIT_LEN_10)
{
ESP_LOGV(TAG, "[0x%02x at %d] Setting default 7-bit address format", dev->addr, dev->port);
dev->addr_bit_len = I2C_ADDR_BIT_LEN_7;
}
#else
ESP_LOGV(TAG, "[0x%02x at %d] Mutex creation skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port);
#endif
return ESP_OK;
}
esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Deleting device mutex and cleaning up resources", dev->addr, dev->port);
// Remove device from bus if handle exists
if (dev->dev_handle)
{
ESP_LOGV(TAG, "[0x%02x at %d] Removing device handle %p from bus", dev->addr, dev->port, dev->dev_handle);
esp_err_t rm_res = i2c_master_bus_rm_device((i2c_master_dev_handle_t)dev->dev_handle);
if (rm_res != ESP_OK)
{
ESP_LOGW(TAG, "[0x%02x at %d] Failed to remove device handle: %s", dev->addr, dev->port, esp_err_to_name(rm_res));
// Continue with cleanup despite error
}
dev->dev_handle = NULL;
}
// Deregister the device
deregister_device(dev);
// Update port reference count if port is valid
if (dev->port < I2C_NUM_MAX)
{
if (xSemaphoreTake(i2c_ports[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE)
{
if (i2c_ports[dev->port].installed && i2c_ports[dev->port].ref_count > 0)
{
i2c_ports[dev->port].ref_count--;
ESP_LOGV(TAG, "[Port %d] Decremented ref_count to %" PRIu32, dev->port, i2c_ports[dev->port].ref_count);
// If last device on this port, delete the bus
if (i2c_ports[dev->port].ref_count == 0)
{
ESP_LOGI(TAG, "[Port %d] Last device removed, cleaning up THIS port's bus", dev->port);
// Just clean up this port's bus
if (i2c_ports[dev->port].bus_handle)
{
ESP_LOGI(TAG, "[Port %d] Deleting bus handle %p", dev->port, i2c_ports[dev->port].bus_handle);
esp_err_t del_bus_res = i2c_del_master_bus(i2c_ports[dev->port].bus_handle);
if (del_bus_res != ESP_OK)
{
ESP_LOGE(TAG, "[Port %d] Failed to delete master bus: %s", dev->port, esp_err_to_name(del_bus_res));
}
i2c_ports[dev->port].bus_handle = NULL;
}
i2c_ports[dev->port].installed = false;
i2c_ports[dev->port].sda_pin_current = -1;
i2c_ports[dev->port].scl_pin_current = -1;
}
}
xSemaphoreGive(i2c_ports[dev->port].lock);
}
else
{
ESP_LOGW(TAG, "[0x%02x at %d] Could not take port mutex for ref_count update", dev->addr, dev->port);
}
}
// Delete the mutex itself last
if (dev->mutex)
{
vSemaphoreDelete(dev->mutex);
dev->mutex = NULL;
}
else
{
ESP_LOGV(TAG, "[0x%02x at %d] Device mutex was NULL, nothing to delete", dev->addr, dev->port);
}
#endif
return ESP_OK;
}
esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Attempting to take device mutex (Handle: %p)...", dev->addr, dev->port, dev->mutex);
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Attempt to take NULL device mutex!", dev->addr, dev->port);
return ESP_ERR_INVALID_STATE; // Mutex doesn't exist
}
TickType_t timeout_ticks = pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT);
ESP_LOGV(TAG, "[0x%02x at %d] Taking device mutex with timeout %d ms (%lu ticks)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT, (unsigned long)timeout_ticks);
if (!xSemaphoreTake(dev->mutex, timeout_ticks))
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take device mutex (Timeout after %d ms)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT);
return ESP_ERR_TIMEOUT;
}
ESP_LOGV(TAG, "[0x%02x at %d] Device mutex taken successfully.", dev->addr, dev->port);
#else
ESP_LOGV(TAG, "[0x%02x at %d] Mutex take skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port);
#endif
return ESP_OK;
}
esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Giving device mutex (Handle: %p)...", dev->addr, dev->port, dev->mutex);
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Attempt to give NULL device mutex!", dev->addr, dev->port);
return ESP_ERR_INVALID_STATE;
}
if (!xSemaphoreGive(dev->mutex))
{
// This case should ideally not happen if the mutex was taken correctly
ESP_LOGE(TAG, "[0x%02x at %d] Could not give device mutex (Was it taken?) (Handle: %p)", dev->addr, dev->port, dev->mutex);
return ESP_FAIL;
}
ESP_LOGV(TAG, "[0x%02x at %d] Device mutex given successfully.", dev->addr, dev->port);
#else
ESP_LOGV(TAG, "[0x%02x at %d] Mutex give skipped (CONFIG_I2CDEV_NOLOCK=1)", dev->addr, dev->port);
#endif
return ESP_OK;
}
// i2c_setup_port: Initializes the I2C master bus for a given port if not already done.
// It uses pin configurations from dev->cfg.sda_io_num and dev->cfg.scl_io_num.
// The pins for a port are fixed after the first device initializes it.
static esp_err_t i2c_setup_port(i2c_dev_t *dev) // dev is non-const to update dev->sda_pin, dev->scl_pin
{
if (!dev)
return ESP_ERR_INVALID_ARG;
if (dev->port >= I2C_NUM_MAX)
{
ESP_LOGE(TAG, "Invalid I2C port number: %d", dev->port);
return ESP_ERR_INVALID_ARG;
}
esp_err_t res = ESP_OK;
i2c_port_state_t *port_state = &i2c_ports[dev->port];
ESP_LOGV(TAG, "[Port %d] Setup request for device 0x%02x", dev->port, dev->addr);
if (xSemaphoreTake(port_state->lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE)
{
ESP_LOGE(TAG, "[Port %d] Could not take port mutex for setup", dev->port);
return ESP_ERR_TIMEOUT;
}
if (!port_state->installed)
{
// Pin Selection Logic: Use device-specified pins, fallback to Kconfig defaults if -1
gpio_num_t sda_pin = (dev->cfg.sda_io_num == (gpio_num_t) -1) ? (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SDA_PIN : dev->cfg.sda_io_num;
gpio_num_t scl_pin = (dev->cfg.scl_io_num == (gpio_num_t) -1) ? (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SCL_PIN : dev->cfg.scl_io_num;
// Validate pins (basic check, gpio_is_valid_gpio could be used for more robust check)
if (sda_pin < 0 || scl_pin < 0)
{
ESP_LOGE(TAG, "[Port %d] Invalid SCL/SDA pins: SDA=%d, SCL=%d. Check driver or Kconfig defaults.", dev->port, sda_pin, scl_pin);
xSemaphoreGive(port_state->lock);
return ESP_ERR_INVALID_ARG;
}
/*
* OPTIONAL I2C PULLUP AUTO-CONFIGURATION
*
* By default: Uses whatever sda_pullup_en/scl_pullup_en you set (usually false)
*
* When CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y: If both pullup flags are false,
* automatically change them to true to enable internal pullups (~45kΩ).
*
* Manual pullup configuration:
* - Set sda_pullup_en=true, scl_pullup_en=true for internal pullups
* - Set sda_pullup_en=false, scl_pullup_en=false for external pullups
*/
// Read user's pullup configuration (default false if not set)
bool sda_pullup = dev->cfg.sda_pullup_en;
bool scl_pullup = dev->cfg.scl_pullup_en;
#if CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS
// CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y: If user didn't configure pullups, enable them automatically
if (!sda_pullup && !scl_pullup)
{
sda_pullup = true;
scl_pullup = true;
ESP_LOGI(TAG, "[Port %d] Auto-enabling internal pullups (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y)", dev->port);
}
#endif
ESP_LOGI(TAG,
"[Port %d] First initialization. Configuring bus with SDA=%d, SCL=%d (Pullups "
"SCL:%d SDA:%d)",
dev->port, sda_pin, scl_pin, scl_pullup, sda_pullup);
i2c_master_bus_config_t bus_config =
{
.i2c_port = dev->port,
.sda_io_num = sda_pin,
.scl_io_num = scl_pin,
.clk_source = I2C_CLK_SRC_DEFAULT,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = (sda_pullup || scl_pullup),
// Bus speed is not set here. It's per-device or a global target for the bus can be set
// if desired, but i2c_master supports per-device speeds.
};
res = i2c_new_master_bus(&bus_config, &port_state->bus_handle);
if (res == ESP_OK)
{
port_state->installed = true;
port_state->ref_count = 0; // Will be incremented when a device is successfully added
port_state->sda_pin_current = sda_pin;
port_state->scl_pin_current = scl_pin;
dev->sda_pin = sda_pin; // Update dev struct with actual pins used
dev->scl_pin = scl_pin;
ESP_LOGI(TAG, "[Port %d] Successfully installed I2C master bus (Handle: %p).", dev->port, port_state->bus_handle);
}
else
{
ESP_LOGE(TAG, "[Port %d] Failed to create master bus: %d (%s)", dev->port, res, esp_err_to_name(res));
port_state->installed = false;
port_state->bus_handle = NULL;
port_state->sda_pin_current = -1;
port_state->scl_pin_current = -1;
}
}
else
{
ESP_LOGV(TAG, "[Port %d] Port already installed (SDA=%d, SCL=%d, Handle: %p).", dev->port, port_state->sda_pin_current, port_state->scl_pin_current, port_state->bus_handle);
// Pin Consistency Check: For subsequent devices, ensure pins match already-configured bus
gpio_num_t sda_desired = (dev->cfg.sda_io_num == (gpio_num_t) -1) ? (gpio_num_t)port_state->sda_pin_current : dev->cfg.sda_io_num;
gpio_num_t scl_desired = (dev->cfg.scl_io_num == (gpio_num_t) -1) ? (gpio_num_t)port_state->scl_pin_current : dev->cfg.scl_io_num;
if (sda_desired != port_state->sda_pin_current || scl_desired != port_state->scl_pin_current)
{
ESP_LOGE(TAG,
"[Port %d] Pin mismatch for device 0x%02x! Bus on SDA=%d,SCL=%d. Device wants "
"SDA=%d,SCL=%d",
dev->port, dev->addr, port_state->sda_pin_current, port_state->scl_pin_current, sda_desired, scl_desired);
res = ESP_ERR_INVALID_STATE; // Cannot change pins for an installed bus
}
else
{
dev->sda_pin = port_state->sda_pin_current; // Update dev struct with actual pins used
dev->scl_pin = port_state->scl_pin_current;
}
// ref_count is managed by i2c_setup_device when adding/removing device handles
}
xSemaphoreGive(port_state->lock);
ESP_LOGV(TAG, "[Port %d] Port setup finished with res %d.", dev->port, res);
return res;
}
// i2c_setup_device: Ensures port is set up and adds the device to the bus if not already added.
// It also registers the device in active_devices for cleanup purposes.
static esp_err_t i2c_setup_device(i2c_dev_t *dev) // dev is non-const - modifies dev->dev_handle, dev->addr_bit_len
{
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Setting up device context...", dev->addr, dev->port);
esp_err_t res = i2c_setup_port(dev);
if (res != ESP_OK)
{
ESP_LOGE(TAG, "[0x%02x at %d] Port setup failed during device setup: %d (%s)", dev->addr, dev->port, res, esp_err_to_name(res));
return res;
}
// If addr_bit_len is not set (e.g. 0, which is invalid for i2c_addr_bit_len_t enum), default to
// 7-bit. Modified to conditionally check for I2C_ADDR_BIT_LEN_10 based on hardware support
if (dev->addr_bit_len != I2C_ADDR_BIT_LEN_7
#if SOC_I2C_SUPPORT_10BIT_ADDR
&& dev->addr_bit_len != I2C_ADDR_BIT_LEN_10
#endif
)
{
ESP_LOGD(TAG, "[0x%02x at %d] addr_bit_len not explicitly set, defaulting to 7-bit.", dev->addr, dev->port);
dev->addr_bit_len = I2C_ADDR_BIT_LEN_7;
}
// Only warn about address size if the device is actually using 10-bit addressing
if (dev->addr_bit_len == I2C_ADDR_BIT_LEN_7 && dev->addr > 0x7F)
{
ESP_LOGW(TAG,
"[0x%02x at %d] Device address > 0x7F but addr_bit_len is 7-bit. Ensure address "
"is correct.",
dev->addr, dev->port);
}
#if !defined(SOC_I2C_SUPPORT_10BIT_ADDR) || !SOC_I2C_SUPPORT_10BIT_ADDR
// On platforms without 10-bit support, force 7-bit addressing regardless of user setting
if (dev->addr_bit_len == I2C_ADDR_BIT_LEN_10)
{
ESP_LOGW(TAG, "[0x%02x at %d] 10-bit addressing not supported on this platform, forcing 7-bit mode", dev->addr, dev->port);
dev->addr_bit_len = I2C_ADDR_BIT_LEN_7;
}
#endif
if (dev->dev_handle == NULL)
{
i2c_port_state_t *port_state = &i2c_ports[dev->port];
if (xSemaphoreTake(port_state->lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE)
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for device add", dev->addr, dev->port);
return ESP_ERR_TIMEOUT;
}
if (!port_state->installed || !port_state->bus_handle)
{
ESP_LOGE(TAG, "[0x%02x at %d] Cannot add device, bus for port %d not ready!", dev->addr, dev->port, dev->port);
xSemaphoreGive(port_state->lock);
return ESP_ERR_INVALID_STATE;
}
ESP_LOGV(TAG, "[0x%02x at %d] Adding device to bus (Bus Handle: %p)...", dev->addr, dev->port, port_state->bus_handle);
uint32_t effective_dev_speed = dev->cfg.master.clk_speed;
if (effective_dev_speed == 0)
{
ESP_LOGW(TAG,
"[0x%02x at %d] Device speed (dev->cfg.master.clk_speed) is 0, using default: "
"%" PRIu32 " Hz",
dev->addr, dev->port, (uint32_t)I2C_DEFAULT_FREQ_HZ);
effective_dev_speed = I2C_DEFAULT_FREQ_HZ;
}
i2c_device_config_t dev_config =
{
// Use the possibly modified addr_bit_len that respects hardware capabilities
.dev_addr_length = dev->addr_bit_len,
.device_address = dev->addr,
.scl_speed_hz = effective_dev_speed,
.flags.disable_ack_check = false,
};
res = i2c_master_bus_add_device(port_state->bus_handle, &dev_config, (i2c_master_dev_handle_t *)&dev->dev_handle);
if (res == ESP_OK)
{
ESP_LOGI(TAG, "[0x%02x at %d] Device added successfully (Device Handle: %p, Speed: %" PRIu32 " Hz).", dev->addr, dev->port, dev->dev_handle, effective_dev_speed);
// Increment the port reference count for each device successfully added
port_state->ref_count++;
ESP_LOGV(TAG, "[Port %d] Incremented ref_count to %" PRIu32, dev->port, port_state->ref_count);
}
else
{
ESP_LOGE(TAG, "[0x%02x at %d] Failed to add device to bus: %d (%s)", dev->addr, dev->port, res, esp_err_to_name(res));
dev->dev_handle = NULL;
}
xSemaphoreGive(port_state->lock);
}
else
{
ESP_LOGV(TAG, "[0x%02x at %d] Device handle %p already exists. Skipping add.", dev->addr, dev->port, dev->dev_handle);
res = ESP_OK;
}
ESP_LOGV(TAG, "[0x%02x at %d] Device context setup finished with res %d.", dev->addr, dev->port, res);
return res;
}
// Helper function with retry mechanism for I2C operations
static esp_err_t i2c_do_operation_with_retry(i2c_dev_t *dev, esp_err_t (*i2c_func)(i2c_master_dev_handle_t, const void *, size_t, void *, size_t, int), const void *write_buffer, size_t write_size,
void *read_buffer, size_t read_size)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
esp_err_t res = ESP_FAIL;
int retry = 0;
int timeout_ms = CONFIG_I2CDEV_TIMEOUT;
ESP_LOGV(TAG, "[0x%02x at %d] Performing I2C operation (timeout %d ms)...", dev->addr, dev->port, timeout_ms);
while (retry <= I2C_MAX_RETRIES)
{
// Ensure device is set up before each attempt, in case handle became stale or bus was reset
// This is more robust if issues like bus errors or device resets occur.
res = i2c_setup_device(dev);
if (res != ESP_OK)
{
ESP_LOGE(TAG, "[0x%02x at %d] Device setup failed (Try %d): %d (%s). Retrying setup...", dev->addr, dev->port, retry, res, esp_err_to_name(res));
// No point continuing this attempt if setup fails, but the loop will retry setup.
vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << (retry))));
retry++;
continue;
}
if (!dev->dev_handle)
{
ESP_LOGE(TAG,
"[0x%02x at %d] Device handle is NULL after setup (Try %d)! Cannot perform "
"operation.",
dev->addr, dev->port, retry);
// This indicates a persistent problem with adding the device to the bus.
// No point retrying the i2c_func if handle is null.
res = ESP_ERR_INVALID_STATE;
vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << (retry))));
retry++;
continue;
}
ESP_LOGV(TAG, "[0x%02x at %d] Attempting I2C op (Try %d, Handle %p)", dev->addr, dev->port, retry, dev->dev_handle);
res = i2c_func(dev->dev_handle, write_buffer, write_size, read_buffer, read_size, timeout_ms);
if (res == ESP_OK)
{
ESP_LOGV(TAG, "[0x%02x at %d] I2C operation successful (Try %d).", dev->addr, dev->port, retry);
return ESP_OK;
}
ESP_LOGW(TAG, "[0x%02x at %d] I2C op failed (Try %d, Handle %p): %d (%s).", dev->addr, dev->port, retry, dev->dev_handle, res, esp_err_to_name(res));
// Only remove handle on errors that indicate handle corruption or permanent invalidity
// Don't remove on temporary errors like ESP_ERR_TIMEOUT, ESP_FAIL (NACK), etc.
bool should_remove_handle = false;
switch (res)
{
case ESP_ERR_INVALID_ARG:
// Handle was likely removed by another task or is corrupted
should_remove_handle = true;
ESP_LOGW(TAG, "[0x%02x at %d] Invalid argument error - handle may be corrupted", dev->addr, dev->port);
break;
case ESP_ERR_INVALID_STATE:
// I2C driver is in invalid state, handle likely needs recreation
should_remove_handle = true;
ESP_LOGW(TAG, "[0x%02x at %d] Invalid state error - handle may need recreation", dev->addr, dev->port);
break;
default:
// For other errors (timeout, NACK, bus busy, etc.), keep the handle
// These are usually temporary and don't require handle recreation
should_remove_handle = false;
ESP_LOGV(TAG, "[0x%02x at %d] Temporary error - keeping handle for retry", dev->addr, dev->port);
break;
}
if (should_remove_handle && dev->dev_handle)
{
ESP_LOGW(TAG, "[0x%02x at %d] Removing potentially corrupted device handle %p after permanent error", dev->addr, dev->port, dev->dev_handle);
// Try to remove the handle from the bus before nullifying
esp_err_t rm_res = i2c_master_bus_rm_device(dev->dev_handle);
if (rm_res != ESP_OK)
{
ESP_LOGW(TAG, "[0x%02x at %d] Failed to remove corrupted handle (expected): %s", dev->addr, dev->port, esp_err_to_name(rm_res));
// This is expected if the handle was already invalid - continue cleanup
}
dev->dev_handle = NULL;
}
retry++;
if (retry <= I2C_MAX_RETRIES)
{
vTaskDelay(pdMS_TO_TICKS(I2C_RETRY_BASE_DELAY_MS * (1 << retry))); // Exponential backoff
ESP_LOGW(TAG, "[0x%02x at %d] Retrying operation...", dev->addr, dev->port);
}
}
ESP_LOGE(TAG, "[0x%02x at %d] I2C operation failed after %d retries. Last error: %d (%s)", dev->addr, dev->port, I2C_MAX_RETRIES + 1, res, esp_err_to_name(res));
return res;
}
// Wrapper functions for the I2C master API to use with the retry mechanism
// i2c_do_operation_with_retry() needs a unified function signature for all I2C operations
static esp_err_t i2c_master_transmit_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms)
{
return i2c_master_transmit(handle, write_buffer, write_size, timeout_ms);
}
static esp_err_t i2c_master_receive_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms)
{
return i2c_master_receive(handle, read_buffer, read_size, timeout_ms);
}
static esp_err_t i2c_master_transmit_receive_wrapper(i2c_master_dev_handle_t handle, const void *write_buffer, size_t write_size, void *read_buffer, size_t read_size, int timeout_ms)
{
return i2c_master_transmit_receive(handle, write_buffer, write_size, read_buffer, read_size, timeout_ms);
}
esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size)
{
if (!dev || !in_data || !in_size)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read called (out_size: %u, in_size: %u)", dev->addr, dev->port, out_size, in_size);
esp_err_t result = i2c_do_operation_with_retry((i2c_dev_t *)dev, // Cast to non-const for i2c_setup_device internal modifications
out_data && out_size ? i2c_master_transmit_receive_wrapper : i2c_master_receive_wrapper, out_data, out_size, in_data, in_size);
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read result: %s (%d)", dev->addr, dev->port, esp_err_to_name(result), result);
return result;
}
esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
if ((!out_reg || !out_reg_size) && (!out_data || !out_size))
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write called (reg_size: %u, data_size: %u)", dev->addr, dev->port, out_reg_size, out_size);
esp_err_t res;
if (out_reg && out_reg_size && out_data && out_size)
{
size_t total_write_size = out_reg_size + out_size;
// Check for overflow before proceeding
if (total_write_size < out_reg_size || total_write_size < out_size)
{
ESP_LOGE(TAG, "[0x%02x at %d] Write size overflow: reg_size=%u + data_size=%u", dev->addr, dev->port, out_reg_size, out_size);
return ESP_ERR_INVALID_ARG;
}
// Use stack for small buffers to avoid heap fragmentation
if (total_write_size <= I2CDEV_MAX_STACK_ALLOC_SIZE)
{
// Use stack allocation for small buffers
uint8_t stack_buf[I2CDEV_MAX_STACK_ALLOC_SIZE];
memcpy(stack_buf, out_reg, out_reg_size);
memcpy(stack_buf + out_reg_size, out_data, out_size);
res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, stack_buf, total_write_size, NULL, 0);
}
else
{
uint8_t *heap_buf = malloc(total_write_size);
if (!heap_buf)
{
ESP_LOGE(TAG, "[0x%02x at %d] Failed to allocate %u bytes for write", dev->addr, dev->port, total_write_size);
return ESP_ERR_NO_MEM;
}
memcpy(heap_buf, out_reg, out_reg_size);
memcpy(heap_buf + out_reg_size, out_data, out_size);
res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, heap_buf, total_write_size, NULL, 0);
free(heap_buf); // Free buffer regardless of operation result
}
}
else if (out_reg && out_reg_size)
{
res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, out_reg, out_reg_size, NULL, 0);
}
else if (out_data && out_size)
{
res = i2c_do_operation_with_retry((i2c_dev_t *)dev, i2c_master_transmit_wrapper, out_data, out_size, NULL, 0);
}
else
{
return ESP_ERR_INVALID_ARG; // Shouldn't reach here given the earlier check
}
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write result: %s (%d)", dev->addr, dev->port, esp_err_to_name(res), res);
return res;
}
esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *data, size_t size)
{
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_read_reg called (reg: 0x%02x, size: %u)", dev->addr, dev->port, reg, size);
return i2c_dev_read(dev, &reg, 1, data, size);
}
esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *data, size_t size)
{
ESP_LOGV(TAG, "[0x%02x at %d] i2c_dev_write_reg called (reg: 0x%02x, size: %u)", dev->addr, dev->port, reg, size);
return i2c_dev_write(dev, &reg, 1, data, size);
}
esp_err_t i2c_dev_check_present(const i2c_dev_t *dev_const)
{
if (!dev_const)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Probing device presence...", dev_const->addr, dev_const->port);
// Cast to non-const for i2c_setup_port (which may modify internal state)
i2c_dev_t *dev = (i2c_dev_t *)dev_const;
// Ensure the I2C port is set up before probing
esp_err_t setup_res = i2c_setup_port(dev);
if (setup_res != ESP_OK)
{
ESP_LOGE(TAG, "[0x%02x at %d] Failed to setup port for probe: %s", dev_const->addr, dev_const->port, esp_err_to_name(setup_res));
return setup_res;
}
// Now probe using the initialized bus
if (dev_const->port < I2C_NUM_MAX && i2c_ports[dev_const->port].lock)
{
if (xSemaphoreTake(i2c_ports[dev_const->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) == pdTRUE)
{
if (i2c_ports[dev_const->port].installed && i2c_ports[dev_const->port].bus_handle)
{
// Use ESP-IDF's built-in probe function - completely non-intrusive
esp_err_t probe_res = i2c_master_probe(i2c_ports[dev_const->port].bus_handle, dev_const->addr, CONFIG_I2CDEV_TIMEOUT);
xSemaphoreGive(i2c_ports[dev_const->port].lock);
if (probe_res == ESP_OK)
{
ESP_LOGV(TAG, "[0x%02x at %d] Device probe successful - device present", dev_const->addr, dev_const->port);
return ESP_OK;
}
else
{
ESP_LOGV(TAG, "[0x%02x at %d] Device probe failed: %s", dev_const->addr, dev_const->port, esp_err_to_name(probe_res));
return probe_res;
}
}
else
{
xSemaphoreGive(i2c_ports[dev_const->port].lock);
ESP_LOGW(TAG, "[0x%02x at %d] Cannot probe - bus not ready on port %d", dev_const->addr, dev_const->port, dev_const->port);
return ESP_ERR_INVALID_STATE;
}
}
else
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for probe", dev_const->addr, dev_const->port);
return ESP_ERR_TIMEOUT;
}
}
else
{
ESP_LOGE(TAG, "[0x%02x at %d] Invalid port or port not initialized", dev_const->addr, dev_const->port);
return ESP_ERR_INVALID_ARG;
}
}
// Compatibility wrapper for legacy code that still calls i2c_dev_probe
// The new driver implementation uses i2c_master_probe which doesn't need operation_type
esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type)
{
ESP_LOGV(TAG, "[0x%02x at %d] Legacy probe called (operation_type %d), redirecting to new implementation", dev->addr, dev->port, operation_type);
return i2c_dev_check_present(dev);
}
// Clean up function to be called at application exit
esp_err_t i2cdev_done(void)
{
esp_err_t result = ESP_OK;
ESP_LOGV(TAG, "Cleaning up I2C subsystem (i2c_master)...");
for (int i = 0; i < I2C_NUM_MAX; i++)
{
if (i2c_ports[i].lock)
{
ESP_LOGV(TAG, "[Port %d] Cleaning up port...", i);
if (xSemaphoreTake(i2c_ports[i].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE)
{
ESP_LOGE(TAG, "[Port %d] Could not take port mutex for cleanup", i);
result = ESP_FAIL;
}
else
{
if (i2c_ports[i].installed)
{
ESP_LOGV(TAG, "[Port %d] Removing active devices before deleting bus...", i);
// Remove all registered devices for this port from the bus
for (int j = 0; j < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; j++)
{
i2c_dev_t *dev_ptr = active_devices[i][j];
if (dev_ptr != NULL && dev_ptr->dev_handle != NULL)
{
ESP_LOGV(TAG, "[Port %d] Removing device 0x%02x (Handle %p)", i, dev_ptr->addr, dev_ptr->dev_handle);
esp_err_t rm_res = i2c_master_bus_rm_device(dev_ptr->dev_handle);
if (rm_res != ESP_OK)
{
ESP_LOGE(TAG, "[Port %d] Failed to remove device 0x%02x handle: %d", i, dev_ptr->addr, rm_res);
// Continue cleanup despite error
if (result == ESP_OK)
result = rm_res; // Report first error
}
dev_ptr->dev_handle = NULL;
}
}
ESP_LOGV(TAG, "[Port %d] Deleting master bus handle %p...", i, i2c_ports[i].bus_handle);
esp_err_t del_res = i2c_del_master_bus(i2c_ports[i].bus_handle);
if (del_res != ESP_OK)
{
ESP_LOGE(TAG, "[Port %d] Failed to delete I2C bus during cleanup: %d", i, del_res);
if (result == ESP_OK)
result = del_res;
}
i2c_ports[i].installed = false;
i2c_ports[i].bus_handle = NULL;
i2c_ports[i].ref_count = 0;
}
xSemaphoreGive(i2c_ports[i].lock);
} // End else (mutex taken)
ESP_LOGV(TAG, "[Port %d] Deleting port mutex...", i);
vSemaphoreDelete(i2c_ports[i].lock);
i2c_ports[i].lock = NULL;
// Clear the active device list for this port
memset(active_devices[i], 0, sizeof(active_devices[i]));
ESP_LOGV(TAG, "[Port %d] Cleanup complete.", i);
} // end if lock exists
} // end for loop
ESP_LOGV(TAG, "I2C subsystem cleanup finished with result: %d", result);
return result;
}

View File

@@ -1,387 +0,0 @@
/**
* @file i2cdev.h
* @defgroup i2cdev i2cdev
* @{
*
* ESP-IDF I2C master thread-safe functions for communication with I2C slave
*
* This implementation uses the newer ESP-IDF I2C master driver (v5.0+).
* For ESP-IDF versions using the legacy I2C driver, use i2cdev_legacy.c instead.
*
* Copyright (C) 2018 Ruslan V. Uss <unclerus@gmail.com>
* Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API
*
* MIT Licensed as described in the file LICENSE
*
* ============================================================================
* OPTIONAL I2C PULLUP AUTO-CONFIGURATION
* ============================================================================
*
* This library can optionally enable internal I2C pullups when no explicit
* pullup configuration is provided. Feature is DISABLED by default for
* backward compatibility (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=n).
*
* Optional auto-pullup (CONFIG_I2CDEV_AUTO_ENABLE_PULLUPS=y):
* - If both pullup flags are false (not set/default state), automatically enables internal pullups
* - Only available on ESP32 family (modern driver)
* - Legacy driver always uses explicit configuration
*
*
* Example - Enable internal pullups:
* i2c_dev_t sensor = {
* .port = I2C_NUM_0,
* .addr = 0x48,
* .cfg = {
* .sda_io_num = GPIO_NUM_21,
* .scl_io_num = GPIO_NUM_22,
* .sda_pullup_en = true, // Enable internal pullups
* .scl_pullup_en = true, // Enable internal pullups
* .master.clk_speed = 400000
* }
* };
*
* ============================================================================
*/
#ifndef __I2CDEV_H__
#define __I2CDEV_H__
#include <esp_err.h>
#include <esp_idf_lib_helpers.h>
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>
#include <esp_idf_version.h>
#include <driver/gpio.h>
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0)
#include <driver/i2c_master.h>
#else
#include <driver/i2c.h>
#endif
// Define missing types for older ESP-IDF versions
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 2, 0)
typedef enum
{
I2C_ADDR_BIT_LEN_7 = 0, /*!< I2C 7bit address for slave mode */
I2C_ADDR_BIT_LEN_10, /*!< I2C 10bit address for slave mode */
} i2c_addr_bit_len_t;
#endif
// Definition for I2CDEV_MAX_STRETCH_TIME
#if HELPER_TARGET_IS_ESP8266
#define I2CDEV_MAX_STRETCH_TIME 0xffffffff
#else
#include <soc/i2c_reg.h> // For I2C_TIME_OUT_VALUE_V, etc.
#if defined(I2C_TIME_OUT_VALUE_V)
#define I2CDEV_MAX_STRETCH_TIME I2C_TIME_OUT_VALUE_V
#elif defined(I2C_TIME_OUT_REG_V)
#define I2CDEV_MAX_STRETCH_TIME I2C_TIME_OUT_REG_V
#else
#define I2CDEV_MAX_STRETCH_TIME 0x00ffffff
#endif
#endif /* HELPER_TARGET_IS_ESP8266 */
#ifndef CONFIG_I2CDEV_TIMEOUT
#define CONFIG_I2CDEV_TIMEOUT 1000 // Default 1 second timeout
#endif
#ifndef CONFIG_I2CDEV_NOLOCK
#define CONFIG_I2CDEV_NOLOCK 0 // Enable locking by default
#endif
#ifndef CONFIG_I2CDEV_MAX_DEVICES_PER_PORT
#define CONFIG_I2CDEV_MAX_DEVICES_PER_PORT 8 // Maximum devices per I2C port
#endif
#ifndef CONFIG_I2CDEV_DEFAULT_SDA_PIN
#define CONFIG_I2CDEV_DEFAULT_SDA_PIN 21 // Default SDA pin
#endif
#ifndef CONFIG_I2CDEV_DEFAULT_SCL_PIN
#define CONFIG_I2CDEV_DEFAULT_SCL_PIN 22 // Default SCL pin
#endif
#ifndef CONFIG_FREERTOS_HZ
#define CONFIG_FREERTOS_HZ 100 // Default value in most ESP-IDF configs
#endif
#ifndef CONFIG_LOG_MAXIMUM_LEVEL
#define CONFIG_LOG_MAXIMUM_LEVEL 3 // INFO level as default
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief I2C transaction type for legacy probe
*/
typedef enum
{
I2C_DEV_WRITE = 0, /**< Write operation for probe */
I2C_DEV_READ /**< Read operation for probe */
} i2c_dev_type_t;
/**
* I2C device descriptor
*
* This structure supports both legacy ESP-IDF I2C driver and modern i2c_master driver.
*
* @note INITIALIZATION CHECKLIST - Set these fields before calling i2c_dev_create_mutex():
*
* ┌─── REQUIRED (Set by user) ───────────────────────────────────────────┐
* │ - dev->port - I2C port number (e.g., I2C_NUM_0) │
* │ - dev->addr - Device I2C address (e.g., 0x48) │
* │ - dev->cfg.sda_io_num - SDA pin (-1 = use Kconfig default) │
* │ - dev->cfg.scl_io_num - SCL pin (-1 = use Kconfig default) │
* │ - dev->cfg.master.clk_speed - Clock speed in Hz (e.g., 400000) │
* └──────────────────────────────────────────────────────────────────────┘
*
* ┌─── OPTIONAL (Set by user if needed) ─────────────────────────────────┐
* │ - dev->addr_bit_len - Address format (defaults to 7-bit) - NEW │
* │ - dev->cfg.sda_pullup_en - Enable internal SDA pullup │
* │ - dev->cfg.scl_pullup_en - Enable internal SCL pullup │
* │ - dev->timeout_ticks - Legacy driver timeout (legacy only) │
* └──────────────────────────────────────────────────────────────────────┘
*
* ┌─── AUTO-POPULATED (library fills these) ─────────────────────────────┐
* │ - dev->mutex - Device mutex handle │
* │ - dev->dev_handle - I2C device handle (modern driver) - NEW │
* │ - dev->sda_pin - Actual SDA pin used by bus │
* │ - dev->scl_pin - Actual SCL pin used by bus │
* └──────────────────────────────────────────────────────────────────────┘
*
* @note BACKWARD COMPATIBILITY DESIGN:
* The custom 'cfg' structure mimics ESP-IDF's deprecated i2c_config_t layout
* to maintain zero-change compatibility with existing device drivers.
* ESP-IDF ≥5.2 deprecated i2c_config_t and split it into separate bus/device
* configs, but this library preserves the familiar field paths like:
* dev->cfg.sda_io_num, dev->cfg.scl_io_num, dev->cfg.master.clk_speed
*/
typedef struct
{
// ═══ Core Device Identity (REQUIRED) ═══
i2c_port_t port; //!< I2C port number (e.g., I2C_NUM_0)
uint16_t addr; //!< Device I2C address (e.g., 0x48 for 7-bit)
i2c_addr_bit_len_t addr_bit_len; //!< Address format: I2C_ADDR_BIT_LEN_7 (default) or I2C_ADDR_BIT_LEN_10
// ═══ Library Internal State (AUTO-POPULATED) ═══
SemaphoreHandle_t mutex; //!< Device mutex - Created by i2c_dev_create_mutex()
void *dev_handle; //!< Device handle - Modern driver only, created lazily (when actual I2C operation is performed)
int sda_pin; //!< Actual SDA pin used - Populated after port setup
int scl_pin; //!< Actual SCL pin used - Populated after port setup
// ═══ Legacy Driver Compatibility ═══
uint32_t timeout_ticks; //!< Clock stretching timeout - Legacy driver only
// ═══ User Configuration (REQUIRED) ═══
// Configuration structure with i2c_config_t compatible field layout.
struct
{
gpio_num_t sda_io_num; //!< Desired SDA pin (-1 = use Kconfig default)
gpio_num_t scl_io_num; //!< Desired SCL pin (-1 = use Kconfig default)
uint8_t sda_pullup_en; //!< Enable internal SDA pullup (optional)
uint8_t scl_pullup_en; //!< Enable internal SCL pullup (optional)
uint32_t clk_flags; //!< Bitwise of ``I2C_SCLK_SRC_FLAG_**FOR_DFS**`` for clk source choice
struct
{
uint32_t clk_speed; //!< Clock speed in Hz
} master; //!< Master-specific config (mimics old i2c_config_t.master)
} cfg; //!< Configuration set by device drivers (i2c_config_t compatible layout)
} i2c_dev_t;
/**
* @brief Initialize I2C subsystem (port mutexes and internal states)
*
* @note This should be called once at the beginning of your application
* before any I2C devices are initialized.
*
* @return ESP_OK on success
*/
esp_err_t i2cdev_init(void);
/**
* @brief Release I2C subsystem (deletes all devices, buses, and mutexes)
*
* @note Call this when no more I2C operations will be performed
* to clean up resources.
*
* @return ESP_OK on success
*/
esp_err_t i2cdev_done(void);
/**
* @brief Create mutex for device descriptor and register device
*
* @note IMPORTANT: Before calling this function, you must properly initialize the i2c_dev_t
* structure with device address, port, and pin settings. For ESP-IDF legacy driver,
* set pins in dev->cfg.sda_io_num and dev->cfg.scl_io_num. For newer ESP-IDF version,
* either method is compatible. See the structure documentation for details.
*
* @param dev Pointer to device descriptor
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev);
/**
* @brief Delete mutex for device descriptor and perform device cleanup
*
* @note This function performs cleanup tasks including removing the device from the
* I2C bus, deregistering it, and deleting its mutex.
*
* @param dev Pointer to device descriptor
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev);
/**
* @brief Take device mutex
*
* @param dev Pointer to device descriptor
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev);
/**
* @brief Give device mutex
*
* @param dev Pointer to device descriptor
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev);
/**
* @brief Check the availability of a device on the I2C bus (New Driver) - legacy's i2c_dev_probe function equivalent.
*
* This function attempts to communicate with the I2C device to see if it ACKs.
* It is non-intrusive; if the device is found, any temporary setup for
* the check is torn down. Uses the new I2C driver logic.
*
* @param dev Pointer to the device descriptor. Pins and address must be configured.
* @return `ESP_OK` if the device ACKs (is present), an error code otherwise.
*/
esp_err_t i2c_dev_check_present(const i2c_dev_t *dev);
/**
* @brief Check the availability of a device on the I2C bus (Legacy Driver).
*
* Issue an operation of `operation_type` to the I2C device then stops.
* Primarily for use with the legacy i2cdev_legacy.c implementation.
*
* @param dev Device descriptor.
* @param operation_type Operation type (I2C_DEV_WRITE or I2C_DEV_READ).
* @return `ESP_OK` if device is available for the specified operation type.
*/
esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type);
/**
* @brief Read from device
*
* @param dev Pointer to device descriptor
* @param[in] out_data Data to write before reading (can be NULL if out_size is 0)
* @param out_size Size of data to write
* @param[out] in_data Buffer to store data read
* @param in_size Number of bytes to read
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size);
/**
* @brief Write to device
*
* @param dev Pointer to device descriptor
* @param[in] out_reg Register address to write to (can be NULL if out_reg_size is 0)
* @param out_reg_size Size of register address
* @param[in] out_data Data to write (can be NULL if out_size is 0)
* @param out_size Size of data to write
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size);
/**
* @brief Read from device register (8-bit register address)
*
* @param dev Pointer to device descriptor
* @param reg Command to write before reading
* @param[out] data Buffer to store data
* @param size Number of bytes to read
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *data, size_t size);
/**
* @brief Write to device register (8-bit register address)
*
* @param dev Pointer to device descriptor
* @param reg Command to write before writing data
* @param data Buffer with data to write
* @param size Number of bytes to write
* @return `ESP_OK` on success
*/
esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *data, size_t size);
/**
* @brief Take device mutex with error checking
*/
#define I2C_DEV_TAKE_MUTEX(dev) \
do \
{ \
esp_err_t __ = i2c_dev_take_mutex(dev); \
if (__ != ESP_OK) \
return __; \
} \
while (0)
/**
* @brief Give device mutex with error checking
*/
#define I2C_DEV_GIVE_MUTEX(dev) \
do \
{ \
esp_err_t __ = i2c_dev_give_mutex(dev); \
if (__ != ESP_OK) \
return __; \
} \
while (0)
/**
* @brief Execute operation, assuming mutex is held. Gives mutex ONLY on error.
*/
#define I2C_DEV_CHECK(dev, X) \
do \
{ \
esp_err_t ___ = X; /* Execute operation */ \
if (___ != ESP_OK) \
{ \
/* Give mutex ONLY if error occurred */ \
i2c_dev_give_mutex(dev); \
return ___; \
} \
} \
while (0)
/**
* @brief Execute operation, assuming mutex is held. Gives mutex ONLY on error, logs error.
*/
#define I2C_DEV_CHECK_LOGE(dev, X, msg, ...) \
do \
{ \
esp_err_t ___ = X; /* Execute operation */ \
if (___ != ESP_OK) \
{ \
/* Give mutex ONLY if error occurred */ \
i2c_dev_give_mutex(dev); \
ESP_LOGE(TAG, msg, ##__VA_ARGS__); \
return ___; \
} \
} \
while (0)
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* __I2CDEV_H__ */

View File

@@ -1,793 +0,0 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2018 Ruslan V. Uss <unclerus@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/**
* @file i2cdev.c
*
* ESP-IDF I2C master thread-safe functions for communication with I2C slave
*
* Copyright (c) 2018 Ruslan V. Uss <unclerus@gmail.com>
* Updated 2025 by quinkq to use newer ESP-IDF I2C master driver API
* MIT Licensed as described in the file LICENSE
*/
#include "esp_idf_lib_helpers.h" // For HELPER_TARGET_IS_ESP32 etc.
#include "i2cdev.h" // Common header
#include <driver/i2c.h> // Legacy I2C driver
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <inttypes.h>
#include <sdkconfig.h>
#if !HELPER_TARGET_IS_ESP8266
#include <soc/clk_tree_defs.h> // For APB_CLK_FREQ
#endif
#include <string.h>
static const char *TAG = "i2cdev_legacy";
typedef struct
{
SemaphoreHandle_t lock;
i2c_config_t config; // Use legacy config struct
bool installed;
uint32_t ref_count;
i2c_dev_t *devices[CONFIG_I2CDEV_MAX_DEVICES_PER_PORT]; // Track devices registered on this port
} i2c_port_state_t;
static i2c_port_state_t states[I2C_NUM_MAX] = { 0 };
#if CONFIG_I2CDEV_NOLOCK
#define SEMAPHORE_TAKE(port)
#else
#define SEMAPHORE_TAKE(port) \
do \
{ \
if (!xSemaphoreTake(states[port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT))) \
{ \
ESP_LOGE(TAG, "Could not take port mutex %d", port); \
return ESP_ERR_TIMEOUT; \
} \
} \
while (0)
#endif
#if CONFIG_I2CDEV_NOLOCK
#define SEMAPHORE_GIVE(port)
#else
#define SEMAPHORE_GIVE(port) \
do \
{ \
if (!xSemaphoreGive(states[port].lock)) \
{ \
ESP_LOGE(TAG, "Could not give port mutex %d", port); \
return ESP_FAIL; \
} \
} \
while (0)
#endif
/**
* @brief Register an I2C device for tracking and resource management
*
* This function adds a device to the port's tracking array, which helps with:
* - Monitoring which devices are active on each port
* - Proper cleanup when the system shuts down
* - Diagnostics and debugging
*
* Each port can track up to CONFIG_I2CDEV_MAX_DEVICES_PER_PORT devices.
*
* @param dev Device descriptor to register
* @return ESP_OK if registration succeeded, or an error code
*/
static esp_err_t register_device(i2c_dev_t *dev)
{
if (!dev || dev->port >= I2C_NUM_MAX)
return ESP_ERR_INVALID_ARG;
if (!states[dev->port].lock)
return ESP_ERR_INVALID_STATE;
esp_err_t ret = ESP_ERR_NO_MEM;
// Take the mutex directly instead of using the macro
if (xSemaphoreTake(states[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE)
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for registration", dev->addr, dev->port);
return ESP_ERR_TIMEOUT;
}
// Search for an empty slot in the device tracking array
for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++)
{
if (states[dev->port].devices[i] == NULL)
{
// Found empty slot - register the device here
states[dev->port].devices[i] = dev;
ESP_LOGV(TAG, "[0x%02x at %d] Registered device in slot %d", dev->addr, dev->port, i);
ret = ESP_OK;
break;
}
}
// All slots full - this will still allow communication but prevents automatic cleanup
if (ret != ESP_OK)
{
ESP_LOGW(TAG, "[0x%02x at %d] No free slots to register device", dev->addr, dev->port);
}
// Release the mutex
if (!xSemaphoreGive(states[dev->port].lock))
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not give port mutex after registration", dev->addr, dev->port);
// If can't give the mutex, that's a serious error that overrides the registration result
return ESP_FAIL;
}
return ret;
}
/**
* @brief Deregister a device and update reference counting
*
* This function:
* 1. Removes the device from the port's tracking array
* 2. Decrements the port's reference count
* 3. Cleans up the I2C driver if this was the last device on the port
*
* This is called during device cleanup to ensure proper resource management.
*
* @param dev Device descriptor to deregister
*/
static void deregister_device(i2c_dev_t *dev)
{
if (!dev || dev->port >= I2C_NUM_MAX)
return;
// Don't use macros that return values since this is a void function
if (states[dev->port].lock)
{
if (xSemaphoreTake(states[dev->port].lock, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)) != pdTRUE)
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take port mutex for deregistration", dev->addr, dev->port);
return; // Cannot proceed without lock
}
// Find the device in the tracking array
for (int i = 0; i < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; i++)
{
if (states[dev->port].devices[i] == dev)
{
// Clear this slot
states[dev->port].devices[i] = NULL;
ESP_LOGV(TAG, "[0x%02x at %d] Deregistered device from slot %d", dev->addr, dev->port, i);
break;
}
}
// Manage reference counting for this port
if (states[dev->port].ref_count > 0)
{
states[dev->port].ref_count--;
ESP_LOGD(TAG, "[Port %d] Decremented ref_count to %" PRIu32, dev->port, states[dev->port].ref_count);
// If this was the last device using this port, clean up the driver
if (states[dev->port].ref_count == 0 && states[dev->port].installed)
{
ESP_LOGI(TAG, "[Port %d] Last device removed, uninstalling driver", dev->port);
i2c_driver_delete(dev->port);
states[dev->port].installed = false;
}
}
// Release the mutex
if (!xSemaphoreGive(states[dev->port].lock))
{
ESP_LOGE(TAG, "[Port %d] Could not give port mutex after deregistration", dev->port);
// Can't do much about this error except log it
}
}
}
esp_err_t i2cdev_init()
{
memset(states, 0, sizeof(states));
#if !CONFIG_I2CDEV_NOLOCK
for (int i = 0; i < I2C_NUM_MAX; i++)
{
states[i].lock = xSemaphoreCreateMutex();
if (!states[i].lock)
{
ESP_LOGE(TAG, "Could not create port mutex %d", i);
return ESP_FAIL;
}
}
#endif
return ESP_OK;
}
esp_err_t i2cdev_done()
{
ESP_LOGV(TAG, "Cleaning up I2C subsystem (legacy)...");
for (int i = 0; i < I2C_NUM_MAX; i++)
{
if (!states[i].lock)
continue;
if (states[i].installed)
{
SEMAPHORE_TAKE(i);
// First, clean up any devices still registered on this port
for (int j = 0; j < CONFIG_I2CDEV_MAX_DEVICES_PER_PORT; j++)
{
if (states[i].devices[j] != NULL)
{
i2c_dev_t *dev = states[i].devices[j];
ESP_LOGW(TAG, "[Port %d] Device 0x%02x still registered during cleanup", i, dev->addr);
states[i].devices[j] = NULL;
}
}
i2c_driver_delete(i);
states[i].installed = false;
states[i].ref_count = 0;
SEMAPHORE_GIVE(i);
}
#if !CONFIG_I2CDEV_NOLOCK
vSemaphoreDelete(states[i].lock);
#endif
states[i].lock = NULL;
}
ESP_LOGV(TAG, "I2C subsystem cleanup finished (legacy).");
return ESP_OK;
}
esp_err_t i2c_dev_create_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Creating device mutex", dev->addr, dev->port);
// Initialize device pins to -1 to ensure consistent pattern with new driver
if (dev->sda_pin == 0 && dev->scl_pin == 0)
{
dev->sda_pin = -1;
dev->scl_pin = -1;
ESP_LOGD(TAG, "[0x%02x at %d] Initialized pins to -1", dev->addr, dev->port);
}
if (dev->mutex)
{
ESP_LOGW(TAG, "[0x%02x at %d] Device mutex already exists", dev->addr, dev->port);
return ESP_OK; // Already created
}
dev->mutex = xSemaphoreCreateMutex();
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not create device mutex", dev->addr, dev->port);
return ESP_FAIL;
}
// Register device for tracking
esp_err_t reg_res = register_device(dev);
if (reg_res != ESP_OK)
{
ESP_LOGW(TAG, "[0x%02x at %d] Could not register device: %s", dev->addr, dev->port, esp_err_to_name(reg_res));
// Continue anyway since this is not critical
}
#endif
return ESP_OK;
}
esp_err_t i2c_dev_delete_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Deleting device mutex and cleaning up", dev->addr, dev->port);
// Deregister and update ref counts
deregister_device(dev);
// Delete mutex if exists
if (dev->mutex)
{
vSemaphoreDelete(dev->mutex);
dev->mutex = NULL;
}
else
{
ESP_LOGV(TAG, "[0x%02x at %d] Device mutex was NULL", dev->addr, dev->port);
}
#endif
return ESP_OK;
}
esp_err_t i2c_dev_take_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Taking mutex", dev->addr, dev->port);
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Attempt to take NULL mutex!", dev->addr, dev->port);
return ESP_ERR_INVALID_STATE;
}
if (!xSemaphoreTake(dev->mutex, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT)))
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not take device mutex (timeout %d ms)", dev->addr, dev->port, CONFIG_I2CDEV_TIMEOUT);
return ESP_ERR_TIMEOUT;
}
#endif
return ESP_OK;
}
esp_err_t i2c_dev_give_mutex(i2c_dev_t *dev)
{
#if !CONFIG_I2CDEV_NOLOCK
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Giving mutex", dev->addr, dev->port);
if (!dev->mutex)
{
ESP_LOGE(TAG, "[0x%02x at %d] Attempt to give NULL mutex!", dev->addr, dev->port);
return ESP_ERR_INVALID_STATE;
}
if (!xSemaphoreGive(dev->mutex))
{
ESP_LOGE(TAG, "[0x%02x at %d] Could not give device mutex", dev->addr, dev->port);
return ESP_FAIL;
}
#endif
return ESP_OK;
}
inline static bool cfg_equal(const i2c_config_t *a, const i2c_config_t *b)
{
bool clock_equal;
#ifdef CONFIG_IDF_TARGET_ESP8266
clock_equal = (a->clk_stretch_tick == b->clk_stretch_tick);
#else
clock_equal = (a->master.clk_speed == b->master.clk_speed);
#endif
return a->mode == b->mode && a->scl_io_num == b->scl_io_num && a->sda_io_num == b->sda_io_num && a->scl_pullup_en == b->scl_pullup_en && a->sda_pullup_en == b->sda_pullup_en && clock_equal;
// Note: Ignoring clk_flags for comparison as it might not be consistently set by users
}
/**
* @brief Configure and initialize the I2C port for a device
*
* This function is responsible for:
* 1. Determining which pins to use (from device or config)
* 2. Validating pin configuration
* 3. Installing/configuring the I2C driver if not already done
* 4. Managing reference counting for the port
* 5. Setting up clock stretching timeout
*
* This is a critical function that must succeed before any I2C operations
* can be performed with a device.
*
* @param dev Device descriptor with configuration info
* @return ESP_OK on success, or an error code on failure
*/
static esp_err_t i2c_setup_port(i2c_dev_t *dev)
{
if (!dev)
{
ESP_LOGE(TAG, "Device is NULL");
return ESP_ERR_INVALID_ARG;
}
if (dev->port >= I2C_NUM_MAX)
{
ESP_LOGE(TAG, "Invalid I2C port number: %d", dev->port);
return ESP_ERR_INVALID_ARG;
}
// Pin Selection Logic:
// Pins are taken from dev->cfg.xyz_io_num.
// If -1, Kconfig defaults are used.
gpio_num_t sda_pin; // Effective SDA pin to be used
gpio_num_t scl_pin; // Effective SCL pin to be used
if (dev->cfg.sda_io_num == (gpio_num_t) -1)
{
sda_pin = (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SDA_PIN;
}
else
{
sda_pin = dev->cfg.sda_io_num;
}
if (dev->cfg.scl_io_num == (gpio_num_t) -1)
{
scl_pin = (gpio_num_t)CONFIG_I2CDEV_DEFAULT_SCL_PIN;
}
else
{
scl_pin = dev->cfg.scl_io_num;
}
ESP_LOGD(TAG, "[0x%02x at %d] Based on cfg: sda_cfg=%d, scl_cfg=%d. Effective pins for setup: SDA=%d, SCL=%d", dev->addr, dev->port, dev->cfg.sda_io_num, dev->cfg.scl_io_num, sda_pin, scl_pin);
// Perform basic validation of effective pins
if (sda_pin < 0 || scl_pin < 0)
{
ESP_LOGE(TAG, "[0x%02x at %d] Invalid effective SDA/SCL pins (%d, %d). Check Kconfig defaults if cfg pins were -1.", dev->addr, dev->port, sda_pin, scl_pin);
return ESP_ERR_INVALID_ARG;
}
if (sda_pin == scl_pin)
{
ESP_LOGE(TAG, "[0x%02x at %d] Effective SDA and SCL pins cannot be the same (%d).", dev->addr, dev->port, sda_pin);
return ESP_ERR_INVALID_ARG;
}
// Initialize common fields
i2c_config_t legacy_cfg = { .mode = I2C_MODE_MASTER,
.sda_io_num = sda_pin, // Use locally determined pins
.scl_io_num = scl_pin, // Use locally determined pins
.sda_pullup_en = dev->cfg.sda_pullup_en ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE,
.scl_pullup_en = dev->cfg.scl_pullup_en ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE
};
#ifdef CONFIG_IDF_TARGET_ESP8266
// ESP8266 uses clk_stretch_tick instead of master.clk_speed
// Clock speed will be handled during driver installation
uint32_t desired_speed = dev->cfg.master.clk_speed > 0 ? dev->cfg.master.clk_speed : 400000;
ESP_LOGD(TAG, "Final I2C config for port %d: SDA=%d, SCL=%d, speed=%lu (ESP8266)", dev->port, legacy_cfg.sda_io_num, legacy_cfg.scl_io_num, (unsigned long)desired_speed);
#else
// ESP32 family uses master.clk_speed
legacy_cfg.master.clk_speed = dev->cfg.master.clk_speed > 0 ? dev->cfg.master.clk_speed : 400000;
ESP_LOGD(TAG, "Final I2C config for port %d: SDA=%d, SCL=%d, speed=%lu", dev->port, legacy_cfg.sda_io_num, legacy_cfg.scl_io_num, (unsigned long)legacy_cfg.master.clk_speed);
#endif
#ifdef CONFIG_IDF_TARGET_ESP32
legacy_cfg.clk_flags = 0;
#endif
esp_err_t err = ESP_OK;
// Part 1: Driver Installation / Reconfiguration
if (!cfg_equal(&legacy_cfg, &states[dev->port].config) || !states[dev->port].installed)
{
ESP_LOGD(TAG, "[0x%02x at %d] Reconfiguring I2C driver", dev->addr, dev->port);
if (states[dev->port].installed)
{
ESP_LOGD(TAG, "Uninstalling previous I2C driver configuration for port %d", dev->port);
i2c_driver_delete(dev->port);
states[dev->port].installed = false;
states[dev->port].ref_count = 0;
}
vTaskDelay(1);
// Target-specific driver installation/configuration sequence
#if HELPER_TARGET_IS_ESP32
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 1, 0)
ESP_LOGD(TAG, "Using IDF >= 5.1.0 driver install order for ESP32 family");
err = i2c_driver_install(dev->port, legacy_cfg.mode, 0, 0, 0);
if (err == ESP_OK)
{
err = i2c_param_config(dev->port, &legacy_cfg);
}
#else
ESP_LOGD(TAG, "Using IDF < 5.1.0 driver install order for ESP32 family");
err = i2c_param_config(dev->port, &legacy_cfg);
if (err == ESP_OK)
{
err = i2c_driver_install(dev->port, legacy_cfg.mode, 0, 0, 0);
}
#endif
#elif HELPER_TARGET_IS_ESP8266
ESP_LOGD(TAG, "Using ESP8266 specific driver installation");
legacy_cfg.clk_stretch_tick = dev->timeout_ticks ? dev->timeout_ticks : I2CDEV_MAX_STRETCH_TIME;
err = i2c_driver_install(dev->port, legacy_cfg.mode);
if (err == ESP_OK)
{
err = i2c_param_config(dev->port, &legacy_cfg);
}
// ESP8266 note: Clock speed is not directly configurable through i2c_config_t
// The desired speed was: %lu Hz", desired_speed
#else
// If legacy mode is off, and target detection fails, this avoids a compile error.
// The legacy driver just won't support any target in this case.
ESP_LOGW(TAG, "i2cdev_legacy.c: No specific target (ESP32/ESP32-S2/ESP32-S3/ESP32-C3/ESP32-C6/ESP8266) detected "
"for driver installation. Legacy driver might be inactive or misconfigured.");
err = ESP_ERR_NOT_SUPPORTED; // Indicate that setup can't proceed.
#endif
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to install/configure I2C driver for port %d: %d (%s)", dev->port, err, esp_err_to_name(err));
states[dev->port].installed = false; // Ensure state reflects failure
return err;
}
memcpy(&states[dev->port].config, &legacy_cfg, sizeof(i2c_config_t));
states[dev->port].installed = true;
states[dev->port].ref_count++;
dev->sda_pin = legacy_cfg.sda_io_num;
dev->scl_pin = legacy_cfg.scl_io_num;
ESP_LOGD(TAG, "I2C driver successfully installed/reconfigured on port %d, ref_count=%" PRIu32, dev->port, states[dev->port].ref_count);
}
else
{
states[dev->port].ref_count++;
ESP_LOGV(TAG, "I2C driver already installed on port %d with matching config, ref_count=%" PRIu32, dev->port, states[dev->port].ref_count);
dev->sda_pin = states[dev->port].config.sda_io_num;
dev->scl_pin = states[dev->port].config.scl_io_num;
}
// Part 2: Timeout Configuration (ESP32 family specific hardware timeout)
#if HELPER_TARGET_IS_ESP32
int current_timeout_hw;
err = i2c_get_timeout(dev->port, &current_timeout_hw);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get HW timeout for port %d: %d (%s)", dev->port, err, esp_err_to_name(err));
return err;
}
uint32_t timeout_ticks_val = dev->timeout_ticks ? dev->timeout_ticks : I2CDEV_MAX_STRETCH_TIME;
if (timeout_ticks_val != (uint32_t)current_timeout_hw)
{
ESP_LOGV(TAG, "Port %d: Updating HW timeout from %d to %" PRIu32 " ticks", dev->port, current_timeout_hw, timeout_ticks_val);
err = i2c_set_timeout(dev->port, timeout_ticks_val);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to set HW timeout for port %d: %d (%s)", dev->port, err, esp_err_to_name(err));
return err;
}
ESP_LOGD(TAG, "HW Timeout: ticks = %" PRIu32 " (%" PRIu32 " usec) on port %d", timeout_ticks_val, timeout_ticks_val / 80, dev->port);
}
#endif
return ESP_OK;
}
esp_err_t i2c_dev_probe(const i2c_dev_t *dev, i2c_dev_type_t operation_type)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
SEMAPHORE_TAKE(dev->port);
esp_err_t res = i2c_setup_port((i2c_dev_t *)dev);
if (res == ESP_OK)
{
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev->addr << 1 | (operation_type == I2C_DEV_READ ? 1 : 0), true);
// Alternative Write-style probe for better device compatibility
// many devices don't respond well to blind read probes.
// i2c_master_write_byte(cmd, dev->addr << 1 | 0, true); // Force write bit (0)
i2c_master_stop(cmd);
res = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT));
i2c_cmd_link_delete(cmd);
}
SEMAPHORE_GIVE(dev->port);
return res;
}
esp_err_t i2c_dev_read(const i2c_dev_t *dev, const void *out_data, size_t out_size, void *in_data, size_t in_size)
{
if (!dev || !in_data || !in_size)
return ESP_ERR_INVALID_ARG;
SEMAPHORE_TAKE(dev->port);
// Use a local status variable to track errors
esp_err_t err = i2c_setup_port((i2c_dev_t *)dev);
if (err == ESP_OK)
{
// Only create a command handle if setup was successful
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
if (out_data && out_size)
{
// Write phase - typically used to specify a register address
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev->addr << 1, true); // Addr + Write bit (0)
i2c_master_write(cmd, (void *)out_data, out_size, true);
}
// Read phase - get data from the device
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->addr << 1) | 1, true); // Addr + Read bit (1)
i2c_master_read(cmd, in_data, in_size,
I2C_MASTER_LAST_NACK); // NACK the last byte to signal end
i2c_master_stop(cmd);
// Execute the command
err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT));
if (err != ESP_OK)
{
ESP_LOGE(TAG, "i2c_master_cmd_begin failed for read: %d (%s)", err, esp_err_to_name(err));
}
// Always delete the command handle
i2c_cmd_link_delete(cmd);
}
// Always release the semaphore before returning
SEMAPHORE_GIVE(dev->port);
return err;
}
esp_err_t i2c_dev_write(const i2c_dev_t *dev, const void *out_reg, size_t out_reg_size, const void *out_data, size_t out_size)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
if ((!out_reg || !out_reg_size) && (!out_data || !out_size))
return ESP_ERR_INVALID_ARG;
SEMAPHORE_TAKE(dev->port);
// Use a local status variable to track errors
esp_err_t err = i2c_setup_port((i2c_dev_t *)dev);
if (err == ESP_OK)
{
// Only create a command handle if setup was successful
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, dev->addr << 1, true);
// Write register address/command if provided
if (out_reg && out_reg_size)
{
i2c_master_write(cmd, (void *)out_reg, out_reg_size, true);
}
// Write data if provided
if (out_data && out_size)
{
i2c_master_write(cmd, (void *)out_data, out_size, true);
}
i2c_master_stop(cmd);
// Execute the command
err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT));
if (err != ESP_OK)
{
ESP_LOGE(TAG, "i2c_master_cmd_begin failed for write: %d (%s)", err, esp_err_to_name(err));
}
// Always delete the command handle
i2c_cmd_link_delete(cmd);
}
// Always release the semaphore before returning
SEMAPHORE_GIVE(dev->port);
return err;
}
esp_err_t i2c_dev_write_reg(const i2c_dev_t *dev, uint8_t reg, const void *out_data, size_t out_size)
{
if (!dev || !out_data || !out_size)
return ESP_ERR_INVALID_ARG;
SEMAPHORE_TAKE(dev->port);
// Use a local status variable to track errors
esp_err_t err = i2c_setup_port((i2c_dev_t *)dev);
if (err == ESP_OK)
{
// Only create a command handle if setup was successful
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true); // Addr + Write bit
i2c_master_write_byte(cmd, reg, true); // Register address
if (out_data && out_size)
{
i2c_master_write(cmd, (void *)out_data, out_size, true); // Data to write
}
i2c_master_stop(cmd);
// Execute the command
err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT));
if (err != ESP_OK)
{
ESP_LOGE(TAG, "i2c_master_cmd_begin failed for write_reg: %d (%s)", err, esp_err_to_name(err));
}
// Always delete the command handle
i2c_cmd_link_delete(cmd);
}
// Always release the semaphore before returning
SEMAPHORE_GIVE(dev->port);
return err;
}
esp_err_t i2c_dev_read_reg(const i2c_dev_t *dev, uint8_t reg, void *in_data, size_t in_size)
{
if (!dev || !in_data || !in_size)
return ESP_ERR_INVALID_ARG;
SEMAPHORE_TAKE(dev->port);
// Use a local status variable to track errors
esp_err_t err = i2c_setup_port((i2c_dev_t *)dev);
if (err == ESP_OK)
{
// Only create a command handle if setup was successful
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_WRITE, true);
i2c_master_write_byte(cmd, reg, true);
i2c_master_start(cmd);
i2c_master_write_byte(cmd, (dev->addr << 1) | I2C_MASTER_READ, true);
i2c_master_read(cmd, in_data, in_size, I2C_MASTER_LAST_NACK);
i2c_master_stop(cmd);
// Execute the command
err = i2c_master_cmd_begin(dev->port, cmd, pdMS_TO_TICKS(CONFIG_I2CDEV_TIMEOUT));
if (err != ESP_OK)
{
ESP_LOGE(TAG, "i2c_master_cmd_begin failed for read_reg: %d (%s)", err, esp_err_to_name(err));
}
// Always delete the command handle
i2c_cmd_link_delete(cmd);
}
// Always release the semaphore before returning
SEMAPHORE_GIVE(dev->port);
return err;
}
// Implementation of i2c_dev_check_present (updated version of i2c_dev_probe) using legacy I2C driver
esp_err_t i2c_dev_check_present(const i2c_dev_t *dev)
{
if (!dev)
return ESP_ERR_INVALID_ARG;
ESP_LOGV(TAG, "[0x%02x at %d] Checking device presence (legacy driver)...", dev->addr, dev->port);
// Use the exact same pattern as i2c_dev_probe with WRITE operation to ensure consistent behavior
return i2c_dev_probe(dev, I2C_DEV_WRITE);
}

View File

@@ -1,30 +0,0 @@
dependencies:
esp-idf-lib/esp_idf_lib_helpers:
version: '*'
description: ESP-IDF I2C master thread-safe utilities
discussion: https://github.com/esp-idf-lib/core/discussions
documentation: https://esp-idf-lib.github.io/i2cdev/
files:
exclude:
- docs/**/*
issues: https://github.com/esp-idf-lib/i2cdev/issues
license: MIT
maintainers:
- Ruslan V. Uss (@UncleRus) <unclerus@gmail.com>
repository: git://github.com/esp-idf-lib/i2cdev.git
repository_info:
commit_sha: b4f09df5a02e576af61846954557bf7a61d35274
path: .
targets:
- esp32
- esp32c2
- esp32c3
- esp32c5
- esp32c6
- esp32c61
- esp32h2
- esp32p4
- esp32s2
- esp32s3
url: https://github.com/esp-idf-lib/core
version: 2.1.0

View File

@@ -1 +0,0 @@
--ignore-dir=build

View File

@@ -1,17 +0,0 @@
--align-reference=name
--attach-classes
--attach-classes
--attach-namespaces
--convert-tabs
--exclude=build
--exclude=common
--exclude=managed_components
--ignore-exclude-errors
--indent-switches
--indent=spaces=4
--keep-one-line-statements
--max-continuation-indent=120
--pad-header
--pad-oper
--style=allman
--unpad-paren

View File

@@ -1,66 +0,0 @@
---
Language: Cpp
BasedOnStyle: WebKit
AlignConsecutiveMacros: true
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Empty
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Always
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: false
BeforeCatch: true
BeforeElse: true
BeforeLambdaBody: false
BeforeWhile: true
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
ColumnLimit: 200
CompactNamespaces: true
Cpp11BracedListStyle: false
FixNamespaceComments: true
IndentCaseLabels: true
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
PointerAlignment: Right
ReflowComments: true
SortIncludes: false
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeInheritanceColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: false
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Auto
TabWidth: 4
UseTab: Never

View File

@@ -1 +0,0 @@
4bbdbd82828cf1fd5c03fd07e3ea2cb0f36daf16cb3ac7219d1e5decb9ec04ee

View File

@@ -1,28 +0,0 @@
---
name: tca95x5
description: Driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus
version: 1.0.7
groups:
- gpio
code_owners: UncleRus
depends:
- i2cdev
- log
- esp_idf_lib_helpers
thread_safe: yes
targets:
- esp32
- esp8266
- esp32s2
- esp32c3
- esp32s3
- esp32c2
- esp32c6
- esp32h2
- esp32p4
- esp32c5
- esp32c61
license: BSD-3
copyrights:
- name: UncleRus
year: 2019

View File

@@ -1,7 +0,0 @@
examples/**/sdkconfig
examples/**/sdkconfig.old
examples/**/build/
examples/**/dependencies.lock
docs/_*/
docs/doxygen.log
*.swp

View File

@@ -1,3 +0,0 @@
[submodule "common"]
path = common
url = https://github.com/esp-idf-lib/common.git

View File

@@ -1,13 +0,0 @@
idf_component_register(
SRCS tca95x5.c
INCLUDE_DIRS .
REQUIRES i2cdev log esp_idf_lib_helpers
)
# include common cmake file for components
set(ESP_IDF_LIB_CMAKE ${CMAKE_CURRENT_LIST_DIR}/common/cmake/esp-idf-lib.cmake)
if(EXISTS ${ESP_IDF_LIB_CMAKE})
include(${ESP_IDF_LIB_CMAKE})
else()
message(WARNING "${ESP_IDF_LIB_CMAKE} not found")
endif()

View File

@@ -1,19 +0,0 @@
config EXAMPLE_I2C_MASTER_SCL
int "SCL GPIO Number"
default 5 if IDF_TARGET_ESP8266
default 6 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61
default 19 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 4 if IDF_TARGET_ESP32H2
default 4 if IDF_TARGET_ESP32P4
help
GPIO number for I2C Master clock line.
config EXAMPLE_I2C_MASTER_SDA
int "SDA GPIO Number"
default 4 if IDF_TARGET_ESP8266
default 5 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
default 3 if IDF_TARGET_ESP32H2
default 3 if IDF_TARGET_ESP32P4
help
GPIO number for I2C Master data line.

View File

@@ -1,26 +0,0 @@
Copyright (c) 2019 Ruslan V. Uss <unclerus@gmail.com>
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 itscontributors
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.

View File

@@ -1,30 +0,0 @@
# esp-idf-lib/tca95x5
[![Build examples](https://github.com/esp-idf-lib/tca95x5/actions/workflows//build.yml/badge.svg)](https://github.com/esp-idf-lib/tca95x5/actions/workflows//build.yml)
[![Build docs](https://github.com/esp-idf-lib/tca95x5/actions/workflows//build-docs.yml/badge.svg)](https://github.com/esp-idf-lib/tca95x5/actions/workflows//build-docs.yml)
[![Validation](https://github.com/esp-idf-lib/tca95x5/actions/workflows//validate-component.yml/badge.svg)](https://github.com/esp-idf-lib/tca95x5/actions/workflows//validate-component.yml)
Driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus.
* [Documentation](https://esp-idf-lib.github.io/tca95x5/)
* [Repository](https://github.com/esp-idf-lib/tca95x5)
* [Issues](https://github.com/esp-idf-lib/tca95x5/issues)
* [Discussions and questions](https://github.com/esp-idf-lib/core/discussions)
* [Component page at the ESP Component Registry](https://components.espressif.com/components/esp-idf-lib/tca95x5)
## Installation
```sh
idf.py add-dependency esp-idf-lib/tca95x5
```
## Support
For questions and discussions about the component, please use
[Discussions](https://github.com/esp-idf-lib/core/discussions)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).
## Contributing
Please read [CONTRIBUTING.md](https://github.com/esp-idf-lib/core/blob/main/CONTRIBUTING.md)
at [esp-idf-lib/core](https://github.com/esp-idf-lib/core).

View File

@@ -1,18 +0,0 @@
#!/usr/bin/env ruby
require "pathname"
require "yaml"
# A simple CLI to get values in .eil.yml
key = ARGV.shift
project_root = Pathname.new(File.expand_path(__FILE__)).parent.parent
eil_file = project_root / ".eil.yml"
doc = YAML.safe_load(File.read eil_file)
case key
when "copyright_string"
puts doc["copyrights"].map { |e| "#{e['year']}, #{e['name']}" }.join(", ")
else
puts doc[key]
end

View File

@@ -1,36 +0,0 @@
# Set common build flags but enable them only when the build is in our CI,
# making them optional. The idea is, fail when compiled in our CI but just
# warn in any other cases. Code that compiles with one toolchain warning-free
# may not do so with another toolchain, which creates a project dependency on
# specific toolchain vendors and versions.
#
# Define flags that may cause failures here.
if (DEFINED ENV{ESP_IDF_LIB_CI})
set(ESP_IDF_LIB_CI_FLAGS
-Werror=unused-variable
-Werror=unused-function
-Werror=write-strings
-Werror
)
endif()
# Set common build flags. Mandatory.
#
# Define flags that do not cause failures here.
set(ESP_IDF_LIB_FLAGS
-Wextra
-Wwrite-strings
-Wunused-variable
-Wunused-function
-Wreturn-type
)
# When COMPONENT_LIB is INTERFACE_LIBRARY, or a header-only library, do not
# set the flags.
get_target_property(COMPONENT_TYPE ${COMPONENT_LIB} TYPE)
if(NOT COMPONENT_TYPE STREQUAL "INTERFACE_LIBRARY")
target_compile_options(${COMPONENT_LIB} PRIVATE
${ESP_IDF_LIB_FLAGS}
${ESP_IDF_LIB_CI_FLAGS}
)
endif()

View File

@@ -1,2 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = .
COMPONENT_DEPENDS = i2cdev log esp_idf_lib_helpers

View File

@@ -1,7 +0,0 @@
# The following four lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(example-tca95x5)

View File

@@ -1,6 +0,0 @@
#V := 1
PROJECT_NAME := example-tca95x5
include $(IDF_PATH)/make/project.mk

View File

@@ -1,13 +0,0 @@
## What the example does
* Initializes the driver
* Configure a pin as input
* Registers an interrupt that logs port value of the INT pin
* Blinks, or toggles, P10 output
## Wiring
Connect an LED with an appropriate register to P10.
Connect a switch that toggle its voltage HIGH or LOW to INT GPIO. The INT GPIO
can be set in `menuconfig`. See the defaults in `Kconfig.projbuild`.

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

View File

@@ -1,21 +0,0 @@
menu "Example configuration"
config EXAMPLE_I2C_ADDR
hex "I2C address of TCA9555"
default 0x20
help
I2C address of TCA9555. The default is `TCA95X5_I2C_ADDR_BASE`, or
0x20. See available options in datasheet.
config EXAMPLE_INT_GPIO
int "INT GPIO Number"
default 14 if IDF_TARGET_ESP8266
default 7 if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C5 || IDF_TARGET_ESP32C6 || IDF_TARGET_ESP32C61
default 5 if IDF_TARGET_ESP32H2
default 5 if IDF_TARGET_ESP32P4
default 5 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3
help
GPIO number connected to INT pin.
rsource "../../../Kconfig.i2c"
endmenu

View File

@@ -1 +0,0 @@
COMPONENT_ADD_INCLUDEDIRS = . include/

View File

@@ -1,9 +0,0 @@
dependencies:
esp-idf-lib/esp_idf_lib_helpers:
version: '*'
esp-idf-lib/i2cdev:
version: '*'
esp-idf-lib/tca95x5:
version: '*'
description: default
version: 1.0.0

View File

@@ -1,80 +0,0 @@
#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/queue.h>
#include <tca95x5.h>
#include <driver/gpio.h>
#include <esp_log.h>
static i2c_dev_t tca9555 = { 0 };
static QueueHandle_t gpio_queue = NULL;
static const char *TAG = "tca95x5-example";
// Interrupt handler
static void IRAM_ATTR intr_handler(void *arg)
{
gpio_num_t gpio = (gpio_num_t)arg;
xQueueSendFromISR(gpio_queue, &gpio, NULL);
}
// Interrupt event receiver
static void gpio_recv_task(void *arg)
{
gpio_num_t gpio;
while (1)
{
if (xQueueReceive(gpio_queue, &gpio, portMAX_DELAY))
{
ESP_LOGI(TAG, "GPIO interrupt on pin %d", gpio);
if (gpio != CONFIG_EXAMPLE_INT_GPIO) continue;
uint16_t val;
esp_err_t res = tca95x5_port_read(&tca9555, &val);
if (res != ESP_OK)
{
ESP_LOGE(TAG, "Error reading TCA9555: %d (%s)", res, esp_err_to_name(res));
continue;
}
ESP_LOGI(TAG, "TCA9555 port value: 0x%04x", val);
}
}
}
void main_task(void *pvParameters)
{
// Init descriptor
ESP_ERROR_CHECK(tca95x5_init_desc(&tca9555, CONFIG_EXAMPLE_I2C_ADDR, 0, CONFIG_EXAMPLE_I2C_MASTER_SDA, CONFIG_EXAMPLE_I2C_MASTER_SCL));
// Setup P00, P01 and P02 as input, others as output
ESP_ERROR_CHECK(tca95x5_port_set_mode(&tca9555, 0x0007)); // 0b0000000000000111
// Create queue
gpio_queue = xQueueCreate(5, sizeof(gpio_num_t));
// Run event receiver
xTaskCreate(gpio_recv_task, "gpio_recv_task", 4096, NULL, 5, NULL);
// Setup GPIO interrupt
gpio_set_direction(CONFIG_EXAMPLE_INT_GPIO, GPIO_MODE_INPUT);
gpio_set_intr_type(CONFIG_EXAMPLE_INT_GPIO, GPIO_INTR_NEGEDGE);
gpio_install_isr_service(0);
gpio_isr_handler_add(CONFIG_EXAMPLE_INT_GPIO, intr_handler, (void *)CONFIG_EXAMPLE_INT_GPIO);
// blink on P10
bool on = true;
while (1)
{
ESP_ERROR_CHECK(tca95x5_set_level(&tca9555, 8, on));
on = !on;
vTaskDelay(pdMS_TO_TICKS(500));
}
}
void app_main()
{
ESP_ERROR_CHECK(i2cdev_init());
xTaskCreate(main_task, "main_task", configMINIMAL_STACK_SIZE * 6, NULL, 5, NULL);
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -1,32 +0,0 @@
dependencies:
esp-idf-lib/esp_idf_lib_helpers:
version: '*'
esp-idf-lib/i2cdev:
version: '*'
description: Driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus
discussion: https://github.com/esp-idf-lib/core/discussions
documentation: https://esp-idf-lib.github.io/tca95x5/
files:
exclude:
- docs/**/*
issues: https://github.com/esp-idf-lib/tca95x5/issues
license: BSD-3
maintainers:
- Ruslan V. Uss (@UncleRus) <unclerus@gmail.com>
repository: git://github.com/esp-idf-lib/tca95x5.git
repository_info:
commit_sha: 1334d902c73251c88a70f37c271a335d6a5868e5
path: .
targets:
- esp32
- esp32c2
- esp32c3
- esp32c5
- esp32c6
- esp32c61
- esp32h2
- esp32p4
- esp32s2
- esp32s3
url: https://github.com/esp-idf-lib/core
version: 1.0.7

View File

@@ -1,138 +0,0 @@
/*
* Copyright (c) 2019 Ruslan V. Uss <unclerus@gmail.com>
*
* 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 itscontributors
* 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.
*/
/**
* @file tca95x5.c
*
* ESP-IDF driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus
*
* Copyright (c) 2019 Ruslan V. Uss <unclerus@gmail.com>
*
* BSD Licensed as described in the file LICENSE
*/
#include <esp_idf_lib_helpers.h>
#include "tca95x5.h"
#define I2C_FREQ_HZ 400000
#define REG_IN0 0x00
#define REG_OUT0 0x02
#define REG_CONF0 0x06
#define CHECK(x) do { esp_err_t __; if ((__ = x) != ESP_OK) return __; } while (0)
#define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0)
#define BV(x) (1 << (x))
static esp_err_t read_reg_16(i2c_dev_t *dev, uint8_t reg, uint16_t *val)
{
CHECK_ARG(dev && val);
I2C_DEV_TAKE_MUTEX(dev);
I2C_DEV_CHECK(dev, i2c_dev_read_reg(dev, reg, val, 2));
I2C_DEV_GIVE_MUTEX(dev);
return ESP_OK;
}
static esp_err_t write_reg_16(i2c_dev_t *dev, uint8_t reg, uint16_t val)
{
CHECK_ARG(dev);
I2C_DEV_TAKE_MUTEX(dev);
I2C_DEV_CHECK(dev, i2c_dev_write_reg(dev, reg, &val, 2));
I2C_DEV_GIVE_MUTEX(dev);
return ESP_OK;
}
///////////////////////////////////////////////////////////////////////////////
esp_err_t tca95x5_init_desc(i2c_dev_t *dev, uint8_t addr, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio)
{
CHECK_ARG(dev && (addr & TCA95X5_I2C_ADDR_BASE));
dev->port = port;
dev->addr = addr;
dev->cfg.sda_io_num = sda_gpio;
dev->cfg.scl_io_num = scl_gpio;
#if HELPER_TARGET_IS_ESP32
dev->cfg.master.clk_speed = I2C_FREQ_HZ;
#endif
return i2c_dev_create_mutex(dev);
}
esp_err_t tca95x5_free_desc(i2c_dev_t *dev)
{
CHECK_ARG(dev);
return i2c_dev_delete_mutex(dev);
}
esp_err_t tca95x5_port_get_mode(i2c_dev_t *dev, uint16_t *mode)
{
return read_reg_16(dev, REG_CONF0, mode);
}
esp_err_t tca95x5_port_set_mode(i2c_dev_t *dev, uint16_t mode)
{
return write_reg_16(dev, REG_CONF0, mode);
}
esp_err_t tca95x5_port_read(i2c_dev_t *dev, uint16_t *val)
{
return read_reg_16(dev, REG_IN0, val);
}
esp_err_t tca95x5_port_write(i2c_dev_t *dev, uint16_t val)
{
return write_reg_16(dev, REG_OUT0, val);
}
esp_err_t tca95x5_get_level(i2c_dev_t *dev, uint8_t pin, uint32_t *val)
{
uint16_t v;
CHECK(read_reg_16(dev, REG_IN0, &v));
*val = v & BV(pin) ? 1 : 0;
return ESP_OK;
}
esp_err_t tca95x5_set_level(i2c_dev_t *dev, uint8_t pin, uint32_t val)
{
uint16_t v;
I2C_DEV_TAKE_MUTEX(dev);
I2C_DEV_CHECK(dev, i2c_dev_read_reg(dev, REG_OUT0, &v, 2));
v = (v & ~BV(pin)) | (val ? BV(pin) : 0);
I2C_DEV_CHECK(dev, i2c_dev_write_reg(dev, REG_OUT0, &v, 2));
I2C_DEV_GIVE_MUTEX(dev);
return ESP_OK;
}

View File

@@ -1,141 +0,0 @@
/*
* Copyright (c) 2019 Ruslan V. Uss <unclerus@gmail.com>
*
* 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 itscontributors
* 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.
*/
/**
* @file tca95x5.h
* @defgroup tca95x5 tca95x5
* @{
*
* ESP-IDF driver for TCA9535/TCA9555 remote 16-bit I/O expanders for I2C-bus
*
* Copyright (c) 2019 Ruslan V. Uss <unclerus@gmail.com>
*
* BSD Licensed as described in the file LICENSE
*/
#ifndef __TCA95X5_H__
#define __TCA95X5_H__
#include <stddef.h>
#include <i2cdev.h>
#include <esp_err.h>
#ifdef __cplusplus
extern "C" {
#endif
#define TCA95X5_I2C_ADDR_BASE 0x20
/**
* @brief Initialize device descriptor
*
* Default SCL frequency is 400kHz
*
* @param dev Pointer to I2C device descriptor
* @param addr I2C address (`0b0100<A2><A1><A0>`)
* @param port I2C port number
* @param sda_gpio SDA GPIO
* @param scl_gpio SCL GPIO
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_init_desc(i2c_dev_t *dev, uint8_t addr, i2c_port_t port, gpio_num_t sda_gpio, gpio_num_t scl_gpio);
/**
* @brief Free device descriptor
* @param dev Pointer to I2C device descriptor
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_free_desc(i2c_dev_t *dev);
/**
* @brief Get GPIO pins mode
*
* 0 - output, 1 - input for each bit in `val`
*
* @param dev Pointer to device descriptor
* @param[out] mode Buffer to store mode, 0 bit for P0.0 .. 15 bit for P1.7
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_port_get_mode(i2c_dev_t *dev, uint16_t *mode);
/**
* @brief Set GPIO pins mode
*
* 0 - output, 1 - input for each bit in `val`
*
* @param dev Pointer to device descriptor
* @param mode Mode, 0 bit for P0.0 .. 15 bit for P1.7
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_port_set_mode(i2c_dev_t *dev, uint16_t mode);
/**
* @brief Read GPIO port value
*
* @param dev Pointer to I2C device descriptor
* @param val 16-bit GPIO port value, 0 bit for P0.0 .. 15 bit for P1.7
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_port_read(i2c_dev_t *dev, uint16_t *val);
/**
* @brief Write value to GPIO port
*
* @param dev Pointer to I2C device descriptor
* @param val GPIO port value, 0 bit for P0.0 .. 15 bit for P1.7
* @return ESP_OK on success
*/
esp_err_t tca95x5_port_write(i2c_dev_t *dev, uint16_t val);
/**
* @brief Read GPIO pin level
*
* @param dev Pointer to device descriptor
* @param pin Pin number, 0 for P0.0 .. 15 for P1.7
* @param[out] val `true` if pin currently in high state
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_get_level(i2c_dev_t *dev, uint8_t pin, uint32_t *val);
/**
* @brief Set GPIO pin level
*
* Pin must be set up as output
*
* @param dev Pointer to device descriptor
* @param pin Pin number, 0 for P0.0 .. 15 for P1.7
* @param[out] val `true` if pin currently in high state
* @return `ESP_OK` on success
*/
esp_err_t tca95x5_set_level(i2c_dev_t *dev, uint8_t pin, uint32_t val);
#ifdef __cplusplus
}
#endif
/**@}*/
#endif /* __TCA95X5_H__ */

View File

@@ -1 +0,0 @@
29e47564b1a7ee778135e17fbbf2a2773f71c97ebabfe626c8eda7c958a7ad16

View File

@@ -1,8 +0,0 @@
---
commitizen:
bump_message: 'bump(mdns): $current_version -> $new_version'
pre_bump_hooks: python ../../ci/changelog.py mdns
tag_format: mdns-v$version
version: 1.9.1
version_files:
- idf_component.yml

View File

@@ -1,607 +0,0 @@
# Changelog
## [1.9.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.9.1)
### Bug Fixes
- Fix to use tagged AFL image + minor format fix ([2b2f009a](https://github.com/espressif/esp-protocols/commit/2b2f009a))
- Fix unused variable `dcst` warning for wifi-remote chips ([081eef88](https://github.com/espressif/esp-protocols/commit/081eef88))
## [1.9.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.9.0)
### Features
- support null value for boolean txt records ([fa96de3b](https://github.com/espressif/esp-protocols/commit/fa96de3b))
### Bug Fixes
- Add test case for bool/NULL txt handling ([5068f221](https://github.com/espressif/esp-protocols/commit/5068f221))
- Temporary fix for build issues on IDF master ([0197c994](https://github.com/espressif/esp-protocols/commit/0197c994))
- Add tests for delegated answers ([487a746d](https://github.com/espressif/esp-protocols/commit/487a746d))
- Add fuzzing into mdns CI ([af6bb1b5](https://github.com/espressif/esp-protocols/commit/af6bb1b5))
- Host test to use hw_support include dir ([8bba3a97](https://github.com/espressif/esp-protocols/commit/8bba3a97))
- Fixes case where we create our own malloc/free allocators, therefore we need to call mdns_mem_free and not free ([63bf7091](https://github.com/espressif/esp-protocols/commit/63bf7091))
- put srv/txt records in additional section for ptr queries ([b7b8c5db](https://github.com/espressif/esp-protocols/commit/b7b8c5db))
### Updated
- ci(common): Update test component dir for IDFv6.0 ([18418c83](https://github.com/espressif/esp-protocols/commit/18418c83))
## [1.8.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.8.2)
### Bug Fixes
- Fix parsing incorrect txt records ([8fd2c99f](https://github.com/espressif/esp-protocols/commit/8fd2c99f))
## [1.8.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.8.1)
### Bug Fixes
- Fix potential task delete race ([8ca45f34](https://github.com/espressif/esp-protocols/commit/8ca45f34))
## [1.8.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.8.0)
### Features
- Add version keys ([e01e67e7](https://github.com/espressif/esp-protocols/commit/e01e67e7))
### Bug Fixes
- Reformat mdns sources per indent-cont=120 ([c7663cde](https://github.com/espressif/esp-protocols/commit/c7663cde))
## [1.7.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.7.0)
### Features
- Support user defined allocators ([88162d1f](https://github.com/espressif/esp-protocols/commit/88162d1f))
- Allow allocate memory with configured caps ([7d29b476](https://github.com/espressif/esp-protocols/commit/7d29b476))
### Bug Fixes
- Adjust some formatting per indent-cont=120 ([5b2077e3](https://github.com/espressif/esp-protocols/commit/5b2077e3))
## [1.6.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.6.0)
### Features
- support allocating mDNS task from SPIRAM ([8fcad10c](https://github.com/espressif/esp-protocols/commit/8fcad10c))
### Bug Fixes
- Use correct task delete function ([eb4ab524](https://github.com/espressif/esp-protocols/commit/eb4ab524))
### Updated
- ci(mdns): Fix mdns host test layers with static task creation ([0690eba3](https://github.com/espressif/esp-protocols/commit/0690eba3))
## [1.5.3](https://github.com/espressif/esp-protocols/commits/mdns-v1.5.3)
### Bug Fixes
- Fix responder to ignore only invalid queries ([cd07228f](https://github.com/espressif/esp-protocols/commit/cd07228f), [#754](https://github.com/espressif/esp-protocols/issues/754))
## [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
- 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
- support update subtype ([062b8dca](https://github.com/espressif/esp-protocols/commit/062b8dca))
### Updated
- chore(mdns): Add more info to idf_component.yml ([4a1cb65c](https://github.com/espressif/esp-protocols/commit/4a1cb65c))
## [1.4.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.4.1)
### Features
- Send PTR query for mdns browse when interface is ready ([010a404a](https://github.com/espressif/esp-protocols/commit/010a404a))
### Bug Fixes
- Prevent deadlock when deleting a browse request ([3f48f9ea](https://github.com/espressif/esp-protocols/commit/3f48f9ea))
- Fix use after free reported by coverity ([25b3d5fd](https://github.com/espressif/esp-protocols/commit/25b3d5fd))
- Fixed dead-code reported by coverity ([11846c7d](https://github.com/espressif/esp-protocols/commit/11846c7d))
## [1.4.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.4.0)
### Major changes
- Fixed mdns API issues when add/remove/update records from multiple threads ([Fix services API races to directly add/remove services](https://github.com/espressif/esp-protocols/commit/8a690503))
### Features
- Unit tests for add/remove/update deleg/selfhosted services ([0660ece1](https://github.com/espressif/esp-protocols/commit/0660ece1))
- Add console command for mdns browsing ([1e8ede33](https://github.com/espressif/esp-protocols/commit/1e8ede33))
- Console test: set instance for service ([f107dcd1](https://github.com/espressif/esp-protocols/commit/f107dcd1))
- Console test: add subtype for service ([ee00e97b](https://github.com/espressif/esp-protocols/commit/ee00e97b))
- Console test: set port for (delegated) srvs ([07b79abf](https://github.com/espressif/esp-protocols/commit/07b79abf))
- Console test: add/remove TXT recs for delegated srvs ([c9a58d73](https://github.com/espressif/esp-protocols/commit/c9a58d73))
- Console test for changing TXT records ([6b9a6ce6](https://github.com/espressif/esp-protocols/commit/6b9a6ce6))
- Console test for add/remove delegated service APIs ([43de7e5c](https://github.com/espressif/esp-protocols/commit/43de7e5c))
- Console test for add/remove delegated host APIs ([ce7f326a](https://github.com/espressif/esp-protocols/commit/ce7f326a))
- Console test for lookup service APIs ([a91ead8e](https://github.com/espressif/esp-protocols/commit/a91ead8e))
- Add linux console functional tests ([50d059af](https://github.com/espressif/esp-protocols/commit/50d059af))
- check if the txt items is changed when browsing ([e2f0477a](https://github.com/espressif/esp-protocols/commit/e2f0477a))
### Bug Fixes
- Fix mdns_delegate_hostname_add() to block until done ([2c1b1661](https://github.com/espressif/esp-protocols/commit/2c1b1661))
- Fix API races when removing all services ([169405b5](https://github.com/espressif/esp-protocols/commit/169405b5))
- Fix API races setting instance name for services ([643dc6d4](https://github.com/espressif/esp-protocols/commit/643dc6d4))
- Fix API races while adding subtypes for services ([f9f234c4](https://github.com/espressif/esp-protocols/commit/f9f234c4))
- Fix API races removing txt item for services ([3f97a822](https://github.com/espressif/esp-protocols/commit/3f97a822))
- Fix API races adding txt item for services ([c62b920b](https://github.com/espressif/esp-protocols/commit/c62b920b))
- Fix API races while setting txt for services ([a927bf3a](https://github.com/espressif/esp-protocols/commit/a927bf3a))
- Fix API races while setting port for services ([99d5fb27](https://github.com/espressif/esp-protocols/commit/99d5fb27))
- Fix services API races to directly add/remove services ([8a690503](https://github.com/espressif/esp-protocols/commit/8a690503))
- Fix mdns mdns_lookup_service() to handle empty TXT ([d4da9cb0](https://github.com/espressif/esp-protocols/commit/d4da9cb0))
## [1.3.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.2)
### Features
- add check of instance when handling PTR query ([6af6ca5](https://github.com/espressif/esp-protocols/commit/6af6ca5))
### Bug Fixes
- Fix of mdns afl tests ([139166c](https://github.com/espressif/esp-protocols/commit/139166c))
- remove same protocol services with different instances ([042533a](https://github.com/espressif/esp-protocols/commit/042533a))
## [1.3.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.1)
### Bug Fixes
- free txt value len ([afd98bb](https://github.com/espressif/esp-protocols/commit/afd98bb))
## [1.3.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.3.0)
### Features
- add a new mdns query mode `browse` ([af330b6](https://github.com/espressif/esp-protocols/commit/af330b6))
- Make including mdns_console KConfigurable ([27adbfe](https://github.com/espressif/esp-protocols/commit/27adbfe))
### Bug Fixes
- Schedule all queued Tx packets from timer task ([d4e693e](https://github.com/espressif/esp-protocols/commit/d4e693e))
- add lock for some common apis ([21c84bf](https://github.com/espressif/esp-protocols/commit/21c84bf))
- fix mdns answer append while host is invalid ([7be16bc](https://github.com/espressif/esp-protocols/commit/7be16bc))
## [1.2.5](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.5)
### Bug Fixes
- Fixed build issues for targets without WiFi caps ([302b46f](https://github.com/espressif/esp-protocols/commit/302b46f))
## [1.2.4](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.4)
### Bug Fixes
- Correction on 6d2c475 MDNS_PREDEF_NETIF_ETH fix ([fc59f87c4e](https://github.com/espressif/esp-protocols/commit/fc59f87c4e))
- fix the logic of creating pcb for networking socket ([5000a9a20a](https://github.com/espressif/esp-protocols/commit/5000a9a20a))
- fix compiling issue when disabling IPv4 ([2646dcd23a](https://github.com/espressif/esp-protocols/commit/2646dcd23a))
- Fix compile error when MDNS_PREDEF_NETIF_ETH is defined, but ETH_ENABLED is not (#459) ([6d2c475c20](https://github.com/espressif/esp-protocols/commit/6d2c475c20))
## [1.2.3](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.3)
### Bug Fixes
- fixed CI issues for host and afl tests ([4be5efc84e](https://github.com/espressif/esp-protocols/commit/4be5efc84e))
- fix copy delegated host addr ([19fb36000c](https://github.com/espressif/esp-protocols/commit/19fb36000c))
- enable CONFIG_ESP_WIFI_ENABLED if CONFIG_SOC_WIFI_SUPPORTED is also enabled (for ESP-IDF <= 5.1) ([d20a718320](https://github.com/espressif/esp-protocols/commit/d20a718320))
- remove protocol_examples_common ([1ee9dae6bf](https://github.com/espressif/esp-protocols/commit/1ee9dae6bf))
- move the example into a subdirectory ([d28232b9f8](https://github.com/espressif/esp-protocols/commit/d28232b9f8))
- reference protocol_examples_common from IDF ([c83b76ea8f](https://github.com/espressif/esp-protocols/commit/c83b76ea8f))
## [1.2.2](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.2)
### Bug Fixes
- add terminator for the getting host name ([b6a4d94](https://github.com/espressif/esp-protocols/commit/b6a4d94))
- Enable ESP_WIFI_CONFIG when ESP-IDF <= 5.1 ([0b783c0](https://github.com/espressif/esp-protocols/commit/0b783c0))
- set host list NULL on destroy ([ea54eef](https://github.com/espressif/esp-protocols/commit/ea54eef))
- removed Wno-format flag and fixed formatting warnings ([c48e442](https://github.com/espressif/esp-protocols/commit/c48e442))
- remove the the range of MDNS_MAX_SERVICES and fix issues of string functions ([3dadce2](https://github.com/espressif/esp-protocols/commit/3dadce2))
## [1.2.1](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.1)
### Features
- Allow setting length of mDNS action queue in menuconfig ([28cd898](https://github.com/espressif/esp-protocols/commit/28cd898))
### Bug Fixes
- fix build issue if CONFIG_ESP_WIFI_ENABLED disabled ([24f7031](https://github.com/espressif/esp-protocols/commit/24f7031))
- added idf_component.yml for examples ([d273e10](https://github.com/espressif/esp-protocols/commit/d273e10))
- added guard check for null pointer ([71bb461](https://github.com/espressif/esp-protocols/commit/71bb461))
## [1.2.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.2.0)
### Features
- add an API for setting address to a delegated host ([ddc3eb6](https://github.com/espressif/esp-protocols/commit/ddc3eb6))
- Add support for lwip build under linux ([588465d](https://github.com/espressif/esp-protocols/commit/588465d))
- Allow for adding a delegated host with no address ([c562461](https://github.com/espressif/esp-protocols/commit/c562461))
- Add APIs for looking up self hosted services and getting the self hostname ([f0df12d](https://github.com/espressif/esp-protocols/commit/f0df12d))
### Bug Fixes
- Refactor freertos linux compat layers ([79a0e57](https://github.com/espressif/esp-protocols/commit/79a0e57))
- Fix delegated service PTR response ([cab0e1d](https://github.com/espressif/esp-protocols/commit/cab0e1d))
- Added unit tests to CI + minor fix to pass it ([c974c14](https://github.com/espressif/esp-protocols/commit/c974c14))
### Updated
- docs: update documentation links ([4de5298](https://github.com/espressif/esp-protocols/commit/4de5298))
## [1.1.0](https://github.com/espressif/esp-protocols/commits/mdns-v1.1.0)
### Features
- Decouple main module from mdns-networking ([d238e93](https://github.com/espressif/esp-protocols/commit/d238e93))
### Bug Fixes
- Use idf-build-apps package for building mdns ([1a0a41f](https://github.com/espressif/esp-protocols/commit/1a0a41f))
- socket networking to init interfaces properly ([ee9b04f](https://github.com/espressif/esp-protocols/commit/ee9b04f))
- Removed unused internal lock from mdns_server struct ([a06fb77](https://github.com/espressif/esp-protocols/commit/a06fb77))
- Resolve conflicts only on self hosted items ([e69a9eb](https://github.com/espressif/esp-protocols/commit/e69a9eb), [#185](https://github.com/espressif/esp-protocols/issues/185))
- Fix memory issues reported by valgrind ([0a682e7](https://github.com/espressif/esp-protocols/commit/0a682e7))
### Updated
- docs(common): updated component and example links ([f48d9b2](https://github.com/espressif/esp-protocols/commit/f48d9b2))
- Add APIs to look up delegated services ([87dcd7d](https://github.com/espressif/esp-protocols/commit/87dcd7d))
- Fix deadly mdns crash ([4fa3023](https://github.com/espressif/esp-protocols/commit/4fa3023))
- docs(common): improving documentation ([ca3fce0](https://github.com/espressif/esp-protocols/commit/ca3fce0))
- append all ipv6 address in mdns answer ([5ed3e9a](https://github.com/espressif/esp-protocols/commit/5ed3e9a))
- test(mdns): Host tests to use IDF's esp_event_stub ([537d170](https://github.com/espressif/esp-protocols/commit/537d170))
## [1.0.9](https://github.com/espressif/esp-protocols/commits/mdns-v1.0.9)
### Features
- Add reverse lookup to the example and test ([d464ed7](https://github.com/espressif/esp-protocols/commit/d464ed7))
- Add support for IPv6 reverse query ([d4825f5](https://github.com/espressif/esp-protocols/commit/d4825f5))
### Bug Fixes
- Reintroduce missing CHANGELOGs ([200cbb3](https://github.com/espressif/esp-protocols/commit/200cbb3))
- use semaphore instead of task notification bits (IDFGH-9380) ([73f2800](https://github.com/espressif/esp-protocols/commit/73f2800), [IDF#10754](https://github.com/espressif/esp-idf/issues/10754))
### Updated
- ci(common): force scoping commit messages with components ([c55fcc0](https://github.com/espressif/esp-protocols/commit/c55fcc0))
- Add homepage URL and License to all components ([ef3f0ee](https://github.com/espressif/esp-protocols/commit/ef3f0ee))
- docs: fix of mdns link translation ([1c850dd](https://github.com/espressif/esp-protocols/commit/1c850dd))
- unite all tags under common structure py test: update tags under common structure ([c6db3ea](https://github.com/espressif/esp-protocols/commit/c6db3ea))
## [1.0.8](https://github.com/espressif/esp-protocols/commits/b9b4a75)
### Features
- Add support for IPv4 reverse query ([b87bef5](https://github.com/espressif/esp-protocols/commit/b87bef5))
### Bug Fixes
- Host test with IDFv5.1 ([fb8a2f0](https://github.com/espressif/esp-protocols/commit/fb8a2f0))
- Remove strict mode as it's invalid ([d0c9070](https://github.com/espressif/esp-protocols/commit/d0c9070))
- Allow setting instance name only after hostname set ([a8339e4](https://github.com/espressif/esp-protocols/commit/a8339e4), [#190](https://github.com/espressif/esp-protocols/issues/190))
- Make unit test executable with pytest ([12cfcb5](https://github.com/espressif/esp-protocols/commit/12cfcb5))
- AFL port layer per IDF-latest changes ([0247926](https://github.com/espressif/esp-protocols/commit/0247926))
### Updated
- bump the component version to 1.0.8 ([b9b4a75](https://github.com/espressif/esp-protocols/commit/b9b4a75))
- Make reverse query conditional per Kconfig ([91134f1](https://github.com/espressif/esp-protocols/commit/91134f1))
- Added badges with version of components to the respective README files ([e4c8a59](https://github.com/espressif/esp-protocols/commit/e4c8a59))
- fix some coverity reported issues ([c73c797](https://github.com/espressif/esp-protocols/commit/c73c797))
- Examples: using pytest.ini from top level directory ([aee016d](https://github.com/espressif/esp-protocols/commit/aee016d))
- mDNS: test_app pytest migration ([f71f61f](https://github.com/espressif/esp-protocols/commit/f71f61f))
- CI: fixing the files to be complient with pre-commit hooks ([945bd17](https://github.com/espressif/esp-protocols/commit/945bd17))
- prevent crash when hostname is null ([3498e86](https://github.com/espressif/esp-protocols/commit/3498e86))
- Example tests integration ([a045c1c](https://github.com/espressif/esp-protocols/commit/a045c1c))
- Replace hardcoded TTL values with named defines ([bb4c002](https://github.com/espressif/esp-protocols/commit/bb4c002))
- Fix add_service() to report error if no-hostname ([656ab21](https://github.com/espressif/esp-protocols/commit/656ab21))
## [1.0.7](https://github.com/espressif/esp-protocols/commits/088f7ac)
### Updated
- bump up the component version ([088f7ac](https://github.com/espressif/esp-protocols/commit/088f7ac))
- fix IPV4 only build and also update CI configuration ([e079f8b](https://github.com/espressif/esp-protocols/commit/e079f8b))
- add test configuration for IPV6 disabled build ([330332a](https://github.com/espressif/esp-protocols/commit/330332a))
## [1.0.6](https://github.com/espressif/esp-protocols/commits/48c157b)
### Bug Fixes
- Example makefile to add only mdns as extra comps ([d74c296](https://github.com/espressif/esp-protocols/commit/d74c296))
- ignore authoritative flag on reception ([415e04a](https://github.com/espressif/esp-protocols/commit/415e04a))
### Updated
- fix build issue with CONFIG_LWIP_IPV6 disabled ([48c157b](https://github.com/espressif/esp-protocols/commit/48c157b))
- fix bit order issue in DNS header flags ([c4e85bd](https://github.com/espressif/esp-protocols/commit/c4e85bd))
- updated package version to 0.1.19 ([469f953](https://github.com/espressif/esp-protocols/commit/469f953))
## [1.0.5](https://github.com/espressif/esp-protocols/commits/36de9af)
### Features
- Define explicit dependencies on esp-wifi ([36de9af](https://github.com/espressif/esp-protocols/commit/36de9af))
### Updated
- bugfix: mdns IPv6 address convert error ([238ee96](https://github.com/espressif/esp-protocols/commit/238ee96))
## [1.0.4](https://github.com/espressif/esp-protocols/commits/57afa38)
### Updated
- Bump asio/mdns/esp_websocket_client versions ([57afa38](https://github.com/espressif/esp-protocols/commit/57afa38))
- ignore format warnings ([d66f9dc](https://github.com/espressif/esp-protocols/commit/d66f9dc))
- Fix test_app build ([0b102f6](https://github.com/espressif/esp-protocols/commit/0b102f6))
## [1.0.3](https://github.com/espressif/esp-protocols/commits/4868689)
### Updated
- Updated mDNS to explicitely use esp-eth dependency if needed ([4868689](https://github.com/espressif/esp-protocols/commit/4868689), [IDF@5e19b9c](https://github.com/espressif/esp-idf/commit/5e19b9c9518ae253d82400ab24b86af8af832425))
## [1.0.2](https://github.com/espressif/esp-protocols/commits/8fe2a3a)
### Features
- fix bug when clean action memory ([81c219d](https://github.com/espressif/esp-protocols/commit/81c219d), [IDF@3d4deb9](https://github.com/espressif/esp-idf/commit/3d4deb972620cae8e8ce4d0050153cc6f39db372))
### Bug Fixes
- add the maximum number of services ([0191d6f](https://github.com/espressif/esp-protocols/commit/0191d6f), [IDF@ba458c6](https://github.com/espressif/esp-idf/commit/ba458c69cfb2f18478d73690c289b09641c62004))
- fix the exception when remove one of multiple service ([b26c866](https://github.com/espressif/esp-protocols/commit/b26c866), [IDF@696d733](https://github.com/espressif/esp-idf/commit/696d733eb04ee98f764dffdc82bcef51a724c9c6))
### Updated
- Minor fixes here and there ([8fe2a3a](https://github.com/espressif/esp-protocols/commit/8fe2a3a))
- mDNS: Initial version based on IDF 5.0 ([b6b20ad](https://github.com/espressif/esp-protocols/commit/b6b20ad))
- soc: moved kconfig options out of the target component. ([4a52cf2](https://github.com/espressif/esp-protocols/commit/4a52cf2), [IDF@d287209](https://github.com/espressif/esp-idf/commit/d2872095f93ed82fb91c776081bc1d032493d93e))
- cmake: fix issue with passing cxx_std option for GCC 11, a common workaround ([87c2699](https://github.com/espressif/esp-protocols/commit/87c2699), [IDF@ea0d212](https://github.com/espressif/esp-idf/commit/ea0d2123c806bd0ad77bc49843ee905cf9be65ff))
- kconfig: Changed default values of bool configs - Some bool configs were using default values true and false, instead of y and n. ([eb536a7](https://github.com/espressif/esp-protocols/commit/eb536a7), [IDF@25c5c21](https://github.com/espressif/esp-idf/commit/25c5c214f38ca690b03533e12fb5a4d774c7eae0))
- esp_netif: Remove tcpip_adapter compatibility layer ([3e93ea9](https://github.com/espressif/esp-protocols/commit/3e93ea9), [IDF@795b7ed](https://github.com/espressif/esp-idf/commit/795b7ed993784e3134195e12b0978504d83dfd56))
- Fix copyright messages, update API descrition ([2c764b1](https://github.com/espressif/esp-protocols/commit/2c764b1), [IDF@42ba8a8](https://github.com/espressif/esp-idf/commit/42ba8a8338fd5efd82498a5989fc5c105938d447))
- Add API to control custom network interfaces ([f836ae7](https://github.com/espressif/esp-protocols/commit/f836ae7), [IDF@b02468d](https://github.com/espressif/esp-idf/commit/b02468dc98d614f931d14cd8b5e2373ca51fb18d))
- CI/mdns: Fix fuzzer build ([4b5f24f](https://github.com/espressif/esp-protocols/commit/4b5f24f), [IDF@98e9426](https://github.com/espressif/esp-idf/commit/98e9426b660a6e825f811cccd45a0722cc801ccd))
- Add support for registering custom netif ([30f37c0](https://github.com/espressif/esp-protocols/commit/30f37c0), [IDF@bec42ff](https://github.com/espressif/esp-idf/commit/bec42ff85d5091d71e1cb1063bea20d7c6ac8c76))
- Indicate interface using esp_netif in search results ([ddc58e8](https://github.com/espressif/esp-protocols/commit/ddc58e8), [IDF@f8495f1](https://github.com/espressif/esp-idf/commit/f8495f1e86de9a8e7d046bf13d0ca04775041b4c))
- Use predefined interfaces to prepare for custom netifs ([fa951bf](https://github.com/espressif/esp-protocols/commit/fa951bf), [IDF@f90b3b7](https://github.com/espressif/esp-idf/commit/f90b3b798b446382d848f8c55c5e1653c81871cd))
- Prepare for dynamic esp-netif support ([605d1fa](https://github.com/espressif/esp-protocols/commit/605d1fa), [IDF@f9892f7](https://github.com/espressif/esp-idf/commit/f9892f77b88ba77dc6608ba746175f6dc64a7607))
- esp_hw_support/esp_system: Re-evaluate header inclusions and include directories ([58bf218](https://github.com/espressif/esp-protocols/commit/58bf218), [IDF@a9fda54](https://github.com/espressif/esp-idf/commit/a9fda54d39d1321005c3bc9b3cc268d0b7e9f052))
- system: move kconfig options out of target component ([ec491ec](https://github.com/espressif/esp-protocols/commit/ec491ec), [IDF@bb88338](https://github.com/espressif/esp-idf/commit/bb88338118957c2214a4c0a33cd4a152e2e1f8ba))
- Update to drop our own packet if bounced back ([94ae672](https://github.com/espressif/esp-protocols/commit/94ae672), [IDF@b5149e3](https://github.com/espressif/esp-idf/commit/b5149e3ee73728f790798e6757d732fe426e21c7))
- Fix potential read behind parsed packet ([e5a3a3d](https://github.com/espressif/esp-protocols/commit/e5a3a3d), [IDF@51a5de2](https://github.com/espressif/esp-idf/commit/51a5de2525d0e82adea2e298a0edcc9b2dee5edd))
- Fix memleak when adding delegated host ([7710ea9](https://github.com/espressif/esp-protocols/commit/7710ea9), [IDF@9cbdb87](https://github.com/espressif/esp-idf/commit/9cbdb8767bdf6e9745e895b2c5af74d0376965e7))
- Fix null-service issue when parsing packets ([034c55e](https://github.com/espressif/esp-protocols/commit/034c55e), [IDF#8307](https://github.com/espressif/esp-idf/issues/8307), [IDF@a57be7b](https://github.com/espressif/esp-idf/commit/a57be7b7d1135ddb29f9da636e9ad315f7fa1fa7))
- Update fuzzer test (add delegation, check memory) ([ec03fec](https://github.com/espressif/esp-protocols/commit/ec03fec), [IDF@2c10071](https://github.com/espressif/esp-idf/commit/2c1007156e01b4707b5c89d73cad05c0eef0264f))
- Remove legacy esp_event API ([5909e9e](https://github.com/espressif/esp-protocols/commit/5909e9e), [IDF@e46aa51](https://github.com/espressif/esp-idf/commit/e46aa515bdf5606a3d868f1034774d5fc96904b8))
- added missing includes ([82e2a5d](https://github.com/espressif/esp-protocols/commit/82e2a5d), [IDF@28d09c7](https://github.com/espressif/esp-idf/commit/28d09c7dbe145ffa6a7dd90531062d4f7669a9c8))
- Clear notification value in mdns_hostname_set ([48e4d40](https://github.com/espressif/esp-protocols/commit/48e4d40), [IDF@83a4ddb](https://github.com/espressif/esp-idf/commit/83a4ddbd250e2b386bccabb4705d4c58c1a22bcb))
- esp_timer: remove legacy ESP32 FRC timer implementation. ([ac6dcb6](https://github.com/espressif/esp-protocols/commit/ac6dcb6), [IDF@edb76f1](https://github.com/espressif/esp-idf/commit/edb76f14d6b3e925568ff04a87befe733ecc4517))
- freertos: Remove legacy data types ([085dbd8](https://github.com/espressif/esp-protocols/commit/085dbd8), [IDF@57fd78f](https://github.com/espressif/esp-idf/commit/57fd78f5baf93a368a82cf4b2e00ca17ffc09115))
- Tools: Custom baud-rate setup is not possible for IDF Monitor from menuconfig anymore ([f78e8cf](https://github.com/espressif/esp-protocols/commit/f78e8cf), [IDF@36a4011](https://github.com/espressif/esp-idf/commit/36a4011ff8985bfbae08ba0272194e6c3ef93bbf))
- Use memcpy() for copy to support non-text TXTs ([6cdf5ee](https://github.com/espressif/esp-protocols/commit/6cdf5ee), [IDF@6aefe9c](https://github.com/espressif/esp-idf/commit/6aefe9c18563ed567d384a956cf02b6f57d6894c))
- Support for null-value TXT records ([fcb5515](https://github.com/espressif/esp-protocols/commit/fcb5515), [IDF#8267](https://github.com/espressif/esp-idf/issues/8267), [IDF@23c2db4](https://github.com/espressif/esp-idf/commit/23c2db406dee8df09dbdba21cb7eef9fbca8bf27))
- Fix alloc issue if TXT has empty value ([9fdbe5f](https://github.com/espressif/esp-protocols/commit/9fdbe5f), [IDF@205f6ba](https://github.com/espressif/esp-idf/commit/205f6ba8541e12d958c7c56af5a7136090f12a0e))
- Fix random crash when defalt service instance queried ([20e6e9e](https://github.com/espressif/esp-protocols/commit/20e6e9e), [IDF@f46dffc](https://github.com/espressif/esp-idf/commit/f46dffca627e9578e49a510580f9754ec1e27e2e))
- Fix minor memory leaks when creating services ([c588263](https://github.com/espressif/esp-protocols/commit/c588263), [IDF@fad62cc](https://github.com/espressif/esp-idf/commit/fad62cc1ed3dce63b58297172a72a489d7af2d9d))
- Fix mDNS memory leak ([6258edf](https://github.com/espressif/esp-protocols/commit/6258edf), [IDF@119b4a9](https://github.com/espressif/esp-idf/commit/119b4a9dd12cf89cc5eaf63f8aa19730607ef30b))
- Fix mDNS memory leak ([c8b0d5e](https://github.com/espressif/esp-protocols/commit/c8b0d5e), [IDF@f5ffd53](https://github.com/espressif/esp-idf/commit/f5ffd53aeb402afc1333a98168bb2fa35d7cdc77))
- Use multi/uni-cast types in API ([5252b1d](https://github.com/espressif/esp-protocols/commit/5252b1d), [IDF@125c312](https://github.com/espressif/esp-idf/commit/125c3125524c71f4f48f635eda12e22fa3bca500))
- Allow for unicast PTR queries ([4e11cc8](https://github.com/espressif/esp-protocols/commit/4e11cc8), [IDF@7eeeb01](https://github.com/espressif/esp-idf/commit/7eeeb01ea705745b027bd8bc11d2b142418e9927))
- Fix potential null deref for ANY query type ([7af91ec](https://github.com/espressif/esp-protocols/commit/7af91ec), [IDF@99dd8ee](https://github.com/espressif/esp-idf/commit/99dd8eedb1a0e957f5f74344e3e4172e61c29ef8))
- Make fuzzer layers compatible with llvm>=6 ([01256d3](https://github.com/espressif/esp-protocols/commit/01256d3), [IDF@1882cbe](https://github.com/espressif/esp-idf/commit/1882cbe44e6140bebb2d27dc18af06dfcb0157f5))
- Fix copyright ([5a2d4ea](https://github.com/espressif/esp-protocols/commit/5a2d4ea), [IDF@c83678f](https://github.com/espressif/esp-idf/commit/c83678f64fe27844fc28050bde6433ccb04a0704))
- Add mDNS miss comment ([9de3f53](https://github.com/espressif/esp-protocols/commit/9de3f53), [IDF@08e0813](https://github.com/espressif/esp-idf/commit/08e081340d9d76d1244e9f2dc527e5ae370b1fbe))
- freertos: remove FREERTOS_ASSERT option ([bcabc8e](https://github.com/espressif/esp-protocols/commit/bcabc8e), [IDF@7255497](https://github.com/espressif/esp-idf/commit/72554971467a5edc9bd6e390cf8fe7b05e6ade81))
- Minor err print fix in socket-networking layer ([dfb27b3](https://github.com/espressif/esp-protocols/commit/dfb27b3), [IDF@f1b8f5c](https://github.com/espressif/esp-idf/commit/f1b8f5c1023df7d649161bc76f2bcc9a8f8f4d8b))
- unified errno format ([076c095](https://github.com/espressif/esp-protocols/commit/076c095), [IDF@87506f4](https://github.com/espressif/esp-idf/commit/87506f46e2922710f48a6b96ca75e53543ff45c4))
- always send A/AAAA records in announcements ([7dd0bc1](https://github.com/espressif/esp-protocols/commit/7dd0bc1), [IDF@456f80b](https://github.com/espressif/esp-idf/commit/456f80b754ebd0bd74e02c7febdf461c6b573b7a))
- filter instance name for ANY queries ([7e82a7c](https://github.com/espressif/esp-protocols/commit/7e82a7c), [IDF@5d0c473](https://github.com/espressif/esp-idf/commit/5d0c47303dd9ead0f2ad291dca1d4b7ce4e23b2b))
- Fix potential null deref reported by fuzzer test ([ae381b7](https://github.com/espressif/esp-protocols/commit/ae381b7), [IDF@cb5653f](https://github.com/espressif/esp-idf/commit/cb5653fd940a9cd41e8554a6d753fab46e0459d7))
- Minor fix of API description and API usage ([941dc5c](https://github.com/espressif/esp-protocols/commit/941dc5c), [IDF@c297301](https://github.com/espressif/esp-idf/commit/c297301ecc350f8315d7eaf78c72b4aba68d422a))
- Added results count to MDNS ([525c649](https://github.com/espressif/esp-protocols/commit/525c649), [IDF@f391d61](https://github.com/espressif/esp-idf/commit/f391d610e8185631b5361dc6c844c4c04aac30b1))
- fix mdns server instance mismatch ([f0839d9](https://github.com/espressif/esp-protocols/commit/f0839d9), [IDF@6173dd7](https://github.com/espressif/esp-idf/commit/6173dd78097216261277c20ebd92a53c68c47f89))
- support multiple instance for mdns service txt set ([69902ea](https://github.com/espressif/esp-protocols/commit/69902ea), [IDF@50f6302](https://github.com/espressif/esp-idf/commit/50f6302c5d7c0498fa1baa6fd6129d8233971a81))
- fix wrong PTR record count ([d0bbe88](https://github.com/espressif/esp-protocols/commit/d0bbe88), [IDF@5d3f815](https://github.com/espressif/esp-idf/commit/5d3f8157e0e481363ef93d54a29d957fc91cca86))
- Build & config: Remove leftover files from the unsupported "make" build system ([4a9d55e](https://github.com/espressif/esp-protocols/commit/4a9d55e), [IDF@766aa57](https://github.com/espressif/esp-idf/commit/766aa5708443099f3f033b739cda0e1de101cca6))
- Build & config: Remove the "make" build system ([be2a924](https://github.com/espressif/esp-protocols/commit/be2a924), [IDF@9c1d4f5](https://github.com/espressif/esp-idf/commit/9c1d4f5b549d6a7125e5c7c323c80d37361991cb))
- freertos: update freertos folder structure to match upstream ([76fcd41](https://github.com/espressif/esp-protocols/commit/76fcd41), [IDF@4846222](https://github.com/espressif/esp-idf/commit/48462221029c7da4b1ea233e9e781cd57ff91c7e))
- support service subtype ([fd8499c](https://github.com/espressif/esp-protocols/commit/fd8499c), [IDF#5508](https://github.com/espressif/esp-idf/issues/5508), [IDF@e7e8610](https://github.com/espressif/esp-idf/commit/e7e8610f563e0b8532a093ea8b803f0eb132fd0e))
- Fix parsing non-standard queries ([38b4fe2](https://github.com/espressif/esp-protocols/commit/38b4fe2), [IDF#7694](https://github.com/espressif/esp-idf/issues/7694), [IDF@d16f9ba](https://github.com/espressif/esp-idf/commit/d16f9bade5beab3785677dd5b39ebc4e9c895008))
- allow mutiple instances with same service type ([b266062](https://github.com/espressif/esp-protocols/commit/b266062), [IDF@b7a99f4](https://github.com/espressif/esp-idf/commit/b7a99f46587a69a2cd07e7616c3bb30b7b1a6edf))
- Update copyright header ([5e087d8](https://github.com/espressif/esp-protocols/commit/5e087d8), [IDF@2a2b95b](https://github.com/espressif/esp-idf/commit/2a2b95b9c22bc5090d87a4f4317288b64b14fcd9))
- Fix potential null dereference identified by fuzzer tests ([91a3d95](https://github.com/espressif/esp-protocols/commit/91a3d95), [IDF@e7dabb1](https://github.com/espressif/esp-idf/commit/e7dabb14f7c8fd9bd2bea55d8f1accc65323a1c0))
- components/bt: move config BT_RESERVE_DRAM from bluedroid to ESP32 controller ([6d6dd2b](https://github.com/espressif/esp-protocols/commit/6d6dd2b), [IDF@b310c06](https://github.com/espressif/esp-idf/commit/b310c062cd25f249e00dd03dd27baed783921630))
- add notification callback for async APIs ([52306e9](https://github.com/espressif/esp-protocols/commit/52306e9), [IDF@986603c](https://github.com/espressif/esp-idf/commit/986603cf07413b46c88c76c324bf500edcfb6171))
- add more mdns result attributes ([d37ab6d](https://github.com/espressif/esp-protocols/commit/d37ab6d), [IDF@76ec76c](https://github.com/espressif/esp-idf/commit/76ec76c12c871554147343bb7141da1e5de58011))
- Add host test using linux target ([5c55ea6](https://github.com/espressif/esp-protocols/commit/5c55ea6), [IDF@fc7e2d9](https://github.com/espressif/esp-idf/commit/fc7e2d9e908f61fb4b852cfae72aa5ff7c662ebc))
- Implement mdns_networking using BSD sockets ([0c71c7b](https://github.com/espressif/esp-protocols/commit/0c71c7b), [IDF@73dfe84](https://github.com/espressif/esp-idf/commit/73dfe84bf295a850edfad39b6b097a71f15964dc))
- fix crash when adding services without hostname set ([4c368c0](https://github.com/espressif/esp-protocols/commit/4c368c0), [IDF@5e98772](https://github.com/espressif/esp-idf/commit/5e98772eaf7e50d96cf2e6ecdfedcd928b61c864))
- Fix fuzzer IDF-mock layer ([af22753](https://github.com/espressif/esp-protocols/commit/af22753), [IDF@619235c](https://github.com/espressif/esp-idf/commit/619235c2ee5a1fe8411bd2be2de8798209f95902))
- Clean the main mdns module from lwip dependencies ([b0957e7](https://github.com/espressif/esp-protocols/commit/b0957e7), [IDF@54e3294](https://github.com/espressif/esp-idf/commit/54e329444a5dd19c51e84b5f1e16455a0f1c6225))
- Add asynchronous query API ([47c7266](https://github.com/espressif/esp-protocols/commit/47c7266), [IDF#7090](https://github.com/espressif/esp-idf/issues/7090), [IDF@d81482d](https://github.com/espressif/esp-idf/commit/d81482d699232b22f4a5cbee2a76199a5285dadb))
- Fix crashes reported by the fuzzer tests ([40da0d2](https://github.com/espressif/esp-protocols/commit/40da0d2), [IDF@4a2e726](https://github.com/espressif/esp-idf/commit/4a2e72677c6fb7681a7e2acd1a878d3deb114079))
- mdns/fuzzer: Fix non-instrumentation test to reproduce fuzzer issues ([5f6b6f9](https://github.com/espressif/esp-protocols/commit/5f6b6f9), [IDF@dae8033](https://github.com/espressif/esp-idf/commit/dae803335e6bc6d9751a360cd3f675ce4027853b))
- return ESP_OK rather than ERR_OK in API functions ([8a12082](https://github.com/espressif/esp-protocols/commit/8a12082), [IDF@2386113](https://github.com/espressif/esp-idf/commit/2386113972ee51ea93e9740d8c34bfe9289ce909))
- fix memory leak in mdns_free when adding delegated hostnames ([46f28a8](https://github.com/espressif/esp-protocols/commit/46f28a8), [IDF@0baee93](https://github.com/espressif/esp-idf/commit/0baee932111268c4a2103e1c1adeb7d99914a937))
- Support for One-Shot mDNS queries ([5a81eae](https://github.com/espressif/esp-protocols/commit/5a81eae), [IDF@f167238](https://github.com/espressif/esp-idf/commit/f167238fac37818aed75dc689eed54ad47528ab9))
- allow explicit txt value length ([2ddaee2](https://github.com/espressif/esp-protocols/commit/2ddaee2), [IDF@b4e0088](https://github.com/espressif/esp-idf/commit/b4e0088b68321acc4698b01faec7e2ffbe1e37c1))
- Fix crashes reported by the fuzzer ([27fc285](https://github.com/espressif/esp-protocols/commit/27fc285), [IDF@79ba738](https://github.com/espressif/esp-idf/commit/79ba738626d643d8c6f32bdcd455e0d2476f94c7))
- Minor correction of the test code ([93e6efe](https://github.com/espressif/esp-protocols/commit/93e6efe), [IDF@7d76245](https://github.com/espressif/esp-idf/commit/7d762451731cb305c3b090509827740f0195a496))
- Fix fuzzer from miss-interpreting adding services as timeouts ([bc4cda8](https://github.com/espressif/esp-protocols/commit/bc4cda8), [IDF@14099fe](https://github.com/espressif/esp-idf/commit/14099fe15efb1b0cde0a8370096c55bba62ff937))
- fix test script delayed response ([8a8d58d](https://github.com/espressif/esp-protocols/commit/8a8d58d), [IDF@a4f2639](https://github.com/espressif/esp-idf/commit/a4f263948c35c13340b6f4b59a649c5073787d5e))
- fix wrong SRV/PTR record handling ([402baeb](https://github.com/espressif/esp-protocols/commit/402baeb), [IDF@e613555](https://github.com/espressif/esp-idf/commit/e6135552d26480e39e11632437020535b1667b7a))
- fix wrong service hostname after mangling ([9fa25ef](https://github.com/espressif/esp-protocols/commit/9fa25ef), [IDF@439b31d](https://github.com/espressif/esp-idf/commit/439b31d065eddfdfb6eb4cf9c00454edfebc3d9b))
- fix empty address change announce packets ([121b525](https://github.com/espressif/esp-protocols/commit/121b525), [IDF@7bbb72d](https://github.com/espressif/esp-idf/commit/7bbb72d86540f04d37b0e2c4efb6dc66ee9c9ea0))
- fix mdns probe/reply behavior ([418fb60](https://github.com/espressif/esp-protocols/commit/418fb60), [IDF@d2a5d25](https://github.com/espressif/esp-idf/commit/d2a5d25984432d149ca31aea4a0d177f3509dd7b))
- make delegate host address a list ([4049b3b](https://github.com/espressif/esp-protocols/commit/4049b3b), [IDF@2d34352](https://github.com/espressif/esp-idf/commit/2d34352f3db0fa71366a838933a29138a90eb2af))
- add remove delegate host api ([c882119](https://github.com/espressif/esp-protocols/commit/c882119), [IDF@2174693](https://github.com/espressif/esp-idf/commit/2174693096b73ce93261611c44ecba647cd01859))
- add mdns delegation ([1eb5df9](https://github.com/espressif/esp-protocols/commit/1eb5df9), [IDF@401ff56](https://github.com/espressif/esp-idf/commit/401ff56cc1ad1d11284143a348cc0c0e4a363e98))
- fix memory free issue when repeating the query in reply ([b62b4b3](https://github.com/espressif/esp-protocols/commit/b62b4b3), [IDF@5f244c8](https://github.com/espressif/esp-idf/commit/5f244c86f29da46c17610563a245d1663a46b439))
- Fix of crash when wifi interface get deleted and mdns receives the packets ([4d8aec1](https://github.com/espressif/esp-protocols/commit/4d8aec1), [IDF#6973](https://github.com/espressif/esp-idf/issues/6973), [IDF@03de74a](https://github.com/espressif/esp-idf/commit/03de74a728d4b278f55e1fc30e0425483b806e80))
- Docs: Added README.md for lwip fuzzer tests ([6d64910](https://github.com/espressif/esp-protocols/commit/6d64910), [IDF@53c18a8](https://github.com/espressif/esp-idf/commit/53c18a85db104bb37ebeadec2faf5d42d764d0f9))
- Fixed the ip header TTL to be correctly set to 255 ([ab3fa69](https://github.com/espressif/esp-protocols/commit/ab3fa69), [IDF@5cce919](https://github.com/espressif/esp-idf/commit/5cce919cbef87f543bb9f5275b77b97b3b1ea67e))
- Fix parsing answers with questions when instance name not set ([c3a5826](https://github.com/espressif/esp-protocols/commit/c3a5826), [IDF#6598](https://github.com/espressif/esp-idf/issues/6598), [IDF@3404945](https://github.com/espressif/esp-idf/commit/34049454dfaf5132d9b258ef4d04921befc8997b))
- Fix the resolver to correctly parse it's own non-strict answers ([cbcbe4f](https://github.com/espressif/esp-protocols/commit/cbcbe4f), [IDF@b649603](https://github.com/espressif/esp-idf/commit/b649603a0d70ec804567f57752c3eddaed56198f))
- Add MDNS_STRICT_MODE config option ([adc3430](https://github.com/espressif/esp-protocols/commit/adc3430), [IDF@0eee315](https://github.com/espressif/esp-idf/commit/0eee31546dd4e6df0d1c1cc2740da0675dffb4bf))
- freertos: common config header ([c30617d](https://github.com/espressif/esp-protocols/commit/c30617d), [IDF@39cf818](https://github.com/espressif/esp-idf/commit/39cf818838b0259b3e00b3c198ad47b4add41939))
- Removed freeRTOS dependancies from fuzzer tests ([1e5eeb1](https://github.com/espressif/esp-protocols/commit/1e5eeb1), [IDF@5571694](https://github.com/espressif/esp-idf/commit/55716945a9908e057743d69e1d59399df03e49bd))
- mDNS: Updated APIs description and shows the warning when hostname contains domain name during the query ([22c7c0a](https://github.com/espressif/esp-protocols/commit/22c7c0a), [IDF#6590](https://github.com/espressif/esp-idf/issues/6590), [IDF@9f8d2b9](https://github.com/espressif/esp-idf/commit/9f8d2b944d2b3736a012e0dff1a8459b6941d295))
- components: Use CONFIG_LWIP_IPV6 to strip IPv6 function in components ([1623c0e](https://github.com/espressif/esp-protocols/commit/1623c0e), [IDF@da58235](https://github.com/espressif/esp-idf/commit/da58235a0ee262ff552c5f1155d531b5c31e8de6))
- add bound check when setting interface as duplicate ([b114ed6](https://github.com/espressif/esp-protocols/commit/b114ed6), [IDF@2b9d2c0](https://github.com/espressif/esp-idf/commit/2b9d2c06f54924b680c41ae641978c8d81612f65))
- mDNS: Fix of text length calculation when detecting a collision ([2ffd223](https://github.com/espressif/esp-protocols/commit/2ffd223), [IDF@be0ae1e](https://github.com/espressif/esp-idf/commit/be0ae1ebbbe9fae6ecf7de09e8d50cba063b61f4))
- global: fix sign-compare warnings ([1fe901f](https://github.com/espressif/esp-protocols/commit/1fe901f), [IDF@753a929](https://github.com/espressif/esp-idf/commit/753a9295259126217a9fe6ef1c5e9da21e9b4e28))
- lwip: Moved default SNTP API to esp_sntp.h ([2cf9fd8](https://github.com/espressif/esp-protocols/commit/2cf9fd8), [IDF@76f6dd6](https://github.com/espressif/esp-idf/commit/76f6dd6214ca583b1a94c7c553ccac739a27f6d5))
- Allow resolve its own non-strict answers ([89439e0](https://github.com/espressif/esp-protocols/commit/89439e0), [IDF#6190](https://github.com/espressif/esp-idf/issues/6190), [IDF@0693e17](https://github.com/espressif/esp-idf/commit/0693e172de392086b9bfd8cf1474d8d133af3298))
- mDNS: Fix of collision detection during txt length calculation ([becd5d0](https://github.com/espressif/esp-protocols/commit/becd5d0), [IDF#6114](https://github.com/espressif/esp-idf/issues/6114), [IDF@f33772c](https://github.com/espressif/esp-idf/commit/f33772c96037c795366e60082bdbbefe2a69165f))
- esp32c3: Apply one-liner/small changes for ESP32-C3 ([0d7a309](https://github.com/espressif/esp-protocols/commit/0d7a309), [IDF@5228d9f](https://github.com/espressif/esp-idf/commit/5228d9f9ced16118d87326f94d9f9dfd411e0be9))
- test: fix several test build error ([1fdffbb](https://github.com/espressif/esp-protocols/commit/1fdffbb), [IDF@b7ecccd](https://github.com/espressif/esp-idf/commit/b7ecccd9010f1deaba83de54374231c3c7f5b472))
- freertos: Add RISC-V port ([988d120](https://github.com/espressif/esp-protocols/commit/988d120), [IDF@87e13ba](https://github.com/espressif/esp-idf/commit/87e13baaf12fe6deae715d95e912a310fea4ba88))
- Fix wrong mdns source address if lwIP IPv6 zones disabled ([fd47df3](https://github.com/espressif/esp-protocols/commit/fd47df3), [IDF@7ac9761](https://github.com/espressif/esp-idf/commit/7ac97616c119e4d2f4cdd377dfc5abbf75ec5e30))
- Whitespace: Automated whitespace fixes (large commit) ([2cb3a6e](https://github.com/espressif/esp-protocols/commit/2cb3a6e), [IDF@66fb5a2](https://github.com/espressif/esp-idf/commit/66fb5a29bbdc2482d67c52e6f66b303378c9b789))
- test_compile_fuzzers: Fix include paths for host build ([825652f](https://github.com/espressif/esp-protocols/commit/825652f), [IDF@98a0cc7](https://github.com/espressif/esp-idf/commit/98a0cc783f701b238bea232b53250a538d34920a))
- CI: Add a test to pre-check fuzzer tests compilation before weekly run ([fc53888](https://github.com/espressif/esp-protocols/commit/fc53888), [IDF@637f5c0](https://github.com/espressif/esp-idf/commit/637f5c0a6842c42ee6cf7f41d3c5ae0cb28a68af))
- soc: descriptive part occupy whole component ([7635c04](https://github.com/espressif/esp-protocols/commit/7635c04), [IDF@79887fd](https://github.com/espressif/esp-idf/commit/79887fdc6c3d9a2e509cc189bb43c998d3f0f4ee))
- Coredump config option rename throughout IDF ([d5fe42b](https://github.com/espressif/esp-protocols/commit/d5fe42b), [IDF@20af94f](https://github.com/espressif/esp-idf/commit/20af94ff53c5147a76342800d007a6c49be50a7b))
- mdns, dns, dhcp, dhcps: update fuzzer test to work in CI ([e0bc60a](https://github.com/espressif/esp-protocols/commit/e0bc60a), [IDF@a43c06a](https://github.com/espressif/esp-idf/commit/a43c06a592bcf9404297b22268c33bb7a246632c))
- cmock: added cmock as component ([9772e49](https://github.com/espressif/esp-protocols/commit/9772e49), [IDF@20c068e](https://github.com/espressif/esp-idf/commit/20c068ef3b49999387896b90f8011b02f718485f))
- Support queries in responses in mDNS non-strict mode ([6021a88](https://github.com/espressif/esp-protocols/commit/6021a88), [IDF#5521](https://github.com/espressif/esp-idf/issues/5521), [IDF@bcfa36d](https://github.com/espressif/esp-idf/commit/bcfa36db8ffff997f1f95eaf6b011ffc4d46a10f))
- Fix include query ID in reponses ([78f71ec](https://github.com/espressif/esp-protocols/commit/78f71ec), [IDF#5574](https://github.com/espressif/esp-idf/issues/5574), [IDF@f62e321](https://github.com/espressif/esp-idf/commit/f62e321d87c1d520cccca951715c27730e06607a))
- Allow config mDNS task stack size ([3319844](https://github.com/espressif/esp-protocols/commit/3319844), [IDF@cf7e48c](https://github.com/espressif/esp-idf/commit/cf7e48c779edd84c3f99d5e8ed81027932302382))
- Remove mbedtls dependency ([ac70c9a](https://github.com/espressif/esp-protocols/commit/ac70c9a), [IDF@f4a4549](https://github.com/espressif/esp-idf/commit/f4a4549a344e7ff2444a188adbebbc136b47a7bb))
- limit the GOT_IP6_EVENT to only known network interfaces ([2b7d43e](https://github.com/espressif/esp-protocols/commit/2b7d43e), [IDF@ab8cab1](https://github.com/espressif/esp-idf/commit/ab8cab1c553ee5312ef47a7dea002f2585605006))
- esp32: add implementation of esp_timer based on TG0 LAC timer ([4eb3e89](https://github.com/espressif/esp-protocols/commit/4eb3e89), [IDF@739eb05](https://github.com/espressif/esp-idf/commit/739eb05bb97736b70507e7ebcfee58e670672d23))
- fixed typos in the variable names and the comments ([b5e5a64](https://github.com/espressif/esp-protocols/commit/b5e5a64), [IDF@ecca39e](https://github.com/espressif/esp-idf/commit/ecca39e19f663e32e16aef2a09df15443de347e9))
- fix preset of esp_netif ptr for local interfaces ([6713ffe](https://github.com/espressif/esp-protocols/commit/6713ffe), [IDF@09e36f9](https://github.com/espressif/esp-idf/commit/09e36f9f3354092b2a528baaaaccab28ff4774d6))
- fixed crash on event during deinit ([817c4fd](https://github.com/espressif/esp-protocols/commit/817c4fd), [IDF@eaa2f12](https://github.com/espressif/esp-idf/commit/eaa2f12d6761710d2633b4934fe09f6f45e20f4f))
- respond to discovery with the proper pseudo name _services._dns-sd._udp ([8f0dc6d](https://github.com/espressif/esp-protocols/commit/8f0dc6d), [IDF#4369](https://github.com/espressif/esp-idf/issues/4369), [IDF@de17a14](https://github.com/espressif/esp-idf/commit/de17a1487f8ba6f432b06199f2261132ec6e735f))
- fixed forgotten merge conflicts in debug code ([d20666f](https://github.com/espressif/esp-protocols/commit/d20666f), [IDF@d9433ef](https://github.com/espressif/esp-idf/commit/d9433ef69223a32d05abdca543fb530f2e6679e4))
- add missing include of esp_task.h ([662a4ce](https://github.com/espressif/esp-protocols/commit/662a4ce), [IDF@5884b80](https://github.com/espressif/esp-idf/commit/5884b80908d680874e27fa0c8b2df85b69d03dd3))
- add configuration values for task priority, affinity and internal service timeouts ([fb1de80](https://github.com/espressif/esp-protocols/commit/fb1de80), [IDF@c6f38f0](https://github.com/espressif/esp-idf/commit/c6f38f04f8eec1aae937cc87c111609772681cb3))
- tcpip_adapter: updated tcpip_adapter compatablity layer to include all public API and keep 100% backward compatibility update build of tcpip adapter when ethernet disabled ([1f35e9a](https://github.com/espressif/esp-protocols/commit/1f35e9a), [IDF@7f5cda1](https://github.com/espressif/esp-idf/commit/7f5cda1b825586903f85dc4ad7736b35712e46d7))
- update mdns to use esp-netif for mdns supported services such as STA, AP, ETH ([48b819b](https://github.com/espressif/esp-protocols/commit/48b819b), [IDF@19e24fe](https://github.com/espressif/esp-idf/commit/19e24fe61ed5ea6698dfd5e1f427e783360aa846))
- esp_netif: Introduction of esp-netif component as a replacement of tcpip_adpter ([53e2aa3](https://github.com/espressif/esp-protocols/commit/53e2aa3), [IDF@ffe043b](https://github.com/espressif/esp-idf/commit/ffe043b1a81a0f9e1cc2cfa8873e21318ec89143))
- examples: removed ip4addr_ntoa and used prefered IP2STR for displaying IP addresses ([3cc6446](https://github.com/espressif/esp-protocols/commit/3cc6446), [IDF@ec9f245](https://github.com/espressif/esp-idf/commit/ec9f245dd35d3e8e7b19a8dec5e05e003dc21f39))
- esp_event, mdns: fixes for CONFIG_ETH_ENABLED=n ([248b11b](https://github.com/espressif/esp-protocols/commit/248b11b), [IDF@569ad75](https://github.com/espressif/esp-idf/commit/569ad7545c32a2f1d0eff3f1e81df70fb76ad125))
- build and link hello-world for esp32s2beta ([901124b](https://github.com/espressif/esp-protocols/commit/901124b), [IDF@84b2f9f](https://github.com/espressif/esp-idf/commit/84b2f9f14d16533c84db2210f13a24cd817e0b0a))
- fix crash for hostname queries ([f6ff165](https://github.com/espressif/esp-protocols/commit/f6ff165), [IDF#4224](https://github.com/espressif/esp-idf/issues/4224), [IDF@3d11700](https://github.com/espressif/esp-idf/commit/3d1170031b340a231949fdc0d9c46d87af0d1b5d))
- fix possible race condition when checking DHCP status on WIFI_EVENT_STA_CONNECTED event. ([f44c569](https://github.com/espressif/esp-protocols/commit/f44c569), [IDF@7f410a0](https://github.com/espressif/esp-idf/commit/7f410a0bcbafa85dba05807c53c3c38999506509))
- use constant size of AAAA answer in mdns packets instead of deriving from lwip struct size, since the struct could contain also zones ([286c646](https://github.com/espressif/esp-protocols/commit/286c646), [IDF@e5e31c5](https://github.com/espressif/esp-idf/commit/e5e31c5d0172d68fd207fa31cc5d3bba82dad020))
- esp_wifi: wifi support new event mechanism ([c70d527](https://github.com/espressif/esp-protocols/commit/c70d527), [IDF@003a987](https://github.com/espressif/esp-idf/commit/003a9872b7de69d799e9d37521cfbcaff9b37e85))
- fix missing bye packet if services removed with mdns_service_remove_all() or mdns_free() ([7cdf96c](https://github.com/espressif/esp-protocols/commit/7cdf96c), [IDF#3660](https://github.com/espressif/esp-idf/issues/3660), [IDF@a001998](https://github.com/espressif/esp-idf/commit/a001998d5283b29ca9a374adf7cef3357b39a03a))
- mdns_service_remove_all doesn't take an argument ([407875d](https://github.com/espressif/esp-protocols/commit/407875d), [IDF@c2764f6](https://github.com/espressif/esp-idf/commit/c2764f6fe85681cfaf5dbbe168295284f09c09cd))
- tools: Mass fixing of empty prototypes (for -Wstrict-prototypes) ([3e753f5](https://github.com/espressif/esp-protocols/commit/3e753f5), [IDF@afbaf74](https://github.com/espressif/esp-idf/commit/afbaf74007e89d016dbade4072bf2e7a3874139a))
- fix ignoring mdns packet with some invalid name entries in question field ([144d4ad](https://github.com/espressif/esp-protocols/commit/144d4ad), [IDF@4bd4c7c](https://github.com/espressif/esp-idf/commit/4bd4c7caf3f9ef8402c5a27ab44561537407eb60))
- add esp_eth component ([680bad6](https://github.com/espressif/esp-protocols/commit/680bad6), [IDF@90c4827](https://github.com/espressif/esp-idf/commit/90c4827bd22aa61894a5b22b3b39247a7e44d6cf))
- components: use new component registration api ([7fb6686](https://github.com/espressif/esp-protocols/commit/7fb6686), [IDF@9eccd7c](https://github.com/espressif/esp-idf/commit/9eccd7c0826d6cc2e9de59304d1e5f76c0063ccf))
- fix static analysis warnings ([4912bef](https://github.com/espressif/esp-protocols/commit/4912bef), [IDF@c34de4c](https://github.com/espressif/esp-idf/commit/c34de4cba658e8331f8a3ab2f466190c7640595b))
- added initial suite of api unit tests ([181a22e](https://github.com/espressif/esp-protocols/commit/181a22e), [IDF@e680191](https://github.com/espressif/esp-idf/commit/e6801912c5c4861f828ab1f447280628bba9a5d7))
- mdns tests: adapt mdns fuzzer test to compile with event loop library ([4172219](https://github.com/espressif/esp-protocols/commit/4172219), [IDF@38d15cb](https://github.com/espressif/esp-idf/commit/38d15cbd637e8b8baacda9fc43e8e99d224530f5))
- fixed mdns crashing on reception of txt packet without a corresponding service closes #2866 ([98d2c1a](https://github.com/espressif/esp-protocols/commit/98d2c1a), [IDF@af48977](https://github.com/espressif/esp-idf/commit/af48977f21cea6b18dae10b2c8b64a78acfc647f))
- use const char* for mdns txt items types to remove warning when assigning ([84cbb1f](https://github.com/espressif/esp-protocols/commit/84cbb1f), [IDF@c050a75](https://github.com/espressif/esp-idf/commit/c050a75616803c7871ef11c060e440fae09000d9))
- updated doxygen comments documenting mdns api ([4c6818e](https://github.com/espressif/esp-protocols/commit/4c6818e), [IDF#1718](https://github.com/espressif/esp-idf/issues/1718), [IDF@a851aac](https://github.com/espressif/esp-idf/commit/a851aac255311124529f504486ca55bad15c1951))
- update mdns_out_question_s to be in line with mdns_parsed_question_s struct ([c440114](https://github.com/espressif/esp-protocols/commit/c440114), [IDF#1568]( https://github.com/espressif/esp-idf/issues/1568), [IDF@eddd5c4](https://github.com/espressif/esp-idf/commit/eddd5c4f2c686d9a1d6d3258569cc33752e78880))
- use esp_event library to handle events ([6ea0ea9](https://github.com/espressif/esp-protocols/commit/6ea0ea9), [IDF@a2d5952](https://github.com/espressif/esp-idf/commit/a2d59525e53099ee1ad63c3d60ff853f573ab535))
- fuzzer tests: update of mdns and lwip host compilation for fuzzer testing ([d9aec9f](https://github.com/espressif/esp-protocols/commit/d9aec9f), [IDF@bc60bbb](https://github.com/espressif/esp-idf/commit/bc60bbbeaf89f2bbfc5db4bd4f1e7ace81a2ab37))
- fix possible crash when probing on particular interface with duplicated service instances due to naming conflicts on network ([985e691](https://github.com/espressif/esp-protocols/commit/985e691), [IDF@265e983](https://github.com/espressif/esp-idf/commit/265e983a452a7eaefc1662cdc0e6ed839a37fe1a))
- enable pcbs before starting service thread to avoid updating pcb's internal variables from concurent tasks ([75deebb](https://github.com/espressif/esp-protocols/commit/75deebb), [IDF@c87f0cb](https://github.com/espressif/esp-idf/commit/c87f0cb6cad3c36b077f4aaeb1ca52fe6ed0cdaf))
- fix possible deadlock on mdns deinit calling mdns_free() ([fdd27dc](https://github.com/espressif/esp-protocols/commit/fdd27dc), [IDF#1696](https://github.com/espressif/esp-idf/issues/1696), [IDF@48b5501](https://github.com/espressif/esp-idf/commit/48b5501c250ed90da51a55ad4fc18e09f466a517))
- mdsn: fix race condition in updating packet data from user task when failed to allocate or queue a new service ([2ec3b55](https://github.com/espressif/esp-protocols/commit/2ec3b55), [IDF@021dc5d](https://github.com/espressif/esp-idf/commit/021dc5d453e21e2d1707f194668e69cf63ef4e84))
- fix possible crash when packet scheduled to transmit contained service which might have been already removed ([450cbf0](https://github.com/espressif/esp-protocols/commit/450cbf0), [IDF@67051a2](https://github.com/espressif/esp-idf/commit/67051a286ba60a01d4755c3682129153c2f95953))
- use binary semaphore instead of mutex when searching ([34f6d8d](https://github.com/espressif/esp-protocols/commit/34f6d8d), [IDF@eef0b50](https://github.com/espressif/esp-idf/commit/eef0b5090aee87efef1a6a37772b3b88c9ce8df8))
- fix memory leak in pbuf if tcpipadapter failed to get netif ([b6efc68](https://github.com/espressif/esp-protocols/commit/b6efc68), [IDF@8462751](https://github.com/espressif/esp-idf/commit/8462751f95a3ff18bdc1b01d02fabd1829fd9135))
- fix malfuctional query_txt ([90e4bab](https://github.com/espressif/esp-protocols/commit/90e4bab), [IDF@1a02773](https://github.com/espressif/esp-idf/commit/1a027734af06abf08fcb1c34ee65bdf50d12be4d))
- fix possible crash when mdns_free called while action queue not empty ([c546ab8](https://github.com/espressif/esp-protocols/commit/c546ab8), [IDF@206b47c](https://github.com/espressif/esp-idf/commit/206b47c03aca0acdf40d1d9c250e18aeddfe1bd7))
- fix memory leak when query for service receives multiple ptr entries for one instance ([6582b41](https://github.com/espressif/esp-protocols/commit/6582b41), [IDF@9a4da97](https://github.com/espressif/esp-idf/commit/9a4da97fb4b3c241998cb969a08c3a917ffb4cd1))
- fix crash after init if no memory for task ([358d26c](https://github.com/espressif/esp-protocols/commit/358d26c), [IDF@a47768d](https://github.com/espressif/esp-idf/commit/a47768dc4e4750fd7e1c29b15d6e2dd3c76e6591))
- fixed crash on free undefined ptr after skipped strdup ([2ac83d0](https://github.com/espressif/esp-protocols/commit/2ac83d0), [IDF@e0a8044](https://github.com/espressif/esp-idf/commit/e0a8044a16907e642001b883469618a999dbe6db))
- Correct Kconfigs according to the coding style ([98e3171](https://github.com/espressif/esp-protocols/commit/98e3171), [IDF@37126d3](https://github.com/espressif/esp-idf/commit/37126d3451eabb44eeeb48b8e2ee554dc233e2a8))
- fix networking running udp_sendif from lwip thread ([2f85c07](https://github.com/espressif/esp-protocols/commit/2f85c07), [IDF@f7d4a4b](https://github.com/espressif/esp-idf/commit/f7d4a4be6a9e0b0ac5edb9400d3b123dbbed2ffc))
- fixed static memory leak ([b30a7fe](https://github.com/espressif/esp-protocols/commit/b30a7fe), [IDF@6bb68a5](https://github.com/espressif/esp-idf/commit/6bb68a5a7567a94c3605136d44960ff060c74663))
- check all mallocs for failure and add default hook to log error with free heap ([7a4fdad](https://github.com/espressif/esp-protocols/commit/7a4fdad), [IDF@c8cb4cd](https://github.com/espressif/esp-idf/commit/c8cb4cd3c8eb56d5901ade03302ad1231d7f3de5))
- resolve memory leak when txt record received multiple times ([b4e5742](https://github.com/espressif/esp-protocols/commit/b4e5742), [IDF@a6b2b73](https://github.com/espressif/esp-idf/commit/a6b2b73f03bbb75a39685ddba6cf877fd1e5e6d7))
- skip sending search when finished, not properly locked timer task ([2763bcd](https://github.com/espressif/esp-protocols/commit/2763bcd), [IDF@31163f0](https://github.com/espressif/esp-idf/commit/31163f02d5c414d8b492dce6f729b43a0061581b))
- sending search packets also in probing and announcing state ([8cd0e8a](https://github.com/espressif/esp-protocols/commit/8cd0e8a), [IDF@d16762a](https://github.com/espressif/esp-idf/commit/d16762a036e35ce86ece86bb44e6e99f9cc7c431))
- fixed crashes on network changes ([9b3b41c](https://github.com/espressif/esp-protocols/commit/9b3b41c), [IDF@097282a](https://github.com/espressif/esp-idf/commit/097282a8e3f85958747430d9931ce0a545d37700))
- Update network code for mDNS to work with newest LwIP ([ea23007](https://github.com/espressif/esp-protocols/commit/ea23007), [IDF@3ec0e7e](https://github.com/espressif/esp-idf/commit/3ec0e7e2d2ddea70e9f8fb5025664d0fe24c301a))
- bugfix: mdns_service_txt_set() wasn't allocating memory for TXT records ([0c17121](https://github.com/espressif/esp-protocols/commit/0c17121), [IDF@e5e2702](https://github.com/espressif/esp-idf/commit/e5e2702ca3f63a29da57eb138f75a20c74fb2a94))
- cmake: make main a component again ([67173f6](https://github.com/espressif/esp-protocols/commit/67173f6), [IDF@d9939ce](https://github.com/espressif/esp-idf/commit/d9939cedd9b44d63dc148354c3a0a139b9c7113d))
- Feature/sync lwip as submodule ([fed787f](https://github.com/espressif/esp-protocols/commit/fed787f), [IDF@3578fe3](https://github.com/espressif/esp-idf/commit/3578fe39e01ba0c2d54824ac70c3276502661c6b))
- Fix a portion of the queries are issued with the wildcard query type ([b4ab30b](https://github.com/espressif/esp-protocols/commit/b4ab30b), [IDF@f3f0445](https://github.com/espressif/esp-idf/commit/f3f0445f4db7c9ad97ae10a9728767337aa7bb62))
- added CI job for AFL fuzzer tests ([dd71494](https://github.com/espressif/esp-protocols/commit/dd71494), [IDF@0c14764](https://github.com/espressif/esp-idf/commit/0c147648f7642d058b63fbe2ddd5de31c2326304))
- Minor fix for mdns_service_remove() ([39de491](https://github.com/espressif/esp-protocols/commit/39de491), [IDF@5c7eb7e](https://github.com/espressif/esp-idf/commit/5c7eb7e27be7508130459d896cf7d13ffefda87f))
- Replace all DOS line endings with Unix ([19acac7](https://github.com/espressif/esp-protocols/commit/19acac7), [IDF@a67d5d8](https://github.com/espressif/esp-idf/commit/a67d5d89e0e90390fa7ff02816a6a79008d75d40))
- remove executable permission from source files ([98069f9](https://github.com/espressif/esp-protocols/commit/98069f9), [IDF@cb649e4](https://github.com/espressif/esp-idf/commit/cb649e452f3c64a7db1f4a61e162a16b70248204))
- Fixed nullptr dereference in MDNS.c ([ad29d34](https://github.com/espressif/esp-protocols/commit/ad29d34), [IDF@fffbf7b](https://github.com/espressif/esp-idf/commit/fffbf7b75065b5852e064e04b0c5102dd0fc2244))
- MDNS-Fuzzer: AFL fuzzer tests for mdsn packet parser ([9f1be36](https://github.com/espressif/esp-protocols/commit/9f1be36), [IDF@e983230](https://github.com/espressif/esp-idf/commit/e983230be933fb83cebdd1945ba6539a7dc99b28))
- cmake: Add component dependency support ([c7701d4](https://github.com/espressif/esp-protocols/commit/c7701d4), [IDF@1cb5712](https://github.com/espressif/esp-idf/commit/1cb5712463a8963cd3e8331da90fb5e03f13575f))
- cmake: Remove defaults for COMPONENT_SRCDIRS, COMPONENT_SRCS, COMPONENT_ADD_INCLUDEDIRS ([f1ccc40](https://github.com/espressif/esp-protocols/commit/f1ccc40), [IDF@4f1a856](https://github.com/espressif/esp-idf/commit/4f1a856dbfd752336cd71730105e02ad8c045541))
- build system: Initial cmake support, work in progress ([84bd1d7](https://github.com/espressif/esp-protocols/commit/84bd1d7), [IDF@c671a0c](https://github.com/espressif/esp-idf/commit/c671a0c3ebf90f18576d6db55b51b62730c58301))
- fix the bug that in mdns test code redefine esp_err_t to uint32_t, which should be int32_t ([259d3fc](https://github.com/espressif/esp-protocols/commit/259d3fc), [IDF@81e4cad](https://github.com/espressif/esp-idf/commit/81e4cad61593cde879a5c44a08060d9d336e5a3f))
- Fix exception when service is removed while there are pending packets that depend on it ([7784d00](https://github.com/espressif/esp-protocols/commit/7784d00), [IDF@421c6f1](https://github.com/espressif/esp-idf/commit/421c6f154b10d9253b78875ab28ee6bdcaaaf3c0))
- Fix case where service is NULL and that will cause exception ([bce7d52](https://github.com/espressif/esp-protocols/commit/bce7d52), [IDF@4fa130a](https://github.com/espressif/esp-idf/commit/4fa130ae4fb5de99ddddc5a7bed7e26ae645591c))
- Fix issue with some mDNS parsers ([ef924f1](https://github.com/espressif/esp-protocols/commit/ef924f1), [IDF@51dde19](https://github.com/espressif/esp-idf/commit/51dde19a765533af67fc7be21f116641773a9be4))
- Import mDNS changes ([ad8c92d](https://github.com/espressif/esp-protocols/commit/ad8c92d), [IDF@4bddbc0](https://github.com/espressif/esp-idf/commit/4bddbc031cee83935c0e4df1dc72cc7000c97ba5))
- Fix compilation errors when using gcc-7.2.0 for the crosstool-ng toolchain ([3aa605f](https://github.com/espressif/esp-protocols/commit/3aa605f), [IDF@519edc3](https://github.com/espressif/esp-idf/commit/519edc332dae0160069fd790467cde8de78f1a0e))
- components/mdns: wrong Message compression detect ([00a72b8](https://github.com/espressif/esp-protocols/commit/00a72b8), [IDF@6e24566](https://github.com/espressif/esp-idf/commit/6e24566186c52dc5432b6b25c81abda577c21e85))
- fix leak after _mdns_create_service if we have a malloc error. ([907e7ee](https://github.com/espressif/esp-protocols/commit/907e7ee), [IDF@b6b36bd](https://github.com/espressif/esp-idf/commit/b6b36bd9ddf169039a5528f8b766048d97b975f7))
- Use LwIP IPC for low-level API calls ([b367484](https://github.com/espressif/esp-protocols/commit/b367484), [IDF@713964f](https://github.com/espressif/esp-idf/commit/713964fe9e98b4fa34145c497b7ab638dc57614c))
- Add AFL fuzz test ([4a8582f](https://github.com/espressif/esp-protocols/commit/4a8582f), [IDF@4c26227](https://github.com/espressif/esp-idf/commit/4c2622755d92efa1818d062d433725553437993c))
- implement fixes for issues found while fuzz testing ([75de31c](https://github.com/espressif/esp-protocols/commit/75de31c), [IDF@99d3990](https://github.com/espressif/esp-idf/commit/99d39909c4f19c63909d663e927ac0a8933a3ed5))
- add simple dns-sd meta query support ([4acf639](https://github.com/espressif/esp-protocols/commit/4acf639), [IDF@96e8a3c](https://github.com/espressif/esp-idf/commit/96e8a3c725095562d2725aaefa15adcfc5d78dd5))
- address security issues with mDNS ([91bb509](https://github.com/espressif/esp-protocols/commit/91bb509), [IDF@c89e11c](https://github.com/espressif/esp-idf/commit/c89e11c8fa64641edddf9a055745d825ae3fab9d))
- Initial mDNS component and example ([7fbf8e5](https://github.com/espressif/esp-protocols/commit/7fbf8e5), [IDF@dd3f18d](https://github.com/espressif/esp-idf/commit/dd3f18d2d88ee78909d4af2840dfdf0b9f715f28))

View File

@@ -1,42 +0,0 @@
if(CONFIG_MDNS_NETWORKING_SOCKET)
set(MDNS_NETWORKING "mdns_networking_socket.c")
else()
set(MDNS_NETWORKING "mdns_networking_lwip.c")
endif()
if(CONFIG_MDNS_ENABLE_CONSOLE_CLI)
set(MDNS_CONSOLE "mdns_console.c")
else()
set(MDNS_CONSOLE "")
endif()
set(MDNS_MEMORY "mdns_mem_caps.c")
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
set(dependencies esp_netif_linux esp_event)
set(private_dependencies esp_timer console esp_system)
set(srcs "mdns.c" ${MDNS_MEMORY} ${MDNS_NETWORKING} ${MDNS_CONSOLE})
else()
set(dependencies lwip console esp_netif)
set(private_dependencies esp_timer esp_wifi)
set(srcs "mdns.c" ${MDNS_MEMORY} ${MDNS_NETWORKING} ${MDNS_CONSOLE})
endif()
idf_component_register(
SRCS ${srcs}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES ${dependencies}
PRIV_REQUIRES ${private_dependencies})
if(${target} STREQUAL "linux")
target_link_libraries(${COMPONENT_LIB} PRIVATE "-lbsd")
endif()
if(CONFIG_ETH_ENABLED)
idf_component_optional_requires(PRIVATE esp_eth)
endif()
idf_component_get_property(MDNS_VERSION ${COMPONENT_NAME} COMPONENT_VERSION)
target_compile_definitions(${COMPONENT_LIB} PUBLIC "-DESP_MDNS_VERSION_NUMBER=\"${MDNS_VERSION}\"")

View File

@@ -1,190 +0,0 @@
menu "mDNS"
config MDNS_MAX_INTERFACES
int "Max number of interfaces"
range 1 9
default 3
help
Number of network interfaces to be served by the mDNS library.
Lowering this number helps to reduce some static RAM usage.
config MDNS_MAX_SERVICES
int "Max number of services"
default 10
help
Services take up a certain amount of memory, and allowing fewer
services to be open at the same time conserves memory. Specify
the maximum amount of services here.
config MDNS_TASK_PRIORITY
int "mDNS task priority"
range 1 255
default 1
help
Allows setting mDNS task priority. Please do not set the task priority
higher than priorities of system tasks. Compile time warning/error
would be emitted if the chosen task priority were too high.
config MDNS_ACTION_QUEUE_LEN
int "Maximum actions pending to the server"
range 8 64
default 16
help
Allows setting the length of mDNS action queue.
config MDNS_TASK_STACK_SIZE
int "mDNS task stack size"
default 4096
help
Allows setting mDNS task stacksize.
choice MDNS_TASK_AFFINITY
prompt "mDNS task affinity"
default MDNS_TASK_AFFINITY_CPU0
help
Allows setting mDNS tasks affinity, i.e. whether the task is pinned to
CPU0, pinned to CPU1, or allowed to run on any CPU.
config MDNS_TASK_AFFINITY_NO_AFFINITY
bool "No affinity"
config MDNS_TASK_AFFINITY_CPU0
bool "CPU0"
config MDNS_TASK_AFFINITY_CPU1
bool "CPU1"
depends on !FREERTOS_UNICORE
endchoice
config MDNS_TASK_AFFINITY
hex
default FREERTOS_NO_AFFINITY if MDNS_TASK_AFFINITY_NO_AFFINITY
default 0x0 if MDNS_TASK_AFFINITY_CPU0
default 0x1 if MDNS_TASK_AFFINITY_CPU1
menu "MDNS Memory Configuration"
choice MDNS_TASK_MEMORY_ALLOC_FROM
prompt "Select mDNS task create on which type of memory"
default MDNS_TASK_CREATE_FROM_INTERNAL
config MDNS_TASK_CREATE_FROM_SPIRAM
bool "mDNS task creates on the SPIRAM (READ HELP)"
depends on (SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC)
help
mDNS task creates on the SPIRAM.
This option requires FreeRTOS component to allow creating
tasks on the external memory.
Please read the documentation about FREERTOS_TASK_CREATE_ALLOW_EXT_MEM
config MDNS_TASK_CREATE_FROM_INTERNAL
bool "mDNS task creates on the internal RAM"
endchoice
choice MDNS_MEMORY_ALLOC_FROM
prompt "Select mDNS memory allocation type"
default MDNS_MEMORY_ALLOC_INTERNAL
config MDNS_MEMORY_ALLOC_SPIRAM
bool "Allocate mDNS memory from SPIRAM"
depends on (SPIRAM_USE_CAPS_ALLOC || SPIRAM_USE_MALLOC)
config MDNS_MEMORY_ALLOC_INTERNAL
bool "Allocate mDNS memory from internal RAM"
endchoice
config MDNS_MEMORY_CUSTOM_IMPL
bool "Implement custom memory functions"
default n
help
Enable to implement custom memory functions for mDNS library.
This option is useful when the application wants to use custom
memory allocation functions for mDNS library.
endmenu # MDNS Memory Configuration
config MDNS_SERVICE_ADD_TIMEOUT_MS
int "mDNS adding service timeout (ms)"
range 10 30000
default 2000
help
Configures timeout for adding a new mDNS service. Adding a service
fails if could not be completed within this time.
config MDNS_TIMER_PERIOD_MS
int "mDNS timer period (ms)"
range 10 10000
default 100
help
Configures period of mDNS timer, which periodically transmits packets
and schedules mDNS searches.
config MDNS_NETWORKING_SOCKET
bool "Use BSD sockets for mDNS networking"
default n
help
Enables optional mDNS networking implementation using BSD sockets
in UDP multicast mode.
This option creates a new thread to serve receiving packets (TODO).
This option uses additional N sockets, where N is number of interfaces.
config MDNS_SKIP_SUPPRESSING_OWN_QUERIES
bool "Skip suppressing our own packets"
default n
help
Enable only if the querier and the responder share the same IP address.
This usually happens in test mode, where we may run multiple instances of
responders/queriers on the same interface.
config MDNS_ENABLE_DEBUG_PRINTS
bool "Enable debug prints of mDNS packets"
default n
help
Enable for the library to log received and sent mDNS packets to stdout.
config MDNS_ENABLE_CONSOLE_CLI
bool "Enable Command Line Interface on device console"
default y
help
Enable for the console cli to be available on the device.
config MDNS_RESPOND_REVERSE_QUERIES
bool "Enable responding to IPv4 reverse queries"
default n
help
Enables support for IPv4 reverse lookup. If enabled, the mDNS library
response to PTR queries of "A.B.C.D.in-addr.arpa" type.
config MDNS_MULTIPLE_INSTANCE
bool "Multiple instances under the same service type"
default y
help
Enables adding multiple service instances under the same service type.
menu "MDNS Predefined interfaces"
config MDNS_PREDEF_NETIF_STA
bool "Use predefined interface for WiFi Station"
default y
help
Set up mDNS for the default WiFi station.
Disable this option if you do not need mDNS on default WiFi STA.
config MDNS_PREDEF_NETIF_AP
bool "Use predefined interface for WiFi Access Point"
default y
help
Set up mDNS for the default WiFi Access Point.
Disable this option if you do not need mDNS on default WiFi AP.
config MDNS_PREDEF_NETIF_ETH
bool "Use predefined interface for Ethernet"
depends on ETH_ENABLED
default y
help
Set up mDNS for the default Ethernet interface.
Disable this option if you do not need mDNS on default Ethernet.
endmenu # MDNS Predefined interfaces
endmenu

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@@ -1,14 +0,0 @@
# mDNS Service
[![Component Registry](https://components.espressif.com/components/espressif/mdns/badge.svg)](https://components.espressif.com/components/espressif/mdns)
mDNS is a multicast UDP service that is used to provide local network service and host discovery.
## Examples
Get started with example test [Example](https://github.com/espressif/esp-protocols/tree/master/components/mdns/examples):
## Documentation
* View the full [documentation(English)](https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/en/index.html)
* View the full [documentation(Chinese)](https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/zh_CN/index.html)

View File

@@ -1,6 +0,0 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(query_advertise)

View File

@@ -1,91 +0,0 @@
# mDNS example
Shows how to use mDNS to advertise and query services and hosts
## Example workflow
- mDNS is initialized with host name and instance name defined through the project configuration and `_http._tcp` service is added to be advertised
- A delegated host `esp32-delegated._local` is added and another `_http._tcp` service is added for this host.
- WiFi STA is started and trying to connect to the access point defined through the project configuration
- The system event handler is used to pass the network events to mDNS so the service is aware when the interface comes up or down
- GPIO0 (BOOT Button) is initialized as pulled-up input that can be monitored for button press
- Example task is started to check if the button is pressed so it can execute the mDNS queries defined
### Configure the project
* Open the project configuration menu (`idf.py menuconfig`)
* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu
* Set `mDNS Hostname` as host name prefix for the device and its instance name in `mDNS Instance Name`
* Disable `Resolve test services` to prevent the example from querying defined names/services on startup (cause warnings in example logs, as illustrated below)
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT flash monitor
```
- Wait for WiFi to connect to your access point
- You can now ping the device at `[board-hostname].local`, where `[board-hostname]` is preconfigured hostname, `esp32-mdns` by default.
- You can also browse for `_http._tcp` on the same network to find the advertised service
- Pressing the BOOT button will start querying the local network for the predefined in `check_button` hosts and services
- Note that for purpose of CI tests, configuration options of `MDNS_RESOLVE_TEST_SERVICES` and `MDNS_ADD_MAC_TO_HOSTNAME` are available, but disabled by default. If enabled, then the hostname suffix of last 3 bytes from device MAC address is added, e.g. `esp32-mdns-80FFFF`, and a query for test service is issued.
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
```
I (0) cpu_start: Starting scheduler on APP CPU.
I (276) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (276) mdns-test: mdns hostname set to: [esp32-mdns]
I (286) wifi: wifi driver task: 3ffc2fa4, prio:23, stack:3584, core=0
I (286) wifi: wifi firmware version: a3be639
I (286) wifi: config NVS flash: enabled
I (296) wifi: config nano formating: disabled
I (296) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (306) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (336) wifi: Init dynamic tx buffer num: 32
I (336) wifi: Init data frame dynamic rx buffer num: 32
I (336) wifi: Init management frame dynamic rx buffer num: 32
I (346) wifi: Init static rx buffer size: 1600
I (346) wifi: Init static rx buffer num: 10
I (346) wifi: Init dynamic rx buffer num: 32
I (356) mdns-test: Setting WiFi configuration SSID myssid...
I (426) phy: phy_version: 4000, b6198fa, Sep 3 2018, 15:11:06, 0, 0
I (426) wifi: mode : sta (30:ae:a4:80:FF:FF)
I (426) gpio: GPIO[0]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0
I (1756) wifi: n:11 0, o:1 0, ap:255 255, sta:11 0, prof:1
I (2736) wifi: state: init -> auth (b0)
I (2756) wifi: state: auth -> assoc (0)
I (2766) wifi: state: assoc -> run (10)
I (2786) wifi: connected with myssid, channel 11
I (2786) wifi: pm start, type: 1
I (4786) event: sta ip: 192.168.0.139, mask: 255.255.255.0, gw: 192.168.0.2
I (21126) mdns-test: Query A: esp32.local
W (23176) mdns-test: ESP_ERR_NOT_FOUND: Host was not found!
I (23176) mdns-test: Query PTR: _arduino._tcp.local
W (26276) mdns-test: No results found!
I (26276) mdns-test: Query PTR: _http._tcp.local
1: Interface: STA, Type: V6
PTR : HP Color LaserJet MFP M277dw (7C2E10)
SRV : NPI7C2E10.local:80
A : 254.128.0.0
2: Interface: STA, Type: V4
PTR : switch4e4919
SRV : switch4e4919.local:80
TXT : [1] path=/config/authentication_page.htm;
A : 192.168.0.118
I (29396) mdns-test: Query PTR: _printer._tcp.local
1: Interface: STA, Type: V6
PTR : HP Color LaserJet MFP M277dw (7C2E10)
SRV : NPI7C2E10.local:515
A : 254.128.0.0
2: Interface: STA, Type: V4
PTR : HP Color LaserJet MFP M277dw (7C2E10)
```

View File

@@ -1,2 +0,0 @@
idf_component_register(SRCS "mdns_example_main.c"
INCLUDE_DIRS ".")

View File

@@ -1,55 +0,0 @@
menu "Example Configuration"
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
config MDNS_HOSTNAME
string "mDNS Hostname"
default "esp32-mdns"
help
mDNS Hostname for example to use
config MDNS_INSTANCE
string "mDNS Instance Name"
default "ESP32 with mDNS"
help
mDNS Instance Name for example to use
config MDNS_PUBLISH_DELEGATE_HOST
bool "Publish a delegated host"
help
Enable publishing a delegated host other than ESP32.
The example will also add a mock service for this host.
config MDNS_RESOLVE_TEST_SERVICES
bool "Resolve test services"
default n
help
Enable resolving test services on startup.
These services are advertized and evaluated in automated tests.
When executed locally, these will not be resolved and warnings appear in the log.
Please set to false to disable initial querying to avoid warnings.
config MDNS_ADD_MAC_TO_HOSTNAME
bool "Add mac suffix to hostname"
default n
help
If enabled, a portion of MAC address is added to the hostname, this is used
for evaluation of tests in CI
config MDNS_BUTTON_GPIO
int "Button GPIO to trigger querries"
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
default 0
help
Set the GPIO number used as mDNS test button
config MDNS_ADD_CUSTOM_NETIF
bool "Add user netif to mdns service"
default n
help
If enabled, we try to add a custom netif to mdns service.
Note that for using with common connection example code, we have to disable
all predefined interfaces in mdns component setup (since we're adding one
of the default interfaces)
endmenu

View File

@@ -1,6 +0,0 @@
dependencies:
espressif/mdns:
version: ^1.0.0
idf: '>=5.0'
protocol_examples_common:
path: ${IDF_PATH}/examples/common_components/protocol_examples_common

View File

@@ -1,423 +0,0 @@
/*
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/*
* MDNS-SD Query and advertise Example
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_netif_ip_addr.h"
#include "esp_mac.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "protocol_examples_common.h"
#include "mdns.h"
#include "driver/gpio.h"
#include "netdb.h"
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
/* CONFIG_LWIP_IPV4 was introduced in IDF v5.1, set CONFIG_LWIP_IPV4 to 1 by default for IDF v5.0 */
#ifndef CONFIG_LWIP_IPV4
#define CONFIG_LWIP_IPV4 1
#endif // CONFIG_LWIP_IPV4
#endif // ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 1, 0)
#define EXAMPLE_MDNS_INSTANCE CONFIG_MDNS_INSTANCE
#define EXAMPLE_BUTTON_GPIO CONFIG_MDNS_BUTTON_GPIO
static const char *TAG = "mdns-test";
static char *generate_hostname(void);
#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1
static void query_mdns_host_with_gethostbyname(char *host);
static void query_mdns_host_with_getaddrinfo(char *host);
#endif
static void initialise_mdns(void)
{
char *hostname = generate_hostname();
//initialize mDNS
ESP_ERROR_CHECK(mdns_init());
//set mDNS hostname (required if you want to advertise services)
ESP_ERROR_CHECK(mdns_hostname_set(hostname));
ESP_LOGI(TAG, "mdns hostname set to: [%s]", hostname);
//set default mDNS instance name
ESP_ERROR_CHECK(mdns_instance_name_set(EXAMPLE_MDNS_INSTANCE));
//structure with TXT records
mdns_txt_item_t serviceTxtData[3] = {
{"board", "esp32"},
{"u", "user"},
{"p", "password"}
};
//initialize service
ESP_ERROR_CHECK(mdns_service_add("ESP32-WebServer", "_http", "_tcp", 80, serviceTxtData, 3));
ESP_ERROR_CHECK(mdns_service_subtype_add_for_host("ESP32-WebServer", "_http", "_tcp", NULL, "_server"));
#if CONFIG_MDNS_MULTIPLE_INSTANCE
ESP_ERROR_CHECK(mdns_service_add("ESP32-WebServer1", "_http", "_tcp", 80, NULL, 0));
#endif
#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST
char *delegated_hostname;
if (-1 == asprintf(&delegated_hostname, "%s-delegated", hostname)) {
abort();
}
mdns_ip_addr_t addr4, addr6;
esp_netif_str_to_ip4("10.0.0.1", &addr4.addr.u_addr.ip4);
addr4.addr.type = ESP_IPADDR_TYPE_V4;
esp_netif_str_to_ip6("fd11:22::1", &addr6.addr.u_addr.ip6);
addr6.addr.type = ESP_IPADDR_TYPE_V6;
addr4.next = &addr6;
addr6.next = NULL;
ESP_ERROR_CHECK(mdns_delegate_hostname_add(delegated_hostname, &addr4));
ESP_ERROR_CHECK(mdns_service_add_for_host("test0", "_http", "_tcp", delegated_hostname, 1234, serviceTxtData, 3));
free(delegated_hostname);
#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST
//add another TXT item
ESP_ERROR_CHECK(mdns_service_txt_item_set("_http", "_tcp", "path", "/foobar"));
//change TXT item value
ESP_ERROR_CHECK(mdns_service_txt_item_set_with_explicit_value_len("_http", "_tcp", "u", "admin", strlen("admin")));
free(hostname);
}
/* these strings match mdns_ip_protocol_t enumeration */
static const char *ip_protocol_str[] = {"V4", "V6", "MAX"};
static void mdns_print_results(mdns_result_t *results)
{
mdns_result_t *r = results;
mdns_ip_addr_t *a = NULL;
int i = 1, t;
while (r) {
if (r->esp_netif) {
printf("%d: Interface: %s, Type: %s, TTL: %" PRIu32 "\n", i++, esp_netif_get_ifkey(r->esp_netif),
ip_protocol_str[r->ip_protocol], r->ttl);
}
if (r->instance_name) {
printf(" PTR : %s.%s.%s\n", r->instance_name, r->service_type, r->proto);
}
if (r->hostname) {
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
}
if (r->txt_count) {
printf(" TXT : [%zu] ", r->txt_count);
for (t = 0; t < r->txt_count; t++) {
printf("%s=%s(%d); ", r->txt[t].key, r->txt[t].value ? r->txt[t].value : "NULL", r->txt_value_len[t]);
}
printf("\n");
}
a = r->addr;
while (a) {
if (a->addr.type == ESP_IPADDR_TYPE_V6) {
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
} else {
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
}
a = a->next;
}
r = r->next;
}
}
static void query_mdns_service(const char *service_name, const char *proto)
{
ESP_LOGI(TAG, "Query PTR: %s.%s.local", service_name, proto);
mdns_result_t *results = NULL;
esp_err_t err = mdns_query_ptr(service_name, proto, 3000, 20, &results);
if (err) {
ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
return;
}
if (!results) {
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST
static void lookup_mdns_delegated_service(const char *service_name, const char *proto)
{
ESP_LOGI(TAG, "Lookup delegated service: %s.%s.local", service_name, proto);
mdns_result_t *results = NULL;
esp_err_t err = mdns_lookup_delegated_service(NULL, service_name, proto, 20, &results);
if (err) {
ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err));
return;
}
if (!results) {
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST
static void lookup_mdns_selfhosted_service(const char *service_name, const char *proto)
{
ESP_LOGI(TAG, "Lookup selfhosted service: %s.%s.local", service_name, proto);
mdns_result_t *results = NULL;
esp_err_t err = mdns_lookup_selfhosted_service(NULL, service_name, proto, 20, &results);
if (err) {
ESP_LOGE(TAG, "Lookup Failed: %s", esp_err_to_name(err));
return;
}
if (!results) {
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
static bool check_and_print_result(mdns_search_once_t *search)
{
// Check if any result is available
mdns_result_t *result = NULL;
if (!mdns_query_async_get_results(search, 0, &result, NULL)) {
return false;
}
if (!result) { // search timeout, but no result
return true;
}
// If yes, print the result
mdns_ip_addr_t *a = result->addr;
while (a) {
if (a->addr.type == ESP_IPADDR_TYPE_V6) {
printf(" AAAA: " IPV6STR "\n", IPV62STR(a->addr.u_addr.ip6));
} else {
printf(" A : " IPSTR "\n", IP2STR(&(a->addr.u_addr.ip4)));
}
a = a->next;
}
// and free the result
mdns_query_results_free(result);
return true;
}
static void query_mdns_hosts_async(const char *host_name)
{
ESP_LOGI(TAG, "Query both A and AAA: %s.local", host_name);
mdns_search_once_t *s_a = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_A, 1000, 1, NULL);
mdns_search_once_t *s_aaaa = mdns_query_async_new(host_name, NULL, NULL, MDNS_TYPE_AAAA, 1000, 1, NULL);
while (s_a || s_aaaa) {
if (s_a && check_and_print_result(s_a)) {
ESP_LOGI(TAG, "Query A %s.local finished", host_name);
mdns_query_async_delete(s_a);
s_a = NULL;
}
if (s_aaaa && check_and_print_result(s_aaaa)) {
ESP_LOGI(TAG, "Query AAAA %s.local finished", host_name);
mdns_query_async_delete(s_aaaa);
s_aaaa = NULL;
}
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
#ifdef CONFIG_LWIP_IPV4
static void query_mdns_host(const char *host_name)
{
ESP_LOGI(TAG, "Query A: %s.local", host_name);
struct esp_ip4_addr addr;
addr.addr = 0;
esp_err_t err = mdns_query_a(host_name, 2000, &addr);
if (err) {
if (err == ESP_ERR_NOT_FOUND) {
ESP_LOGW(TAG, "%s: Host was not found!", esp_err_to_name(err));
return;
}
ESP_LOGE(TAG, "Query Failed: %s", esp_err_to_name(err));
return;
}
ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
}
#endif // CONFIG_LWIP_IPV4
static void initialise_button(void)
{
gpio_config_t io_conf = {0};
io_conf.intr_type = GPIO_INTR_DISABLE;
io_conf.pin_bit_mask = BIT64(EXAMPLE_BUTTON_GPIO);
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
io_conf.pull_down_en = 0;
gpio_config(&io_conf);
}
static void check_button(void)
{
static bool old_level = true;
bool new_level = gpio_get_level(EXAMPLE_BUTTON_GPIO);
if (!new_level && old_level) {
query_mdns_hosts_async("esp32-mdns");
#ifdef CONFIG_LWIP_IPV4
query_mdns_host("esp32");
#endif
query_mdns_service("_arduino", "_tcp");
query_mdns_service("_http", "_tcp");
query_mdns_service("_printer", "_tcp");
query_mdns_service("_ipp", "_tcp");
query_mdns_service("_afpovertcp", "_tcp");
query_mdns_service("_smb", "_tcp");
query_mdns_service("_ftp", "_tcp");
query_mdns_service("_nfs", "_tcp");
#if CONFIG_MDNS_PUBLISH_DELEGATE_HOST
lookup_mdns_delegated_service("_http", "_tcp");
#endif // CONFIG_MDNS_PUBLISH_DELEGATE_HOST
lookup_mdns_selfhosted_service("_http", "_tcp");
}
old_level = new_level;
}
static void mdns_example_task(void *pvParameters)
{
#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1
/* Send initial queries that are started by CI tester */
#ifdef CONFIG_LWIP_IPV4
query_mdns_host("tinytester");
#endif
query_mdns_host_with_gethostbyname("tinytester-lwip.local");
query_mdns_host_with_getaddrinfo("tinytester-lwip.local");
#endif
while (1) {
check_button();
vTaskDelay(50 / portTICK_PERIOD_MS);
}
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_LOGI(TAG, "mDNS Ver: %s", ESP_MDNS_VERSION_NUMBER);
initialise_mdns();
/* 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());
#if defined(CONFIG_MDNS_ADD_CUSTOM_NETIF) && !defined(CONFIG_MDNS_PREDEF_NETIF_STA) && !defined(CONFIG_MDNS_PREDEF_NETIF_ETH)
/* Demonstration of adding a custom netif to mdns service, but we're adding the default example one,
* so we must disable all predefined interfaces (PREDEF_NETIF_STA, AP and ETH) first
*/
ESP_ERROR_CHECK(mdns_register_netif(EXAMPLE_INTERFACE));
/* It is not enough to just register the interface, we have to enable is manually.
* This is typically performed in "GOT_IP" event handler, but we call it here directly
* since the `EXAMPLE_INTERFACE` netif is connected already, to keep the example simple.
*/
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_ENABLE_IP6));
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4 | MDNS_EVENT_ANNOUNCE_IP6));
#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP));
#endif
#endif // CONFIG_MDNS_ADD_CUSTOM_NETIF
initialise_button();
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
}
/** Generate host name based on sdkconfig, optionally adding a portion of MAC address to it.
* @return host name string allocated from the heap
*/
static char *generate_hostname(void)
{
#ifndef CONFIG_MDNS_ADD_MAC_TO_HOSTNAME
return strdup(CONFIG_MDNS_HOSTNAME);
#else
uint8_t mac[6];
char *hostname;
esp_read_mac(mac, ESP_MAC_WIFI_STA);
if (-1 == asprintf(&hostname, "%s-%02X%02X%02X", CONFIG_MDNS_HOSTNAME, mac[3], mac[4], mac[5])) {
abort();
}
return hostname;
#endif
}
#if CONFIG_MDNS_RESOLVE_TEST_SERVICES == 1
/**
* @brief Executes gethostbyname and displays list of resolved addresses.
* Note: This function is used only to test advertised mdns hostnames resolution
*/
static void query_mdns_host_with_gethostbyname(char *host)
{
struct hostent *res = gethostbyname(host);
if (res) {
unsigned int i = 0;
while (res->h_addr_list[i] != NULL) {
ESP_LOGI(TAG, "gethostbyname: %s resolved to: %s", host,
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4)
res->h_addrtype == AF_INET ? inet_ntoa(*(struct in_addr *)(res->h_addr_list[i])) :
inet6_ntoa(*(struct in6_addr *)(res->h_addr_list[i]))
#elif defined(CONFIG_LWIP_IPV6)
inet6_ntoa(*(struct in6_addr *)(res->h_addr_list[i]))
#else
inet_ntoa(*(struct in_addr *)(res->h_addr_list[i]))
#endif
);
i++;
}
}
}
/**
* @brief Executes getaddrinfo and displays list of resolved addresses.
* Note: This function is used only to test advertised mdns hostnames resolution
*/
static void query_mdns_host_with_getaddrinfo(char *host)
{
struct addrinfo hints;
struct addrinfo *res;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (!getaddrinfo(host, NULL, &hints, &res)) {
while (res) {
char *resolved_addr;
#if defined(CONFIG_LWIP_IPV6) && defined(CONFIG_LWIP_IPV4)
resolved_addr = res->ai_family == AF_INET ?
inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr) :
inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
#elif defined(CONFIG_LWIP_IPV6)
resolved_addr = inet6_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr);
#else
resolved_addr = inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr);
#endif // CONFIG_LWIP_IPV6
ESP_LOGI(TAG, "getaddrinfo: %s resolved to: %s", host, resolved_addr);
res = res->ai_next;
}
}
}
#endif

View File

@@ -1,203 +0,0 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import re
import select
import socket
import struct
import subprocess
import time
from threading import Event, Thread
try:
import dpkt
import dpkt.dns
except ImportError:
pass
def get_dns_query_for_esp(esp_host):
dns = dpkt.dns.DNS(
b'\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x01'
)
dns.qd[0].name = esp_host + u'.local'
print('Created query for esp host: {} '.format(dns.__repr__()))
return dns.pack()
def get_dns_answer_to_mdns(tester_host):
dns = dpkt.dns.DNS(
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
)
dns.op = dpkt.dns.DNS_QR | dpkt.dns.DNS_AA
dns.rcode = dpkt.dns.DNS_RCODE_NOERR
arr = dpkt.dns.DNS.RR()
arr.cls = dpkt.dns.DNS_IN
arr.type = dpkt.dns.DNS_A
arr.name = tester_host
arr.ip = socket.inet_aton('127.0.0.1')
dns.an.append(arr)
print('Created answer to mdns query: {} '.format(dns.__repr__()))
return dns.pack()
def get_dns_answer_to_mdns_lwip(tester_host, id):
dns = dpkt.dns.DNS(
b'\x5e\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x0a\x64\x61\x76\x69\x64'
b'\x2d\x63\x6f\x6d\x70\x05\x6c\x6f\x63\x61\x6c\x00\x00\x01\x00\x01\xc0\x0c'
b'\x00\x01\x00\x01\x00\x00\x00\x0a\x00\x04\xc0\xa8\x0a\x6c')
dns.qd[0].name = tester_host
dns.an[0].name = tester_host
dns.an[0].ip = socket.inet_aton('127.0.0.1')
dns.an[0].rdata = socket.inet_aton('127.0.0.1')
dns.id = id
print('Created answer to mdns (lwip) query: {} '.format(dns.__repr__()))
return dns.pack()
def mdns_server(esp_host, events):
UDP_IP = '0.0.0.0'
UDP_PORT = 5353
MCAST_GRP = '224.0.0.251'
TESTER_NAME = u'tinytester.local'
TESTER_NAME_LWIP = u'tinytester-lwip.local'
QUERY_TIMEOUT = 0.2
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
sock.setblocking(False)
sock.bind((UDP_IP, UDP_PORT))
mreq = struct.pack('4sl', socket.inet_aton(MCAST_GRP), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
last_query_timepoint = time.time()
while not events['stop'].is_set():
try:
current_time = time.time()
if current_time - last_query_timepoint > QUERY_TIMEOUT:
last_query_timepoint = current_time
if not events['esp_answered'].is_set():
sock.sendto(get_dns_query_for_esp(esp_host),
(MCAST_GRP, UDP_PORT))
if not events['esp_delegated_answered'].is_set():
sock.sendto(get_dns_query_for_esp(esp_host + '-delegated'),
(MCAST_GRP, UDP_PORT))
timeout = max(
0, QUERY_TIMEOUT - (current_time - last_query_timepoint))
read_socks, _, _ = select.select([sock], [], [], timeout)
if not read_socks:
continue
data, addr = sock.recvfrom(1024)
dns = dpkt.dns.DNS(data)
if len(dns.qd) > 0:
for dns_query in dns.qd:
if dns_query.type == dpkt.dns.DNS_A:
if dns_query.name == TESTER_NAME:
print('Received query: {} '.format(dns.__repr__()))
sock.sendto(get_dns_answer_to_mdns(TESTER_NAME),
(MCAST_GRP, UDP_PORT))
elif dns_query.name == TESTER_NAME_LWIP:
print('Received query: {} '.format(dns.__repr__()))
sock.sendto(
get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id),
addr)
if len(dns.an) > 0:
for dns_answer in dns.an:
if dns_answer.type == dpkt.dns.DNS_A:
print('Received answer from {}'.format(dns_answer.name))
if dns_answer.name == esp_host + u'.local':
print('Received answer to esp32-mdns query: {}'.format(
dns.__repr__()))
events['esp_answered'].set()
if dns_answer.name == esp_host + u'-delegated.local':
print('Received answer to esp32-mdns-delegate query: {}'.format(
dns.__repr__()))
events['esp_delegated_answered'].set()
except socket.timeout:
break
except dpkt.UnpackError:
continue
def test_examples_protocol_mdns(dut):
"""
steps: |
1. obtain IP address + init mdns example
2. get the dut host name (and IP address)
3. check the mdns name is accessible
4. check DUT output if mdns advertized host is resolved
5. check if DUT responds to dig
6. check the DUT is searchable via reverse IP lookup
"""
specific_host = dut.expect(r'mdns hostname set to: \[(.*?)\]')[1].decode()
mdns_server_events = {
'stop': Event(),
'esp_answered': Event(),
'esp_delegated_answered': Event()
}
mdns_responder = Thread(target=mdns_server,
args=(str(specific_host), mdns_server_events))
ip_addresses = []
if dut.app.sdkconfig.get('LWIP_IPV4') is True:
ipv4 = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]',
timeout=30)[1].decode()
ip_addresses.append(ipv4)
if dut.app.sdkconfig.get('LWIP_IPV6') is True:
ipv6_r = r':'.join((r'[0-9a-fA-F]{4}', ) * 8)
ipv6 = dut.expect(ipv6_r, timeout=30)[0].decode()
ip_addresses.append(ipv6)
print('Connected with IP addresses: {}'.format(','.join(ip_addresses)))
try:
# TODO: Add test for example disabling IPV4
mdns_responder.start()
if dut.app.sdkconfig.get('LWIP_IPV4') is True:
# 3. check the mdns name is accessible.
if not mdns_server_events['esp_answered'].wait(timeout=30):
raise ValueError(
'Test has failed: did not receive mdns answer within timeout')
if not mdns_server_events['esp_delegated_answered'].wait(timeout=30):
raise ValueError(
'Test has failed: did not receive mdns answer for delegated host within timeout'
)
# 4. check DUT output if mdns advertized host is resolved
dut.expect(
re.compile(
b'mdns-test: Query A: tinytester.local resolved to: 127.0.0.1')
)
dut.expect(
re.compile(
b'mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1'
))
dut.expect(
re.compile(
b'mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1'
))
# 5. check the DUT answers to `dig` command
dig_output = subprocess.check_output([
'dig', '+short', '-p', '5353', '@224.0.0.251',
'{}.local'.format(specific_host)
])
print('Resolving {} using "dig" succeeded with:\n{}'.format(
specific_host, dig_output))
if not ipv4.encode('utf-8') in dig_output:
raise ValueError(
'Test has failed: Incorrectly resolved DUT hostname using dig'
"Output should've contained DUT's IP address:{}".format(ipv4))
# 6. check the DUT reverse lookup
if dut.app.sdkconfig.get('MDNS_RESPOND_REVERSE_QUERIES') is True:
for ip_address in ip_addresses:
dig_output = subprocess.check_output([
'dig', '+short', '-p', '5353', '@224.0.0.251', '-x',
'{}'.format(ip_address)
])
print('Reverse lookup for {} using "dig" succeeded with:\n{}'.
format(ip_address, dig_output))
if specific_host not in dig_output.decode():
raise ValueError(
'Test has failed: Incorrectly resolved DUT IP address using dig'
"Output should've contained DUT's name:{}".format(
specific_host))
finally:
mdns_server_events['stop'].set()
mdns_responder.join()

View File

@@ -1,21 +0,0 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
CONFIG_MDNS_PREDEF_NETIF_STA=n
CONFIG_MDNS_PREDEF_NETIF_AP=n
CONFIG_MDNS_PREDEF_NETIF_ETH=n
CONFIG_MDNS_ADD_CUSTOM_NETIF=y
CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_PHY_GENERIC=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=y
CONFIG_MDNS_BUTTON_GPIO=32

View File

@@ -1,15 +0,0 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=y
CONFIG_MDNS_BUTTON_GPIO=32

View File

@@ -1,15 +0,0 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
CONFIG_LWIP_IPV4=n
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_MDNS_BUTTON_GPIO=32

View File

@@ -1,16 +0,0 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
CONFIG_LWIP_IPV6=n
CONFIG_EXAMPLE_CONNECT_IPV6=n
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_MDNS_BUTTON_GPIO=32

View File

@@ -1,16 +0,0 @@
CONFIG_IDF_TARGET="esp32"
CONFIG_MDNS_RESOLVE_TEST_SERVICES=y
CONFIG_MDNS_ADD_MAC_TO_HOSTNAME=y
CONFIG_MDNS_PUBLISH_DELEGATE_HOST=y
CONFIG_MDNS_NETWORKING_SOCKET=y
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y
CONFIG_EXAMPLE_ETH_PHY_IP101=y
CONFIG_EXAMPLE_ETH_MDC_GPIO=23
CONFIG_EXAMPLE_ETH_MDIO_GPIO=18
CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5
CONFIG_EXAMPLE_ETH_PHY_ADDR=1
CONFIG_EXAMPLE_CONNECT_IPV6=y
CONFIG_MDNS_BUTTON_GPIO=32

View File

@@ -1,13 +0,0 @@
dependencies:
idf:
version: '>=5.0'
description: Multicast UDP service used to provide local network service and host
discovery.
documentation: https://docs.espressif.com/projects/esp-protocols/mdns/docs/latest/en/index.html
issues: https://github.com/espressif/esp-protocols/issues
repository: git://github.com/espressif/esp-protocols.git
repository_info:
commit_sha: 3bfa00389de6f0d6d40efda8bea808380899a43d
path: components/mdns
url: https://github.com/espressif/esp-protocols/tree/master/components/mdns
version: 1.9.1

View File

@@ -1,937 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ESP_MDNS_H_
#define ESP_MDNS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "sdkconfig.h"
#include <esp_netif.h>
#define MDNS_TYPE_A 0x0001
#define MDNS_TYPE_PTR 0x000C
#define MDNS_TYPE_TXT 0x0010
#define MDNS_TYPE_AAAA 0x001C
#define MDNS_TYPE_SRV 0x0021
#define MDNS_TYPE_OPT 0x0029
#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
*/
typedef struct mdns_search_once_s mdns_search_once_t;
/**
* @brief Daemon query handle
*/
typedef struct mdns_browse_s mdns_browse_t;
typedef enum {
MDNS_EVENT_ENABLE_IP4 = 1 << 1,
MDNS_EVENT_ENABLE_IP6 = 1 << 2,
MDNS_EVENT_ANNOUNCE_IP4 = 1 << 3,
MDNS_EVENT_ANNOUNCE_IP6 = 1 << 4,
MDNS_EVENT_DISABLE_IP4 = 1 << 5,
MDNS_EVENT_DISABLE_IP6 = 1 << 6,
MDNS_EVENT_IP4_REVERSE_LOOKUP = 1 << 7,
MDNS_EVENT_IP6_REVERSE_LOOKUP = 1 << 8,
} mdns_event_actions_t;
/**
* @brief mDNS enum to specify the ip_protocol type
*/
typedef enum {
MDNS_IP_PROTOCOL_V4,
MDNS_IP_PROTOCOL_V6,
MDNS_IP_PROTOCOL_MAX
} mdns_ip_protocol_t;
/**
* @brief mDNS basic text item structure
* Used in mdns_service_add()
*/
typedef struct {
const char *key; /*!< item key name */
const char *value; /*!< item value string */
} mdns_txt_item_t;
/**
* @brief mDNS basic subtype item structure
* Used in mdns_service_subtype_xxx() APIs
*/
typedef struct {
const char *subtype; /*!< subtype name */
} mdns_subtype_item_t;
/**
* @brief mDNS query linked list IP item
*/
typedef struct mdns_ip_addr_s {
esp_ip_addr_t addr; /*!< IP address */
struct mdns_ip_addr_s *next; /*!< next IP, or NULL for the last IP in the list */
} mdns_ip_addr_t;
/**
* @brief mDNS query type to be explicitly set to either Unicast or Multicast
*/
typedef enum {
MDNS_QUERY_UNICAST,
MDNS_QUERY_MULTICAST,
} mdns_query_transmission_type_t;
/**
* @brief mDNS query result structure
*/
typedef struct mdns_result_s {
struct mdns_result_s *next; /*!< next result, or NULL for the last result in the list */
esp_netif_t *esp_netif; /*!< ptr to corresponding esp-netif */
uint32_t ttl; /*!< time to live */
mdns_ip_protocol_t ip_protocol; /*!< ip_protocol type of the interface (v4/v6) */
// PTR
char *instance_name; /*!< instance name */
char *service_type; /*!< service type */
char *proto; /*!< srevice protocol */
// SRV
char *hostname; /*!< hostname */
uint16_t port; /*!< service port */
// TXT
mdns_txt_item_t *txt; /*!< txt record */
uint8_t *txt_value_len; /*!< array of txt value len of each record */
size_t txt_count; /*!< number of txt items */
// A and AAAA
mdns_ip_addr_t *addr; /*!< linked list of IP addresses found */
} mdns_result_t;
typedef void (*mdns_query_notify_t)(mdns_search_once_t *search);
typedef void (*mdns_browse_notify_t)(mdns_result_t *result);
/**
* @brief Initialize mDNS on given interface
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE when failed to register event handler
* - ESP_ERR_NO_MEM on memory error
* - ESP_FAIL when failed to start mdns task
*/
esp_err_t mdns_init(void);
/**
* @brief Stop and free mDNS server
*
*/
void mdns_free(void);
/**
* @brief Set the hostname for mDNS server
* required if you want to advertise services
*
* @param hostname Hostname to set
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_hostname_set(const char *hostname);
/**
* @brief Get the hostname for mDNS server
*
* @param hostname pointer to the hostname, it should be allocated
* and hold at least MDNS_NAME_BUF_LEN chars
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_INVALID_STATE when mdns is not initialized
*/
esp_err_t mdns_hostname_get(char *hostname);
/**
* @brief Adds a hostname and address to be delegated
* A/AAAA queries will be replied for the hostname and
* services can be added to this host.
*
* @param hostname Hostname to add
* @param address_list The IP address list of the host
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*
*/
esp_err_t mdns_delegate_hostname_add(const char *hostname, const mdns_ip_addr_t *address_list);
/**
* @brief Set the address to a delegated hostname
*
* @param hostname Hostname to set
* @param address_list The IP address list of the host
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*
*/
esp_err_t mdns_delegate_hostname_set_address(const char *hostname, const mdns_ip_addr_t *address_list);
/**
* @brief Remove a delegated hostname
* All the services added to this host will also be removed.
*
* @param hostname Hostname to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*
*/
esp_err_t mdns_delegate_hostname_remove(const char *hostname);
/**
* @brief Query whether a hostname has been added
*
* @param hostname Hostname to query
*
* @return
* - true The hostname has been added.
* - false The hostname has not been added.
*
*/
bool mdns_hostname_exists(const char *hostname);
/**
* @brief Set the default instance name for mDNS server
*
* @param instance_name Instance name to set
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_instance_name_set(const char *instance_name);
/**
* @brief Add service to mDNS server
*
* @note The value length of txt items will be automatically decided by strlen
*
* @param instance_name instance name to set. If NULL,
* global instance name or hostname will be used.
* Note that MDNS_MULTIPLE_INSTANCE config option
* needs to be enabled for adding multiple instances
* with the same instance type.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param port service port
* @param txt string array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
* - ESP_FAIL failed to add service
*/
esp_err_t mdns_service_add(const char *instance_name, const char *service_type, const char *proto, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
/**
* @brief Add service to mDNS server with a delegated hostname
*
* @note The value length of txt items will be automatically decided by strlen
*
* @param instance_name instance name to set. If NULL,
* global instance name or hostname will be used
* Note that MDNS_MULTIPLE_INSTANCE config option
* needs to be enabled for adding multiple instances
* with the same instance type.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param port service port
* @param txt string array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NO_MEM memory error
* - ESP_FAIL failed to add service
*/
esp_err_t mdns_service_add_for_host(const char *instance_name, const char *service_type, const char *proto,
const char *hostname, uint16_t port, mdns_txt_item_t txt[], size_t num_items);
/**
* @brief Check whether a service has been added.
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, checks for the local hostname.
*
* @return
* - true Correspondding service has been added.
* - false Service not found.
*/
bool mdns_service_exists(const char *service_type, const char *proto, const char *hostname);
/**
* @brief Check whether a service has been added.
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, checks for the local hostname.
*
* @return
* - true Correspondding service has been added.
* - false Service not found.
*/
bool mdns_service_exists_with_instance(const char *instance, const char *service_type, const char *proto,
const char *hostname);
/**
* @brief Remove service from mDNS server
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_remove(const char *service_type, const char *proto);
/**
* @brief Remove service from mDNS server with hostname
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_remove_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname);
/**
* @brief Set instance name for service
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param instance_name instance name to set
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_instance_name_set(const char *service_type, const char *proto, const char *instance_name);
/**
* @brief Set instance name for service with hostname
*
* @param instance_old original instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param instance_name instance name to set
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_instance_name_set_for_host(const char *instance_old, const char *service_type, const char *proto, const char *hostname,
const char *instance_name);
/**
* @brief Set service port
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param port service port
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_port_set(const char *service_type, const char *proto, uint16_t port);
/**
* @brief Set service port with hostname
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param port service port
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_port_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname,
uint16_t port);
/**
* @brief Replace all TXT items for service
*
* @note The value length of txt items will be automatically decided by strlen
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_set(const char *service_type, const char *proto, mdns_txt_item_t txt[], uint8_t num_items);
/**
* @brief Replace all TXT items for service with hostname
*
* @note The value length of txt items will be automatically decided by strlen
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param txt array of TXT data (eg. {{"var","val"},{"other","2"}})
* @param num_items number of items in TXT data
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname,
mdns_txt_item_t txt[], uint8_t num_items);
/**
* @brief Set/Add TXT item for service TXT record
*
* @note The value length will be automatically decided by strlen
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update
* @param value the new value of the key
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set(const char *service_type, const char *proto, const char *key, const char *value);
/**
* @brief Set/Add TXT item for service TXT record
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to add/update
* @param value the new value of the key
* @param value_len the length of the value
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set_with_explicit_value_len(const char *service_type, const char *proto,
const char *key, const char *value, uint8_t value_len);
/**
* @brief Set/Add TXT item for service TXT record with hostname
*
* @note The value length will be automatically decided by strlen
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param key the key that you want to add/update
* @param value the new value of the key
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname,
const char *key, const char *value);
/**
* @brief Set/Add TXT item for service TXT record with hostname and txt value length
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param key the key that you want to add/update
* @param value the new value of the key
* @param value_len the length of the value
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_set_for_host_with_explicit_value_len(const char *instance, const char *service_type, const char *proto,
const char *hostname, const char *key,
const char *value, uint8_t value_len);
/**
* @brief Remove TXT item for service TXT record
*
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param key the key that you want to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_remove(const char *service_type, const char *proto, const char *key);
/**
* @brief Remove TXT item for service TXT record with hostname
*
* @param instance instance name
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param key the key that you want to remove
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_txt_item_remove_for_host(const char *instance, const char *service_type, const char *proto, const char *hostname,
const char *key);
/**
* @brief Add a subtype for service.
*
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param subtype The subtype to add.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_subtype_add_for_host(const char *instance_name, const char *service_type, const char *proto,
const char *hostname, const char *subtype);
/**
* @brief Remove a subtype for service.
*
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param subtype The subtype to remove.
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
*/
esp_err_t mdns_service_subtype_remove_for_host(const char *instance_name, const char *service_type, const char *proto,
const char *hostname, const char *subtype);
/**
* @brief Add multiple subtypes for service at once.
*
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @param subtype the pointer of subtype array to add.
* @param num_items number of items in subtype array
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_service_subtype_add_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);
/**
* @brief Update subtype for service.
*
* @param instance_name instance name. If NULL, will find the first service with the same service type and protocol.
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param hostname service hostname. If NULL, local hostname will be used.
* @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
* - ESP_ERR_NOT_FOUND Service not found
* - ESP_ERR_NO_MEM memory error
*/
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);
/**
* @brief Remove and free all services from mDNS server
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t mdns_service_remove_all(void);
/**
* @brief Deletes the finished query. Call this only after the search has ended!
*
* @param search pointer to search object
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE search has not finished
* - ESP_ERR_INVALID_ARG pointer to search object is NULL
*/
esp_err_t mdns_query_async_delete(mdns_search_once_t *search);
/**
* @brief Get results from search pointer. Results available as a pointer to the output parameter.
* Pointer to search object has to be deleted via `mdns_query_async_delete` once the query has finished.
* The results although have to be freed manually.
*
* @param search pointer to search object
* @param timeout time in milliseconds to wait for answers
* @param results pointer to the results of the query
* @param num_results pointer to the number of the actual result items (set to NULL to ignore this return value)
*
* @return
* True if search has finished before or at timeout
* False if search timeout is over
*/
bool mdns_query_async_get_results(mdns_search_once_t *search, uint32_t timeout, mdns_result_t **results, uint8_t *num_results);
/**
* @brief Query mDNS for host or service asynchronousely.
* Search has to be tested for progress and deleted manually!
*
* @param name service instance or host name (NULL for PTR queries)
* @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries)
* @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries)
* @param type type of query (MDNS_TYPE_*)
* @param timeout time in milliseconds during which mDNS query is active
* @param max_results maximum results to be collected
* @param notifier Notification function to be called when the result is ready, can be NULL
*
* @return mdns_search_once_s pointer to new search object if query initiated successfully.
* NULL otherwise.
*/
mdns_search_once_t *mdns_query_async_new(const char *name, const char *service_type, const char *proto, uint16_t type,
uint32_t timeout, size_t max_results, mdns_query_notify_t notifier);
/**
* @brief Generic mDNS query
* All following query methods are derived from this one
*
* @param name service instance or host name (NULL for PTR queries)
* @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries)
* @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries)
* @param type type of query (MDNS_TYPE_*)
* @param transmission_type either Unicast query, or Multicast query
* @param timeout time in milliseconds to wait for answers.
* @param max_results maximum results to be collected
* @param results pointer to the results of the query
* results must be freed using mdns_query_results_free below
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG timeout was not given
*/
esp_err_t mdns_query_generic(const char *name, const char *service_type, const char *proto, uint16_t type,
mdns_query_transmission_type_t transmission_type, uint32_t timeout, size_t max_results, mdns_result_t **results);
/**
* @brief Query mDNS for host or service
*
* Note that querying PTR types sends Multicast query, all other types send Unicast queries
*
* @param name service instance or host name (NULL for PTR queries)
* @param service_type service type (_http, _arduino, _ftp etc.) (NULL for host queries)
* @param proto service protocol (_tcp, _udp, etc.) (NULL for host queries)
* @param type type of query (MDNS_TYPE_*)
* @param timeout time in milliseconds to wait for answers.
* @param max_results maximum results to be collected
* @param results pointer to the results of the query
* results must be freed using mdns_query_results_free below
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG timeout was not given
*/
esp_err_t mdns_query(const char *name, const char *service_type, const char *proto, uint16_t type, uint32_t timeout, size_t max_results, mdns_result_t **results);
/**
* @brief Free query results
*
* @param results linked list of results to be freed
*/
void mdns_query_results_free(mdns_result_t *results);
/**
* @brief Query mDNS for service
*
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param max_results maximum results to be collected
* @param results pointer to the results of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_ptr(const char *service_type, const char *proto, uint32_t timeout, size_t max_results, mdns_result_t **results);
/**
* @brief Query mDNS for SRV record
*
* @param instance_name service instance name
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param result pointer to the result of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_srv(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result);
/**
* @brief Query mDNS for TXT record
*
* @param instance_name service instance name
* @param service_type service type (_http, _arduino, _ftp etc.)
* @param proto service protocol (_tcp, _udp, etc.)
* @param timeout time in milliseconds to wait for answer.
* @param result pointer to the result of the query
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_txt(const char *instance_name, const char *service_type, const char *proto, uint32_t timeout, mdns_result_t **result);
/**
* @brief Look up delegated services.
*
* @param instance instance name (NULL for uncertain instance)
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param max_results maximum results to be collected
* @param result pointer to the result of the search
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_lookup_delegated_service(const char *instance, const char *service_type, const char *proto, size_t max_results,
mdns_result_t **result);
/**
* @brief Look up self hosted services.
*
* @param instance instance name (NULL for uncertain instance)
* @param service_type service type (_http, _ftp, etc)
* @param proto service protocol (_tcp, _udp)
* @param max_results maximum results to be collected
* @param result pointer to the result of the search
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_lookup_selfhosted_service(const char *instance, const char *service_type, const char *proto, size_t max_results,
mdns_result_t **result);
/**
* @brief Query mDNS for A record
*
* @param host_name host name to look for
* @param timeout time in milliseconds to wait for answer.
* @param addr pointer to the resulting IP4 address
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_a(const char *host_name, uint32_t timeout, esp_ip4_addr_t *addr);
#if CONFIG_LWIP_IPV6
/**
* @brief Query mDNS for A record
*
* Please note that hostname must not contain domain name, as mDNS uses '.local' domain.
*
* @param host_name host name to look for
* @param timeout time in milliseconds to wait for answer. If 0, max_results needs to be defined
* @param addr pointer to the resulting IP6 address
*
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NO_MEM memory error
* - ESP_ERR_INVALID_ARG parameter error
*/
esp_err_t mdns_query_aaaa(const char *host_name, uint32_t timeout, esp_ip6_addr_t *addr);
#endif
/**
* @brief Register custom esp_netif with mDNS functionality
* mDNS service runs by default on preconfigured interfaces (STA, AP, ETH).
* This API enables running the service on any customized interface,
* either using standard WiFi or Ethernet driver or any kind of user defined driver.
*
* @param esp_netif Pointer to esp-netif interface
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running or this netif is already registered
* - ESP_ERR_NO_MEM not enough memory for this in interface in the netif list (see CONFIG_MDNS_MAX_INTERFACES)
*/
esp_err_t mdns_register_netif(esp_netif_t *esp_netif);
/**
* @brief Unregister esp-netif already registered in mDNS service
*
* @param esp_netif Pointer to esp-netif interface
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running
* - ESP_ERR_NOT_FOUND this esp-netif was not registered in mDNS service
*/
esp_err_t mdns_unregister_netif(esp_netif_t *esp_netif);
/**
* @brief Set esp_netif to a desired state, or perform a desired action, such as enable/disable this interface
* or send announcement packets to this netif
*
* * This function is used to enable (probe, resolve conflicts and announce), announce, or disable (send bye) mDNS
* services on the specified network interface.
* * This function must be called if users registers a specific interface using mdns_register_netif()
* to enable mDNS services on that interface.
* * This function could be used in IP/connection event handlers to automatically enable/announce mDNS services
* when network properties change and/or disable them on disconnection.
*
* @param esp_netif Pointer to esp-netif interface
* @param event_action Disable/Enable/Announce on this interface over IPv4/IPv6 protocol.
* Actions enumerated in mdns_event_actions_t type.
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_STATE mDNS is not running or this netif is not registered
* - ESP_ERR_NO_MEM memory error
*/
esp_err_t mdns_netif_action(esp_netif_t *esp_netif, mdns_event_actions_t event_action);
/**
* @brief Browse mDNS for a service `_service._proto`.
*
* @param service Pointer to the `_service` which will be browsed.
* @param proto Pointer to the `_proto` which will be browsed.
* @param notifier The callback which will be called when the browsing service changed.
* @return mdns_browse_t pointer to new browse object if initiated successfully.
* NULL otherwise.
*/
mdns_browse_t *mdns_browse_new(const char *service, const char *proto, mdns_browse_notify_t notifier);
/**
* @brief Stop the `_service._proto` browse.
* @param service Pointer to the `_service` which will be browsed.
* @param proto Pointer to the `_proto` which will be browsed.
* @return
* - ESP_OK success.
* - ESP_ERR_FAIL mDNS is not running or the browsing of `_service._proto` is never started.
* - ESP_ERR_NO_MEM memory error.
*/
esp_err_t mdns_browse_delete(const char *service, const char *proto);
#ifdef __cplusplus
}
#endif
#endif /* ESP_MDNS_H_ */

View File

@@ -1,14 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _MDNS_CONSOLE_H_
#define _MDNS_CONSOLE_H_
/**
* @brief Register MDNS functions with the console component
*/
void mdns_console_register(void);
#endif /* _MDNS_CONSOLE_H_ */

Some files were not shown because too many files have changed in this diff Show More