Merge branch 'component/mdns_migration' into 'master'

mdns: Remove internal component, examples, test and docs

Closes IDF-4074

See merge request espressif/esp-idf!17683
pull/9328/head
David Čermák 2022-07-04 17:45:27 +08:00
commit 46fe7dbc8c
127 zmienionych plików z 62 dodań i 14226 usunięć

Wyświetl plik

@ -117,7 +117,6 @@
/components/log/ @esp-idf-codeowners/system
/components/lwip/ @esp-idf-codeowners/lwip
/components/mbedtls/ @esp-idf-codeowners/app-utilities/mbedtls @esp-idf-codeowners/security
/components/mdns/ @esp-idf-codeowners/network
/components/mqtt/ @esp-idf-codeowners/network
/components/newlib/ @esp-idf-codeowners/system @esp-idf-codeowners/tools
/components/nvs_flash/ @esp-idf-codeowners/storage

Wyświetl plik

@ -103,17 +103,6 @@ test_reproducible_build:
# check no crashes found
- test -z "$(ls out/crashes/)" || exit 1
test_mdns_fuzzer_on_host:
extends: .host_fuzzer_test_template
variables:
FUZZER_TEST_DIR: components/mdns/test_afl_fuzz_host
test_mdns_no_serv_fuzzer_on_host:
extends: .host_fuzzer_test_template
variables:
FUZZER_TEST_DIR: components/mdns/test_afl_fuzz_host
FUZZER_PARAMS: MDNS_NO_SERVICES=on
test_lwip_dns_fuzzer_on_host:
extends: .host_fuzzer_test_template
variables:

Wyświetl plik

@ -101,8 +101,6 @@ check_fuzzer_compilation:
- make MODE=dhcp_server
- make MODE=dhcp_client
- make MODE=dns
- cd ${IDF_PATH}/components/mdns/test_afl_fuzz_host
- make
check_public_headers:
extends:

Wyświetl plik

@ -16,8 +16,11 @@ if(CONFIG_BT_ENABLED)
endif()
endif()
idf_component_register(SRCS "${srcs}"
INCLUDE_DIRS "${include_dirs}"
PRIV_INCLUDE_DIRS "${priv_include_dirs}"
REQUIRES protocomm esp_https_server
PRIV_REQUIRES protobuf-c mdns)
PRIV_REQUIRES protobuf-c)
idf_component_optional_requires(PRIVATE espressif__mdns mdns)

Wyświetl plik

@ -9,7 +9,14 @@
#include <esp_err.h>
#include <esp_log.h>
#include <mdns.h>
#if defined __has_include
# if __has_include("mdns.h")
# define WITH_MDNS
# include "mdns.h"
# endif
#endif
#include <esp_netif.h>
#include <protocomm_httpd.h>
#include <esp_local_ctrl.h>
#include <esp_https_server.h>
@ -29,14 +36,15 @@ static esp_err_t start_httpd_transport(protocomm_t *pc, const esp_local_ctrl_tra
return ESP_ERR_INVALID_ARG;
}
esp_err_t err;
#ifdef WITH_MDNS
/* Extract configured port */
uint16_t port = (
config->httpd->transport_mode == HTTPD_SSL_TRANSPORT_SECURE ?
config->httpd->port_secure :
config->httpd->port_insecure
);
esp_err_t err = mdns_service_add("Local Control Service", "_esp_local_ctrl",
err = mdns_service_add("Local Control Service", "_esp_local_ctrl",
"_tcp", port, NULL, 0);
if (err != ESP_OK) {
/* mDNS is not mandatory for provisioning to work,
@ -55,11 +63,13 @@ static esp_err_t start_httpd_transport(protocomm_t *pc, const esp_local_ctrl_tra
ESP_LOGE(TAG, "Error adding mDNS service text item");
}
}
#endif
err = httpd_ssl_start(&server_handle, config->httpd);
if (ESP_OK != err) {
ESP_LOGE(TAG, "Error starting HTTPS service!");
#ifdef WITH_MDNS
mdns_service_remove("_esp_local_ctrl", "_tcp");
#endif
return err;
}
@ -75,7 +85,9 @@ static esp_err_t start_httpd_transport(protocomm_t *pc, const esp_local_ctrl_tra
static void stop_httpd_transport(protocomm_t *pc)
{
#ifdef WITH_MDNS
mdns_service_remove("_esp_local_ctrl", "_tcp");
#endif
protocomm_httpd_stop(pc);
if (httpd_ssl_stop(server_handle) == ESP_OK) {
server_handle = NULL;

Wyświetl plik

@ -1,26 +0,0 @@
if(CONFIG_MDNS_NETWORKING_SOCKET)
set(MDNS_NETWORKING "mdns_networking_socket.c")
else()
set(MDNS_NETWORKING "mdns_networking_lwip.c")
endif()
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
set(dependencies esp_system_protocols_linux)
set(srcs "mdns.c" ${MDNS_NETWORKING})
else()
set(dependencies lwip console esp_netif)
set(private_dependencies esp_timer)
set(srcs "mdns.c" ${MDNS_NETWORKING} "mdns_console.c")
endif()
idf_component_register(
SRCS ${srcs}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "private_include"
REQUIRES ${dependencies}
PRIV_REQUIRES ${private_dependencies})
if(CONFIG_ETH_ENABLED)
idf_component_optional_requires(PRIVATE esp_eth)
endif()

Wyświetl plik

@ -1,127 +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"
range 1 64
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. The valid value is from 1
to 64.
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_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
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_STRICT_MODE
bool "mDNS strict mode"
default "n"
help
Configures strict mode. Set this to 1 for the mDNS library to strictly follow the RFC6762:
Currently the only strict feature: Do not repeat original questions in response packets
(defined in RFC6762 sec. 6).
Default configuration is 0, i.e. non-strict mode, since some implementations,
such as lwIP mDNS resolver (used by standard POSIX API like getaddrinfo, gethostbyname)
could not correctly resolve advertised names.
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_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

Wyświetl plik

@ -1,5 +0,0 @@
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
project(mdns_host)

Wyświetl plik

@ -1,25 +0,0 @@
# Setup dummy network interfaces
```
sudo ip link add eth2 type dummy
sudo ip addr add 192.168.1.200/24 dev eth2
sudo ip link set eth2 up
sudo ifconfig eth2 multicast
```
# Dig on a specified interface
```
dig +short -b 192.168.1.200 -p 5353 @224.0.0.251 myesp.local
```
# Run avahi to browse services
Avahi needs the netif to have the "multicast" flag set
```bash
david@david-comp:~/esp/idf (feature/mdns_networking_socket)$ avahi-browse -a -r -p
+;eth2;IPv6;myesp-service2;Web Site;local
+;eth2;IPv4;myesp-service2;Web Site;local
=;eth2;IPv6;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password"
=;eth2;IPv4;myesp-service2;Web Site;local;myesp.local;192.168.1.200;80;"board=esp32" "u=user" "p=password"
```

Wyświetl plik

@ -1,3 +0,0 @@
idf_component_register(SRCS esp_event_mock.c
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)

Wyświetl plik

@ -1,29 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_err.h"
#include "esp_event.h"
const char * WIFI_EVENT = "WIFI_EVENT";
const char * IP_EVENT = "IP_EVENT";
esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id, void* event_handler, void* event_handler_arg)
{
return ESP_OK;
}
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler)
{
return ESP_OK;
}

Wyświetl plik

@ -1,32 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "stdbool.h"
#include "esp_err.h"
#include "esp_event_base.h"
#include "bsd_strings.h"
#define ESP_EVENT_DECLARE_BASE(x)
#define ESP_EVENT_ANY_ID (-1)
typedef void * esp_event_base_t;
typedef void * system_event_t;
const char* WIFI_EVENT;
const char* IP_EVENT;
esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id, void* event_handler, void* event_handler_arg);
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler);

Wyświetl plik

@ -1,21 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
typedef enum {
WIFI_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
WIFI_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */
WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */
WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
} mdns_used_event_t;

Wyświetl plik

@ -1,3 +0,0 @@
idf_component_register(SRCS esp_netif_linux.c
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)

Wyświetl plik

@ -1,9 +0,0 @@
menu "LWIP-MOCK-CONFIG"
config LWIP_IPV6
bool "Enable IPv6"
default y
help
Enable/disable IPv6
endmenu

Wyświetl plik

@ -1,163 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include<stdio.h>
#include <stdlib.h>
#include "esp_netif.h"
#include "esp_err.h"
#include <string.h> //strlen
#include <sys/socket.h>
#include <arpa/inet.h> //inet_addr
#include <sys/types.h>
#include <ifaddrs.h>
#include <net/if.h>
#include "esp_netif_types.h"
#define MAX_NETIFS 4
static esp_netif_t* s_netif_list[MAX_NETIFS] = { 0 };
struct esp_netif_obj
{
const char *if_key;
const char *if_desc;
};
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
{
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] && strcmp(s_netif_list[i]->if_key, if_key) == 0) {
return s_netif_list[i];
}
}
return NULL;
}
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
struct ifaddrs *addrs, *tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp) {
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) {
char addr[20];
struct sockaddr_in *pAddr = (struct sockaddr_in *) tmp->ifa_addr;
inet_ntop(AF_INET, &pAddr->sin_addr, addr, sizeof(addr) );
if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) {
printf("AF_INET: %s: %s\n", tmp->ifa_name, addr);
memcpy(&ip_info->ip.addr, &pAddr->sin_addr, 4);
break;
}
}
tmp = tmp->ifa_next;
}
return ESP_OK;
}
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
return ESP_OK;
}
esp_err_t esp_netif_get_ip6_linklocal(esp_netif_t *esp_netif, esp_ip6_addr_t *if_ip6)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
struct ifaddrs *addrs, *tmp;
getifaddrs(&addrs);
tmp = addrs;
while (tmp)
{
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) {
char addr[64];
struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)tmp->ifa_addr;
inet_ntop(AF_INET6, &pAddr->sin6_addr, addr, sizeof(addr) );
if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) {
printf("AF_INET6: %s: %s\n", tmp->ifa_name, addr);
memcpy(if_ip6->addr, &pAddr->sin6_addr, 4*4);
break;
}
}
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
return ESP_OK;
}
int esp_netif_get_netif_impl_index(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return -1;
}
uint32_t interfaceIndex = if_nametoindex(esp_netif->if_desc);
return interfaceIndex;
}
esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
{
if (esp_netif == NULL) {
return ESP_ERR_INVALID_STATE;
}
strcpy(name, esp_netif->if_desc);
return ESP_OK;
}
const char *esp_netif_get_desc(esp_netif_t *esp_netif)
{
if (esp_netif == NULL) {
return NULL;
}
return esp_netif->if_desc;
}
esp_netif_t *esp_netif_new(const esp_netif_config_t *config)
{
if (esp_netif_get_handle_from_ifkey(config->base->if_key)) {
return NULL;
}
esp_netif_t* netif = calloc(1, sizeof(struct esp_netif_obj));
if (netif) {
netif->if_desc = config->base->if_desc;
netif->if_key = config->base->if_key;
}
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] == NULL) {
s_netif_list[i] = netif;
break;
}
}
return netif;
}
void esp_netif_destroy(esp_netif_t *esp_netif)
{
for (int i=0; i<MAX_NETIFS; ++i) {
if (s_netif_list[i] == esp_netif) {
s_netif_list[i] = NULL;
break;
}
}
free(esp_netif);
}

Wyświetl plik

@ -1,15 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "esp_event.h"

Wyświetl plik

@ -1,3 +0,0 @@
idf_component_register(SRCS esp_log_impl.c strlcat.c
INCLUDE_DIRS include
REQUIRES esp_netif_linux esp_timer_linux freertos_linux esp_event_mock esp_netif log esp_common)

Wyświetl plik

@ -1,35 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_err.h"
#include "esp_log.h"
#include <stdlib.h>
void _esp_error_check_failed(esp_err_t rc, const char *file, int line, const char *function, const char *expression)
{
ESP_LOGE("ESP_ERROR_CHECK", "Failed with esp_err_t: 0x%x", rc);
ESP_LOGE("ESP_ERROR_CHECK", "Expression: %s", expression);
ESP_LOGE("ESP_ERROR_CHECK", "Functions: %s %s(%d)", function, file, line);
abort();
}
void esp_log_buffer_hexdump_internal(const char *tag, const void *buffer, uint16_t buff_len, esp_log_level_t log_level)
{
if ( LOG_LOCAL_LEVEL >= log_level ) {
ESP_LOG_LEVEL(log_level, tag, "Buffer:%p length:%d", buffer, buff_len);
for (int i=0; i<buff_len; ++i) {
printf("%02x ", ((uint8_t*)buffer)[i]);
}
printf("\n");
}
}

Wyświetl plik

@ -1,16 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
size_t strlcat(char *dest, const char *src, size_t size);

Wyświetl plik

@ -1,16 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include_next "endian.h"

Wyświetl plik

@ -1,68 +0,0 @@
/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */
/*-
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
*/
#include "string.h"
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(dst, src, siz)
char *dst;
const char *src;
size_t siz;
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}

Wyświetl plik

@ -1,9 +0,0 @@
idf_component_register(SRCS esp_timer_linux.c timer_task.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux freertos_linux)
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)

Wyświetl plik

@ -1,47 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "esp_err.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void * create_tt(esp_timer_cb_t cb);
void destroy_tt(void* tt);
void set_tout(void* tt, uint32_t ms);
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
esp_timer_handle_t* out_handle)
{
*out_handle = (esp_timer_handle_t)create_tt(create_args->callback);
return ESP_OK;
}
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
{
set_tout(timer, period/1000);
return ESP_OK;
}
esp_err_t esp_timer_stop(esp_timer_handle_t timer)
{
return ESP_OK;
}
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
{
destroy_tt(timer);
return ESP_OK;
}

Wyświetl plik

@ -1,41 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <stdbool.h>
#include <stdint.h>
typedef struct esp_timer* esp_timer_handle_t;
typedef void (*esp_timer_cb_t)(void* arg);
typedef enum {
ESP_TIMER_TASK,
} esp_timer_dispatch_t;
typedef struct {
esp_timer_cb_t callback; //!< Function to call when timer expires
void* arg; //!< Argument to pass to the callback
esp_timer_dispatch_t dispatch_method; //!< Call the callback from task or from ISR
const char* name; //!< Timer name, used in esp_timer_dump function
bool skip_unhandled_events; //!< Skip unhandled events for periodic timers
} esp_timer_create_args_t;
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
esp_timer_handle_t* out_handle);
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period);
esp_err_t esp_timer_stop(esp_timer_handle_t timer);
esp_err_t esp_timer_delete(esp_timer_handle_t timer);

Wyświetl plik

@ -1,38 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "timer_task.hpp"
#include <cstdint>
#include <vector>
#include <memory>
#include <cstring>
extern "C" void * create_tt(cb_t cb)
{
auto * tt = new TimerTaskMock(cb);
return tt;
}
extern "C" void destroy_tt(void* tt)
{
auto * timer_task = static_cast<TimerTaskMock *>(tt);
delete(timer_task);
}
extern "C" void set_tout(void* tt, uint32_t ms)
{
auto * timer_task = static_cast<TimerTaskMock *>(tt);
timer_task->SetTimeout(ms);
}

Wyświetl plik

@ -1,61 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <thread>
#include <atomic>
typedef void (*cb_t)(void* arg);
class TimerTaskMock
{
public:
TimerTaskMock(cb_t cb): cb(cb), t(run_static, this), active(false), ms(INT32_MAX) {}
~TimerTaskMock(void) { active = false; t.join(); }
void SetTimeout(uint32_t m)
{
ms = m;
active = true;
}
private:
static void run_static(TimerTaskMock* timer)
{
timer->run();
}
void run(void)
{
while (!active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
while (active.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
cb(nullptr);
}
}
cb_t cb;
std::thread t;
std::atomic<bool> active;
uint32_t ms;
};

Wyświetl plik

@ -1,13 +0,0 @@
idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries(${COMPONENT_LIB} PRIVATE Threads::Threads)
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS ON
)

Wyświetl plik

@ -1,7 +0,0 @@
menu "FreeRTOS"
config FREERTOS_NO_AFFINITY
hex
default 0x7FFFFFFF
endmenu

Wyświetl plik

@ -1,192 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include <pthread.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
void * create_q(void);
void destroy_q(void* q);
bool send_q(void* q, uint8_t *data, size_t len);
bool recv_q(void* q, uint8_t *data, size_t len, uint32_t ms);
static uint64_t s_semaphore_data = 0;
struct queue_handle {
size_t item_size;
void * q;
};
QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize )
{
struct queue_handle * h = calloc(1, sizeof(struct queue_handle));
h->item_size = uxItemSize;
h->q = create_q();
return (QueueHandle_t)h;
}
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait)
{
struct queue_handle * h = xQueue;
return send_q(h->q, (uint8_t*)pvItemToQueue, h->item_size) ? pdTRUE : pdFAIL;
}
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
{
struct queue_handle * h = xQueue;
return recv_q(h->q, (uint8_t*)pvBuffer, h->item_size, xTicksToWait) ? pdTRUE : pdFAIL;
}
BaseType_t xSemaphoreGive( QueueHandle_t xQueue)
{
return xQueueSend(xQueue, &s_semaphore_data, portMAX_DELAY);
}
BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask )
{
return xQueueReceive(xQueue, &s_semaphore_data, portMAX_DELAY);
}
void vQueueDelete( QueueHandle_t xQueue )
{
struct queue_handle * h = xQueue;
if (h->q) {
destroy_q(h->q);
}
free(xQueue);
}
QueueHandle_t xSemaphoreCreateBinary(void)
{
QueueHandle_t sempaphore = xQueueCreate(1, 1);
return sempaphore;
}
QueueHandle_t xSemaphoreCreateMutex(void)
{
QueueHandle_t sempaphore = xQueueCreate(1, 1);
if (sempaphore) {
xSemaphoreGive(sempaphore);
}
return sempaphore;
}
void vTaskDelete(TaskHandle_t *task)
{
if (task == NULL) {
pthread_exit(0);
}
void *thread_rval = NULL;
pthread_join((pthread_t)task, &thread_rval);
}
TickType_t xTaskGetTickCount( void )
{
struct timespec spec;
clock_gettime(CLOCK_REALTIME, &spec);
return spec.tv_nsec / 1000000 + spec.tv_sec * 1000;
}
void vTaskDelay( const TickType_t xTicksToDelay )
{
usleep(xTicksToDelay*1000);
}
void * pthread_task(void * params)
{
struct {
void * const param;
TaskFunction_t task;
bool started;
} *pthread_params = params;
void * const param = pthread_params->param;
TaskFunction_t task = pthread_params->task;
pthread_params->started = true;
task(param);
return NULL;
}
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pvCreatedTask,
const BaseType_t xCoreID)
{
xTaskCreate(pvTaskCode, pcName, usStackDepth, pvParameters, uxPriority, pvCreatedTask);
return pdTRUE;
}
void xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint32_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pvCreatedTask)
{
pthread_t new_thread = (pthread_t)NULL;
pthread_attr_t attr;
struct {
void * const param;
TaskFunction_t task;
bool started;
} pthread_params = { .param = pvParameters, .task = pvTaskCode};
int res = pthread_attr_init(&attr);
assert(res == 0);
res = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
assert(res == 0);
res = pthread_create(&new_thread, &attr, pthread_task, &pthread_params);
assert(res == 0);
if (pvCreatedTask) {
*pvCreatedTask = (void*)new_thread;
}
// just wait till the task started so we can unwind params from the stack
while (pthread_params.started == false) {
usleep(1000);
}
}
uint32_t esp_get_free_heap_size(void)
{
return 0;
}
uint32_t esp_random(void)
{
return rand();
}
void xTaskNotifyGive(TaskHandle_t task)
{
}
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time )
{
return true;
}
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
return NULL;
}

Wyświetl plik

@ -1,20 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define ESP_TASK_PRIO_MAX 25
#define ESP_TASKD_EVENT_PRIO 5

Wyświetl plik

@ -1,34 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#define portTICK_PERIOD_MS 1
#define portMAX_DELAY ( TickType_t ) 0xffffffffUL
typedef void * SemaphoreHandle_t;
typedef void * QueueHandle_t;
typedef void * TaskHandle_t;
typedef uint32_t TickType_t;
typedef void (*TaskFunction_t)( void * );
typedef unsigned int UBaseType_t;
typedef int BaseType_t;
#define pdFALSE ( ( BaseType_t ) 0 )
#define pdTRUE ( ( BaseType_t ) 1 )
#define pdPASS ( pdTRUE )
#define pdFAIL ( pdFALSE )
#define pdMS_TO_TICKS(tick) (tick)
uint32_t esp_get_free_heap_size(void);
uint32_t esp_random(void);

Wyświetl plik

@ -1,50 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "freertos/FreeRTOS.h"
#define TaskHandle_t TaskHandle_t
#define vSemaphoreDelete( xSemaphore ) vQueueDelete( ( QueueHandle_t ) ( xSemaphore ) )
void vTaskDelay( const TickType_t xTicksToDelay );
void xTaskNotifyGive(TaskHandle_t task);
TaskHandle_t xTaskGetCurrentTaskHandle(void);
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time );
BaseType_t xTaskCreatePinnedToCore( TaskFunction_t pvTaskCode,
const char * const pcName,
const uint32_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pvCreatedTask,
const BaseType_t xCoreID);
void xTaskCreate(TaskFunction_t pvTaskCode, const char * const pcName, const uint32_t usStackDepth, void * const pvParameters, UBaseType_t uxPriority, TaskHandle_t * const pvCreatedTask);
TickType_t xTaskGetTickCount( void );
void vQueueDelete( QueueHandle_t xQueue );
QueueHandle_t xSemaphoreCreateBinary(void);
QueueHandle_t xSemaphoreCreateMutex(void);
BaseType_t xSemaphoreGive( QueueHandle_t xQueue);
BaseType_t xSemaphoreTake( QueueHandle_t xQueue, TickType_t pvTask );
void vTaskDelete(TaskHandle_t *task);
QueueHandle_t xQueueCreate( uint32_t uxQueueLength,
uint32_t uxItemSize );
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);

Wyświetl plik

@ -1,51 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "queue_unique_ptr.hpp"
#include <cstdint>
#include <vector>
#include <memory>
#include <cstring>
extern "C" void * create_q(void)
{
auto * q = new QueueMock<std::vector<uint8_t>>();
return q;
}
extern "C" void destroy_q(void* q)
{
auto * queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
delete(queue);
}
extern "C" bool send_q(void* q, uint8_t *data, size_t len)
{
auto v = std::make_unique<std::vector<uint8_t>>(len);
v->assign(data, data+len);
auto queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
queue->send(std::move(v));
return true;
}
extern "C" bool recv_q(void* q, uint8_t *data, size_t len, uint32_t ms)
{
auto queue = static_cast<QueueMock<std::vector<uint8_t>> *>(q);
auto v = queue->receive(ms);
if (v == nullptr) {
return false;
}
memcpy(data, (void *)v->data(), len);
return true;
}

Wyświetl plik

@ -1,55 +0,0 @@
// Copyright 2021 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <queue>
#include <mutex>
#include <condition_variable>
#include <memory>
#include <thread>
#include <atomic>
template <class T>
class QueueMock
{
public:
QueueMock(void): q(), m(), c() {}
~QueueMock(void) {}
void send(std::unique_ptr<T> t)
{
std::lock_guard<std::mutex> lock(m);
q.push(std::move(t));
c.notify_one();
}
std::unique_ptr<T> receive(uint32_t ms)
{
std::unique_lock<std::mutex> lock(m);
while(q.empty()) {
if (c.wait_for(lock, std::chrono::milliseconds(ms)) == std::cv_status::timeout) {
return nullptr;
}
}
std::unique_ptr<T> val = std::move(q.front());
q.pop();
return val;
}
private:
std::queue<std::unique_ptr<T>> q;
mutable std::mutex m;
std::condition_variable c;
};

Wyświetl plik

@ -1,4 +0,0 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS
"."
REQUIRES mdns)

Wyświetl plik

@ -1,59 +0,0 @@
#include <stdio.h>
#include "mdns.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
static const char *TAG = "mdns-test";
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, "%x: Host was not found!", (err));
return;
}
ESP_LOGE(TAG, "Query Failed: %x", (err));
return;
}
ESP_LOGI(TAG, "Query A: %s.local resolved to: " IPSTR, host_name, IP2STR(&addr));
}
int main(int argc , char *argv[])
{
setvbuf(stdout, NULL, _IONBF, 0);
const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = "eth2" };
esp_netif_config_t cfg = { .base = &base_cg };
esp_netif_t *sta = esp_netif_new(&cfg);
mdns_init();
mdns_hostname_set("myesp");
ESP_LOGI(TAG, "mdns hostname set to: [%s]", "myesp");
//set default mDNS instance name
mdns_instance_name_set("myesp-inst");
//structure with TXT records
mdns_txt_item_t serviceTxtData[3] = {
{"board","esp32"},
{"u","user"},
{"p","password"}
};
vTaskDelay(1000);
ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3));
vTaskDelay(2000);
query_mdns_host("david-comp");
vTaskDelay(2000);
esp_netif_destroy(sta);
mdns_free();
ESP_LOGI(TAG, "Exit");
return 0;
}

Wyświetl plik

@ -1,773 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 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 <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
/**
* @brief Asynchronous query handle
*/
typedef struct mdns_search_once_s mdns_search_once_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_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 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);
/**
* @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 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 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 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 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 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);
#ifdef __cplusplus
}
#endif
#endif /* ESP_MDNS_H_ */

Wyświetl plik

@ -1,22 +0,0 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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_ */

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,370 +0,0 @@
/*
* MDNS Server Networking
*
*/
#include <string.h>
#include "esp_log.h"
#include "lwip/ip_addr.h"
#include "lwip/pbuf.h"
#include "lwip/igmp.h"
#include "lwip/udp.h"
#include "lwip/mld6.h"
#include "lwip/priv/tcpip_priv.h"
#include "esp_system.h"
#include "esp_event.h"
#include "mdns_networking.h"
#include "esp_netif_net_stack.h"
extern mdns_server_t * _mdns_server;
/*
* MDNS Server Networking
*
*/
static const char *TAG = "MDNS_Networking";
static struct udp_pcb * _pcb_main = NULL;
static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport);
/**
* @brief Low level UDP PCB Initialize
*/
static esp_err_t _udp_pcb_main_init(void)
{
if(_pcb_main) {
return ESP_OK;
}
_pcb_main = udp_new();
if (!_pcb_main) {
return ESP_ERR_NO_MEM;
}
if (udp_bind(_pcb_main, IP_ANY_TYPE, MDNS_SERVICE_PORT) != 0) {
udp_remove(_pcb_main);
_pcb_main = NULL;
return ESP_ERR_INVALID_STATE;
}
_pcb_main->mcast_ttl = 255;
_pcb_main->remote_port = MDNS_SERVICE_PORT;
ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE));
udp_recv(_pcb_main, &_udp_recv, _mdns_server);
return ESP_OK;
}
/**
* @brief Low level UDP PCB Free
*/
static void _udp_pcb_main_deinit(void)
{
if(_pcb_main){
udp_recv(_pcb_main, NULL, NULL);
udp_disconnect(_pcb_main);
udp_remove(_pcb_main);
_pcb_main = NULL;
}
}
/**
* @brief Low level UDP Multicast membership control
*/
static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protocol, bool join)
{
struct netif * netif = NULL;
esp_netif_t *tcpip_if = _mdns_get_esp_netif(if_inx);
if (!esp_netif_is_netif_up(tcpip_if)) {
// Network interface went down before event propagated, skipping IGMP config
return ESP_ERR_INVALID_STATE;
}
netif = esp_netif_get_netif_impl(tcpip_if);
assert(netif);
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
ip4_addr_t multicast_addr;
IP4_ADDR(&multicast_addr, 224, 0, 0, 251);
if(join){
if (igmp_joingroup_netif(netif, &multicast_addr)) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (igmp_leavegroup_netif(netif, &multicast_addr)) {
return ESP_ERR_INVALID_STATE;
}
}
}
#if CONFIG_LWIP_IPV6
else {
ip_addr_t multicast_addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000);
if(join){
if (mld6_joingroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
return ESP_ERR_INVALID_STATE;
}
} else {
if (mld6_leavegroup_netif(netif, &(multicast_addr.u_addr.ip6))) {
return ESP_ERR_INVALID_STATE;
}
}
}
#endif
return ESP_OK;
}
/**
* @brief the receive callback of the raw udp api. Packets are received here
*
*/
static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport)
{
uint8_t i;
while (pb != NULL) {
struct pbuf * this_pb = pb;
pb = pb->next;
this_pb->next = NULL;
mdns_rx_packet_t * packet = (mdns_rx_packet_t *)malloc(sizeof(mdns_rx_packet_t));
if (!packet) {
HOOK_MALLOC_FAILED;
//missed packet - no memory
pbuf_free(this_pb);
continue;
}
packet->tcpip_if = MDNS_MAX_INTERFACES;
packet->pb = this_pb;
packet->src_port = rport;
#if CONFIG_LWIP_IPV6
packet->src.type = raddr->type;
memcpy(&packet->src.u_addr, &raddr->u_addr, sizeof(raddr->u_addr));
#else
packet->src.type = IPADDR_TYPE_V4;
memcpy(&packet->src.u_addr.ip4, &raddr->addr, sizeof(ip_addr_t));
#endif
packet->dest.type = packet->src.type;
if (packet->src.type == IPADDR_TYPE_V4) {
packet->ip_protocol = MDNS_IP_PROTOCOL_V4;
struct ip_hdr * iphdr = (struct ip_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP_HLEN);
packet->dest.u_addr.ip4.addr = iphdr->dest.addr;
packet->multicast = ip4_addr_ismulticast(&(packet->dest.u_addr.ip4));
}
#if CONFIG_LWIP_IPV6
else {
packet->ip_protocol = MDNS_IP_PROTOCOL_V6;
struct ip6_hdr * ip6hdr = (struct ip6_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP6_HLEN);
memcpy(&packet->dest.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16);
packet->multicast = ip6_addr_ismulticast(&(packet->dest.u_addr.ip6));
}
#endif
//lwip does not return the proper pcb if you have more than one for the same multicast address (but different interfaces)
struct netif * netif = NULL;
struct udp_pcb * pcb = NULL;
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb;
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
if (pcb && netif && netif == ip_current_input_netif ()) {
if (packet->src.type == IPADDR_TYPE_V4) {
#if CONFIG_LWIP_IPV6
if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) {
#else
if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
#endif //packet source is not in the same subnet
pcb = NULL;
break;
}
}
packet->tcpip_if = i;
break;
}
pcb = NULL;
}
if (!pcb || !_mdns_server || !_mdns_server->action_queue
|| _mdns_send_rx_action(packet) != ESP_OK) {
pbuf_free(this_pb);
free(packet);
}
}
}
/**
* @brief Check if any of the interfaces is up
*/
static bool _udp_pcb_is_in_use(void){
int i, p;
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (p=0; p<MDNS_IP_PROTOCOL_MAX; p++) {
if(_mdns_server->interfaces[i].pcbs[p].pcb){
return true;
}
}
}
return false;
}
/**
* @brief Stop PCB Main code
*/
static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server) {
return;
}
mdns_pcb_t * _pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
if (_pcb->pcb) {
free(_pcb->probe_services);
_pcb->state = PCB_OFF;
_pcb->pcb = NULL;
_pcb->probe_ip = false;
_pcb->probe_services = NULL;
_pcb->probe_services_len = 0;
_pcb->probe_running = false;
_pcb->failed_probes = 0;
_udp_join_group(tcpip_if, ip_protocol, false);
if(!_udp_pcb_is_in_use()) {
_udp_pcb_main_deinit();
}
}
}
/**
* @brief Start PCB Main code
*/
static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
return ESP_ERR_INVALID_STATE;
}
esp_err_t err = _udp_join_group(tcpip_if, ip_protocol, true);
if(err){
return err;
}
err = _udp_pcb_main_init();
if(err){
return err;
}
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = _pcb_main;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
return ESP_OK;
}
typedef struct {
struct tcpip_api_call_data call;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
struct pbuf *pbt;
const ip_addr_t *ip;
uint16_t port;
esp_err_t err;
} mdns_api_call_t;
/**
* @brief Start PCB from LwIP thread
*/
static err_t _mdns_pcb_init_api(struct tcpip_api_call_data *api_call_msg)
{
mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
msg->err = _udp_pcb_init(msg->tcpip_if, msg->ip_protocol);
return msg->err;
}
/**
* @brief Stop PCB from LwIP thread
*/
static err_t _mdns_pcb_deinit_api(struct tcpip_api_call_data *api_call_msg)
{
mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
_udp_pcb_deinit(msg->tcpip_if, msg->ip_protocol);
msg->err = ESP_OK;
return ESP_OK;
}
/*
* Non-static functions below are
* - _mdns prefixed
* - commented in mdns_networking.h header
*/
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_api_call_t msg = {
.tcpip_if = tcpip_if,
.ip_protocol = ip_protocol
};
tcpip_api_call(_mdns_pcb_init_api, &msg.call);
return msg.err;
}
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
mdns_api_call_t msg = {
.tcpip_if = tcpip_if,
.ip_protocol = ip_protocol
};
tcpip_api_call(_mdns_pcb_deinit_api, &msg.call);
return msg.err;
}
static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
{
void * nif = NULL;
mdns_api_call_t * msg = (mdns_api_call_t *)api_call_msg;
mdns_pcb_t * _pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol];
nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
if (!nif) {
pbuf_free(msg->pbt);
msg->err = ERR_IF;
return ERR_IF;
}
esp_err_t err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
pbuf_free(msg->pbt);
msg->err = err;
return err;
}
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
{
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
if (pbt == NULL) {
return 0;
}
memcpy((uint8_t *)pbt->payload, data, len);
mdns_api_call_t msg = {
.tcpip_if = tcpip_if,
.ip_protocol = ip_protocol,
.pbt = pbt,
.ip = (ip_addr_t *)ip,
.port = port
};
tcpip_api_call(_mdns_udp_pcb_write_api, &msg.call);
if (msg.err) {
return 0;
}
return len;
}
void* _mdns_get_packet_data(mdns_rx_packet_t *packet)
{
return packet->pb->payload;
}
size_t _mdns_get_packet_len(mdns_rx_packet_t *packet)
{
return packet->pb->len;
}
void _mdns_packet_free(mdns_rx_packet_t *packet)
{
pbuf_free(packet->pb);
free(packet);
}

Wyświetl plik

@ -1,495 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @brief MDNS Server Networking module implemented using BSD sockets
*/
#include <string.h>
#include "esp_event.h"
#include "mdns_networking.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include "esp_log.h"
#if defined(CONFIG_IDF_TARGET_LINUX)
#include <sys/ioctl.h>
#include <net/if.h>
#endif
extern mdns_server_t * _mdns_server;
static const char *TAG = "MDNS_Networking";
static bool s_run_sock_recv_task = false;
static int create_socket(esp_netif_t *netif);
static int join_mdns_multicast_group(int sock, esp_netif_t *netif, mdns_ip_protocol_t ip_protocol);
#if defined(CONFIG_IDF_TARGET_LINUX)
// Need to define packet buffer struct on linux
struct pbuf {
struct pbuf * next;
void * payload;
size_t tot_len;
size_t len;
};
#else
// Compatibility define to access sock-addr struct the same way for lwip and linux
#define s6_addr32 un.u32_addr
#endif // CONFIG_IDF_TARGET_LINUX
static void delete_socket(int sock)
{
close(sock);
}
static struct udp_pcb* sock_to_pcb(int sock)
{
if (sock < 0) {
return NULL;
}
// Note: sock=0 is a valid descriptor, so save it as +1 ("1" is a valid pointer)
intptr_t sock_plus_one = sock + 1;
return (struct udp_pcb*)sock_plus_one;
}
static int pcb_to_sock(struct udp_pcb* pcb)
{
if (pcb == NULL) {
return -1;
}
intptr_t sock_plus_one = (intptr_t)pcb;
return sock_plus_one - 1;
}
void* _mdns_get_packet_data(mdns_rx_packet_t *packet)
{
return packet->pb->payload;
}
size_t _mdns_get_packet_len(mdns_rx_packet_t *packet)
{
return packet->pb->len;
}
void _mdns_packet_free(mdns_rx_packet_t *packet)
{
free(packet->pb->payload);
free(packet->pb);
free(packet);
}
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
struct udp_pcb * pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = NULL;
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb == NULL &&
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb == NULL) {
// if the interface for both protocol uninitialized, close the interface socket
int sock = pcb_to_sock(pcb);
if (sock >= 0) {
delete_socket(sock);
}
}
for (int i=0; i<MDNS_MAX_INTERFACES; i++) {
for (int j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb)
// If any of the interfaces/protocol initialized
return ESP_OK;
}
}
// no interface alive, stop the rx task
s_run_sock_recv_task = false;
vTaskDelay(pdMS_TO_TICKS(500));
return ESP_OK;
}
#if defined(CONFIG_IDF_TARGET_LINUX)
#ifdef CONFIG_LWIP_IPV6
static char* inet6_ntoa_r(struct in6_addr addr, char* ptr, size_t size)
{
inet_ntop(AF_INET6, &(addr.s6_addr32[0]), ptr, size);
return ptr;
}
#endif // CONFIG_LWIP_IPV6
static char* inet_ntoa_r(struct in_addr addr, char* ptr, size_t size)
{
char * res = inet_ntoa(addr);
if (res && strlen(res) < size) {
strcpy(ptr, res);
}
return res;
}
#endif // CONFIG_IDF_TARGET_LINUX
static inline char* get_string_address(struct sockaddr_storage *source_addr)
{
static char address_str[40]; // 40=(8*4+7+term) is the max size of ascii IPv6 addr "XXXX:XX...XX:XXXX"
char *res = NULL;
// Convert ip address to string
if (source_addr->ss_family == PF_INET) {
res = inet_ntoa_r(((struct sockaddr_in *)source_addr)->sin_addr, address_str, sizeof(address_str));
}
#ifdef CONFIG_LWIP_IPV6
else if (source_addr->ss_family == PF_INET6) {
res = inet6_ntoa_r(((struct sockaddr_in6 *)source_addr)->sin6_addr, address_str, sizeof(address_str));
}
#endif
if (!res) {
address_str[0] = '\0'; // Returns empty string if conversion didn't succeed
}
return address_str;
}
static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t port, const mdns_ip_protocol_t ip_protocol, struct sockaddr_storage *in_addr)
{
size_t ss_addr_len = 0;
memset(in_addr, 0, sizeof(struct sockaddr_storage));
if (ip_protocol == MDNS_IP_PROTOCOL_V4 && addr->type == ESP_IPADDR_TYPE_V4) {
in_addr->ss_family = PF_INET;
#if !defined(CONFIG_IDF_TARGET_LINUX)
in_addr->s2_len = sizeof(struct sockaddr_in);
#endif
ss_addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in *in_addr_ip4 = (struct sockaddr_in *) in_addr;
in_addr_ip4->sin_port = port;
in_addr_ip4->sin_addr.s_addr = addr->u_addr.ip4.addr;
}
#if CONFIG_LWIP_IPV6
else if (ip_protocol == MDNS_IP_PROTOCOL_V6 && addr->type == ESP_IPADDR_TYPE_V6) {
memset(in_addr, 0, sizeof(struct sockaddr_storage));
in_addr->ss_family = PF_INET6;
#if !defined(CONFIG_IDF_TARGET_LINUX)
in_addr->s2_len = sizeof(struct sockaddr_in6);
#endif
ss_addr_len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 * in_addr_ip6 = (struct sockaddr_in6 *)in_addr;
uint32_t *u32_addr = in_addr_ip6->sin6_addr.s6_addr32;
in_addr_ip6->sin6_port = port;
u32_addr[0] = addr->u_addr.ip6.addr[0];
u32_addr[1] = addr->u_addr.ip6.addr[1];
u32_addr[2] = addr->u_addr.ip6.addr[2];
u32_addr[3] = addr->u_addr.ip6.addr[3];
}
#endif // CONFIG_LWIP_IPV6
return ss_addr_len;
}
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len)
{
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb);
if (sock < 0) {
return 0;
}
struct sockaddr_storage in_addr;
size_t ss_size = espaddr_to_inet(ip, htons(port), ip_protocol, &in_addr);
if (!ss_size) {
ESP_LOGE(TAG, "espaddr_to_inet() failed: Mismatch of IP protocols");
return 0;
}
ESP_LOGD(TAG, "[sock=%d]: Sending to IP %s port %d", sock, get_string_address(&in_addr), port);
ssize_t actual_len = sendto(sock, data, len, 0, (struct sockaddr *)&in_addr, ss_size);
if (actual_len < 0) {
ESP_LOGE(TAG, "[sock=%d]: _mdns_udp_pcb_write sendto() has failed\n errno=%d: %s", sock, errno, strerror(errno));
}
return actual_len;
}
static inline void inet_to_espaddr(const struct sockaddr_storage *in_addr, esp_ip_addr_t *addr, uint16_t *port)
{
if (in_addr->ss_family == PF_INET) {
struct sockaddr_in * in_addr_ip4 = (struct sockaddr_in *)in_addr;
memset(addr, 0, sizeof(esp_ip_addr_t));
*port = in_addr_ip4->sin_port;
addr->u_addr.ip4.addr = in_addr_ip4->sin_addr.s_addr;
addr->type = ESP_IPADDR_TYPE_V4;
}
#if CONFIG_LWIP_IPV6
else if (in_addr->ss_family == PF_INET6) {
struct sockaddr_in6 * in_addr_ip6 = (struct sockaddr_in6 *)in_addr;
memset(addr, 0, sizeof(esp_ip_addr_t));
*port = in_addr_ip6->sin6_port;
uint32_t *u32_addr = in_addr_ip6->sin6_addr.s6_addr32;
if (u32_addr[0] == 0 && u32_addr[1] == 0 && u32_addr[2] == esp_netif_htonl(0x0000FFFFUL)) {
// Mapped IPv4 address, convert directly to IPv4
addr->type = ESP_IPADDR_TYPE_V4;
addr->u_addr.ip4.addr = u32_addr[3];
} else {
addr->type = ESP_IPADDR_TYPE_V6;
addr->u_addr.ip6.addr[0] = u32_addr[0];
addr->u_addr.ip6.addr[1] = u32_addr[1];
addr->u_addr.ip6.addr[2] = u32_addr[2];
addr->u_addr.ip6.addr[3] = u32_addr[3];
}
}
#endif // CONFIG_LWIP_IPV6
}
void sock_recv_task(void* arg)
{
while (s_run_sock_recv_task) {
struct timeval tv = {
.tv_sec = 1,
.tv_usec = 0,
};
fd_set rfds;
FD_ZERO(&rfds);
int max_sock = -1;
for (int i=0; i<MDNS_MAX_INTERFACES; i++) {
for (int j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
int sock = pcb_to_sock(_mdns_server->interfaces[i].pcbs[j].pcb);
if (sock >= 0) {
FD_SET(sock, &rfds);
max_sock = MAX(max_sock, sock);
}
}
}
if (max_sock < 0) {
vTaskDelay(pdMS_TO_TICKS(1000));
ESP_LOGI(TAG, "No sock!");
continue;
}
int s = select(max_sock + 1, &rfds, NULL, NULL, &tv);
if (s < 0) {
ESP_LOGE(TAG, "Select failed. errno=%d: %s", errno, strerror(errno));
break;
} else if (s > 0) {
for (int tcpip_if=0; tcpip_if<MDNS_MAX_INTERFACES; tcpip_if++) {
// Both protocols share once socket
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb);
if (sock < 0) {
sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb);
}
if (sock < 0) {
continue;
}
if (FD_ISSET(sock, &rfds)) {
static char recvbuf[MDNS_MAX_PACKET_SIZE];
uint16_t port = 0;
struct sockaddr_storage raddr; // Large enough for both IPv4 or IPv6
socklen_t socklen = sizeof(struct sockaddr_storage);
esp_ip_addr_t addr = {0};
int len = recvfrom(sock, recvbuf, sizeof(recvbuf), 0,
(struct sockaddr *) &raddr, &socklen);
if (len < 0) {
ESP_LOGE(TAG, "multicast recvfrom failed. errno=%d: %s", errno, strerror(errno));
break;
}
ESP_LOGD(TAG, "[sock=%d]: Received from IP:%s", sock, get_string_address(&raddr));
ESP_LOG_BUFFER_HEXDUMP(TAG, recvbuf, len, ESP_LOG_VERBOSE);
inet_to_espaddr(&raddr, &addr, &port);
// Allocate the packet structure and pass it to the mdns main engine
mdns_rx_packet_t *packet = (mdns_rx_packet_t *) calloc(1, sizeof(mdns_rx_packet_t));
struct pbuf *packet_pbuf = calloc(1, sizeof(struct pbuf));
uint8_t *buf = malloc(len);
if (packet == NULL || packet_pbuf == NULL || buf == NULL ) {
free(buf);
free(packet_pbuf);
free(packet);
HOOK_MALLOC_FAILED;
ESP_LOGE(TAG, "Failed to allocate the mdns packet");
continue;
}
memcpy(buf, recvbuf, len);
packet_pbuf->next = NULL;
packet_pbuf->payload = buf;
packet_pbuf->tot_len = len;
packet_pbuf->len = len;
packet->tcpip_if = tcpip_if;
packet->pb = packet_pbuf;
packet->src_port = ntohs(port);
memcpy(&packet->src, &addr, sizeof(esp_ip_addr_t));
// TODO(IDF-3651): Add the correct dest addr -- for mdns to decide multicast/unicast
// Currently it's enough to assume the packet is multicast and mdns to check the source port of the packet
memset(&packet->dest, 0, sizeof(esp_ip_addr_t));
packet->multicast = 1;
packet->dest.type = packet->src.type;
packet->ip_protocol =
packet->src.type == ESP_IPADDR_TYPE_V4 ? MDNS_IP_PROTOCOL_V4 : MDNS_IP_PROTOCOL_V6;
if (!_mdns_server || !_mdns_server->action_queue || _mdns_send_rx_action(packet) != ESP_OK) {
ESP_LOGE(TAG, "_mdns_send_rx_action failed!");
free(packet->pb->payload);
free(packet->pb);
free(packet);
}
}
}
}
}
vTaskDelete(NULL);
}
static void mdns_networking_init(void)
{
if (s_run_sock_recv_task == false) {
s_run_sock_recv_task = true;
xTaskCreate( sock_recv_task, "mdns recv task", 3*1024, NULL, 5, NULL );
}
}
static struct udp_pcb* create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
return _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
}
mdns_ip_protocol_t other_ip_proto = ip_protocol==MDNS_IP_PROTOCOL_V4?MDNS_IP_PROTOCOL_V6:MDNS_IP_PROTOCOL_V4;
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
if (_mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb) {
struct udp_pcb* other_pcb = _mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb;
int err = join_mdns_multicast_group(pcb_to_sock(other_pcb), netif, ip_protocol);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
return NULL;
}
return other_pcb;
}
int sock = create_socket(netif);
if (sock < 0) {
ESP_LOGE(TAG, "Failed to create the socket!");
return NULL;
}
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
if (err < 0) {
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
}
return sock_to_pcb(sock);
}
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
{
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = create_pcb(tcpip_if, ip_protocol);
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
mdns_networking_init();
return ESP_OK;
}
static int create_socket(esp_netif_t *netif)
{
#if CONFIG_LWIP_IPV6
int sock = socket(PF_INET6, SOCK_DGRAM, 0);
#else
int sock = socket(PF_INET, SOCK_DGRAM, 0);
#endif
if (sock < 0) {
ESP_LOGE(TAG, "Failed to create socket. errno=%d: %s", errno, strerror(errno));
return -1;
}
int on = 1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) ) < 0) {
ESP_LOGE(TAG, "Failed setsockopt() to set SO_REUSEADDR. errno=%d: %s\n", errno, strerror(errno));
}
// Bind the socket to any address
#if CONFIG_LWIP_IPV6
struct sockaddr_in6 saddr = { INADDR_ANY };
saddr.sin6_family = AF_INET6;
saddr.sin6_port = htons(5353);
bzero(&saddr.sin6_addr.s6_addr, sizeof(saddr.sin6_addr.s6_addr));
int err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6));
if (err < 0) {
ESP_LOGE(TAG, "Failed to bind socket. errno=%d: %s", errno, strerror(errno));
goto err;
}
#else
struct sockaddr_in saddr = { 0 };
saddr.sin_family = AF_INET;
saddr.sin_port = htons(5353);
bzero(&saddr.sin_addr.s_addr, sizeof(saddr.sin_addr.s_addr));
int err = bind(sock, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in));
if (err < 0) {
ESP_LOGE(TAG, "Failed to bind socket. errno=%d: %s", errno, strerror(errno));
goto err;
}
#endif // CONFIG_LWIP_IPV6
struct ifreq ifr;
esp_netif_get_netif_impl_name(netif, ifr.ifr_name);
int ret = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void*)&ifr, sizeof(struct ifreq));
if (ret < 0) {
ESP_LOGE(TAG, "\"%s\" Unable to bind socket to specified interface. errno=%d: %s", esp_netif_get_desc(netif), errno, strerror(errno));
goto err;
}
return sock;
err:
close(sock);
return -1;
}
#if CONFIG_LWIP_IPV6
static int socket_add_ipv6_multicast_group(int sock, esp_netif_t *netif)
{
int ifindex = esp_netif_get_netif_impl_index(netif);
int err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex));
if (err < 0) {
ESP_LOGE(TAG, "Failed to set IPV6_MULTICAST_IF. errno=%d: %s", errno, strerror(errno));
return err;
}
struct ipv6_mreq v6imreq = { 0 };
esp_ip_addr_t multi_addr = ESP_IP6ADDR_INIT(0x000002ff, 0, 0, 0xfb000000);
memcpy(&v6imreq.ipv6mr_multiaddr, &multi_addr.u_addr.ip6.addr, sizeof(v6imreq.ipv6mr_multiaddr));
v6imreq.ipv6mr_interface = ifindex;
err = setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &v6imreq, sizeof(struct ipv6_mreq));
if (err < 0) {
ESP_LOGE(TAG, "Failed to set IPV6_ADD_MEMBERSHIP. errno=%d: %s", errno, strerror(errno));
return err;
}
return err;
}
#endif // CONFIG_LWIP_IPV6
static int socket_add_ipv4_multicast_group(int sock, esp_netif_t *netif)
{
struct ip_mreq imreq = { 0 };
int err = 0;
esp_netif_ip_info_t ip_info = { 0 };
if (esp_netif_get_ip_info(netif, &ip_info) != ESP_OK) {
ESP_LOGE(TAG, "Failed to esp_netif_get_ip_info()");
goto err;
}
imreq.imr_interface.s_addr = ip_info.ip.addr;
esp_ip_addr_t multicast_addr = ESP_IP4ADDR_INIT(224, 0, 0, 251);
imreq.imr_multiaddr.s_addr = multicast_addr.u_addr.ip4.addr;
err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imreq, sizeof(struct ip_mreq));
if (err < 0) {
ESP_LOGE(TAG, "[sock=%d] Failed to set IP_ADD_MEMBERSHIP. errno=%d: %s", sock, errno, strerror(errno));
goto err;
}
err:
return err;
}
static int join_mdns_multicast_group(int sock, esp_netif_t *netif, mdns_ip_protocol_t ip_protocol)
{
if (ip_protocol == MDNS_IP_PROTOCOL_V4) {
return socket_add_ipv4_multicast_group(sock, netif);
}
#if CONFIG_LWIP_IPV6
if (ip_protocol == MDNS_IP_PROTOCOL_V6) {
return socket_add_ipv6_multicast_group(sock, netif);
}
#endif // CONFIG_LWIP_IPV6
return -1;
}

Wyświetl plik

@ -1,53 +0,0 @@
#ifndef ESP_MDNS_NETWORKING_H_
#define ESP_MDNS_NETWORKING_H_
/*
* MDNS Server Networking -- private include
*
*/
#include "mdns.h"
#include "mdns_private.h"
/**
* @brief Queue RX packet action
*/
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t * packet);
/**
* @brief Start PCB
*/
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/**
* @brief Stop PCB
*/
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
/**
* @brief send packet over UDP
*
* @param server The server
* @param data byte array containing the packet data
* @param len length of the packet data
*
* @return length of sent packet or 0 on error
*/
size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len);
/**
* @brief Gets data pointer to the mDNS packet
*/
void* _mdns_get_packet_data(mdns_rx_packet_t *packet);
/**
* @brief Gets data length of c
*/
size_t _mdns_get_packet_len(mdns_rx_packet_t *packet);
/**
* @brief Free the mDNS packet
*/
void _mdns_packet_free(mdns_rx_packet_t *packet);
#endif /* ESP_MDNS_NETWORKING_H_ */

Wyświetl plik

@ -1,493 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef MDNS_PRIVATE_H_
#define MDNS_PRIVATE_H_
#include "sdkconfig.h"
#include "mdns.h"
#include "esp_task.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_timer.h"
//#define MDNS_ENABLE_DEBUG
#ifdef MDNS_ENABLE_DEBUG
#define _mdns_dbg_printf(...) printf(__VA_ARGS__)
#endif
/** mDNS strict mode: Set this to 1 for the mDNS library to strictly follow the RFC6762:
* Strict features:
* - to do not set original questions in response packets per RFC6762, sec 6
*
* The actual configuration is 0, i.e. non-strict mode, since some implementations,
* such as lwIP mdns resolver (used by standard POSIX API like getaddrinfo, gethostbyname)
* could not correctly resolve advertised names.
*/
#ifndef CONFIG_MDNS_STRICT_MODE
#define MDNS_STRICT_MODE 0
#else
#define MDNS_STRICT_MODE 1
#endif
#if !MDNS_STRICT_MODE
/* mDNS responders sometimes repeat queries in responses
* but according to RFC6762, sec 6: Responses MUST NOT contain
* any item in question field */
#define MDNS_REPEAT_QUERY_IN_RESPONSE 1
#endif
/** Number of predefined interfaces */
#ifndef CONFIG_MDNS_PREDEF_NETIF_STA
#define CONFIG_MDNS_PREDEF_NETIF_STA 0
#endif
#ifndef CONFIG_MDNS_PREDEF_NETIF_AP
#define CONFIG_MDNS_PREDEF_NETIF_AP 0
#endif
#ifndef CONFIG_MDNS_PREDEF_NETIF_ETH
#define CONFIG_MDNS_PREDEF_NETIF_ETH 0
#endif
#define MDNS_MAX_PREDEF_INTERFACES (CONFIG_MDNS_PREDEF_NETIF_STA + CONFIG_MDNS_PREDEF_NETIF_AP + CONFIG_MDNS_PREDEF_NETIF_ETH)
/** Number of configured interfaces */
#if MDNS_MAX_PREDEF_INTERFACES > CONFIG_MDNS_MAX_INTERFACES
#warning Number of configured interfaces is less then number of predefined interfaces. Please update CONFIG_MDNS_MAX_INTERFACES.
#define MDNS_MAX_INTERFACES (MDNS_MAX_PREDEF_INTERFACES)
#else
#define MDNS_MAX_INTERFACES (CONFIG_MDNS_MAX_INTERFACES)
#endif
/** The maximum number of services */
#define MDNS_MAX_SERVICES CONFIG_MDNS_MAX_SERVICES
#define MDNS_ANSWER_PTR_TTL 4500
#define MDNS_ANSWER_TXT_TTL 4500
#define MDNS_ANSWER_SRV_TTL 120
#define MDNS_ANSWER_A_TTL 120
#define MDNS_ANSWER_AAAA_TTL 120
#define MDNS_FLAGS_AUTHORITATIVE 0x8400
#define MDNS_FLAGS_DISTRIBUTED 0x0200
#define MDNS_NAME_REF 0xC000
//custom type! only used by this implementation
//to help manage service discovery handling
#define MDNS_TYPE_SDPTR 0x0032
#define MDNS_CLASS_IN 0x0001
#define MDNS_CLASS_ANY 0x00FF
#define MDNS_CLASS_IN_FLUSH_CACHE 0x8001
#define MDNS_ANSWER_ALL 0x3F
#define MDNS_ANSWER_PTR 0x08
#define MDNS_ANSWER_TXT 0x04
#define MDNS_ANSWER_SRV 0x02
#define MDNS_ANSWER_A 0x01
#define MDNS_ANSWER_AAAA 0x10
#define MDNS_ANSWER_NSEC 0x20
#define MDNS_ANSWER_SDPTR 0x80
#define MDNS_ANSWER_AAAA_SIZE 16
#define MDNS_SERVICE_PORT 5353 // UDP port that the server runs on
#define MDNS_SERVICE_STACK_DEPTH CONFIG_MDNS_TASK_STACK_SIZE
#define MDNS_TASK_PRIORITY CONFIG_MDNS_TASK_PRIORITY
#if (MDNS_TASK_PRIORITY > ESP_TASK_PRIO_MAX)
#error "mDNS task priority is higher than ESP_TASK_PRIO_MAX"
#elif (MDNS_TASK_PRIORITY > ESP_TASKD_EVENT_PRIO)
#warning "mDNS task priority is higher than ESP_TASKD_EVENT_PRIO, mDNS library might not work correctly"
#endif
#define MDNS_TASK_AFFINITY CONFIG_MDNS_TASK_AFFINITY
#define MDNS_SERVICE_ADD_TIMEOUT_MS CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS
#define MDNS_PACKET_QUEUE_LEN 16 // Maximum packets that can be queued for parsing
#define MDNS_ACTION_QUEUE_LEN 16 // Maximum actions pending to the server
#define MDNS_TXT_MAX_LEN 1024 // Maximum string length of text data in TXT record
#define MDNS_NAME_MAX_LEN 64 // Maximum string length of hostname, instance, service and proto
#define MDNS_NAME_BUF_LEN (MDNS_NAME_MAX_LEN+1) // Maximum char buffer size to hold hostname, instance, service or proto
#define MDNS_MAX_PACKET_SIZE 1460 // Maximum size of mDNS outgoing packet
#define MDNS_HEAD_LEN 12
#define MDNS_HEAD_ID_OFFSET 0
#define MDNS_HEAD_FLAGS_OFFSET 2
#define MDNS_HEAD_QUESTIONS_OFFSET 4
#define MDNS_HEAD_ANSWERS_OFFSET 6
#define MDNS_HEAD_SERVERS_OFFSET 8
#define MDNS_HEAD_ADDITIONAL_OFFSET 10
#define MDNS_TYPE_OFFSET 0
#define MDNS_CLASS_OFFSET 2
#define MDNS_TTL_OFFSET 4
#define MDNS_LEN_OFFSET 8
#define MDNS_DATA_OFFSET 10
#define MDNS_SRV_PRIORITY_OFFSET 0
#define MDNS_SRV_WEIGHT_OFFSET 2
#define MDNS_SRV_PORT_OFFSET 4
#define MDNS_SRV_FQDN_OFFSET 6
#define MDNS_TIMER_PERIOD_US (CONFIG_MDNS_TIMER_PERIOD_MS*1000)
#define MDNS_SERVICE_LOCK() xSemaphoreTake(_mdns_service_semaphore, portMAX_DELAY)
#define MDNS_SERVICE_UNLOCK() xSemaphoreGive(_mdns_service_semaphore)
#define queueToEnd(type, queue, item) \
if (!queue) { \
queue = item; \
} else { \
type * _q = queue; \
while (_q->next) { _q = _q->next; } \
_q->next = item; \
}
#define queueDetach(type, queue, item) \
if (queue) { \
if (queue == item) { \
queue = queue->next; \
} else { \
type * _q = queue; \
while (_q->next && _q->next != item) { \
_q = _q->next; \
} \
if (_q->next == item) { \
_q->next = item->next; \
item->next = NULL; \
} \
} \
}
#define queueFree(type, queue) while (queue) { type * _q = queue; queue = queue->next; free(_q); }
#define PCB_STATE_IS_PROBING(s) (s->state > PCB_OFF && s->state < PCB_ANNOUNCE_1)
#define PCB_STATE_IS_ANNOUNCING(s) (s->state > PCB_PROBE_3 && s->state < PCB_RUNNING)
#define PCB_STATE_IS_RUNNING(s) (s->state == PCB_RUNNING)
#ifndef HOOK_MALLOC_FAILED
#define HOOK_MALLOC_FAILED ESP_LOGE(TAG, "Cannot allocate memory (line: %d, free heap: %d bytes)", __LINE__, esp_get_free_heap_size());
#endif
typedef size_t mdns_if_t;
typedef enum {
PCB_OFF, PCB_DUP, PCB_INIT,
PCB_PROBE_1, PCB_PROBE_2, PCB_PROBE_3,
PCB_ANNOUNCE_1, PCB_ANNOUNCE_2, PCB_ANNOUNCE_3,
PCB_RUNNING
} mdns_pcb_state_t;
typedef enum {
MDNS_ANSWER, MDNS_NS, MDNS_EXTRA
} mdns_parsed_record_type_t;
typedef enum {
ACTION_SYSTEM_EVENT,
ACTION_HOSTNAME_SET,
ACTION_INSTANCE_SET,
ACTION_SERVICE_ADD,
ACTION_SERVICE_DEL,
ACTION_SERVICE_INSTANCE_SET,
ACTION_SERVICE_PORT_SET,
ACTION_SERVICE_TXT_REPLACE,
ACTION_SERVICE_TXT_SET,
ACTION_SERVICE_TXT_DEL,
ACTION_SERVICE_SUBTYPE_ADD,
ACTION_SERVICES_CLEAR,
ACTION_SEARCH_ADD,
ACTION_SEARCH_SEND,
ACTION_SEARCH_END,
ACTION_TX_HANDLE,
ACTION_RX_HANDLE,
ACTION_TASK_STOP,
ACTION_DELEGATE_HOSTNAME_ADD,
ACTION_DELEGATE_HOSTNAME_REMOVE,
ACTION_MAX
} mdns_action_type_t;
typedef struct {
uint16_t id;
union {
struct {
uint16_t qr :1;
uint16_t opCode :4;
uint16_t aa :1;
uint16_t tc :1;
uint16_t rd :1;
uint16_t ra :1;
uint16_t z :1;
uint16_t ad :1;
uint16_t cd :1;
uint16_t rCode :4;//response/error code
};
uint16_t value;
} flags;
uint16_t questions; //QDCOUNT
uint16_t answers; //ANCOUNT
uint16_t servers; //NSCOUNT
uint16_t additional;//ARCOUNT
} mdns_header_t;
typedef struct {
char host[MDNS_NAME_BUF_LEN]; // hostname for A/AAAA records, instance name for SRV records
char service[MDNS_NAME_BUF_LEN];
char proto[MDNS_NAME_BUF_LEN];
char domain[MDNS_NAME_BUF_LEN];
uint8_t parts;
uint8_t sub;
bool invalid;
} mdns_name_t;
typedef struct mdns_parsed_question_s {
struct mdns_parsed_question_s * next;
uint16_t type;
bool sub;
bool unicast;
char * host;
char * service;
char * proto;
char * domain;
} mdns_parsed_question_t;
typedef struct mdns_parsed_record_s {
struct mdns_parsed_record_s * next;
mdns_parsed_record_type_t record_type;
uint16_t type;
uint16_t clas;
uint8_t flush;
uint32_t ttl;
char * host;
char * service;
char * proto;
char * domain;
uint16_t data_len;
uint8_t *data;
} mdns_parsed_record_t;
typedef struct {
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
esp_ip_addr_t src;
uint16_t src_port;
uint8_t multicast;
uint8_t authoritative;
uint8_t probe;
uint8_t discovery;
uint8_t distributed;
mdns_parsed_question_t * questions;
mdns_parsed_record_t * records;
uint16_t id;
} mdns_parsed_packet_t;
typedef struct {
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
struct pbuf *pb;
esp_ip_addr_t src;
esp_ip_addr_t dest;
uint16_t src_port;
uint8_t multicast;
} mdns_rx_packet_t;
typedef struct mdns_txt_linked_item_s {
const char * key; /*!< item key name */
char * value; /*!< item value string */
uint8_t value_len; /*!< item value length */
struct mdns_txt_linked_item_s * next; /*!< next result, or NULL for the last result in the list */
} mdns_txt_linked_item_t;
typedef struct mdns_subtype_s {
const char *subtype; /*!< subtype */
struct mdns_subtype_s * next; /*!< next result, or NULL for the last result in the list */
} mdns_subtype_t;
typedef struct {
const char * instance;
const char * service;
const char * proto;
const char * hostname;
uint16_t priority;
uint16_t weight;
uint16_t port;
mdns_txt_linked_item_t * txt;
mdns_subtype_t *subtype;
} mdns_service_t;
typedef struct mdns_srv_item_s {
struct mdns_srv_item_s * next;
mdns_service_t * service;
} mdns_srv_item_t;
typedef struct mdns_out_question_s {
struct mdns_out_question_s * next;
uint16_t type;
bool unicast;
const char * host;
const char * service;
const char * proto;
const char * domain;
bool own_dynamic_memory;
} mdns_out_question_t;
typedef struct mdns_host_item_t {
const char * hostname;
mdns_ip_addr_t *address_list;
struct mdns_host_item_t *next;
} mdns_host_item_t;
typedef struct mdns_out_answer_s {
struct mdns_out_answer_s * next;
uint16_t type;
uint8_t bye;
uint8_t flush;
mdns_service_t * service;
mdns_host_item_t* host;
const char * custom_instance;
const char * custom_service;
const char * custom_proto;
} mdns_out_answer_t;
typedef struct mdns_tx_packet_s {
struct mdns_tx_packet_s * next;
uint32_t send_at;
mdns_if_t tcpip_if;
mdns_ip_protocol_t ip_protocol;
esp_ip_addr_t dst;
uint16_t port;
uint16_t flags;
uint8_t distributed;
mdns_out_question_t * questions;
mdns_out_answer_t * answers;
mdns_out_answer_t * servers;
mdns_out_answer_t * additional;
bool queued;
uint16_t id;
} mdns_tx_packet_t;
typedef struct {
mdns_pcb_state_t state;
struct udp_pcb * pcb;
mdns_srv_item_t ** probe_services;
uint8_t probe_services_len;
uint8_t probe_ip;
uint8_t probe_running;
uint16_t failed_probes;
} mdns_pcb_t;
typedef enum {
SEARCH_OFF,
SEARCH_INIT,
SEARCH_RUNNING,
SEARCH_MAX
} mdns_search_once_state_t;
typedef struct mdns_search_once_s {
struct mdns_search_once_s * next;
mdns_search_once_state_t state;
uint32_t started_at;
uint32_t sent_at;
uint32_t timeout;
mdns_query_notify_t notifier;
SemaphoreHandle_t done_semaphore;
uint16_t type;
bool unicast;
uint8_t max_results;
uint8_t num_results;
char * instance;
char * service;
char * proto;
mdns_result_t * result;
} mdns_search_once_t;
typedef struct mdns_server_s {
struct {
mdns_pcb_t pcbs[MDNS_IP_PROTOCOL_MAX];
} interfaces[MDNS_MAX_INTERFACES];
const char * hostname;
const char * instance;
mdns_srv_item_t * services;
SemaphoreHandle_t lock;
QueueHandle_t action_queue;
mdns_tx_packet_t * tx_queue_head;
mdns_search_once_t * search_once;
esp_timer_handle_t timer_handle;
} mdns_server_t;
typedef struct {
mdns_action_type_t type;
union {
struct {
char * hostname;
TaskHandle_t calling_task;
} hostname_set;
char * instance;
struct {
mdns_if_t interface;
mdns_event_actions_t event_action;
} sys_event;
struct {
mdns_srv_item_t * service;
} srv_add;
struct {
mdns_srv_item_t * service;
} srv_del;
struct {
mdns_srv_item_t * service;
char * instance;
} srv_instance;
struct {
mdns_srv_item_t * service;
uint16_t port;
} srv_port;
struct {
mdns_srv_item_t * service;
mdns_txt_linked_item_t * txt;
} srv_txt_replace;
struct {
mdns_srv_item_t * service;
char * key;
char * value;
uint8_t value_len;
} srv_txt_set;
struct {
mdns_srv_item_t * service;
char * key;
} srv_txt_del;
struct {
mdns_srv_item_t * service;
char * subtype;
} srv_subtype_add;
struct {
mdns_search_once_t * search;
} search_add;
struct {
mdns_tx_packet_t * packet;
} tx_handle;
struct {
mdns_rx_packet_t * packet;
} rx_handle;
struct {
const char * hostname;
mdns_ip_addr_t *address_list;
} delegate_hostname;
} data;
} mdns_action_t;
/*
* @brief Convert mnds if to esp-netif handle
*
* @param tcpip_if mdns supported interface as internal enum
*
* @return
* - ptr to esp-netif on success
* - NULL if no available netif for current interface index
*/
esp_netif_t *_mdns_get_esp_netif(mdns_if_t tcpip_if);
#endif /* MDNS_PRIVATE_H_ */

Wyświetl plik

@ -1,8 +0,0 @@
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "esp32c2")
# IDF-5046
return()
endif()
idf_component_register(SRC_DIRS "."
PRIV_REQUIRES cmock test_utils mdns)

Wyświetl plik

@ -1,115 +0,0 @@
#include "test_utils.h"
#include "mdns.h"
#include "esp_event.h"
#include "unity.h"
#define MDNS_HOSTNAME "test-hostname"
#define MDNS_DELEGATE_HOSTNAME "delegate-hostname"
#define MDNS_INSTANCE "test-instance"
#define MDNS_SERVICE_NAME "_http"
#define MDNS_SERVICE_PROTO "_tcp"
#define MDNS_SERVICE_PORT 80
static void yield_to_all_priorities(void)
{
// Lower the test-task priority before testing to ensure other tasks got executed on forced context switch
size_t test_task_prio_before = uxTaskPriorityGet(NULL);
vTaskPrioritySet(NULL, tskIDLE_PRIORITY);
taskYIELD(); // Let the RTOS to switch context
vTaskPrioritySet(NULL, test_task_prio_before);
}
TEST_CASE("mdns api to fail in invalid state", "[mdns][leaks=64]")
{
TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_init() );
TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME) );
TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE) );
TEST_ASSERT_NOT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0) );
}
TEST_CASE("mdns init and deinit", "[mdns][leaks=64]")
{
test_case_uses_tcpip();
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
TEST_ASSERT_EQUAL(ESP_OK, mdns_init() );
yield_to_all_priorities(); // Make sure that mdns task has executed to complete initialization
mdns_free();
esp_event_loop_delete_default();
}
TEST_CASE("mdns api return expected err-code and do not leak memory", "[mdns][leaks=64]")
{
mdns_txt_item_t serviceTxtData[CONFIG_MDNS_MAX_SERVICES] = { {NULL, NULL},
};
mdns_ip_addr_t addr;
addr.addr.type = ESP_IPADDR_TYPE_V4;
addr.addr.u_addr.ip4.addr = esp_ip4addr_aton("127.0.0.1");
addr.next = NULL;
for (int i=0; i<CONFIG_MDNS_MAX_SERVICES; ++i) {
serviceTxtData[i].key = "Key";
serviceTxtData[i].value = "Value";
}
test_case_uses_tcpip();
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
TEST_ASSERT_EQUAL(ESP_OK, mdns_init() );
TEST_ASSERT_EQUAL(ESP_OK, mdns_hostname_set(MDNS_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_add(MDNS_DELEGATE_HOSTNAME, &addr) );
yield_to_all_priorities(); // Make sure that mdns task has executed to add the hostname
TEST_ASSERT_TRUE(mdns_hostname_exists(MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_instance_name_set(MDNS_INSTANCE) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add_for_host(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME,
MDNS_SERVICE_PORT, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_TRUE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, serviceTxtData, CONFIG_MDNS_MAX_SERVICES) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1", "value1") );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_txt_item_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, "key1") );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_port_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 8080) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO) );
yield_to_all_priorities(); // Make sure that mdns task has executed to remove the service
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_add(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_SERVICE_PORT, NULL, 0) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_delegate_hostname_remove(MDNS_DELEGATE_HOSTNAME) );
yield_to_all_priorities(); // Make sure that mdns task has executed to remove the hostname
TEST_ASSERT_FALSE(mdns_service_exists(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, MDNS_DELEGATE_HOSTNAME) );
TEST_ASSERT_EQUAL(ESP_OK, mdns_service_remove_all() );
yield_to_all_priorities(); // Make sure that mdns task has executed to remove all services
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, mdns_service_port_set(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 8080) );
mdns_free();
esp_event_loop_delete_default();
}
TEST_CASE("mdns query api return expected err-code and do not leak memory", "[leaks=64]")
{
mdns_result_t * results = NULL;
esp_ip6_addr_t addr6;
esp_ip4_addr_t addr4;
test_case_uses_tcpip();
TEST_ASSERT_EQUAL(ESP_OK, esp_event_loop_create_default());
TEST_ASSERT_EQUAL(ESP_OK, mdns_init() );
TEST_ASSERT_EQUAL(ESP_OK, mdns_query_ptr(MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, CONFIG_MDNS_MAX_SERVICES, &results) );
mdns_query_results_free(results);
TEST_ASSERT_EQUAL(ESP_OK, mdns_query_srv(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, &results) );
mdns_query_results_free(results);
TEST_ASSERT_EQUAL(ESP_OK, mdns_query_txt(MDNS_INSTANCE, MDNS_SERVICE_NAME, MDNS_SERVICE_PROTO, 10, &results) );
mdns_query_results_free(results);
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, mdns_query_a(MDNS_HOSTNAME, 10, &addr4) );
mdns_query_results_free(results);
TEST_ASSERT_EQUAL(ESP_ERR_NOT_FOUND, mdns_query_aaaa(MDNS_HOSTNAME, 10, &addr6) );
mdns_query_results_free(results);
mdns_free();
esp_event_loop_delete_default();
}

Wyświetl plik

@ -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.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(fuzz_test_update)

Wyświetl plik

@ -1,83 +0,0 @@
TEST_NAME=test
FUZZ=afl-fuzz
COMPONENTS_DIR=../..
COMPILER_ICLUDE_DIR=$(shell echo `which xtensa-esp32-elf-gcc | xargs dirname | xargs dirname`/xtensa-esp32-elf)
CFLAGS=-g -Wno-unused-value -Wno-missing-declarations -Wno-pointer-bool-conversion -Wno-macro-redefined -Wno-int-to-void-pointer-cast -DHOOK_MALLOC_FAILED -DESP_EVENT_H_ -D__ESP_LOG_H__ \
-I. -I.. -I../include -I../private_include -I ./build/config \
-I$(COMPONENTS_DIR) \
-I$(COMPONENTS_DIR)/driver/include \
-I$(COMPONENTS_DIR)/esp_common/include \
-I$(COMPONENTS_DIR)/esp_event/include \
-I$(COMPONENTS_DIR)/esp_eth/include \
-I$(COMPONENTS_DIR)/esp_hw_support/include \
-I$(COMPONENTS_DIR)/esp_netif/include \
-I$(COMPONENTS_DIR)/esp_netif/private_include \
-I$(COMPONENTS_DIR)/esp_netif/lwip \
-I$(COMPONENTS_DIR)/esp_rom/include \
-I$(COMPONENTS_DIR)/esp_system/include \
-I$(COMPONENTS_DIR)/esp_timer/include \
-I$(COMPONENTS_DIR)/esp_wifi/include \
-I$(COMPONENTS_DIR)/freertos/FreeRTOS-Kernel \
-I$(COMPONENTS_DIR)/freertos/FreeRTOS-Kernel/include \
-I$(COMPONENTS_DIR)/freertos/esp_additions/include/freertos \
-I$(COMPONENTS_DIR)/hal/include \
-I$(COMPONENTS_DIR)/hal/esp32/include \
-I$(COMPONENTS_DIR)/heap/include \
-I$(COMPONENTS_DIR)/log/include \
-I$(COMPONENTS_DIR)/lwip/lwip/src/include \
-I$(COMPONENTS_DIR)/lwip/port/esp32/include \
-I$(COMPONENTS_DIR)/lwip/lwip/src/include/lwip/apps \
-I$(COMPONENTS_DIR)/newlib/platform_include \
-I$(COMPONENTS_DIR)/soc/include \
-I$(COMPONENTS_DIR)/soc/include \
-I$(COMPONENTS_DIR)/soc/esp32/include \
-I$(COMPONENTS_DIR)/soc/src/esp32/include \
-I$(COMPONENTS_DIR)/xtensa/include \
-I$(COMPONENTS_DIR)/xtensa/esp32/include \
-I$(COMPILER_ICLUDE_DIR)/include
MDNS_C_DEPENDENCY_INJECTION=-include mdns_di.h
ifeq ($(MDNS_NO_SERVICES),on)
CFLAGS+=-DMDNS_NO_SERVICES
endif
ifeq ($(INSTR),off)
CC=gcc
CFLAGS+=-DINSTR_IS_OFF
TEST_NAME=test_sim
else
CC=afl-clang-fast
endif
CPP=$(CC)
LD=$(CC)
OBJECTS=esp32_mock.o mdns.o test.o esp_netif_mock.o
OS := $(shell uname)
ifeq ($(OS),Darwin)
LDLIBS=
else
LDLIBS=-lbsd
CFLAGS+=-DUSE_BSD_STRING
endif
all: $(TEST_NAME)
%.o: %.c
@echo "[CC] $<"
@$(CC) $(CFLAGS) -c $< -o $@
mdns.o: ../mdns.c
@echo "[CC] $<"
@$(CC) $(CFLAGS) -include mdns_mock.h $(MDNS_C_DEPENDENCY_INJECTION) -c $< -o $@
$(TEST_NAME): $(OBJECTS)
@echo "[LD] $@"
@$(LD) $(OBJECTS) -o $@ $(LDLIBS)
fuzz: $(TEST_NAME)
@$(FUZZ) -i "in" -o "out" -- ./$(TEST_NAME)
clean:
@rm -rf *.o *.SYM $(TEST_NAME) out

Wyświetl plik

@ -1,80 +0,0 @@
## Introduction
This test uses [american fuzzy lop](http://lcamtuf.coredump.cx/afl/) to mangle real mdns packets and look for exceptions caused by the parser.
A few actual packets are collected and exported as bins in the `in` folder, which is then passed as input to AFL when testing. The setup procedure for the test includes all possible services and scenarios that could be used with the given input packets.The output of the parser before fuzzing can be found in [input_packets.txt](input_packets.txt)
## Building and running the tests using AFL
To build and run the tests using AFL(afl-clang-fast) instrumentation
```bash
cd $IDF_PATH/components/mdns/test_afl_host
make fuzz
```
(Please note you have to install AFL instrumentation first, check `Installing AFL` section)
## Building the tests using GCC INSTR(off)
To build the tests without AFL instrumentations and instead of that use GCC compiler(In this case it will only check for compilation issues and will not run AFL tests).
```bash
cd $IDF_PATH/components/mdns/test_afl_host
make INSTR=off
```
Note, that this setup is useful if we want to reproduce issues reported by fuzzer tests executed in the CI, or to simulate how the packet parser treats the input packets on the host machine.
## Installing AFL
To run the test yourself, you need to download the [latest afl archive](http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz) and extract it to a folder on your computer.
The rest of the document will refer to that folder as ```PATH_TO_AFL```.
### Preparation
- On Mac, you will need to install the latest Xcode and llvm support from [Homebrew](https://brew.sh)
```bash
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install --with-clang --with-lld --HEAD llvm
export PATH="/usr/local/opt/llvm/bin:$PATH"
```
- On Ubuntu you need the following packages:
```bash
sudo apt-get install make clang-4.0(or <=4.0) llvm-4.0(or <=4.0) libbsd-dev
```
Please note that if specified package version can't be installed(due to system is the latest), you can download, build and install it manually.
### Compile AFL
Compiling AFL is as easy as running make:
```bash
cd [PATH_TO_AFL]
make
cd llvm_mode/
make
```
After successful compilation, you can export the following variables to your shell (you can also add them to your profile if you want to use AFL in other projects).
```bash
export AFL_PATH=[PATH_TO_AFL]
export PATH="$AFL_PATH:$PATH"
```
Please note LLVM must be <=4.0.0, otherwise afl does not compile, as there are some limitations with building AFL on MacOS/Linux with the latest LLVM. Also, Windows build on cygwin is not fully supported.
## Additional info
Apple has a crash reporting service that could interfere with AFLs normal operation. To turn that off, run the following command:
```bash
launchctl unload -w /System/Library/LaunchAgents/com.apple.ReportCrash.plist
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.ReportCrash.Root.plist
```
Ubuntu has a similar service. To turn that off, run as root:
```bash
echo core >/proc/sys/kernel/core_pattern
```

Wyświetl plik

@ -1,111 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include "esp32_mock.h"
void* g_queue;
int g_queue_send_shall_fail = 0;
int g_size = 0;
const char * WIFI_EVENT = "wifi_event";
const char * ETH_EVENT = "eth_event";
esp_err_t esp_event_handler_register(const char * event_base,
int32_t event_id,
void* event_handler,
void* event_handler_arg)
{
return ESP_OK;
}
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler)
{
return ESP_OK;
}
esp_err_t esp_timer_delete(esp_timer_handle_t timer)
{
return ESP_OK;
}
esp_err_t esp_timer_stop(esp_timer_handle_t timer)
{
return ESP_OK;
}
esp_err_t esp_timer_start_periodic(esp_timer_handle_t timer, uint64_t period)
{
return ESP_OK;
}
esp_err_t esp_timer_create(const esp_timer_create_args_t* create_args,
esp_timer_handle_t* out_handle)
{
return ESP_OK;
}
uint32_t xTaskGetTickCount(void)
{
static uint32_t tick = 0;
return tick++;
}
/// Queue mock
QueueHandle_t xQueueCreate( uint32_t uxQueueLength, uint32_t uxItemSize )
{
g_size = uxItemSize;
g_queue = malloc((uxQueueLength)*(uxItemSize));
return g_queue;
}
void vQueueDelete( QueueHandle_t xQueue )
{
free(xQueue);
}
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait)
{
if (g_queue_send_shall_fail)
{
return pdFALSE;
}
else
{
memcpy(xQueue, pvItemToQueue, g_size);
return pdPASS;
}
}
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait)
{
return pdFALSE;
}
void GetLastItem(void *pvBuffer)
{
memcpy(pvBuffer, g_queue, g_size);
}
void ForceTaskDelete(void)
{
g_queue_send_shall_fail = 1;
}
TaskHandle_t xTaskGetCurrentTaskHandle(void)
{
return NULL;
}
void xTaskNotifyGive(TaskHandle_t task)
{
return;
}
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t * value, TickType_t wait_time)
{
return pdTRUE;
}

Wyświetl plik

@ -1,146 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP32_COMPAT_H_
#define _ESP32_COMPAT_H_
// Skip these include files
#define ESP_MDNS_NETWORKING_H_
#define INC_FREERTOS_H
#define QUEUE_H
#define SEMAPHORE_H
#define _ESP_TASK_H_
#ifdef USE_BSD_STRING
#include <features.h>
#include <bsd/string.h>
#endif
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#include <sys/time.h>
#include "esp_timer.h"
#define ESP_FAIL -1
#define ESP_ERR_NO_MEM 0x101
#define ESP_ERR_INVALID_ARG 0x102
#define ESP_ERR_INVALID_STATE 0x103
#define ESP_ERR_INVALID_SIZE 0x104
#define ESP_ERR_NOT_FOUND 0x105
#define ESP_ERR_NOT_SUPPORTED 0x106
#define ESP_ERR_TIMEOUT 0x107
#define ESP_ERR_INVALID_RESPONSE 0x108
#define ESP_ERR_INVALID_CRC 0x109
#define pdTRUE true
#define pdFALSE false
#define pdPASS ( pdTRUE )
#define pdFAIL ( pdFALSE )
#define portMAX_DELAY 0xFFFFFFFF
#define portTICK_PERIOD_MS 1
#define ESP_LOGW(a,b)
#define ESP_LOGD(a,b)
#define ESP_LOGE(a,b,c)
#define ESP_LOGV(a,b,c,d)
#define LWIP_HDR_PBUF_H
#define __ESP_RANDOM_H__
#define INC_TASK_H
#define pdMS_TO_TICKS(a) a
#define portTICK_PERIOD_MS 10
#define xSemaphoreTake(s,d) true
#define xTaskDelete(a)
#define vTaskDelete(a) free(a)
#define xSemaphoreGive(s)
#define xQueueCreateMutex(s)
#define _mdns_pcb_init(a,b) true
#define _mdns_pcb_deinit(a,b) true
#define xSemaphoreCreateMutex() malloc(1)
#define xSemaphoreCreateBinary() malloc(1)
#define vSemaphoreDelete(s) free(s)
#define queueQUEUE_TYPE_MUTEX ( ( uint8_t ) 1U
#define xTaskCreatePinnedToCore(a,b,c,d,e,f,g) *(f) = malloc(1)
#define vTaskDelay(m) usleep((m)*0)
#define esp_random() (rand()%UINT32_MAX)
#define ESP_TASK_PRIO_MAX 25
#define ESP_TASKD_EVENT_PRIO 5
#define _mdns_udp_pcb_write(tcpip_if, ip_protocol, ip, port, data, len) len
#define TaskHandle_t TaskHandle_t
typedef int32_t esp_err_t;
typedef void * SemaphoreHandle_t;
typedef void * QueueHandle_t;
typedef void * TaskHandle_t;
typedef int BaseType_t;
typedef uint32_t TickType_t;
extern const char * WIFI_EVENT;
extern const char * IP_EVENT;
extern const char * ETH_EVENT;
struct udp_pcb {
uint8_t dummy;
};
struct ip4_addr {
uint32_t addr;
};
typedef struct ip4_addr ip4_addr_t;
struct ip6_addr {
uint32_t addr[4];
};
typedef struct ip6_addr ip6_addr_t;
typedef void* system_event_t;
struct pbuf {
struct pbuf *next;
void *payload;
uint16_t tot_len;
uint16_t len;
uint8_t /*pbuf_type*/ type;
uint8_t flags;
uint16_t ref;
};
uint32_t xTaskGetTickCount(void);
typedef void (*esp_timer_cb_t)(void* arg);
// Queue mock
QueueHandle_t xQueueCreate( uint32_t uxQueueLength,
uint32_t uxItemSize );
void vQueueDelete( QueueHandle_t xQueue );
uint32_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);
uint32_t xQueueReceive(QueueHandle_t xQueue, void *pvBuffer, TickType_t xTicksToWait);
void GetLastItem(void *pvBuffer);
void ForceTaskDelete(void);
esp_err_t esp_event_handler_register(const char * event_base, int32_t event_id, void* event_handler, void* event_handler_arg);
esp_err_t esp_event_handler_unregister(const char * event_base, int32_t event_id, void* event_handler);
TaskHandle_t xTaskGetCurrentTaskHandle(void);
void xTaskNotifyGive(TaskHandle_t task);
BaseType_t xTaskNotifyWait(uint32_t bits_entry_clear, uint32_t bits_exit_clear, uint32_t *value, TickType_t wait_time );
#endif //_ESP32_COMPAT_H_

Wyświetl plik

@ -1,9 +0,0 @@
#pragma once
#define IRAM_ATTR
#define FLAG_ATTR(TYPE)
#define QUEUE_H
#define __ARCH_CC_H__
#define __XTENSA_API_H__
#define SSIZE_MAX INT_MAX
#define LWIP_HDR_IP6_ADDR_H
#define LWIP_HDR_IP4_ADDR_H

Wyświetl plik

@ -1,63 +0,0 @@
// Copyright 2020 Espressif Systems (Shanghai) CO LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include "esp32_mock.h"
typedef struct esp_netif_s esp_netif_t;
typedef struct esp_netif_ip_info esp_netif_ip_info_t;
typedef struct esp_netif_dhcp_status esp_netif_dhcp_status_t;
const char * IP_EVENT = "IP_EVENT";
esp_err_t esp_netif_add_to_list(esp_netif_t *netif)
{
return ESP_OK;
}
esp_err_t esp_netif_remove_from_list(esp_netif_t *netif)
{
return ESP_ERR_NOT_FOUND;
}
esp_netif_t* esp_netif_next(esp_netif_t* netif)
{
return NULL;
}
esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif)
{
return NULL;
}
esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
{
return NULL;
}
esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_info)
{
return ESP_ERR_NOT_SUPPORTED;
}
esp_err_t esp_netif_dhcpc_get_status(esp_netif_t *esp_netif, esp_netif_dhcp_status_t *status)
{
return ESP_ERR_NOT_SUPPORTED;
}

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -1,166 +0,0 @@
Input: in/test-14.bin
Packet Length: 568
Questions: 18
Q: _airport._tcp.local. PTR IN
Q: _http._tcp.local. PTR IN
Q: _printer._tcp.local. PTR IN
Q: _sub._http._tcp.local. PTR IN
Q: _airplay._tcp.local. PTR IN
Q: _raop._tcp.local. PTR IN
Q: _uscan._tcp.local. PTR IN
Q: _uscans._tcp.local. PTR IN
Q: _ippusb._tcp.local. PTR IN
Q: _scanner._tcp.local. PTR IN
Q: _ipp._tcp.local. PTR IN
Q: _ipps._tcp.local. PTR IN
Q: _pdl-datastream._tcp.local. PTR IN
Q: _ptp._tcp.local. PTR IN
Q: _sleep-proxy._udp.local. PTR IN
Q: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. TXT IN
Q: Hristo's AirPort Express._airport._tcp.local. TXT IN
Q: Hristo's Time Capsule._airport._tcp.local. TXT IN
Answers: 7 + 0
A: _airport._tcp.local. PTR IN 2272 [2] Hristo's AirPort Express._airport._tcp.local.
A: _airport._tcp.local. PTR IN 2272 [2] Hristo's Time Capsule._airport._tcp.local.
A: _http._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._http._tcp.local.
A: _printer._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._printer._tcp.local.
A: _ipp._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._ipp._tcp.local.
A: _pdl-datastream._tcp.local. PTR IN 2535 [23] HP LaserJet CP1025nw._pdl-datastream._tcp.local.
A: _sleep-proxy._udp.local. PTR IN 2535 [38] 50-34-10-70.1 Hristo's Time Capsule._sleep-proxy._udp.local.
Input: in/test-15.bin
Packet Length: 524
Answers: 3 + 3
A: Hristo's AirPort Express._airport._tcp.local. TXT IN FLUSH 4500 [166] waMA=98-01-A7-E5-8F-A1,raMA=98-01-A7-E8-C2-2E,raM2=98-01-A7-E8-C2-2F,raNm=your-ssid,raCh=1,rCh2=52,raSt=0,raNA=1,syFl=0x8A0C,syAP=115,syVs=7.6.8,srcv=76800.1,bjSd=23
A: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. TXT IN FLUSH 4500 [134] txtvers=1; ch=2; cn=0,1; et=0,4; sv=false; da=true; sr=44100; ss=16; pw=false; vn=65537; tp=TCP,UDP; vs=105.1; am=AirPort10,115; fv=76800.1; sf=0x1
A: _raop._tcp.local. PTR IN 4500 [2] 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local.
A: 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. SRV IN FLUSH 120 [32] 5000 Hristos-AirPort-Express.local.
A: Hristo's AirPort Express.local. NSEC IN FLUSH 4500 [9] Hristo's AirPort Express._airport._tcp.local. 00 05 00 00 80 00 40
A: 9801A7E58FA1@Hristo's AirPort Express.local. NSEC IN FLUSH 4500 [9] 9801A7E58FA1@Hristo's AirPort Express._raop._tcp.local. 00 05 00 00 80 00 40
Input: in/test-16.bin
Packet Length: 254
Answers: 1 + 1
A: Hristo's Time Capsule._airport._tcp.local. TXT IN FLUSH 4500 [168] waMA=70-73-CB-B4-C9-B3,raMA=70-73-CB-BB-04-E7,raM2=70-73-CB-BB-04-E8,raNm=nbis-test,raCh=11,rCh2=132,raSt=0,raNA=0,syFl=0x820C,syAP=116,syVs=7.6.8,srcv=76800.1,bjSd=30
A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._airport._tcp.local. 00 05 00 00 80 00 40
Input: in/test-28.bin
Packet Length: 62
Questions: 1
Q: Hristo's Time Capsule._afpovertcp._tcp.local. SRV IN FLUSH
Input: in/test-29.bin
Packet Length: 39
Questions: 2
Q: minifritz.local. A IN FLUSH
Q: minifritz.local. AAAA IN FLUSH
Input: in/test-31.bin
Packet Length: 91
Answers: 2 + 1
A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09
A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16
A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08
Input: in/test-53.bin
Packet Length: 140
Questions: 2
Q: _smb._tcp.local. PTR IN
Q: Sofiya-Ivanovas-MacBook.local. A IN
Answers: 2 + 0
A: _smb._tcp.local. PTR IN 3061 [29] Sofiya Ivanovas MacBook._smb._tcp.local.
A: _smb._tcp.local. PTR IN 3062 [24] Hristo's Time Capsule._smb._tcp.local.
Input: in/test-56.bin
Packet Length: 262
Answers: 2 + 6
A: Hristos Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16
A: _smb._tcp.local. PTR IN 4500 [22] Hristos Mac mini._smb._tcp.local.
A: Hristos Mac mini._smb._tcp.local. TXT IN FLUSH 4500 [1]
A: Hristos Mac mini._smb._tcp.local. SRV IN FLUSH 120 [18] 445 minifritz.local.
A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09
A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16
A: Hristos Mac mini.local. NSEC IN FLUSH 4500 [9] Hristos Mac mini._smb._tcp.local. 00 05 00 00 80 00 40
A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08
Input: in/test-63.bin
Packet Length: 147
Questions: 2
Q: _afpovertcp._tcp.local. PTR IN
Q: Sofiya-Ivanovas-MacBook.local. A IN
Answers: 2 + 0
A: _afpovertcp._tcp.local. PTR IN 2881 [29] Sofiya Ivanovas MacBook._afpovertcp._tcp.local.
A: _afpovertcp._tcp.local. PTR IN 2881 [24] Hristo's Time Capsule._afpovertcp._tcp.local.
Input: in/test-66.bin
Packet Length: 269
Answers: 2 + 6
A: Hristos Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16
A: _afpovertcp._tcp.local. PTR IN 4500 [22] Hristos Mac mini._afpovertcp._tcp.local.
A: Hristos Mac mini._afpovertcp._tcp.local. TXT IN FLUSH 4500 [1]
A: Hristos Mac mini._afpovertcp._tcp.local. SRV IN FLUSH 120 [18] 548 minifritz.local.
A: minifritz.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:142e:54ff:b8c4:fd09
A: minifritz.local. A IN FLUSH 120 [4] 192.168.254.16
A: Hristos Mac mini.local. NSEC IN FLUSH 4500 [9] Hristos Mac mini._afpovertcp._tcp.local. 00 05 00 00 80 00 40
A: minifritz.local. NSEC IN FLUSH 120 [8] minifritz...local. 00 04 40 00 00 08
Input: in/test-83.bin
Packet Length: 105
Answers: 1 + 2
A: Sofiya-Ivanovas-MacBook.local. A IN FLUSH 120 [4] 192.168.254.20
A: Sofiya-Ivanovas-MacBook.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:021c:b3ff:feb2:72a3
A: Sofiya-Ivanovas-MacBook.local. NSEC IN FLUSH 120 [8] Sofiya-Ivanovas-MacBook...local. 00 04 40 00 00 08
Input: in/test-88.bin
Packet Length: 48
Questions: 2
Q: _rfb._tcp.local. PTR IN
Q: _airport._tcp.local. PTR IN
Input: in/test-89.bin
Packet Length: 459
Answers: 2 + 7
A: _airport._tcp.local. PTR IN 4500 [24] Hristo's Time Capsule._airport._tcp.local.
A: Hristo's Time Capsule._device-info._tcp.local. TXT IN 4500 [23] model=TimeCapsule6,116
A: Hristos-Time-Capsule.local. A IN FLUSH 120 [4] 192.168.254.49
A: Hristo's Time Capsule._airport._tcp.local. TXT IN FLUSH 4500 [168] waMA=70-73-CB-B4-C9-B3,raMA=70-73-CB-BB-04-E7,raM2=70-73-CB-BB-04-E8,raNm=nbis-test,raCh=11,rCh2=132,raSt=0,raNA=0,syFl=0x820C,syAP=116,syVs=7.6.8,srcv=76800.1,bjSd=30
A: Hristos-Time-Capsule.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:7273:cbff:feb4:c9b3
A: Hristo's Time Capsule._airport._tcp.local. SRV IN FLUSH 120 [8] 5009 Hristos-Time-Capsule.local.
A: Hristos-Time-Capsule.local. A IN FLUSH 120 [4] 169.254.23.40
A: Hristos-Time-Capsule.local. NSEC IN FLUSH 120 [8] Hristos-Time-Capsule...local. 00 04 40 00 00 08
A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._airport._tcp.local. 00 05 00 00 80 00 40
Input: in/test-91.bin
Packet Length: 279
Answers: 2 + 6
A: Sofiya Ivanovas MacBook._device-info._tcp.local. TXT IN 4500 [17] model=Macmini2,1
A: _rfb._tcp.local. PTR IN 4500 [29] Sofiya Ivanovas MacBook._rfb._tcp.local.
A: Sofiya Ivanovas MacBook._rfb._tcp.local. TXT IN FLUSH 4500 [1]
A: Sofiya Ivanovas MacBook._rfb._tcp.local. SRV IN FLUSH 120 [32] 5900 Sofiya-Ivanovas-MacBook.local.
A: Sofiya-Ivanovas-MacBook.local. AAAA IN FLUSH 120 [16] fe80:0000:0000:0000:021c:b3ff:feb2:72a3
A: Sofiya-Ivanovas-MacBook.local. A IN FLUSH 120 [4] 192.168.254.20
A: Sofiya Ivanovas MacBook.local. NSEC IN FLUSH 4500 [9] Sofiya Ivanovas MacBook._rfb._tcp.local. 00 05 00 00 80 00 40
A: Sofiya-Ivanovas-MacBook.local. NSEC IN FLUSH 120 [8] Sofiya-Ivanovas-MacBook...local. 00 04 40 00 00 08
Input: in/test-95.bin
Packet Length: 286
Questions: 3
Q: _afpovertcp._tcp.local. PTR IN
Q: _smb._tcp.local. PTR IN
Q: _adisk._tcp.local. PTR IN
Answers: 6 + 0
A: _afpovertcp._tcp.local. PTR IN 2353 [29] Sofiya Ivanovas MacBook._afpovertcp._tcp.local.
A: _afpovertcp._tcp.local. PTR IN 3973 [22] Hristos Mac mini._afpovertcp._tcp.local.
A: _afpovertcp._tcp.local. PTR IN 2353 [24] Hristo's Time Capsule._afpovertcp._tcp.local.
A: _smb._tcp.local. PTR IN 2353 [29] Sofiya Ivanovas MacBook._smb._tcp.local.
A: _smb._tcp.local. PTR IN 3792 [22] Hristos Mac mini._smb._tcp.local.
A: _smb._tcp.local. PTR IN 2353 [24] Hristo's Time Capsule._smb._tcp.local.
Input: in/test-96.bin
Packet Length: 319
Answers: 2 + 3
A: Hristo's Time Capsule._device-info._tcp.local. TXT IN 4500 [23] model=TimeCapsule6,116
A: _adisk._tcp.local. PTR IN 4500 [24] Hristo's Time Capsule._adisk._tcp.local.
A: Hristo's Time Capsule._adisk._tcp.local. TXT IN FLUSH 4500 [110] sys=waMA=70:73:CB:B4:C9:B3,adVF=0x1000; dk2=adVF=0x1083,adVN=Capsule,adVU=55fabb8b-a63b-5441-9874-6edb504eb30a
A: Hristo's Time Capsule._adisk._tcp.local. SRV IN FLUSH 120 [29] 9 Hristos-Time-Capsule.local.
A: Hristo's Time Capsule.local. NSEC IN FLUSH 4500 [9] Hristo's Time Capsule._adisk._tcp.local. 00 05 00 00 80 00 40

Wyświetl plik

@ -1,56 +0,0 @@
/*
* MDNS Dependecy injection -- preincluded to inject interface test functions into static variables
*
*/
#include "mdns.h"
#include "mdns_private.h"
void (*mdns_test_static_execute_action)(mdns_action_t *) = NULL;
mdns_srv_item_t * (*mdns_test_static_mdns_get_service_item)(const char * service, const char * proto, const char *hostname) = NULL;
mdns_search_once_t *(*mdns_test_static_search_init)(const char *name, const char *service, const char *proto, uint16_t type, bool unicast,
uint32_t timeout, uint8_t max_results,
mdns_query_notify_t notifier) = NULL;
esp_err_t (*mdns_test_static_send_search_action)(mdns_action_type_t type, mdns_search_once_t * search) = NULL;
void (*mdns_test_static_search_free)(mdns_search_once_t * search) = NULL;
static void _mdns_execute_action(mdns_action_t * action);
static mdns_srv_item_t * _mdns_get_service_item(const char * service, const char * proto, const char *hostname);
static mdns_search_once_t *_mdns_search_init(const char *name, const char *service, const char *proto, uint16_t type, bool unicast,
uint32_t timeout, uint8_t max_results, mdns_query_notify_t notifier);
static esp_err_t _mdns_send_search_action(mdns_action_type_t type, mdns_search_once_t * search);
static void _mdns_search_free(mdns_search_once_t * search);
void mdns_test_init_di(void)
{
mdns_test_static_execute_action = _mdns_execute_action;
mdns_test_static_mdns_get_service_item = _mdns_get_service_item;
mdns_test_static_search_init = _mdns_search_init;
mdns_test_static_send_search_action = _mdns_send_search_action;
mdns_test_static_search_free = _mdns_search_free;
}
void mdns_test_execute_action(void * action)
{
mdns_test_static_execute_action((mdns_action_t *)action);
}
void mdns_test_search_free(mdns_search_once_t * search)
{
return mdns_test_static_search_free(search);
}
esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t * search)
{
return mdns_test_static_send_search_action(type, search);
}
mdns_search_once_t * mdns_test_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results)
{
return mdns_test_static_search_init(name, service, proto, type, timeout, type != MDNS_TYPE_PTR, max_results, NULL);
}
mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto)
{
return mdns_test_static_mdns_get_service_item(service, proto, NULL);
}

Wyświetl plik

@ -1,21 +0,0 @@
#pragma once
#include "esp32_mock.h"
#include "mdns.h"
#include "mdns_private.h"
static inline void* _mdns_get_packet_data(mdns_rx_packet_t *packet)
{
return packet->pb->payload;
}
static inline size_t _mdns_get_packet_len(mdns_rx_packet_t *packet)
{
return packet->pb->len;
}
static inline void _mdns_packet_free(mdns_rx_packet_t *packet)
{
free(packet->pb);
free(packet);
}

Wyświetl plik

@ -1,417 +0,0 @@
/*
* This config file commited in order to not run `idf.py reconfigure` each time when running fuzzer test. You can modify it manually or run `idf.py reconfigure` to generate new one if needed.
* Espressif IoT Development Framework (ESP-IDF) Configuration Header
*/
#pragma once
#define CONFIG_IDF_TARGET "esp32"
#define CONFIG_IDF_TARGET_ESP32 1
#define CONFIG_IDF_FIRMWARE_CHIP_ID 0x0000
#define CONFIG_SDK_TOOLPREFIX "xtensa-esp32-elf-"
#define CONFIG_APP_BUILD_TYPE_APP_2NDBOOT 1
#define CONFIG_APP_BUILD_GENERATE_BINARIES 1
#define CONFIG_APP_BUILD_BOOTLOADER 1
#define CONFIG_APP_BUILD_USE_FLASH_SECTIONS 1
#define CONFIG_APP_COMPILE_TIME_DATE 1
#define CONFIG_APP_RETRIEVE_LEN_ELF_SHA 16
#define CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE 1
#define CONFIG_BOOTLOADER_LOG_LEVEL_INFO 1
#define CONFIG_BOOTLOADER_LOG_LEVEL 3
#define CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V 1
#define CONFIG_BOOTLOADER_WDT_ENABLE 1
#define CONFIG_BOOTLOADER_WDT_TIME_MS 9000
#define CONFIG_BOOTLOADER_RESERVE_RTC_SIZE 0x0
#define CONFIG_ESPTOOLPY_WITH_STUB 1
#define CONFIG_ESPTOOLPY_FLASHMODE_DIO 1
#define CONFIG_ESPTOOLPY_FLASHMODE "dio"
#define CONFIG_ESPTOOLPY_FLASHFREQ_40M 1
#define CONFIG_ESPTOOLPY_FLASHFREQ "40m"
#define CONFIG_ESPTOOLPY_FLASHSIZE_2MB 1
#define CONFIG_ESPTOOLPY_FLASHSIZE "2MB"
#define CONFIG_ESPTOOLPY_FLASHSIZE_DETECT 1
#define CONFIG_ESPTOOLPY_BEFORE_RESET 1
#define CONFIG_ESPTOOLPY_BEFORE "default_reset"
#define CONFIG_ESPTOOLPY_AFTER_RESET 1
#define CONFIG_ESPTOOLPY_AFTER "hard_reset"
#define CONFIG_PARTITION_TABLE_SINGLE_APP 1
#define CONFIG_PARTITION_TABLE_CUSTOM_FILENAME "partitions.csv"
#define CONFIG_PARTITION_TABLE_FILENAME "partitions_singleapp.csv"
#define CONFIG_PARTITION_TABLE_OFFSET 0x8000
#define CONFIG_PARTITION_TABLE_MD5 1
#define CONFIG_COMPILER_OPTIMIZATION_DEFAULT 1
#define CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE 1
#define CONFIG_COMPILER_STACK_CHECK_MODE_NONE 1
#define CONFIG_APPTRACE_DEST_NONE 1
#define CONFIG_APPTRACE_LOCK_ENABLE 1
#define CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF 0
#define CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF 0
#define CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF 0
#define CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF 0
#define CONFIG_BTDM_CTRL_PINNED_TO_CORE 0
#define CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF 1
#define CONFIG_BTDM_RESERVE_DRAM 0x0
#define CONFIG_COAP_MBEDTLS_PSK 1
#define CONFIG_COAP_LOG_DEFAULT_LEVEL 0
#define CONFIG_ADC_DISABLE_DAC 1
#define CONFIG_SPI_MASTER_ISR_IN_IRAM 1
#define CONFIG_SPI_SLAVE_ISR_IN_IRAM 1
#define CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4 1
#define CONFIG_EFUSE_MAX_BLK_LEN 192
#define CONFIG_ESP_TLS_USING_MBEDTLS 1
#define CONFIG_ESP32_REV_MIN_0 1
#define CONFIG_ESP32_REV_MIN 0
#define CONFIG_ESP32_DPORT_WORKAROUND 1
#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 1
#define CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ 160
#define CONFIG_ESP32_TRACEMEM_RESERVE_DRAM 0x0
#define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR 1
#define CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES 4
#define CONFIG_ULP_COPROC_RESERVE_MEM 0
#define CONFIG_ESP_DEBUG_OCDAWARE 1
#define CONFIG_ESP_BROWNOUT_DET 1
#define CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0 1
#define CONFIG_ESP_BROWNOUT_DET_LVL 0
#define CONFIG_ESP32_REDUCE_PHY_TX_POWER 1
#define CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT 1
#define CONFIG_RTC_CLK_SRC_INT_RC 1
#define CONFIG_RTC_CLK_CAL_CYCLES 1024
#define CONFIG_ESP_SLEEP_DEEP_SLEEP_WAKEUP_DELAY 2000
#define CONFIG_ESP32_XTAL_FREQ_40 1
#define CONFIG_ESP32_XTAL_FREQ 40
#define CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL 5
#define CONFIG_ADC_CAL_EFUSE_TP_ENABLE 1
#define CONFIG_ADC_CAL_EFUSE_VREF_ENABLE 1
#define CONFIG_ADC_CAL_LUT_ENABLE 1
#define CONFIG_ESP_ERR_TO_NAME_LOOKUP 1
#define CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE 32
#define CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE 2304
#define CONFIG_ESP_MAIN_TASK_STACK_SIZE 3584
#define CONFIG_ESP_IPC_TASK_STACK_SIZE 1024
#define CONFIG_ESP_IPC_USES_CALLERS_PRIORITY 1
#define CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE 2048
#define CONFIG_ESP_CONSOLE_UART_DEFAULT 1
#define CONFIG_ESP_CONSOLE_UART_NUM 0
#define CONFIG_ESP_CONSOLE_UART_TX_GPIO 1
#define CONFIG_ESP_CONSOLE_UART_RX_GPIO 3
#define CONFIG_ESP_CONSOLE_UART_BAUDRATE 115200
#define CONFIG_ESP_INT_WDT 1
#define CONFIG_ESP_INT_WDT_TIMEOUT_MS 300
#define CONFIG_ESP_INT_WDT_CHECK_CPU1 1
#define CONFIG_ESP_TASK_WDT 1
#define CONFIG_ESP_TASK_WDT_TIMEOUT_S 5
#define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 1
#define CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1 1
#define CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA 1
#define CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP 1
#define CONFIG_ESP_MAC_ADDR_UNIVERSE_BT 1
#define CONFIG_ESP_MAC_ADDR_UNIVERSE_BT_OFFSET 2
#define CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH 1
#define CONFIG_ETH_ENABLED 1
#define CONFIG_ETH_USE_ESP32_EMAC 1
#define CONFIG_ETH_PHY_INTERFACE_RMII 1
#define CONFIG_ETH_RMII_CLK_INPUT 1
#define CONFIG_ETH_RMII_CLK_IN_GPIO 0
#define CONFIG_ETH_DMA_BUFFER_SIZE 512
#define CONFIG_ETH_DMA_RX_BUFFER_NUM 10
#define CONFIG_ETH_DMA_TX_BUFFER_NUM 10
#define CONFIG_ETH_USE_SPI_ETHERNET 1
#define CONFIG_ESP_EVENT_POST_FROM_ISR 1
#define CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR 1
#define CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS 1
#define CONFIG_HTTPD_MAX_REQ_HDR_LEN 512
#define CONFIG_HTTPD_MAX_URI_LEN 512
#define CONFIG_HTTPD_ERR_RESP_NO_DELAY 1
#define CONFIG_HTTPD_PURGE_BUF_LEN 32
#define CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL 120
#define CONFIG_ESP_NETIF_TCPIP_LWIP 1
#define CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT 1
#define CONFIG_ESP_TIMER_TASK_STACK_SIZE 3584
#define CONFIG_ESP_TIMER_IMPL_TG0_LAC 1
#define CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM 10
#define CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM 32
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER 1
#define CONFIG_ESP32_WIFI_TX_BUFFER_TYPE 1
#define CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM 32
#define CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED 1
#define CONFIG_ESP32_WIFI_TX_BA_WIN 6
#define CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED 1
#define CONFIG_ESP32_WIFI_RX_BA_WIN 6
#define CONFIG_ESP32_WIFI_NVS_ENABLED 1
#define CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 1
#define CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN 752
#define CONFIG_ESP32_WIFI_MGMT_SBUF_NUM 32
#define CONFIG_ESP32_WIFI_IRAM_OPT 1
#define CONFIG_ESP32_WIFI_RX_IRAM_OPT 1
#define CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE 1
#define CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE 1
#define CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER 20
#define CONFIG_ESP32_PHY_MAX_TX_POWER 20
#define CONFIG_ESP_COREDUMP_ENABLE_TO_NONE 1
#define CONFIG_FATFS_CODEPAGE_437 1
#define CONFIG_FATFS_CODEPAGE 437
#define CONFIG_FATFS_LFN_NONE 1
#define CONFIG_FATFS_FS_LOCK 0
#define CONFIG_FATFS_TIMEOUT_MS 10000
#define CONFIG_FATFS_PER_FILE_CACHE 1
#define CONFIG_FMB_COMM_MODE_RTU_EN 1
#define CONFIG_FMB_COMM_MODE_ASCII_EN 1
#define CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND 150
#define CONFIG_FMB_MASTER_DELAY_MS_CONVERT 200
#define CONFIG_FMB_QUEUE_LENGTH 20
#define CONFIG_FMB_SERIAL_TASK_STACK_SIZE 2048
#define CONFIG_FMB_SERIAL_BUF_SIZE 256
#define CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB 8
#define CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS 1000
#define CONFIG_FMB_SERIAL_TASK_PRIO 10
#define CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT 20
#define CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE 20
#define CONFIG_FMB_CONTROLLER_STACK_SIZE 4096
#define CONFIG_FMB_EVENT_QUEUE_TIMEOUT 20
#define CONFIG_FMB_TIMER_PORT_ENABLED 1
#define CONFIG_FMB_TIMER_GROUP 0
#define CONFIG_FMB_TIMER_INDEX 0
#define CONFIG_FREERTOS_NO_AFFINITY 0x7FFFFFFF
#define CONFIG_FREERTOS_CORETIMER_0 1
#define CONFIG_FREERTOS_HZ 100
#define CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION 1
#define CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY 1
#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1
#define CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS 1
#define CONFIG_FREERTOS_IDLE_TASK_STACKSIZE 1536
#define CONFIG_FREERTOS_ISR_STACKSIZE 1536
#define CONFIG_FREERTOS_MAX_TASK_NAME_LEN 16
#define CONFIG_FREERTOS_TIMER_TASK_PRIORITY 1
#define CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH 2048
#define CONFIG_FREERTOS_TIMER_QUEUE_LENGTH 10
#define CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE 0
#define CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER 1
#define CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER 1
#define CONFIG_FREERTOS_DEBUG_OCDAWARE 1
#define CONFIG_HEAP_POISONING_DISABLED 1
#define CONFIG_HEAP_TRACING_OFF 1
#define CONFIG_LOG_DEFAULT_LEVEL_INFO 1
#define CONFIG_LOG_DEFAULT_LEVEL 3
#define CONFIG_LOG_COLORS 1
#define CONFIG_LOG_TIMESTAMP_SOURCE_RTOS 1
#define CONFIG_LWIP_LOCAL_HOSTNAME "espressif"
#define CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES 1
#define CONFIG_LWIP_TIMERS_ONDEMAND 1
#define CONFIG_LWIP_MAX_SOCKETS 10
#define CONFIG_LWIP_SO_REUSE 1
#define CONFIG_LWIP_SO_REUSE_RXTOALL 1
#define CONFIG_LWIP_IP_FRAG 1
#define CONFIG_LWIP_ESP_GRATUITOUS_ARP 1
#define CONFIG_LWIP_GARP_TMR_INTERVAL 60
#define CONFIG_LWIP_TCPIP_RECVMBOX_SIZE 32
#define CONFIG_LWIP_DHCP_DOES_ARP_CHECK 1
#define CONFIG_LWIP_DHCPS_LEASE_UNIT 60
#define CONFIG_LWIP_DHCPS_MAX_STATION_NUM 8
#define CONFIG_LWIP_NETIF_LOOPBACK 1
#define CONFIG_LWIP_LOOPBACK_MAX_PBUFS 8
#define CONFIG_LWIP_MAX_ACTIVE_TCP 16
#define CONFIG_LWIP_MAX_LISTENING_TCP 16
#define CONFIG_LWIP_TCP_MAXRTX 12
#define CONFIG_LWIP_TCP_SYNMAXRTX 6
#define CONFIG_LWIP_TCP_MSS 1440
#define CONFIG_LWIP_TCP_TMR_INTERVAL 250
#define CONFIG_LWIP_TCP_MSL 60000
#define CONFIG_LWIP_TCP_SND_BUF_DEFAULT 5744
#define CONFIG_LWIP_TCP_WND_DEFAULT 5744
#define CONFIG_LWIP_TCP_RECVMBOX_SIZE 6
#define CONFIG_LWIP_TCP_QUEUE_OOSEQ 1
#define CONFIG_LWIP_TCP_OVERSIZE_MSS 1
#define CONFIG_LWIP_MAX_UDP_PCBS 16
#define CONFIG_LWIP_UDP_RECVMBOX_SIZE 6
#define CONFIG_LWIP_TCPIP_TASK_STACK_SIZE 3072
#define CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY 1
#define CONFIG_LWIP_TCPIP_TASK_AFFINITY 0x7FFFFFFF
#define CONFIG_LWIP_MAX_RAW_PCBS 16
#define CONFIG_LWIP_DHCP_MAX_NTP_SERVERS 1
#define CONFIG_LWIP_SNTP_UPDATE_DELAY 3600000
#define CONFIG_LWIP_ESP_LWIP_ASSERT 1
#define CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC 1
#define CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN 1
#define CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN 16384
#define CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN 4096
#define CONFIG_MBEDTLS_CERTIFICATE_BUNDLE 1
#define CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL 1
#define CONFIG_MBEDTLS_HARDWARE_AES 1
#define CONFIG_MBEDTLS_HARDWARE_MPI 1
#define CONFIG_MBEDTLS_HARDWARE_SHA 1
#define CONFIG_MBEDTLS_HAVE_TIME 1
#define CONFIG_MBEDTLS_ECDSA_DETERMINISTIC 1
#define CONFIG_MBEDTLS_SHA512_C 1
#define CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT 1
#define CONFIG_MBEDTLS_TLS_SERVER 1
#define CONFIG_MBEDTLS_TLS_CLIENT 1
#define CONFIG_MBEDTLS_TLS_ENABLED 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_RSA 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA 1
#define CONFIG_MBEDTLS_SSL_RENEGOTIATION 1
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1 1
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_1 1
#define CONFIG_MBEDTLS_SSL_PROTO_TLS1_2 1
#define CONFIG_MBEDTLS_SSL_ALPN 1
#define CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS 1
#define CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS 1
#define CONFIG_MBEDTLS_AES_C 1
#define CONFIG_MBEDTLS_RC4_DISABLED 1
#define CONFIG_MBEDTLS_CCM_C 1
#define CONFIG_MBEDTLS_GCM_C 1
#define CONFIG_MBEDTLS_PEM_PARSE_C 1
#define CONFIG_MBEDTLS_PEM_WRITE_C 1
#define CONFIG_MBEDTLS_X509_CRL_PARSE_C 1
#define CONFIG_MBEDTLS_X509_CSR_PARSE_C 1
#define CONFIG_MBEDTLS_ECP_C 1
#define CONFIG_MBEDTLS_ECDH_C 1
#define CONFIG_MBEDTLS_ECDSA_C 1
#define CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED 1
#define CONFIG_MBEDTLS_ECP_NIST_OPTIM 1
#define CONFIG_MDNS_MAX_SERVICES 25
#define CONFIG_MDNS_MAX_INTERFACES 3
#define CONFIG_MDNS_TASK_PRIORITY 1
#define CONFIG_MDNS_TASK_STACK_SIZE 4096
#define CONFIG_MDNS_TASK_AFFINITY_CPU0 1
#define CONFIG_MDNS_TASK_AFFINITY 0x0
#define CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS 1
#define CONFIG_MDNS_TIMER_PERIOD_MS 100
#define CONFIG_MQTT_PROTOCOL_311 1
#define CONFIG_MQTT_TRANSPORT_SSL 1
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE 1
#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1
#define CONFIG_NEWLIB_STDIN_LINE_ENDING_CR 1
#define CONFIG_OPENSSL_ASSERT_EXIT 1
#define CONFIG_PTHREAD_TASK_PRIO_DEFAULT 5
#define CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT 3072
#define CONFIG_PTHREAD_STACK_MIN 768
#define CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY 1
#define CONFIG_PTHREAD_TASK_CORE_DEFAULT -1
#define CONFIG_PTHREAD_TASK_NAME_DEFAULT "pthread"
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
#define CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS 1
#define CONFIG_SPI_FLASH_YIELD_DURING_ERASE 1
#define CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS 20
#define CONFIG_SPI_FLASH_ERASE_YIELD_TICKS 1
#define CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP 1
#define CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP 1
#define CONFIG_SPI_FLASH_SUPPORT_GD_CHIP 1
#define CONFIG_SPIFFS_MAX_PARTITIONS 3
#define CONFIG_SPIFFS_CACHE 1
#define CONFIG_SPIFFS_CACHE_WR 1
#define CONFIG_SPIFFS_PAGE_CHECK 1
#define CONFIG_SPIFFS_GC_MAX_RUNS 10
#define CONFIG_SPIFFS_PAGE_SIZE 256
#define CONFIG_SPIFFS_OBJ_NAME_LEN 32
#define CONFIG_SPIFFS_USE_MAGIC 1
#define CONFIG_SPIFFS_USE_MAGIC_LENGTH 1
#define CONFIG_SPIFFS_META_LENGTH 4
#define CONFIG_SPIFFS_USE_MTIME 1
#define CONFIG_USB_DESC_CUSTOM_VID 0x1234
#define CONFIG_USB_DESC_CUSTOM_PID 0x5678
#define CONFIG_UNITY_ENABLE_FLOAT 1
#define CONFIG_UNITY_ENABLE_DOUBLE 1
#define CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER 1
#define CONFIG_VFS_SUPPORT_IO 1
#define CONFIG_VFS_SUPPORT_DIR 1
#define CONFIG_VFS_SUPPORT_SELECT 1
#define CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT 1
#define CONFIG_VFS_SUPPORT_TERMIOS 1
#define CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS 1
#define CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN 128
#define CONFIG_WL_SECTOR_SIZE_4096 1
#define CONFIG_WL_SECTOR_SIZE 4096
#define CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES 16
#define CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT 30
#define CONFIG_WPA_MBEDTLS_CRYPTO 1
/* List of deprecated options */
#define CONFIG_ADC2_DISABLE_DAC CONFIG_ADC_DISABLE_DAC
#define CONFIG_BROWNOUT_DET CONFIG_ESP_BROWNOUT_DET
#define CONFIG_BROWNOUT_DET_LVL_SEL_0 CONFIG_ESP_BROWNOUT_DET_LVL_SEL_0
#define CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT
#define CONFIG_CONSOLE_UART_BAUDRATE CONFIG_ESP_CONSOLE_UART_BAUDRATE
#define CONFIG_CONSOLE_UART_DEFAULT CONFIG_ESP_CONSOLE_UART_DEFAULT
#define CONFIG_CONSOLE_UART_RX_GPIO CONFIG_ESP_CONSOLE_UART_RX_GPIO
#define CONFIG_CONSOLE_UART_TX_GPIO CONFIG_ESP_CONSOLE_UART_TX_GPIO
#define CONFIG_ESP32S2_PANIC_PRINT_REBOOT CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT
#define CONFIG_ESP32_APPTRACE_DEST_NONE CONFIG_APPTRACE_DEST_NONE
#define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY
#define CONFIG_ESP32_PANIC_PRINT_REBOOT CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT
#define CONFIG_ESP32_PTHREAD_STACK_MIN CONFIG_PTHREAD_STACK_MIN
#define CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT CONFIG_PTHREAD_TASK_NAME_DEFAULT
#define CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT CONFIG_PTHREAD_TASK_PRIO_DEFAULT
#define CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT
#define CONFIG_ESP_GRATUITOUS_ARP CONFIG_LWIP_ESP_GRATUITOUS_ARP
#define CONFIG_FLASHMODE_DIO CONFIG_ESPTOOLPY_FLASHMODE_DIO
#define CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR
#define CONFIG_GARP_TMR_INTERVAL CONFIG_LWIP_GARP_TMR_INTERVAL
#define CONFIG_INT_WDT CONFIG_ESP_INT_WDT
#define CONFIG_INT_WDT_CHECK_CPU1 CONFIG_ESP_INT_WDT_CHECK_CPU1
#define CONFIG_INT_WDT_TIMEOUT_MS CONFIG_ESP_INT_WDT_TIMEOUT_MS
#define CONFIG_IPC_TASK_STACK_SIZE CONFIG_ESP_IPC_TASK_STACK_SIZE
#define CONFIG_LOG_BOOTLOADER_LEVEL_INFO CONFIG_BOOTLOADER_LOG_LEVEL_INFO
#define CONFIG_MAIN_TASK_STACK_SIZE CONFIG_ESP_MAIN_TASK_STACK_SIZE
#define CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE
#define CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT
#define CONFIG_MB_CONTROLLER_STACK_SIZE CONFIG_FMB_CONTROLLER_STACK_SIZE
#define CONFIG_MB_EVENT_QUEUE_TIMEOUT CONFIG_FMB_EVENT_QUEUE_TIMEOUT
#define CONFIG_MB_MASTER_DELAY_MS_CONVERT CONFIG_FMB_MASTER_DELAY_MS_CONVERT
#define CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND
#define CONFIG_MB_QUEUE_LENGTH CONFIG_FMB_QUEUE_LENGTH
#define CONFIG_MB_SERIAL_BUF_SIZE CONFIG_FMB_SERIAL_BUF_SIZE
#define CONFIG_MB_SERIAL_TASK_PRIO CONFIG_FMB_SERIAL_TASK_PRIO
#define CONFIG_MB_SERIAL_TASK_STACK_SIZE CONFIG_FMB_SERIAL_TASK_STACK_SIZE
#define CONFIG_MB_TIMER_GROUP CONFIG_FMB_TIMER_GROUP
#define CONFIG_MB_TIMER_INDEX CONFIG_FMB_TIMER_INDEX
#define CONFIG_MB_TIMER_PORT_ENABLED CONFIG_FMB_TIMER_PORT_ENABLED
#define CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE
#define CONFIG_OPTIMIZATION_LEVEL_DEBUG CONFIG_COMPILER_OPTIMIZATION_DEFAULT
#define CONFIG_POST_EVENTS_FROM_IRAM_ISR CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR
#define CONFIG_POST_EVENTS_FROM_ISR CONFIG_ESP_EVENT_POST_FROM_ISR
#define CONFIG_REDUCE_PHY_TX_POWER CONFIG_ESP32_REDUCE_PHY_TX_POWER
#define CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN
#define CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS
#define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS
#define CONFIG_STACK_CHECK_NONE CONFIG_COMPILER_STACK_CHECK_MODE_NONE
#define CONFIG_SUPPORT_TERMIOS CONFIG_VFS_SUPPORT_TERMIOS
#define CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT
#define CONFIG_SYSTEM_EVENT_QUEUE_SIZE CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE
#define CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE
#define CONFIG_TASK_WDT CONFIG_ESP_TASK_WDT
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
#define CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1
#define CONFIG_TASK_WDT_TIMEOUT_S CONFIG_ESP_TASK_WDT_TIMEOUT_S
#define CONFIG_TCPIP_RECVMBOX_SIZE CONFIG_LWIP_TCPIP_RECVMBOX_SIZE
#define CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY
#define CONFIG_TCPIP_TASK_STACK_SIZE CONFIG_LWIP_TCPIP_TASK_STACK_SIZE
#define CONFIG_TCP_MAXRTX CONFIG_LWIP_TCP_MAXRTX
#define CONFIG_TCP_MSL CONFIG_LWIP_TCP_MSL
#define CONFIG_TCP_MSS CONFIG_LWIP_TCP_MSS
#define CONFIG_TCP_OVERSIZE_MSS CONFIG_LWIP_TCP_OVERSIZE_MSS
#define CONFIG_TCP_QUEUE_OOSEQ CONFIG_LWIP_TCP_QUEUE_OOSEQ
#define CONFIG_TCP_RECVMBOX_SIZE CONFIG_LWIP_TCP_RECVMBOX_SIZE
#define CONFIG_TCP_SND_BUF_DEFAULT CONFIG_LWIP_TCP_SND_BUF_DEFAULT
#define CONFIG_TCP_SYNMAXRTX CONFIG_LWIP_TCP_SYNMAXRTX
#define CONFIG_TCP_WND_DEFAULT CONFIG_LWIP_TCP_WND_DEFAULT
#define CONFIG_TIMER_QUEUE_LENGTH CONFIG_FREERTOS_TIMER_QUEUE_LENGTH
#define CONFIG_TIMER_TASK_PRIORITY CONFIG_FREERTOS_TIMER_TASK_PRIORITY
#define CONFIG_TIMER_TASK_STACK_DEPTH CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH
#define CONFIG_TIMER_TASK_STACK_SIZE CONFIG_ESP_TIMER_TASK_STACK_SIZE
#define CONFIG_TOOLPREFIX CONFIG_SDK_TOOLPREFIX
#define CONFIG_UDP_RECVMBOX_SIZE CONFIG_LWIP_UDP_RECVMBOX_SIZE

Wyświetl plik

@ -1,280 +0,0 @@
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include "esp32_mock.h"
#include "mdns.h"
#include "mdns_private.h"
//
// Global stuctures containing packet payload, search
mdns_rx_packet_t g_packet;
struct pbuf mypbuf;
mdns_search_once_t * search = NULL;
//
// Dependency injected test functions
void mdns_test_execute_action(void * action);
mdns_srv_item_t * mdns_test_mdns_get_service_item(const char * service, const char * proto);
mdns_search_once_t * mdns_test_search_init(const char * name, const char * service, const char * proto, uint16_t type, uint32_t timeout, uint8_t max_results);
esp_err_t mdns_test_send_search_action(mdns_action_type_t type, mdns_search_once_t * search);
void mdns_test_search_free(mdns_search_once_t * search);
void mdns_test_init_di(void);
extern mdns_server_t * _mdns_server;
//
// mdns function wrappers for mdns setup in test mode
static int mdns_test_hostname_set(const char * mdns_hostname)
{
for (int i=0; i<MDNS_MAX_INTERFACES; i++) {
_mdns_server->interfaces[i].pcbs[MDNS_IP_PROTOCOL_V4].state = PCB_RUNNING; // mark the PCB running to exercise mdns in fully operational mode
_mdns_server->interfaces[i].pcbs[MDNS_IP_PROTOCOL_V6].state = PCB_RUNNING;
}
int ret = mdns_hostname_set(mdns_hostname);
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return ret;
}
static int mdns_test_add_delegated_host(const char * mdns_hostname)
{
mdns_ip_addr_t addr = { .addr = { .u_addr = ESP_IPADDR_TYPE_V4 } };
addr.addr.u_addr.ip4.addr = 0x11111111;
int ret = mdns_delegate_hostname_add(mdns_hostname, &addr);
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return ret;
}
static int mdns_test_service_instance_name_set(const char * service, const char * proto, const char * instance)
{
int ret = mdns_service_instance_name_set(service, proto, instance);
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return ret;
}
static int mdns_test_service_txt_set(const char * service, const char * proto, uint8_t num_items, mdns_txt_item_t txt[])
{
int ret = mdns_service_txt_set(service, proto, txt, num_items);
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return ret;
}
static int mdns_test_sub_service_add(const char * sub_name, const char * service_name, const char * proto, uint32_t port)
{
if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) {
// This is expected failure as the service thread is not running
}
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
if (mdns_test_mdns_get_service_item(service_name, proto)==NULL) {
return ESP_FAIL;
}
int ret = mdns_service_subtype_add_for_host(NULL, service_name, proto, NULL, sub_name);
a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return ret;
}
static int mdns_test_service_add(const char * service_name, const char * proto, uint32_t port)
{
if (mdns_service_add(NULL, service_name, proto, port, NULL, 0)) {
// This is expected failure as the service thread is not running
}
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
if (mdns_test_mdns_get_service_item(service_name, proto)==NULL) {
return ESP_FAIL;
}
return ESP_OK;
}
static mdns_result_t* mdns_test_query(const char * name, const char * service, const char * proto, uint16_t type)
{
search = mdns_test_search_init(name, service, proto, type, 3000, 20);
if (!search) {
abort();
}
if (mdns_test_send_search_action(ACTION_SEARCH_ADD, search)) {
mdns_test_search_free(search);
abort();
}
mdns_action_t * a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
return NULL;
}
static void mdns_test_query_free(void)
{
mdns_test_search_free(search);
}
//
// function "under test" where afl-mangled packets passed
//
void mdns_parse_packet(mdns_rx_packet_t * packet);
//
// Test starts here
//
int main(int argc, char** argv)
{
int i;
const char * mdns_hostname = "minifritz";
const char * mdns_instance = "Hristo's Time Capsule";
mdns_txt_item_t arduTxtData[4] = {
{"board","esp32"},
{"tcp_check","no"},
{"ssh_upload","no"},
{"auth_upload","no"}
};
const uint8_t mac[6] = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x32};
uint8_t buf[1460];
char winstance[21+strlen(mdns_hostname)];
sprintf(winstance, "%s [%02x:%02x:%02x:%02x:%02x:%02x]", mdns_hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
// Init depencency injected methods
mdns_test_init_di();
if (mdns_init()) {
abort();
}
if (mdns_test_hostname_set(mdns_hostname)) {
abort();
}
if (mdns_test_add_delegated_host(mdns_hostname) || mdns_test_add_delegated_host("megafritz")) {
abort();
}
#ifndef MDNS_NO_SERVICES
if (mdns_test_sub_service_add("_server", "_fritz", "_tcp", 22)) {
abort();
}
if (mdns_test_service_add("_telnet", "_tcp", 22)) {
abort();
}
if (mdns_test_service_add("_workstation", "_tcp", 9)) {
abort();
}
if (mdns_test_service_instance_name_set("_workstation", "_tcp", winstance)) {
abort();
}
if (mdns_test_service_add("_arduino", "_tcp", 3232)) {
abort();
}
if (mdns_test_service_txt_set("_arduino", "_tcp", 4, arduTxtData)) {
abort();
}
if (mdns_test_service_add("_http", "_tcp", 80)) {
abort();
}
if (mdns_test_service_instance_name_set("_http", "_tcp", "ESP WebServer")) {
abort();
}
if (
mdns_test_service_add("_afpovertcp", "_tcp", 548)
|| mdns_test_service_add("_rfb", "_tcp", 885)
|| mdns_test_service_add("_smb", "_tcp", 885)
|| mdns_test_service_add("_adisk", "_tcp", 885)
|| mdns_test_service_add("_airport", "_tcp", 885)
|| mdns_test_service_add("_printer", "_tcp", 885)
|| mdns_test_service_add("_airplay", "_tcp", 885)
|| mdns_test_service_add("_raop", "_tcp", 885)
|| mdns_test_service_add("_uscan", "_tcp", 885)
|| mdns_test_service_add("_uscans", "_tcp", 885)
|| mdns_test_service_add("_ippusb", "_tcp", 885)
|| mdns_test_service_add("_scanner", "_tcp", 885)
|| mdns_test_service_add("_ipp", "_tcp", 885)
|| mdns_test_service_add("_ipps", "_tcp", 885)
|| mdns_test_service_add("_pdl-datastream", "_tcp", 885)
|| mdns_test_service_add("_ptp", "_tcp", 885)
|| mdns_test_service_add("_sleep-proxy", "_udp", 885))
{
abort();
}
#endif
mdns_result_t * results = NULL;
FILE *file;
size_t nread;
#ifdef INSTR_IS_OFF
size_t len = 1460;
memset(buf, 0, 1460);
if (argc != 2)
{
printf("Non-instrumentation mode: please supply a file name created by AFL to reproduce crash\n");
return 1;
}
else
{
//
// Note: parameter1 is a file (mangled packet) which caused the crash
file = fopen(argv[1], "r");
assert(file >= 0 );
len = fread(buf, 1, 1460, file);
fclose(file);
}
for (i=0; i<1; i++) {
#else
while (__AFL_LOOP(1000)) {
memset(buf, 0, 1460);
size_t len = read(0, buf, 1460);
#endif
mypbuf.payload = malloc(len);
memcpy(mypbuf.payload, buf, len);
mypbuf.len = len;
g_packet.pb = &mypbuf;
mdns_test_query("minifritz", "_fritz", "_tcp", MDNS_TYPE_ANY);
mdns_test_query(NULL, "_fritz", "_tcp", MDNS_TYPE_PTR);
mdns_test_query(NULL, "_afpovertcp", "_tcp", MDNS_TYPE_PTR);
mdns_parse_packet(&g_packet);
free(mypbuf.payload);
}
#ifndef MDNS_NO_SERVICES
mdns_service_remove_all();
mdns_action_t *a = NULL;
GetLastItem(&a);
mdns_test_execute_action(a);
#endif
ForceTaskDelete();
mdns_free();
return 0;
}

Wyświetl plik

@ -165,7 +165,6 @@ api-reference/protocols/esp_https_server
api-reference/protocols/openssl_apis
api-reference/protocols/esp_spi_slave_protocol
api-reference/protocols/esp_tls
api-reference/protocols/mdns
api-reference/protocols/index
api-reference/protocols/asio
get-started/establish-serial-connection

Wyświetl plik

@ -178,7 +178,6 @@ INPUT = \
$(PROJECT_PATH)/components/lwip/include/apps/esp_sntp.h \
$(PROJECT_PATH)/components/lwip/include/apps/ping/ping_sock.h \
$(PROJECT_PATH)/components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h \
$(PROJECT_PATH)/components/mdns/include/mdns.h \
$(PROJECT_PATH)/components/mqtt/esp-mqtt/include/mqtt_client.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs.h \
$(PROJECT_PATH)/components/nvs_flash/include/nvs_flash.h \

Wyświetl plik

@ -82,7 +82,8 @@ The default stack sizes for these tasks are usually set conservatively high, to
:SOC_BT_SUPPORTED: - :doc:`NimBLE Bluetooth Host </api-reference/bluetooth/nimble/index>` has task stack size :ref:`CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE`
- The Ethernet driver creates a task for the MAC to receive Ethernet frames. If using the default config ``ETH_MAC_DEFAULT_CONFIG`` then the task stack size is 4 KB. This setting can be changed by passing a custom :cpp:class:`eth_mac_config_t` struct when initializing the Ethernet MAC.
- FreeRTOS idle task stack size is configured by :ref:`CONFIG_FREERTOS_IDLE_TASK_STACKSIZE`.
- If using the :doc:`mDNS </api-reference/protocols/mdns>` and/or :doc:`MQTT </api-reference/protocols/mqtt>` components, they create tasks with stack sizes configured by :ref:`CONFIG_MDNS_TASK_STACK_SIZE` and :ref:`CONFIG_MQTT_TASK_STACK_SIZE`, respectively. MQTT stack size can also be configured using ``task_stack`` field of :cpp:class:`esp_mqtt_client_config_t`.
- If using the :doc:`MQTT </api-reference/protocols/mqtt>` component, it creates a task with stack size configured by :ref:`CONFIG_MQTT_TASK_STACK_SIZE`. MQTT stack size can also be configured using ``task_stack`` field of :cpp:class:`esp_mqtt_client_config_t`.
- To see how to optimize RAM usage when using ``mDNS``, please check `Performance Optimization <https://espressif.github.io/esp-protocols/mdns/en/index.html#minimizing-ram-usage>`__.
.. note::

Wyświetl plik

@ -168,8 +168,8 @@ Common priorities are:
:SOC_BT_SUPPORTED: - :doc:`Bluetooth Controller </api-reference/bluetooth/index>` task has high priority (23, ``ESP_TASK_BT_CONTROLLER_PRIO``). The Bluetooth Controller needs to respond to requests with low latency, so it should always be close to the highest priority task in the system.
:SOC_BT_SUPPORTED: - :doc:`NimBLE Bluetooth Host </api-reference/bluetooth/nimble/index>` host task has high priority (21).
- The Ethernet driver creates a task for the MAC to receive Ethernet frames. If using the default config ``ETH_MAC_DEFAULT_CONFIG`` then the priority is medium-high (15). This setting can be changed by passing a custom :cpp:class:`eth_mac_config_t` struct when initializing the Ethernet MAC.
- If using the :doc:`mDNS </api-reference/protocols/mdns>` component, it creates a task with default low priority 1 (:ref:`configurable<CONFIG_MDNS_TASK_PRIORITY>`.
- If using the :doc:`MQTT </api-reference/protocols/mqtt>` component, it creates a task with default priority 5 (:ref:`configurable<CONFIG_MQTT_TASK_PRIORITY>`, depends on :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG` (also configurable runtime by ``task_prio`` field in the :cpp:class:`esp_mqtt_client_config_t`)
- To see what is the task priority for ``mDNS`` service, please check `Performance Optimization <https://espressif.github.io/esp-protocols/mdns/en/index.html#execution-speed>`__.
.. only :: not CONFIG_FREERTOS_UNICORE
@ -191,8 +191,8 @@ Common priorities are:
All Bluedroid Tasks are pinned to the same core, which is Core 0 by default (:ref:`configurable <CONFIG_BT_BLUEDROID_PINNED_TO_CORE_CHOICE>`).
- The Ethernet driver creates a task for the MAC to receive Ethernet frames. If using the default config ``ETH_MAC_DEFAULT_CONFIG`` then the priority is medium-high (15) and the task is not pinned to any core. These settings can be changed by passing a custom :cpp:class:`eth_mac_config_t` struct when initializing the Ethernet MAC.
- If using the :doc:`mDNS </api-reference/protocols/mdns>` component, it creates a task with default low priority 1 (:ref:`configurable <CONFIG_MDNS_TASK_PRIORITY>`) and pinned to CPU0 (:ref:`configurable <CONFIG_MDNS_TASK_AFFINITY>`).
- If using the :doc:`MQTT </api-reference/protocols/mqtt>` component, it creates a task with default priority 5 (:ref:`configurable <CONFIG_MQTT_TASK_PRIORITY>`, depends on :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG`) and not pinned to any core (:ref:`configurable <CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED>`).
- To see what is the task priority for ``mDNS`` service, please check `Performance Optimization <https://espressif.github.io/esp-protocols/mdns/en/index.html#execution-speed>`__.
Choosing application task priorities
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Wyświetl plik

@ -2,188 +2,15 @@ mDNS Service
============
:link_to_translation:`zh_CN:[中文]`
Overview
--------
mDNS is a multicast UDP service that is used to provide local network service and host discovery.
mDNS is installed by default on most operating systems or is available as separate package. On ``Mac OS`` it is installed by default and is called ``Bonjour``. Apple releases an installer for ``Windows`` that can be found `on Apple's support page <https://support.apple.com/downloads/bonjour-for-windows>`_. On ``Linux``, mDNS is provided by `avahi <https://github.com/lathiat/avahi>`_ and is usually installed by default.
The ESP-IDF component `mDNS` has been moved from ESP-IDF since version v5.0 to a separate repository:
mDNS Properties
^^^^^^^^^^^^^^^
* `mDNS component on GitHub <https://github.com/espressif/esp-protocols/tree/master/components/mdns>`__
* ``hostname``: the hostname that the device will respond to. If not set, the ``hostname`` will be read from the interface. Example: ``my-{IDF_TARGET_PATH_NAME}`` will resolve to ``my-{IDF_TARGET_PATH_NAME}.local``
* ``default_instance``: friendly name for your device, like ``Jhon's {IDF_TARGET_NAME} Thing``. If not set, ``hostname`` will be used.
Example method to start mDNS for the STA interface and set ``hostname`` and ``default_instance``:
.. highlight:: c
::
void start_mdns_service()
{
//initialize mDNS service
esp_err_t err = mdns_init();
if (err) {
printf("MDNS Init failed: %d\n", err);
return;
}
//set hostname
mdns_hostname_set("my-{IDF_TARGET_PATH_NAME}");
//set default instance
mdns_instance_name_set("Jhon's {IDF_TARGET_NAME} Thing");
}
mDNS Services
^^^^^^^^^^^^^
mDNS can advertise information about network services that your device offers. Each service is defined by a few properties.
* ``instance_name``: friendly name for your service, like ``Jhon's E{IDF_TARGET_NAME} Web Server``. If not defined, ``default_instance`` will be used.
* ``service_type``: (required) service type, prepended with underscore. Some common types can be found `here <http://www.dns-sd.org/serviceTypes.html>`_.
* ``proto``: (required) protocol that the service runs on, prepended with underscore. Example: ``_tcp`` or ``_udp``
* ``port``: (required) network port that the service runs on
* ``txt``: ``{var, val}`` array of strings, used to define properties for your service
Example method to add a few services and different properties::
void add_mdns_services()
{
//add our services
mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
//NOTE: services must be added before their properties can be set
//use custom instance for the web server
mdns_service_instance_name_set("_http", "_tcp", "Jhon's {IDF_TARGET_NAME} Web Server");
mdns_txt_item_t serviceTxtData[3] = {
{"board","{{IDF_TARGET_PATH_NAME}}"},
{"u","user"},
{"p","password"}
};
//set txt data for service (will free and replace current data)
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
//change service port
mdns_service_port_set("_myservice", "_udp", 4321);
}
mDNS Query
^^^^^^^^^^
mDNS provides methods for browsing for services and resolving host's IP/IPv6 addresses.
Results for services are returned as a linked list of ``mdns_result_t`` objects.
Example method to resolve host IPs::
void resolve_mdns_host(const char * host_name)
{
printf("Query A: %s.local", host_name);
struct 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){
printf("Host was not found!");
return;
}
printf("Query Failed");
return;
}
printf(IPSTR, IP2STR(&addr));
}
Example method to resolve local services::
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
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){
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
if(r->instance_name){
printf(" PTR : %s\n", r->instance_name);
}
if(r->hostname){
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
}
if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count);
for(t=0; t<r->txt_count; t++){
printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
}
printf("\n");
}
a = r->addr;
while(a){
if(a->addr.type == 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;
}
}
void find_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");
return;
}
if(!results){
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
Example of using the methods above::
void my_app_some_method(){
//search for {IDF_TARGET_PATH_NAME}-mdns.local
resolve_mdns_host("{IDF_TARGET_PATH_NAME}-mdns");
//search for HTTP servers
find_mdns_service("_http", "_tcp");
//or file servers
find_mdns_service("_smb", "_tcp"); //windows sharing
find_mdns_service("_afpovertcp", "_tcp"); //apple sharing
find_mdns_service("_nfs", "_tcp"); //NFS server
find_mdns_service("_ftp", "_tcp"); //FTP server
//or networked printer
find_mdns_service("_printer", "_tcp");
find_mdns_service("_ipp", "_tcp");
}
Application Example
-------------------
mDNS server/scanner example: :example:`protocols/mdns`.
API Reference
-------------
.. include-build-file:: inc/mdns.inc
Hosted Documentation
--------------------
The documentation can be found on the link below:
* `mDNS documentation <https://espressif.github.io/esp-protocols/mdns/en/index.html>`__

Wyświetl plik

@ -90,6 +90,8 @@ ESP-Protocols components:
* `esp_modem <https://components.espressif.com/component/espressif/esp_modem>`_ enables connectivity with GSM/LTE modems using AT commands or PPP protocol, see the `esp_modem documentation <https://espressif.github.io/esp-protocols/esp_modem/index.html>`_.
* `mdns <https://components.espressif.com/component/espressif/mdns>`_ (mDNS) is a multicast UDP service that is used to provide local network service and host discovery, see the `mdns documentation <https://espressif.github.io/esp-protocols/mdns/en/index.html>`_.
* `esp_websocket_client <https://components.espressif.com/component/espressif/esp_websocket_client>`_ is a managed component for `esp-idf` that contains implementation of [WebSocket protocol client](https://datatracker.ietf.org/doc/html/rfc6455) for ESP32, see the `esp_websocket_client documentation <https://espressif.github.io/esp-protocols/esp_websocket_client/index.html>`_.

Wyświetl plik

@ -11,6 +11,7 @@ Following components are removed from ESP-IDF and moved to `IDF Component Regist
* `jsmn <https://components.espressif.com/component/espressif/jsmn>`_
* `esp_modem <https://components.espressif.com/component/espressif/esp_modem>`_
* `nghttp <https://components.espressif.com/component/espressif/nghttp>`_
* `mdns <https://components.espressif.com/component/espressif/mdns>`_
* `esp_websocket_client <https://components.espressif.com/component/espressif/esp_websocket_client>`_
* `freemodbus <https://components.espressif.com/component/espressif/esp-modbus>`_

Wyświetl plik

@ -2,188 +2,15 @@ mDNS 服务
=========
:link_to_translation:`en:[English]`
概述
----
mDNS 是一种组播 UDP 服务,用来提供本地网络服务和主机发现。
绝大多数的操作系统默认都会安装 mDNS 服务,或者提供单独的安装包。``Mac OS`` 默认会安装名为 ``Bonjour`` 的服务(该服务基于 mDNS此外 Apple 还发布了适用于 Windows 系统的安装程序,可以在 `官方支持 <https://support.apple.com/downloads/bonjour-for-windows>`_ 找到。在 ``Linux``mDNS 服务由 `avahi <https://github.com/lathiat/avahi>`_ 提供,通常也会被默认安装。
自 v5.0 版本起ESP-IDF 组件 `mDNS` 已从 ESP-IDF 中迁出至独立的仓库:
mDNS 属性
^^^^^^^^^
* GitHub 上 `mDNS 组件 <https://github.com/espressif/esp-protocols/tree/master/components/mdns>`__
* ``hostname``:设备会去响应的主机名,如果没有设置,会根据设备的网络接口名定义 ``hostname`` 。例如,``my-{IDF_TARGET_PATH_NAME}`` 会被解析为 ``my-{IDF_TARGET_PATH_NAME}.local``
* ``default_instance``:默认实例名(即易记的设备名),例如 ``Jhon's {IDF_TARGET_NAME} Thing``。如果没有设置,将会使用 ``hostname``
以下为 STA 接口启动 mDNS 服务并设置 ``hostname````default_instance`` 的示例方法:
.. highlight:: c
::
void start_mdns_service()
{
// 初始化 mDNS 服务
esp_err_t err = mdns_init();
if (err) {
printf("MDNS Init failed: %d\n", err);
return;
}
// 设置 hostname
mdns_hostname_set("my-{IDF_TARGET_PATH_NAME}");
// 设置默认实例
mdns_instance_name_set("Jhon's {IDF_TARGET_NAME} Thing");
}
mDNS 服务
^^^^^^^^^
mDNS 可以广播设备能够提供的网络服务的相关信息,每个服务会由以下属性构成。
* ``instance_name``:实例名(即易记的服务名),例如 ``Jhon's {IDF_TARGET_NAME} Web Server``。如果没有定义,会使用 ``default_instance``
* ``service_type``:(必需)服务类型,以下划线为前缀,`这里 <http://www.dns-sd.org/serviceTypes.html>`_ 列出了常见的类型。
* ``proto``:(必需)服务运行所依赖的协议,以下划线为前缀,例如 ``_tcp`` 或者 ``_udp``
* ``port``:(必需)服务运行所用的端口号。
* ``txt``:形如 ``{var, val}`` 的字符串数组,用于定义服务的属性。
添加一些服务和不同属性的示例方法::
void add_mdns_services()
{
// 添加服务
mdns_service_add(NULL, "_http", "_tcp", 80, NULL, 0);
mdns_service_add(NULL, "_arduino", "_tcp", 3232, NULL, 0);
mdns_service_add(NULL, "_myservice", "_udp", 1234, NULL, 0);
// 注意:必须先添加服务,然后才能设置其属性
// web 服务器使用自定义的实例名
mdns_service_instance_name_set("_http", "_tcp", "Jhon's {IDF_TARGET_NAME} Web Server");
mdns_txt_item_t serviceTxtData[3] = {
{"board","{IDF_TARGET_PATH_NAME}"},
{"u","user"},
{"p","password"}
};
// 设置服务的文本数据(会释放并替换当前数据)
mdns_service_txt_set("_http", "_tcp", serviceTxtData, 3);
// 修改服务端口号
mdns_service_port_set("_myservice", "_udp", 4321);
}
mDNS 查询
^^^^^^^^^
mDNS 提供查询服务和解析主机 IP/IPv6 地址的方法。
服务查询的结果会作为 ``mdns_result_t`` 类型对象的链表返回。
解析主机 IP 地址的示例方法::
void resolve_mdns_host(const char * host_name)
{
printf("Query A: %s.local", host_name);
struct 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){
printf("Host was not found!");
return;
}
printf("Query Failed");
return;
}
printf(IPSTR, IP2STR(&addr));
}
解析本地服务的示例方法::
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
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){
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
if(r->instance_name){
printf(" PTR : %s\n", r->instance_name);
}
if(r->hostname){
printf(" SRV : %s.local:%u\n", r->hostname, r->port);
}
if(r->txt_count){
printf(" TXT : [%u] ", r->txt_count);
for(t=0; t<r->txt_count; t++){
printf("%s=%s; ", r->txt[t].key, r->txt[t].value);
}
printf("\n");
}
a = r->addr;
while(a){
if(a->addr.type == 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;
}
}
void find_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");
return;
}
if(!results){
ESP_LOGW(TAG, "No results found!");
return;
}
mdns_print_results(results);
mdns_query_results_free(results);
}
使用上述方法的示例::
void my_app_some_method(){
// 搜索 {IDF_TARGET_PATH_NAME}-mdns.local
resolve_mdns_host("{IDF_TARGET_PATH_NAME}-mdns");
// 搜索 HTTP 服务器
find_mdns_service("_http", "_tcp");
// 或者搜索文件服务器
find_mdns_service("_smb", "_tcp"); // Windows 系统的共享服务
find_mdns_service("_afpovertcp", "_tcp"); // Apple AFP 文件共享服务
find_mdns_service("_nfs", "_tcp"); // NFS 服务器
find_mdns_service("_ftp", "_tcp"); // FTP 服务器
// 或者网络打印机
find_mdns_service("_printer", "_tcp");
find_mdns_service("_ipp", "_tcp");
}
应用示例
--------
有关 mDNS 服务器和查询器的应用示例请参考 :example:`protocols/mdns`
API 参考
--------
.. include-build-file:: inc/mdns.inc
托管的文档
--------------------
请点击如下链接,查看 mDNS 的相关文档:
* `mDNS 文档 <https://espressif.github.io/esp-protocols/mdns/en/index.html>`__

Wyświetl plik

@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
espressif/mdns: "^1.0.3"
## Required IDF version
idf:
version: ">=5.0"

Wyświetl plik

@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
espressif/mdns: "^1.0.3"
## Required IDF version
idf:
version: ">=5.0"

Wyświetl plik

@ -0,0 +1,6 @@
## IDF Component Manager Manifest File
dependencies:
espressif/mdns: "^1.0.3"
## Required IDF version
idf:
version: ">=5.0"

Wyświetl plik

@ -1,10 +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.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mdns_test)

Wyświetl plik

@ -1,96 +0,0 @@
| Supported Targets | ESP32 | ESP32-S2 | ESP32-S3 | ESP32-C3 |
| ----------------- | ----- | -------- | -------- | -------- |
# mDNS example
Shows how to use mDNS to advertise lookup 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. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../README.md) for more details.
* 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)
```
See the README.md file in the upper level 'examples' directory for more information about examples.

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -1,343 +0,0 @@
/* MDNS-SD Query and advertise Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <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"
#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) {
printf("%d: Interface: %s, Type: %s, TTL: %u\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);
}
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);
}
}
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));
}
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");
query_mdns_host("esp32");
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");
}
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 */
query_mdns_host("tinytester");
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());
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));
ESP_ERROR_CHECK(mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_ANNOUNCE_IP4));
#endif
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, inet_ntoa(*(struct in_addr *) (res->h_addr_list[i])));
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) {
ESP_LOGI(TAG, "getaddrinfo: %s resolved to: %s", host,
res->ai_family == AF_INET?
inet_ntoa(((struct sockaddr_in *) res->ai_addr)->sin_addr):
inet_ntoa(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr));
res = res->ai_next;
}
}
}
#endif

Wyświetl plik

@ -1,166 +0,0 @@
import os
import re
import select
import socket
import struct
import subprocess
import time
from threading import Event, Thread
import dpkt
import dpkt.dns
import ttfw_idf
from tiny_test_fw import DUT
from tiny_test_fw.Utility import console_log
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'
console_log('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)
console_log('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 and dns.qd[0].type == dpkt.dns.DNS_A:
if dns.qd[0].name == TESTER_NAME:
console_log('Received query: {} '.format(dns.__repr__()))
sock.sendto(get_dns_answer_to_mdns(TESTER_NAME), (MCAST_GRP, UDP_PORT))
elif dns.qd[0].name == TESTER_NAME_LWIP:
console_log('Received query: {} '.format(dns.__repr__()))
sock.sendto(get_dns_answer_to_mdns_lwip(TESTER_NAME_LWIP, dns.id), addr)
if len(dns.an) > 0 and dns.an[0].type == dpkt.dns.DNS_A:
console_log('Received answer from {}'.format(dns.an[0].name))
if dns.an[0].name == esp_host + u'.local':
console_log('Received answer to esp32-mdns query: {}'.format(dns.__repr__()))
events['esp_answered'].set()
if dns.an[0].name == esp_host + u'-delegated.local':
console_log('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(env, config):
"""
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
"""
dut1 = env.get_dut('mdns-test', 'examples/protocols/mdns', dut_class=ttfw_idf.ESP32DUT, app_config_name=config)
# check and log bin size
binary_file = os.path.join(dut1.app.binary_path, 'mdns_test.bin')
bin_size = os.path.getsize(binary_file)
ttfw_idf.log_performance('mdns-test_bin_size', '{}KB'.format(bin_size // 1024))
# 1. start mdns application
dut1.start_app()
# 2. get the dut host name (and IP address)
specific_host = dut1.expect(re.compile(r'mdns hostname set to: \[([^\]]+)\]'), timeout=30)[0]
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))
try:
ip_address = dut1.expect(re.compile(r' eth ip: ([^,]+),'), timeout=30)[0]
console_log('Connected to AP with IP: {}'.format(ip_address))
except DUT.ExpectTimeout:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
try:
# 3. check the mdns name is accessible
mdns_responder.start()
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
dut1.expect(re.compile(r'mdns-test: Query A: tinytester.local resolved to: 127.0.0.1'), timeout=30)
dut1.expect(re.compile(r'mdns-test: gethostbyname: tinytester-lwip.local resolved to: 127.0.0.1'), timeout=30)
dut1.expect(re.compile(r'mdns-test: getaddrinfo: tinytester-lwip.local resolved to: 127.0.0.1'), timeout=30)
# 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)])
console_log('Resolving {} using "dig" succeeded with:\n{}'.format(specific_host, dig_output))
if not ip_address.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(ip_address))
finally:
mdns_server_events['stop'].set()
mdns_responder.join()
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1')
def test_examples_protocol_mdns_default(env, _):
test_examples_protocol_mdns(env, 'eth_def')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1')
def test_examples_protocol_mdns_socket(env, _):
test_examples_protocol_mdns(env, 'eth_socket')
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1')
def test_examples_protocol_mdns_custom_netif(env, _):
test_examples_protocol_mdns(env, 'eth_custom_netif')
if __name__ == '__main__':
test_examples_protocol_mdns_default()

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