Initial public release of the 2024A software.

This commit is contained in:
Joe Kearney 2025-01-25 14:04:42 -06:00
parent 7b9ad3edfd
commit 303e9e1dad
361 changed files with 60083 additions and 2 deletions

View file

@ -0,0 +1,16 @@
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
if(${IDF_TARGET} STREQUAL "linux")
set(EXTRA_COMPONENT_DIRS "../../../../common_components/linux_compat")
set(COMPONENTS main)
endif()
project(mdns_host)
# Enable sanitizers only without console (we'd see some leaks on argtable when console exits)
if(NOT CONFIG_TEST_CONSOLE AND CONFIG_IDF_TARGET_LINUX)
idf_component_get_property(mdns mdns COMPONENT_LIB)
target_link_options(${mdns} INTERFACE -fsanitize=address -fsanitize=undefined)
endif()

View file

@ -0,0 +1,33 @@
# 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
```
# Dig on a specified interface
```
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
```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"
```

View file

@ -0,0 +1,8 @@
idf_build_get_property(idf_target IDF_TARGET)
if(${IDF_TARGET} STREQUAL "linux")
idf_component_register(SRCS esp_netif_linux.c
INCLUDE_DIRS include $ENV{IDF_PATH}/components/esp_netif/include
REQUIRES esp_event)
else()
idf_component_register()
endif()

View file

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

View file

@ -0,0 +1,197 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#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"
#include "esp_log.h"
#define MAX_NETIFS 4
static const char *TAG = "esp_netif_linux";
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) {
ESP_LOGD(TAG, "AF_INET4: %s: %s\n", tmp->ifa_name, addr);
memcpy(&ip_info->ip.addr, &pAddr->sin_addr, 4);
}
}
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
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;
}
int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[])
{
if (esp_netif == NULL) {
return 0;
}
struct ifaddrs *addrs, *tmp;
int addr_count = 0;
getifaddrs(&addrs);
tmp = addrs;
while (tmp) {
if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)tmp->ifa_addr;
if (strcmp(esp_netif->if_desc, tmp->ifa_name) == 0) {
memcpy(&if_ip6[addr_count++], &pAddr->sin6_addr, 4 * 4);
}
}
tmp = tmp->ifa_next;
}
freeifaddrs(addrs);
return addr_count;
}
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) {
ESP_LOGD(TAG, "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);
}
const char *esp_netif_get_ifkey(esp_netif_t *esp_netif)
{
return esp_netif->if_key;
}
esp_err_t esp_netif_str_to_ip4(const char *src, esp_ip4_addr_t *dst)
{
if (src == NULL || dst == NULL) {
return ESP_ERR_INVALID_ARG;
}
struct in_addr addr;
if (inet_pton(AF_INET, src, &addr) != 1) {
return ESP_FAIL;
}
dst->addr = addr.s_addr;
return ESP_OK;
}

View file

@ -0,0 +1,7 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include "esp_event.h"

View file

@ -0,0 +1,8 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include_next "endian.h"

View file

@ -0,0 +1,130 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import re
import socket
import sys
import dns.message
import dns.query
import dns.rdataclass
import dns.rdatatype
import dns.resolver
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class DnsPythonWrapper:
def __init__(self, server='224.0.0.251', port=5353, retries=3):
self.server = server
self.port = port
self.retries = retries
def send_and_receive_query(self, query, timeout=3):
logger.info(f'Sending DNS query to {self.server}:{self.port}')
try:
# Create a UDP socket
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
sock.settimeout(timeout)
# Send the DNS query
query_data = query.to_wire()
sock.sendto(query_data, (self.server, self.port))
# Receive the DNS response
response_data, _ = sock.recvfrom(512) # 512 bytes is the typical size for a DNS response
# Parse the response
response = dns.message.from_wire(response_data)
return response
except socket.timeout as e:
logger.warning(f'DNS query timed out: {e}')
return None
except dns.exception.DNSException as e:
logger.error(f'DNS query failed: {e}')
return None
def run_query(self, name, query_type='PTR', timeout=3):
logger.info(f'Running DNS query for {name} with type {query_type}')
query = dns.message.make_query(name, dns.rdatatype.from_text(query_type), dns.rdataclass.IN)
# Print the DNS question section
logger.info(f'DNS question section: {query.question}')
# Send and receive the DNS query
response = None
for attempt in range(1, self.retries + 1):
logger.info(f'Attempt {attempt}/{self.retries}')
response = self.send_and_receive_query(query, timeout)
if response:
break
if response:
logger.info(f'DNS query response:\n{response}')
else:
logger.warning('No response received or response was invalid.')
return response
def parse_answer_section(self, response, query_type):
answers = []
if response:
for answer in response.answer:
if dns.rdatatype.to_text(answer.rdtype) == query_type:
for item in answer.items:
full_answer = (
f'{answer.name} {answer.ttl} '
f'{dns.rdataclass.to_text(answer.rdclass)} '
f'{dns.rdatatype.to_text(answer.rdtype)} '
f'{item.to_text()}'
)
answers.append(full_answer)
return answers
def check_record(self, name, query_type, expected=True, expect=None):
output = self.run_query(name, query_type=query_type)
answers = self.parse_answer_section(output, query_type)
logger.info(f'answers: {answers}')
if expect is None:
expect = name
if expected:
assert any(expect in answer for answer in answers), f"Expected record '{expect}' not found in answer section"
else:
assert not any(expect in answer for answer in answers), f"Unexpected record '{expect}' found in answer section"
if __name__ == '__main__':
if len(sys.argv) < 3:
print('Usage: python dns_fixture.py <query_type> <name>')
sys.exit(1)
query_type = sys.argv[1]
name = sys.argv[2]
ip_only = len(sys.argv) > 3 and sys.argv[3] == '--ip_only'
if ip_only:
logger.setLevel(logging.WARNING)
dns_wrapper = DnsPythonWrapper()
if query_type == 'X' and '.' in name:
# Sends an IPv4 reverse query
reversed_ip = '.'.join(reversed(name.split('.')))
name = f'{reversed_ip}.in-addr.arpa'
query_type = 'PTR'
response = dns_wrapper.run_query(name, query_type=query_type)
answers = dns_wrapper.parse_answer_section(response, query_type)
if answers:
for answer in answers:
logger.info(f'DNS query response: {answer}')
if ip_only:
ipv4_pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')
ipv4_addresses = ipv4_pattern.findall(answer)
if ipv4_addresses:
print(f"{', '.join(ipv4_addresses)}")
else:
logger.info(f'No response for {name} with query type {query_type}')
exit(9) # Same as dig timeout

View file

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

View file

@ -0,0 +1,21 @@
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
config TEST_CONSOLE
bool "Start console"
default n
help
Test uses esp_console for interactive testing.
endmenu

View file

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

View file

@ -0,0 +1,126 @@
/*
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <stdio.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_console.h"
#include "mdns.h"
#include "mdns_console.h"
static const char *TAG = "mdns-test";
static void mdns_test_app(esp_netif_t *interface);
#ifdef CONFIG_TEST_CONSOLE
static EventGroupHandle_t s_exit_signal = NULL;
static int exit_console(int argc, char **argv)
{
xEventGroupSetBits(s_exit_signal, 1);
return 0;
}
#else
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));
}
#endif // TEST_CONSOLE
#ifndef CONFIG_IDF_TARGET_LINUX
#include "protocol_examples_common.h"
#include "esp_event.h"
#include "nvs_flash.h"
/**
* @brief This is an entry point for the real target device,
* need to init few components and connect to a network interface
*/
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
mdns_test_app(EXAMPLE_INTERFACE);
ESP_ERROR_CHECK(example_disconnect());
}
#else
/**
* @brief This is an entry point for the linux target (simulator on host)
* need to create a dummy WiFi station and use it as mdns network interface
*/
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 = CONFIG_TEST_NETIF_NAME };
esp_netif_config_t cfg = { .base = &base_cg };
esp_netif_t *sta = esp_netif_new(&cfg);
mdns_test_app(sta);
esp_netif_destroy(sta);
return 0;
}
#endif
static void mdns_test_app(esp_netif_t *interface)
{
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(interface));
ESP_ERROR_CHECK(mdns_netif_action(interface, MDNS_EVENT_ENABLE_IP4 /*| MDNS_EVENT_ENABLE_IP6 */ | MDNS_EVENT_IP4_REVERSE_LOOKUP | MDNS_EVENT_IP6_REVERSE_LOOKUP));
#ifdef CONFIG_TEST_CONSOLE
esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
esp_console_dev_uart_config_t uart_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
s_exit_signal = xEventGroupCreate();
repl_config.prompt = "mdns>";
// init console REPL environment
ESP_ERROR_CHECK(esp_console_new_repl_uart(&uart_config, &repl_config, &repl));
const esp_console_cmd_t cmd_exit = {
.command = "exit",
.help = "exit mDNS console application",
.hint = NULL,
.func = exit_console,
.argtable = NULL
};
ESP_ERROR_CHECK( esp_console_cmd_register(&cmd_exit) );
mdns_console_register();
ESP_ERROR_CHECK(esp_console_start_repl(repl));
xEventGroupWaitBits(s_exit_signal, 1, pdTRUE, pdFALSE, portMAX_DELAY);
repl->del(repl);
#else
vTaskDelay(pdMS_TO_TICKS(10000));
query_mdns_host("david-work");
vTaskDelay(pdMS_TO_TICKS(1000));
#endif
mdns_free();
ESP_LOGI(TAG, "Exit");
}

View file

@ -0,0 +1,180 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import pexpect
import pytest
from dnsfixture import DnsPythonWrapper
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
ipv6_enabled = False
class MdnsConsole:
def __init__(self, command):
self.process = pexpect.spawn(command, encoding='utf-8')
self.process.logfile = open('mdns_interaction.log', 'w') # Log all interactions
self.process.expect('mdns> ', timeout=10)
def send_input(self, input_data):
logger.info(f'Sending to stdin: {input_data}')
self.process.sendline(input_data)
def get_output(self, expected_data):
logger.info(f'Expecting: {expected_data}')
self.process.expect(expected_data, timeout=10)
output = self.process.before.strip()
logger.info(f'Received from stdout: {output}')
return output
def terminate(self):
self.send_input('exit')
self.get_output('Exit')
self.process.wait()
self.process.close()
assert self.process.exitstatus == 0
@pytest.fixture(scope='module')
def mdns_console():
app = MdnsConsole('./build_linux_console/mdns_host.elf')
yield app
app.terminate()
@pytest.fixture(scope='module')
def dig_app():
return DnsPythonWrapper()
def test_mdns_init(mdns_console, dig_app):
mdns_console.send_input('mdns_init -h hostname')
mdns_console.get_output('MDNS: Hostname: hostname')
dig_app.check_record('hostname.local', query_type='A', expected=True)
if ipv6_enabled:
dig_app.check_record('hostname.local', query_type='AAAA', expected=True)
def test_add_service(mdns_console, dig_app):
mdns_console.send_input('mdns_service_add _http _tcp 80 -i test_service')
mdns_console.get_output('MDNS: Service Instance: test_service')
mdns_console.send_input('mdns_service_lookup _http _tcp')
mdns_console.get_output('PTR : test_service')
dig_app.check_record('_http._tcp.local', query_type='PTR', expected=True)
def test_remove_service(mdns_console, dig_app):
mdns_console.send_input('mdns_service_remove _http _tcp')
mdns_console.send_input('mdns_service_lookup _http _tcp')
mdns_console.get_output('No results found!')
dig_app.check_record('_http._tcp.local', query_type='PTR', expected=False)
def test_delegate_host(mdns_console, dig_app):
mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4')
dig_app.check_record('delegated.local', query_type='A', expected=True)
def test_undelegate_host(mdns_console, dig_app):
mdns_console.send_input('mdns_undelegate_host delegated')
dig_app.check_record('delegated.local', query_type='A', expected=False)
def test_add_delegated_service(mdns_console, dig_app):
mdns_console.send_input('mdns_delegate_host delegated 1.2.3.4')
dig_app.check_record('delegated.local', query_type='A', expected=True)
mdns_console.send_input('mdns_service_add _test _tcp 80 -i local')
mdns_console.get_output('MDNS: Service Instance: local')
mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated')
mdns_console.get_output('MDNS: Service Instance: extern')
mdns_console.send_input('mdns_service_lookup _test _tcp')
mdns_console.get_output('PTR : local')
mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
mdns_console.get_output('PTR : extern')
dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=True)
dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True)
def test_remove_delegated_service(mdns_console, dig_app):
mdns_console.send_input('mdns_service_remove _test2 _tcp -h delegated')
mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
mdns_console.get_output('No results found!')
dig_app.check_record('_test2._tcp.local', query_type='PTR', expected=False)
# add the delegated service again, would be used in the TXT test
mdns_console.send_input('mdns_service_add _test2 _tcp 80 -i extern -h delegated')
mdns_console.get_output('MDNS: Service Instance: extern')
def check_txt_for_service(instance, service, proto, mdns_console, dig_app, host=None, with_inst=False):
for_host_arg = f'-h {host}' if host is not None else ''
for_inst_arg = f'-i {instance}' if with_inst else ''
mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key1 value1')
dig_app.check_record(f'{instance}.{service}.{proto}.local', query_type='SRV', expected=True)
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1')
mdns_console.send_input(f'mdns_service_txt_set {service} {proto} {for_host_arg} {for_inst_arg} key2 value2')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key2=value2')
mdns_console.send_input(f'mdns_service_txt_remove {service} {proto} {for_host_arg} {for_inst_arg} key2')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key2=value2')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key1=value1')
mdns_console.send_input(f'mdns_service_txt_replace {service} {proto} {for_host_arg} {for_inst_arg} key3=value3 key4=value4')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=False, expect='key1=value1')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key3=value3')
dig_app.check_record(f'{service}.{proto}.local', query_type='TXT', expected=True, expect='key4=value4')
def test_update_txt(mdns_console, dig_app):
check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app)
check_txt_for_service('local', '_test', '_tcp', mdns_console=mdns_console, dig_app=dig_app, with_inst=True)
def test_update_delegated_txt(mdns_console, dig_app):
check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated')
check_txt_for_service('extern', '_test2', '_tcp', mdns_console=mdns_console, dig_app=dig_app, host='delegated', with_inst=True)
def test_service_port_set(mdns_console, dig_app):
dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='80')
mdns_console.send_input('mdns_service_port_set _test _tcp 81')
dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True, expect='81')
mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated 82')
dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='82')
mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i extern 83')
dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83')
mdns_console.send_input('mdns_service_port_set _test2 _tcp -h delegated -i invalid_inst 84')
mdns_console.get_output('ESP_ERR_NOT_FOUND')
dig_app.check_record('extern._test2._tcp.local', query_type='SRV', expected=True, expect='83')
def test_service_subtype(mdns_console, dig_app):
dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True)
mdns_console.send_input('mdns_service_subtype _test _tcp _subtest -i local')
dig_app.check_record('_subtest._sub._test._tcp.local', query_type='PTR', expected=True)
mdns_console.send_input('mdns_service_subtype _test2 _tcp _subtest2 -i extern -h delegated')
dig_app.check_record('_subtest2._sub._test2._tcp.local', query_type='PTR', expected=True)
def test_service_set_instance(mdns_console, dig_app):
dig_app.check_record('local._test._tcp.local', query_type='SRV', expected=True)
mdns_console.send_input('mdns_service_instance_set _test _tcp local2')
dig_app.check_record('local2._test._tcp.local', query_type='SRV', expected=True)
mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern2 -h delegated')
mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
mdns_console.get_output('PTR : extern2')
dig_app.check_record('extern2._test2._tcp.local', query_type='SRV', expected=True)
mdns_console.send_input('mdns_service_instance_set _test2 _tcp extern3 -h delegated -i extern')
mdns_console.get_output('ESP_ERR_NOT_FOUND')
def test_service_remove_all(mdns_console, dig_app):
mdns_console.send_input('mdns_service_remove_all')
mdns_console.send_input('mdns_service_lookup _test2 _tcp -d')
mdns_console.get_output('No results found!')
mdns_console.send_input('mdns_service_lookup _test _tcp')
mdns_console.get_output('No results found!')
dig_app.check_record('_test._tcp.local', query_type='PTR', expected=False)
if __name__ == '__main__':
pytest.main(['-s', 'test_mdns.py'])

View file

@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="linux"
CONFIG_TEST_HOSTNAME="myesp"
CONFIG_MDNS_ENABLE_DEBUG_PRINTS=y
CONFIG_MDNS_RESPOND_REVERSE_QUERIES=y

View file

@ -0,0 +1,4 @@
CONFIG_IDF_TARGET="linux"
CONFIG_ESP_EVENT_POST_FROM_ISR=n
CONFIG_MDNS_ENABLE_CONSOLE_CLI=y
CONFIG_TEST_CONSOLE=y

View file

@ -0,0 +1 @@
CONFIG_IDF_TARGET="esp32"

View file

@ -0,0 +1,6 @@
CONFIG_TEST_NETIF_NAME="eth0"
CONFIG_ESP_EVENT_POST_FROM_ISR=n
CONFIG_MDNS_NETWORKING_SOCKET=y
CONFIG_MDNS_SKIP_SUPPRESSING_OWN_QUERIES=y
CONFIG_MDNS_PREDEF_NETIF_STA=n
CONFIG_MDNS_PREDEF_NETIF_AP=n