mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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
This commit is contained in:
commit
46fe7dbc8c
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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()
|
@ -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
|
@ -1,5 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(COMPONENTS main)
|
||||
project(mdns_host)
|
@ -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"
|
||||
```
|
@ -1,3 +0,0 @@
|
||||
idf_component_register(SRCS esp_event_mock.c
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES esp_system_protocols_linux)
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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;
|
@ -1,3 +0,0 @@
|
||||
idf_component_register(SRCS esp_netif_linux.c
|
||||
INCLUDE_DIRS include
|
||||
REQUIRES esp_system_protocols_linux)
|
@ -1,9 +0,0 @@
|
||||
menu "LWIP-MOCK-CONFIG"
|
||||
|
||||
config LWIP_IPV6
|
||||
bool "Enable IPv6"
|
||||
default y
|
||||
help
|
||||
Enable/disable IPv6
|
||||
|
||||
endmenu
|
@ -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);
|
||||
}
|
@ -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"
|
@ -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)
|
@ -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");
|
||||
}
|
||||
}
|
@ -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);
|
@ -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"
|
@ -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 */
|
||||
}
|
@ -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
|
||||
)
|
@ -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;
|
||||
}
|
@ -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);
|
@ -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);
|
||||
}
|
@ -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;
|
||||
|
||||
};
|
@ -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
|
||||
)
|
@ -1,7 +0,0 @@
|
||||
menu "FreeRTOS"
|
||||
|
||||
config FREERTOS_NO_AFFINITY
|
||||
hex
|
||||
default 0x7FFFFFFF
|
||||
|
||||
endmenu
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
@ -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);
|
@ -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;
|
||||
}
|
@ -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;
|
||||
};
|
@ -1,4 +0,0 @@
|
||||
idf_component_register(SRCS "main.c"
|
||||
INCLUDE_DIRS
|
||||
"."
|
||||
REQUIRES mdns)
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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_ */
|
@ -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)
|
@ -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();
|
||||
}
|
@ -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)
|
@ -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
|
@ -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
|
||||
```
|
@ -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;
|
||||
}
|
@ -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_
|
@ -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
|
@ -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;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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 Ivanova’s 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: Hristo’s Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16
|
||||
A: _smb._tcp.local. PTR IN 4500 [22] Hristo’s Mac mini._smb._tcp.local.
|
||||
A: Hristo’s Mac mini._smb._tcp.local. TXT IN FLUSH 4500 [1]
|
||||
A: Hristo’s 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: Hristo’s Mac mini.local. NSEC IN FLUSH 4500 [9] Hristo’s 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 Ivanova’s 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: Hristo’s Mac mini._device-info._tcp.local. TXT IN 4500 [28] model=Macmini6,2; osxvers=16
|
||||
A: _afpovertcp._tcp.local. PTR IN 4500 [22] Hristo’s Mac mini._afpovertcp._tcp.local.
|
||||
A: Hristo’s Mac mini._afpovertcp._tcp.local. TXT IN FLUSH 4500 [1]
|
||||
A: Hristo’s 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: Hristo’s Mac mini.local. NSEC IN FLUSH 4500 [9] Hristo’s 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 Ivanova’s MacBook._device-info._tcp.local. TXT IN 4500 [17] model=Macmini2,1
|
||||
A: _rfb._tcp.local. PTR IN 4500 [29] Sofiya Ivanova’s MacBook._rfb._tcp.local.
|
||||
A: Sofiya Ivanova’s MacBook._rfb._tcp.local. TXT IN FLUSH 4500 [1]
|
||||
A: Sofiya Ivanova’s 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 Ivanova’s MacBook.local. NSEC IN FLUSH 4500 [9] Sofiya Ivanova’s 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 Ivanova’s MacBook._afpovertcp._tcp.local.
|
||||
A: _afpovertcp._tcp.local. PTR IN 3973 [22] Hristo’s 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 Ivanova’s MacBook._smb._tcp.local.
|
||||
A: _smb._tcp.local. PTR IN 3792 [22] Hristo’s 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
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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::
|
||||
|
||||
|
@ -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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -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>`__
|
||||
|
@ -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>`_.
|
||||
|
||||
|
||||
|
@ -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>`_
|
||||
|
||||
|
@ -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>`__
|
||||
|
6
examples/openthread/ot_br/main/idf_component.yml
Normal file
6
examples/openthread/ot_br/main/idf_component.yml
Normal file
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns: "^1.0.3"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0"
|
6
examples/protocols/esp_local_ctrl/main/idf_component.yml
Normal file
6
examples/protocols/esp_local_ctrl/main/idf_component.yml
Normal file
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns: "^1.0.3"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0"
|
@ -0,0 +1,6 @@
|
||||
## IDF Component Manager Manifest File
|
||||
dependencies:
|
||||
espressif/mdns: "^1.0.3"
|
||||
## Required IDF version
|
||||
idf:
|
||||
version: ">=5.0"
|
@ -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)
|
@ -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.
|
@ -1,2 +0,0 @@
|
||||
idf_component_register(SRCS "mdns_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
@ -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
|
@ -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
|
@ -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
Loading…
x
Reference in New Issue
Block a user