Merge pull request #203 from david-cermak/feat/mdns_reverse_query

feat(mdns): Add support for IPv4 reverse query
This commit is contained in:
david-cermak
2023-02-03 15:21:38 +01:00
committed by GitHub
36 changed files with 323 additions and 187 deletions

View File

@ -3,8 +3,8 @@ name: Host test
on: [push, pull_request]
jobs:
host_test:
name: Build and Test on Host
host_test_esp_modem:
name: esp-modem Build and Test on Host
runs-on: ubuntu-20.04
container: espressif/idf:release-v4.3
env:
@ -38,3 +38,26 @@ jobs:
if: always()
with:
files: esp-protocols/components/esp_modem/test/host_test/junit.xml
host_test_mdns:
name: mdns Build and Test on Host
runs-on: ubuntu-20.04
container: espressif/idf:latest
steps:
- name: Checkout esp-protocols
uses: actions/checkout@master
with:
path: esp-protocols
- name: Build and Test
shell: bash
run: |
apt-get update && apt-get install -y dnsutils gcc g++
. ${IDF_PATH}/export.sh
cd $GITHUB_WORKSPACE/esp-protocols/components/mdns/tests/host_test
idf.py build
./build/mdns_host.elf &
dig +short -p 5353 @224.0.0.251 myesp.local > ip.txt
cat ip.txt | xargs dig +short -p 5353 @224.0.0.251 -x
cat ip.txt

View File

@ -6,7 +6,7 @@ endif()
idf_build_get_property(target IDF_TARGET)
if(${target} STREQUAL "linux")
set(dependencies esp_system_protocols_linux)
set(dependencies esp_event esp_netif_linux esp_timer_linux esp_system)
set(srcs "mdns.c" ${MDNS_NETWORKING})
else()
set(dependencies lwip console esp_netif)
@ -22,6 +22,11 @@ idf_component_register(
PRIV_REQUIRES ${private_dependencies})
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
if(${target} STREQUAL "linux")
target_link_libraries(${COMPONENT_LIB} PRIVATE "-lbsd")
endif()
if(CONFIG_ETH_ENABLED)
idf_component_optional_requires(PRIVATE esp_eth)
endif()

View File

@ -81,6 +81,27 @@ menu "mDNS"
This option creates a new thread to serve receiving packets (TODO).
This option uses additional N sockets, where N is number of interfaces.
config MDNS_SKIP_SUPPRESSING_OWN_QUERIES
bool "Skip suppressing our own packets"
default n
help
Enable only if the querier and the responder share the same IP address.
This usually happens in test mode, where we may run multiple instances of
responders/queriers on the same interface.
config MDNS_ENABLE_DEBUG_PRINTS
bool "Enable debug prints of mDNS packets"
default n
help
Enable for the library to log received and sent mDNS packets to stdout.
config MDNS_RESPOND_REVERSE_QUERIES
bool "Enable responding to IPv4 reverse queries"
default n
help
Enables support for IPv4 reverse lookup. If enabled, the mDNS library
response to PTR queries of "A.B.C.D.in-addr.arpa" type.
config MDNS_MULTIPLE_INSTANCE
bool "Multiple instances under the same service type"
default y

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -279,6 +279,13 @@ void app_main(void)
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
#if defined(CONFIG_MDNS_RESPOND_REVERSE_QUERIES)
while (mdns_netif_action(EXAMPLE_INTERFACE, MDNS_EVENT_IP4_REVERSE_LOOKUP) != ESP_OK) {
vTaskDelay(50 / portTICK_PERIOD_MS);
}
#endif
initialise_button();
xTaskCreate(&mdns_example_task, "mdns_example_task", 2048, NULL, 5, NULL);
}

View File

@ -34,6 +34,8 @@ typedef enum {
MDNS_EVENT_ANNOUNCE_IP6 = 1 << 4,
MDNS_EVENT_DISABLE_IP4 = 1 << 5,
MDNS_EVENT_DISABLE_IP6 = 1 << 6,
MDNS_EVENT_IP4_REVERSE_LOOKUP = 1 << 7,
MDNS_EVENT_IP6_REVERSE_LOOKUP = 1 << 8,
} mdns_event_actions_t;
/**

View File

@ -17,10 +17,13 @@
#include "mdns_networking.h"
#include "esp_log.h"
#include "esp_random.h"
#if CONFIG_ETH_ENABLED
#if CONFIG_ETH_ENABLED && CONFIG_MDNS_PREDEF_NETIF_ETH
#include "esp_eth.h"
#endif
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP
#include "esp_wifi.h"
#endif
#ifdef MDNS_ENABLE_DEBUG
@ -435,7 +438,10 @@ static const uint8_t *_mdns_read_fqdn(const uint8_t *packet, const uint8_t *star
&& (strcasecmp(buf, MDNS_DEFAULT_DOMAIN) != 0)
&& (strcasecmp(buf, "arpa") != 0)
&& (strcasecmp(buf, "ip6") != 0)
&& (strcasecmp(buf, "in-addr") != 0)) {
#ifndef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
&& (strcasecmp(buf, "in-addr") != 0)
#endif
) {
strlcat(name->host, ".", sizeof(name->host));
strlcat(name->host, buf, sizeof(name->host));
} else if (strcasecmp(buf, MDNS_SUB_STR) == 0) {
@ -639,6 +645,60 @@ static inline int append_one_txt_record_entry(uint8_t *packet, uint16_t *index,
return len + 1;
}
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
static inline int append_single_str(uint8_t *packet, uint16_t *index, const char *str, int len)
{
if ((*index + len + 1) >= MDNS_MAX_PACKET_SIZE) {
return 0;
}
if (!_mdns_append_u8(packet, index, len)) {
return 0;
}
memcpy(packet + *index, str, len);
*index += len;
return *index;
}
/**
* @brief appends FQDN to a packet from hostname separated by dots. This API works the same way as
* _mdns_append_fqdn(), but refrains from DNS compression (as it's mainly used for IP addresses (many short items),
* where we gain very little (or compression even gets counter-productive mainly for IPv6 addresses)
*
* @param packet MDNS packet
* @param index offset in the packet
* @param name name representing FQDN in '.' separated parts
* @param last true if appending the last part (domain, typically "arpa")
*
* @return length of added data: 0 on error or length on success
*/
static uint16_t append_fqdn_dots(uint8_t *packet, uint16_t *index, const char *name, bool last)
{
int len = strlen(name);
char *host = (char *)name;
char *end = host;
char *start = host;
do {
end = memchr(start, '.', len);
end = end ? end : host + len;
int part_len = end - start;
if (!append_single_str(packet, index, start, part_len)) {
return 0;
}
start = ++end;
} while (end < name + len);
if (!append_single_str(packet, index, "arpa", sizeof("arpa") - 1)) {
return 0;
}
//empty string so terminate
if (!_mdns_append_u8(packet, index, 0)) {
return 0;
}
return *index;
}
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
/**
* @brief appends FQDN to a packet, incrementing the index and
* compressing the output if previous occurrence of the string (or part of it) has been found
@ -680,7 +740,7 @@ search_next:
const uint8_t *content = _mdns_read_fqdn(packet, len_location, &name, buf, packet_len);
if (!content) {
//not a readable fqdn?
return 0;
goto search_next; // could be our unfinished fqdn, continue searching
}
if (name.parts == count) {
uint8_t i;
@ -1100,25 +1160,34 @@ static uint16_t _mdns_append_aaaa_record(uint8_t *packet, uint16_t *index, const
*/
static uint16_t _mdns_append_question(uint8_t *packet, uint16_t *index, mdns_out_question_t *q)
{
const char *str[4];
uint8_t str_index = 0;
uint8_t part_length;
if (q->host) {
str[str_index++] = q->host;
}
if (q->service) {
str[str_index++] = q->service;
}
if (q->proto) {
str[str_index++] = q->proto;
}
if (q->domain) {
str[str_index++] = q->domain;
}
part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE);
if (!part_length) {
return 0;
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
if (q->host && strstr(q->host, "in-addr")) {
part_length = append_fqdn_dots(packet, index, q->host, false);
if (!part_length) {
return 0;
}
} else
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
{
const char *str[4];
uint8_t str_index = 0;
if (q->host) {
str[str_index++] = q->host;
}
if (q->service) {
str[str_index++] = q->service;
}
if (q->proto) {
str[str_index++] = q->proto;
}
if (q->domain) {
str[str_index++] = q->domain;
}
part_length = _mdns_append_fqdn(packet, index, str, str_index, MDNS_MAX_PACKET_SIZE);
if (!part_length) {
return 0;
}
}
part_length += _mdns_append_u16(packet, index, q->type);
@ -1200,6 +1269,37 @@ static uint8_t _mdns_append_host_answer(uint8_t *packet, uint16_t *index, mdns_h
return num_records;
}
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
/**
* @brief Appends reverse lookup PTR record
*/
static uint8_t _mdns_append_reverse_ptr_record(uint8_t *packet, uint16_t *index, const char *name)
{
if (strstr(name, "in-addr") == NULL) {
return 0;
}
if (!append_fqdn_dots(packet, index, name, false)) {
return 0;
}
if (!_mdns_append_type(packet, index, MDNS_ANSWER_PTR, false, 10 /* TTL set to 10s*/ )) {
return 0;
}
uint16_t data_len_location = *index - 2; /* store the position of size (2=16bis) of this record */
const char *str[2] = { _mdns_self_host.hostname, MDNS_DEFAULT_DOMAIN };
int part_length = _mdns_append_fqdn(packet, index, str, 2, MDNS_MAX_PACKET_SIZE);
if (!part_length) {
return 0;
}
_mdns_set_u16(packet, data_len_location, part_length);
return 1; /* appending only 1 record */
}
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
/**
* @brief Append PTR answers to packet
*
@ -1238,6 +1338,10 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
if (answer->type == MDNS_TYPE_PTR) {
if (answer->service) {
return _mdns_append_service_ptr_answers(packet, index, answer->service, answer->flush, answer->bye);
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
} else if (answer->host && answer->host->hostname && strstr(answer->host->hostname, "in-addr")) {
return _mdns_append_reverse_ptr_record(packet, index, answer->host->hostname) > 0;
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
} else {
return _mdns_append_ptr_record(packet, index,
answer->custom_instance, answer->custom_service, answer->custom_proto,
@ -1723,13 +1827,24 @@ static void _mdns_create_answer_from_parsed_packet(mdns_parsed_packet_t *parsed_
_mdns_free_tx_packet(packet);
return;
}
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
} else if (q->type == MDNS_TYPE_PTR) {
mdns_host_item_t *host = mdns_get_host_item(q->host);
if (!_mdns_alloc_answer(&packet->answers, MDNS_TYPE_PTR, NULL, host, send_flush, false)) {
return;
}
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
} else if (!_mdns_alloc_answer(&packet->answers, q->type, NULL, NULL, send_flush, false)) {
_mdns_free_tx_packet(packet);
return;
}
if (parsed_packet->src_port != MDNS_SERVICE_PORT && // Repeat the queries only for "One-Shot mDNS queries"
(q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA)) {
(q->type == MDNS_TYPE_ANY || q->type == MDNS_TYPE_A || q->type == MDNS_TYPE_AAAA
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
|| q->type == MDNS_TYPE_PTR
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
)) {
mdns_out_question_t *out_question = malloc(sizeof(mdns_out_question_t));
if (out_question == NULL) {
HOOK_MALLOC_FAILED;
@ -2948,7 +3063,11 @@ static bool _mdns_name_is_discovery(mdns_name_t *name, uint16_t type)
static bool _mdns_name_is_ours(mdns_name_t *name)
{
//domain have to be "local"
if (_str_null_or_empty(name->domain) || strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN)) {
if (_str_null_or_empty(name->domain) || ( strcasecmp(name->domain, MDNS_DEFAULT_DOMAIN)
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
&& strcasecmp(name->domain, "arpa")
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
) ) {
return false;
}
@ -3308,6 +3427,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
mdns_debug_packet(data, len);
#endif
#ifndef CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES
// Check if the packet wasn't sent by us
if (packet->ip_protocol == MDNS_IP_PROTOCOL_V4) {
esp_netif_ip_info_t if_ip_info;
@ -3324,6 +3444,7 @@ void mdns_parse_packet(mdns_rx_packet_t *packet)
}
#endif
}
#endif
// Check for the minimum size of mdns packet
if (len <= MDNS_HEAD_ADDITIONAL_OFFSET) {
@ -3871,6 +3992,22 @@ static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
if (action & MDNS_EVENT_ANNOUNCE_IP6) {
_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
}
#ifdef CONFIG_MDNS_RESPOND_REVERSE_QUERIES
if (action & MDNS_EVENT_IP4_REVERSE_LOOKUP) {
esp_netif_ip_info_t if_ip_info;
if (esp_netif_get_ip_info(_mdns_get_esp_netif(mdns_if), &if_ip_info) == ESP_OK) {
esp_ip4_addr_t *ip = &if_ip_info.ip;
char *reverse_query_name = NULL;
if (asprintf(&reverse_query_name, "%d.%d.%d.%d.in-addr",
esp_ip4_addr4_16(ip), esp_ip4_addr3_16(ip),
esp_ip4_addr2_16(ip), esp_ip4_addr1_16(ip)) > 0 && reverse_query_name) {
ESP_LOGD(TAG, "Registered reverse query: %s.arpa", reverse_query_name);
_mdns_delegate_hostname_add(reverse_query_name, NULL);
}
}
}
#endif /* CONFIG_MDNS_RESPOND_REVERSE_QUERIES */
}
/**
@ -3891,6 +4028,7 @@ static inline void post_mdns_announce_pcb(mdns_predef_if_t preset_if, mdns_ip_pr
mdns_post_custom_action_tcpip_if(mdns_if_from_preset_if(preset_if), protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_EVENT_ANNOUNCE_IP4 : MDNS_EVENT_ANNOUNCE_IP6);
}
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH
void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
@ -3968,6 +4106,7 @@ void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base,
}
}
}
#endif /* CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH */
/*
* MDNS Search
@ -6065,19 +6204,19 @@ void mdns_debug_packet(const uint8_t *data, size_t len)
_mdns_dbg_printf("Packet[%u]: ", t);
header.id = _mdns_read_u16(data, MDNS_HEAD_ID_OFFSET);
header.flags.value = _mdns_read_u16(data, MDNS_HEAD_FLAGS_OFFSET);
header.flags = _mdns_read_u16(data, MDNS_HEAD_FLAGS_OFFSET);
header.questions = _mdns_read_u16(data, MDNS_HEAD_QUESTIONS_OFFSET);
header.answers = _mdns_read_u16(data, MDNS_HEAD_ANSWERS_OFFSET);
header.servers = _mdns_read_u16(data, MDNS_HEAD_SERVERS_OFFSET);
header.additional = _mdns_read_u16(data, MDNS_HEAD_ADDITIONAL_OFFSET);
_mdns_dbg_printf("%s",
(header.flags.value == MDNS_FLAGS_QR_AUTHORITATIVE) ? "AUTHORITATIVE\n" :
(header.flags.value == MDNS_FLAGS_DISTRIBUTED) ? "DISTRIBUTED\n" :
(header.flags.value == 0) ? "\n" : " "
(header.flags == MDNS_FLAGS_QR_AUTHORITATIVE) ? "AUTHORITATIVE\n" :
(header.flags == MDNS_FLAGS_DISTRIBUTED) ? "DISTRIBUTED\n" :
(header.flags == 0) ? "\n" : " "
);
if (header.flags.value && header.flags.value != MDNS_FLAGS_QR_AUTHORITATIVE) {
_mdns_dbg_printf("0x%04X\n", header.flags.value);
if (header.flags && header.flags != MDNS_FLAGS_QR_AUTHORITATIVE) {
_mdns_dbg_printf("0x%04X\n", header.flags);
}
if (header.questions) {

View File

@ -14,10 +14,10 @@
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "esp_timer.h"
#include "esp_system.h"
//#define MDNS_ENABLE_DEBUG
#ifdef MDNS_ENABLE_DEBUG
#ifdef CONFIG_MDNS_ENABLE_DEBUG_PRINTS
#define MDNS_ENABLE_DEBUG
#define _mdns_dbg_printf(...) printf(__VA_ARGS__)
#endif

View File

@ -1,5 +1,7 @@
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS "../..")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
set(COMPONENTS main)
set(COMPONENTS main esp_netif_linux)
project(mdns_host)

View File

@ -1,7 +1,10 @@
# Setup dummy network interfaces
Note: Set two addresses so we could use one as source and another as destination
```
sudo ip link add eth2 type dummy
sudo ip addr add 192.168.1.200/24 dev eth2
sudo ip addr add 192.168.1.201/24 dev eth2
sudo ip link set eth2 up
sudo ifconfig eth2 multicast
```
@ -12,6 +15,11 @@ sudo ifconfig eth2 multicast
dig +short -b 192.168.1.200 -p 5353 @224.0.0.251 myesp.local
```
or a reverse query:
```
dig +short -b 192.168.2.200 -p 5353 @224.0.0.251 -x 192.168.1.200
```
# Run avahi to browse services
Avahi needs the netif to have the "multicast" flag set

View File

@ -0,0 +1,2 @@
idf_component_register(SRCS esp_event_mock.c
INCLUDE_DIRS include)

View File

@ -8,16 +8,7 @@
#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;
#include "bsd/string.h"
esp_err_t esp_event_handler_register(const char *event_base, int32_t event_id, void *event_handler, void *event_handler_arg);

View File

@ -11,3 +11,9 @@ typedef enum {
WIFI_EVENT_AP_START, /**< ESP32 soft-AP start */
WIFI_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
} mdns_used_event_t;
#define ESP_EVENT_DECLARE_BASE(x)
#define ESP_EVENT_ANY_ID (-1)
typedef void *esp_event_base_t;
typedef void *system_event_t;

View File

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

View File

@ -1,3 +1,3 @@
idf_component_register(SRCS esp_netif_linux.c
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)
INCLUDE_DIRS include $ENV{IDF_PATH}/components/esp_netif/include
REQUIRES esp_event)

View File

@ -50,9 +50,7 @@ esp_err_t esp_netif_get_ip_info(esp_netif_t *esp_netif, esp_netif_ip_info_t *ip_
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;

View File

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

View File

@ -1,27 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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");
}
}

View File

@ -1,8 +0,0 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
size_t strlcat(char *dest, const char *src, size_t size);

View File

@ -1,70 +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 */
}

View File

@ -1,6 +1,6 @@
idf_component_register(SRCS esp_timer_linux.c timer_task.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux freertos_linux)
REQUIRES esp_event)
set_target_properties(${COMPONENT_LIB} PROPERTIES
CXX_STANDARD 17

View File

@ -16,7 +16,7 @@ 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(cb_t cb): cb(cb), active(false), ms(INT32_MAX) {}
~TimerTaskMock(void)
{
active = false;
@ -27,6 +27,7 @@ public:
{
ms = m;
active = true;
t = std::thread(run_static, this);
}
private:

View File

@ -1,6 +1,5 @@
idf_component_register(SRCS freertos_linux.c queue_unique_ptr.cpp
INCLUDE_DIRS include
REQUIRES esp_system_protocols_linux)
INCLUDE_DIRS include)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

View File

@ -158,16 +158,6 @@ void xTaskCreate(TaskFunction_t pvTaskCode, const char *const pcName, const uint
}
}
uint32_t esp_get_free_heap_size(void)
{
return 0;
}
uint32_t esp_random(void)
{
return rand();
}
void xTaskNotifyGive(TaskHandle_t task)
{

View File

@ -32,3 +32,4 @@ typedef int BaseType_t;
uint32_t esp_get_free_heap_size(void);
uint32_t esp_random(void);
void vTaskSuspendAll(void);

View File

@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
//
// Created by david on 1/13/23.
//
#ifndef _QUEUE_H_
#define _QUEUE_H_
#endif //_QUEUE_H_

View File

@ -0,0 +1,13 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
//
// Created by david on 1/13/23.
//
#ifndef _SEMAPHR_H_
#define _SEMAPHR_H_
#endif //_SEMAPHR_H_

View File

@ -0,0 +1,15 @@
menu "Test Configuration"
config TEST_HOSTNAME
string "mDNS Hostname"
default "esp32-mdns"
help
mDNS Hostname for example to use
config TEST_NETIF_NAME
string "Network interface name"
default "eth2"
help
Name/ID if the network interface on which we run the mDNS host test
endmenu

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@ -35,14 +35,16 @@ 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" };
const esp_netif_inherent_config_t base_cg = { .if_key = "WIFI_STA_DEF", .if_desc = CONFIG_TEST_NETIF_NAME };
esp_netif_config_t cfg = { .base = &base_cg };
esp_netif_t *sta = esp_netif_new(&cfg);
ESP_ERROR_CHECK(mdns_init());
ESP_ERROR_CHECK(mdns_hostname_set(CONFIG_TEST_HOSTNAME));
ESP_LOGI(TAG, "mdns hostname set to: [%s]", CONFIG_TEST_HOSTNAME);
ESP_ERROR_CHECK(mdns_register_netif(sta));
ESP_ERROR_CHECK(mdns_netif_action(sta, MDNS_EVENT_ENABLE_IP4 | MDNS_EVENT_IP4_REVERSE_LOOKUP));
mdns_init();
mdns_hostname_set("myesp");
ESP_LOGI(TAG, "mdns hostname set to: [%s]", "myesp");
#ifdef REGISTER_SERVICE
//set default mDNS instance name
mdns_instance_name_set("myesp-inst");
//structure with TXT records
@ -51,12 +53,12 @@ int main(int argc, char *argv[])
{"u", "user"},
{"p", "password"}
};
vTaskDelay(1000);
vTaskDelay(pdMS_TO_TICKS(10000));
ESP_ERROR_CHECK(mdns_service_add("myesp-service2", "_http", "_tcp", 80, serviceTxtData, 3));
vTaskDelay(2000);
query_mdns_host("david-comp");
vTaskDelay(2000);
#endif
vTaskDelay(pdMS_TO_TICKS(10000));
query_mdns_host("david-work");
vTaskDelay(pdMS_TO_TICKS(1000));
esp_netif_destroy(sta);
mdns_free();
ESP_LOGI(TAG, "Exit");

View File

@ -0,0 +1,9 @@
CONFIG_IDF_TARGET="linux"
CONFIG_MDNS_NETWORKING_SOCKET=y
CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES=y
CONFIG_TEST_NETIF_NAME="eth0"
CONFIG_TEST_HOSTNAME="myesp"
CONFIG_MDNS_PREDEF_NETIF_STA=n
CONFIG_MDNS_PREDEF_NETIF_AP=n
CONFIG_MDNS_ENABLE_DEBUG_PRINTS=y
CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y