Merge branch 'feature/mdns_dynamic_interfaces' into 'master'

mdns: Add support for dynamic network interfaces

Closes IDF-939

See merge request espressif/esp-idf!14875
pull/8526/head
David Čermák 2022-03-10 15:11:35 +08:00
commit 0b58f987cd
17 zmienionych plików z 532 dodań i 176 usunięć

Wyświetl plik

@ -309,6 +309,7 @@ example_test_001A:
example_test_001B:
extends: .example_test_esp32_template
parallel: 2
tags:
- ESP32
- Example_EthKitV1

Wyświetl plik

@ -1,5 +1,13 @@
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
@ -64,7 +72,7 @@ menu "mDNS"
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)
such as lwIP mDNS resolver (used by standard POSIX API like getaddrinfo, gethostbyname)
could not correctly resolve advertised names.
config MDNS_TIMER_PERIOD_MS
@ -76,10 +84,10 @@ menu "mDNS"
and schedules mDNS searches.
config MDNS_NETWORKING_SOCKET
bool "Use BSD sockets for mdns networking"
bool "Use BSD sockets for mDNS networking"
default n
help
Enables optional mdns networking implementation using BSD sockets
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.
@ -90,4 +98,30 @@ menu "mDNS"
help
Enables adding multiple service instances under the same service type.
menu "MDNS Predefined interfaces"
config MDNS_PREDEF_NETIF_STA
bool "Use predefined interface for WiFi Station"
default y
help
Set up mDNS for the default WiFi station.
Disable this option if you do not need mDNS on default WiFi STA.
config MDNS_PREDEF_NETIF_AP
bool "Use predefined interface for WiFi Access Point"
default y
help
Set up mDNS for the default WiFi Access Point.
Disable this option if you do not need mDNS on default WiFi AP.
config MDNS_PREDEF_NETIF_ETH
bool "Use predefined interface for Ethernet"
depends on ETH_ENABLED
default y
help
Set up mDNS for the default Ethernet interface.
Disable this option if you do not need mDNS on default Ethernet.
endmenu # MDNS Predefined interfaces
endmenu

Wyświetl plik

@ -26,6 +26,16 @@ extern "C" {
*/
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
*/
@ -52,13 +62,6 @@ typedef struct mdns_ip_addr_s {
struct mdns_ip_addr_s * next; /*!< next IP, or NULL for the last IP in the list */
} mdns_ip_addr_t;
typedef enum mdns_if_internal {
MDNS_IF_STA = 0,
MDNS_IF_AP = 1,
MDNS_IF_ETH = 2,
MDNS_IF_MAX
} mdns_if_t;
/**
* @brief mDNS query type to be explicitly set to either Unicast or Multicast
*/
@ -73,7 +76,7 @@ typedef enum {
typedef struct mdns_result_s {
struct mdns_result_s * next; /*!< next result, or NULL for the last result in the list */
mdns_if_t tcpip_if; /*!< interface index */
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) */
@ -716,6 +719,53 @@ esp_err_t mdns_query_a(const char * host_name, uint32_t timeout, esp_ip4_addr_t
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

Wyświetl plik

@ -57,32 +57,98 @@ static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search,
static bool _mdns_append_host_list_in_services(mdns_out_answer_t ** destination, mdns_srv_item_t * services[], size_t services_len, bool flush, bool bye);
static bool _mdns_append_host_list(mdns_out_answer_t ** destination, bool flush, bool bye);
static void _mdns_remap_self_service_hostname(const char *old_hostname, const char *new_hostname);
static esp_err_t mdns_post_custom_action_tcpip_if(mdns_if_t mdns_if, mdns_event_actions_t event_action);
typedef enum {
MDNS_IF_STA = 0,
MDNS_IF_AP = 1,
MDNS_IF_ETH = 2,
} mdns_predef_if_t;
typedef struct mdns_interfaces mdns_interfaces_t;
struct mdns_interfaces {
const bool predefined;
esp_netif_t * netif;
const mdns_predef_if_t predef_if;
mdns_if_t duplicate;
};
/*
* @brief Internal collection of mdns supported interfaces
*
*/
static esp_netif_t * s_esp_netifs[MDNS_IF_MAX] = {};
static mdns_interfaces_t s_esp_netifs[MDNS_MAX_INTERFACES] = {
#if CONFIG_MDNS_PREDEF_NETIF_STA
{ .predefined = true, .netif = NULL, .predef_if = MDNS_IF_STA, .duplicate = MDNS_MAX_INTERFACES },
#endif
#if CONFIG_MDNS_PREDEF_NETIF_AP
{ .predefined = true, .netif = NULL, .predef_if = MDNS_IF_AP, .duplicate = MDNS_MAX_INTERFACES },
#endif
#if CONFIG_MDNS_PREDEF_NETIF_ETH
{ .predefined = true, .netif = NULL, .predef_if = MDNS_IF_ETH, .duplicate = MDNS_MAX_INTERFACES },
#endif
};
/*
* @brief Convert mdns if to esp-netif handle
/**
* @brief Convert Predefined interface to the netif id from the internal netif list
* @param predef_if Predefined interface enum
* @return Ordinal number of internal list of mdns network interface.
* Returns MDNS_MAX_INTERFACES if the predefined interface wasn't found in the list
*/
static mdns_if_t mdns_if_from_preset_if(mdns_predef_if_t predef_if)
{
for (int i=0; i<MDNS_MAX_INTERFACES; ++i) {
if (s_esp_netifs[i].predefined && s_esp_netifs[i].predef_if == predef_if) {
return i;
}
}
return MDNS_MAX_INTERFACES;
}
/**
* @brief Convert Predefined interface to esp-netif handle
* @param predef_if Predefined interface enum
* @return esp_netif pointer from system list of network interfaces
*/
static inline esp_netif_t *esp_netif_from_preset_if(mdns_predef_if_t predef_if)
{
switch (predef_if) {
case MDNS_IF_STA:
return esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
case MDNS_IF_AP:
return esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
#if CONFIG_ETH_ENABLED
case MDNS_IF_ETH:
return esp_netif_get_handle_from_ifkey("ETH_DEF");
#endif
default:
return NULL;
}
}
/**
* @brief Gets the actual esp_netif pointer from the internal network interface list
*
* The supplied ordinal number could
* - point to a predef netif -> "STA", "AP", "ETH"
* - if no entry in the list (NULL) -> check if the system added this netif
* - point to a custom netif -> just return the entry in the list
* - users is responsible for the lifetime of this netif (to be valid between mdns-init -> deinit)
*
* @param tcpip_if Ordinal number of the interface
* @return Pointer ot the esp_netif object if the interface is available, NULL otherwise
*/
esp_netif_t *_mdns_get_esp_netif(mdns_if_t tcpip_if)
{
if (tcpip_if < MDNS_IF_MAX) {
if (s_esp_netifs[tcpip_if] == NULL) {
// if local netif copy is NULL, try to search for the default interface key
if (tcpip_if == MDNS_IF_STA) {
s_esp_netifs[MDNS_IF_STA] = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
} else if (tcpip_if == MDNS_IF_AP) {
s_esp_netifs[MDNS_IF_AP] = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
#if CONFIG_ETH_ENABLED
} else if (tcpip_if == MDNS_IF_ETH) {
s_esp_netifs[MDNS_IF_ETH] = esp_netif_get_handle_from_ifkey("ETH_DEF");
#endif
}
if (tcpip_if < MDNS_MAX_INTERFACES) {
if (s_esp_netifs[tcpip_if].netif == NULL && s_esp_netifs[tcpip_if].predefined) {
// If the local copy is NULL and this netif is predefined -> we can find it in the global netif list
s_esp_netifs[tcpip_if].netif = esp_netif_from_preset_if(s_esp_netifs[tcpip_if].predef_if);
// failing to find it means that the netif is *not* available -> return NULL
}
return s_esp_netifs[tcpip_if];
return s_esp_netifs[tcpip_if].netif;
}
return NULL;
}
@ -92,8 +158,8 @@ esp_netif_t *_mdns_get_esp_netif(mdns_if_t tcpip_if)
* @brief Clean internal mdns interface's pointer
*/
static inline void _mdns_clean_netif_ptr(mdns_if_t tcpip_if) {
if (tcpip_if < MDNS_IF_MAX) {
s_esp_netifs[tcpip_if] = NULL;
if (tcpip_if < MDNS_MAX_INTERFACES) {
s_esp_netifs[tcpip_if].netif = NULL;
}
}
@ -101,13 +167,14 @@ static inline void _mdns_clean_netif_ptr(mdns_if_t tcpip_if) {
/*
* @brief Convert esp-netif handle to mdns if
*/
static mdns_if_t _mdns_get_if_from_esp_netif(esp_netif_t *interface)
static mdns_if_t _mdns_get_if_from_esp_netif(esp_netif_t *esp_netif)
{
for (int i=0; i<MDNS_IF_MAX; ++i) {
if (interface == s_esp_netifs[i])
for (int i=0; i<MDNS_MAX_INTERFACES; ++i) {
if (esp_netif == s_esp_netifs[i].netif) {
return i;
}
}
return MDNS_IF_MAX;
return MDNS_MAX_INTERFACES;
}
@ -1057,12 +1124,10 @@ static uint16_t _mdns_append_question(uint8_t * packet, uint16_t * index, mdns_o
*/
static mdns_if_t _mdns_get_other_if (mdns_if_t tcpip_if)
{
if (tcpip_if == MDNS_IF_STA) {
return MDNS_IF_ETH;
} else if (tcpip_if == MDNS_IF_ETH) {
return MDNS_IF_STA;
if (tcpip_if < MDNS_MAX_INTERFACES) {
return s_esp_netifs[tcpip_if].duplicate;
}
return MDNS_IF_MAX;
return MDNS_MAX_INTERFACES;
}
/**
@ -1071,7 +1136,7 @@ static mdns_if_t _mdns_get_other_if (mdns_if_t tcpip_if)
static bool _mdns_if_is_dup(mdns_if_t tcpip_if)
{
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
if (other_if == MDNS_MAX_INTERFACES) {
return false;
}
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state == PCB_DUP
@ -2077,7 +2142,7 @@ static void _mdns_send_bye(mdns_srv_item_t ** services, size_t len, bool include
return;
}
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
_mdns_pcb_send_bye((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
@ -2135,7 +2200,7 @@ static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
static void _mdns_probe_all_pcbs(mdns_srv_item_t ** services, size_t len, bool probe_ip, bool clear_old_probe)
{
uint8_t i, j;
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
if (_mdns_server->interfaces[i].pcbs[j].pcb) {
mdns_pcb_t * _pcb = &_mdns_server->interfaces[i].pcbs[j];
@ -2157,7 +2222,7 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t ** services, size_t len, bool p
static void _mdns_announce_all_pcbs(mdns_srv_item_t ** services, size_t len, bool include_ip)
{
uint8_t i, j;
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_announce_pcb((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
}
@ -2642,7 +2707,7 @@ static void _mdns_dup_interface(mdns_if_t tcpip_if)
{
uint8_t i;
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
if (other_if == MDNS_MAX_INTERFACES) {
return; // no other interface found
}
for (i=0; i<MDNS_IP_PROTOCOL_MAX; i++) {
@ -2678,7 +2743,7 @@ static int _mdns_check_a_collision(esp_ip4_addr_t * ip, mdns_if_t tcpip_if)
} else if (ret < 0) {
//is it the other interface?
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
if (other_if == MDNS_MAX_INTERFACES) {
return 1;//AP interface! They win
}
if (esp_netif_get_ip_info(_mdns_get_esp_netif(other_if), &other_ip_info)) {
@ -2713,7 +2778,7 @@ static int _mdns_check_aaaa_collision(esp_ip6_addr_t * ip, mdns_if_t tcpip_if)
} else if (ret < 0) {
//is it the other interface?
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if == MDNS_IF_MAX) {
if (other_if == MDNS_MAX_INTERFACES) {
return 1;//AP interface! They win
}
if (esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(other_if), &other_ip6)) {
@ -3460,7 +3525,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
if (search_result && search_result->type == MDNS_TYPE_PTR) {
result = search_result->result;
while (result) {
if (packet->tcpip_if == result->tcpip_if
if (_mdns_get_esp_netif(packet->tcpip_if) == result->esp_netif
&& packet->ip_protocol == result->ip_protocol
&& result->instance_name && !strcmp(name->host, result->instance_name)) {
break;
@ -3560,7 +3625,7 @@ void mdns_parse_packet(mdns_rx_packet_t * packet)
if (search_result->type == MDNS_TYPE_PTR) {
result = search_result->result;
while (result) {
if (packet->tcpip_if == result->tcpip_if
if (_mdns_get_esp_netif(packet->tcpip_if) == result->esp_netif
&& packet->ip_protocol == result->ip_protocol
&& result->instance_name && !strcmp(name->host, result->instance_name)) {
break;
@ -3768,7 +3833,7 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
_mdns_pcb_deinit(tcpip_if, ip_protocol);
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
if (other_if != MDNS_IF_MAX && _mdns_server->interfaces[other_if].pcbs[ip_protocol].state == PCB_DUP) {
if (other_if != MDNS_MAX_INTERFACES && _mdns_server->interfaces[other_if].pcbs[ip_protocol].state == PCB_DUP) {
_mdns_server->interfaces[other_if].pcbs[ip_protocol].state = PCB_OFF;
_mdns_enable_pcb(other_if, ip_protocol);
}
@ -3776,11 +3841,54 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state = PCB_OFF;
}
/**
* @brief Performs interface changes based on system events or custom commands
*/
static void perform_event_action(mdns_if_t mdns_if, mdns_event_actions_t action)
{
if (!_mdns_server || mdns_if >= MDNS_MAX_INTERFACES) {
return;
}
if (action & MDNS_EVENT_ENABLE_IP4) {
_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V4);
}
if (action & MDNS_EVENT_ENABLE_IP6) {
_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
}
if (action & MDNS_EVENT_DISABLE_IP4) {
_mdns_disable_pcb(mdns_if, MDNS_IP_PROTOCOL_V4);
}
if (action & MDNS_EVENT_DISABLE_IP6) {
_mdns_disable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
}
if (action & MDNS_EVENT_ANNOUNCE_IP4) {
_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4, NULL, 0, true);
}
if (action & MDNS_EVENT_ANNOUNCE_IP6) {
_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
}
}
/**
* @brief Dispatch interface changes based on system events
*/
static void _mdns_handle_system_event(esp_event_base_t event_base,
int32_t event_id, esp_netif_t* interface)
static inline void post_mdns_disable_pcb(mdns_predef_if_t preset_if, mdns_ip_protocol_t protocol)
{
mdns_post_custom_action_tcpip_if(mdns_if_from_preset_if(preset_if), protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_EVENT_DISABLE_IP4 : MDNS_EVENT_DISABLE_IP6);
}
static inline void post_mdns_enable_pcb(mdns_predef_if_t preset_if, mdns_ip_protocol_t protocol)
{
mdns_post_custom_action_tcpip_if(mdns_if_from_preset_if(preset_if), protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_EVENT_ENABLE_IP4 : MDNS_EVENT_ENABLE_IP6);
}
static inline void post_mdns_announce_pcb(mdns_predef_if_t preset_if, mdns_ip_protocol_t protocol)
{
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);
}
void mdns_preset_if_handle_system_event(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (!_mdns_server) {
return;
@ -3790,22 +3898,22 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
if (event_base == WIFI_EVENT) {
switch(event_id) {
case WIFI_EVENT_STA_CONNECTED:
if (!esp_netif_dhcpc_get_status(_mdns_get_esp_netif(MDNS_IF_STA), &dcst)) {
if (!esp_netif_dhcpc_get_status(esp_netif_from_preset_if(MDNS_IF_STA), &dcst)) {
if (dcst == ESP_NETIF_DHCP_STOPPED) {
_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
post_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
}
}
break;
case WIFI_EVENT_STA_DISCONNECTED:
_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6);
post_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
post_mdns_disable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6);
break;
case WIFI_EVENT_AP_START:
_mdns_enable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
post_mdns_enable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
break;
case WIFI_EVENT_AP_STOP:
_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V6);
post_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V4);
post_mdns_disable_pcb(MDNS_IF_AP, MDNS_IP_PROTOCOL_V6);
break;
default:
break;
@ -3815,15 +3923,15 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
else if (event_base == ETH_EVENT) {
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
if (!esp_netif_dhcpc_get_status(_mdns_get_esp_netif(MDNS_IF_ETH), &dcst)) {
if (!esp_netif_dhcpc_get_status(esp_netif_from_preset_if(MDNS_IF_ETH), &dcst)) {
if (dcst == ESP_NETIF_DHCP_STOPPED) {
_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
post_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
}
}
break;
case ETHERNET_EVENT_DISCONNECTED:
_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V6);
post_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
post_mdns_disable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V6);
break;
default:
break;
@ -3833,20 +3941,21 @@ static void _mdns_handle_system_event(esp_event_base_t event_base,
else if (event_base == IP_EVENT) {
switch (event_id) {
case IP_EVENT_STA_GOT_IP:
_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
_mdns_announce_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6, NULL, 0, true);
post_mdns_enable_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V4);
post_mdns_announce_pcb(MDNS_IF_STA, MDNS_IP_PROTOCOL_V6);
break;
#if CONFIG_ETH_ENABLED
case IP_EVENT_ETH_GOT_IP:
_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
post_mdns_enable_pcb(MDNS_IF_ETH, MDNS_IP_PROTOCOL_V4);
break;
#endif
case IP_EVENT_GOT_IP6:
{
mdns_if_t mdns_if = _mdns_get_if_from_esp_netif(interface);
if (mdns_if != MDNS_IF_MAX) {
_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4, NULL, 0, true);
ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data;
mdns_if_t mdns_if = _mdns_get_if_from_esp_netif(event->esp_netif);
if (mdns_if < MDNS_MAX_INTERFACES) {
post_mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6);
post_mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4);
}
}
@ -4033,7 +4142,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
|| search->type == MDNS_TYPE_ANY) {
r = search->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol) {
_mdns_result_add_ip(r, ip);
_mdns_result_update_ttl(r, ttl);
return;
@ -4057,7 +4166,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
a->next = r->addr;
r->hostname = strdup(hostname);
r->addr = a;
r->tcpip_if = tcpip_if;
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
r->ip_protocol = ip_protocol;
r->next = search->result;
r->ttl = ttl;
@ -4067,7 +4176,7 @@ static void _mdns_search_result_add_ip(mdns_search_once_t * search, const char *
} else if (search->type == MDNS_TYPE_PTR || search->type == MDNS_TYPE_SRV) {
r = search->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(hostname, r->hostname)) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(hostname, r->hostname)) {
_mdns_result_add_ip(r, ip);
_mdns_result_update_ttl(r, ttl);
break;
@ -4086,7 +4195,7 @@ static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search,
{
mdns_result_t * r = search->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->instance_name) && !strcasecmp(instance, r->instance_name)) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->instance_name) && !strcasecmp(instance, r->instance_name)) {
_mdns_result_update_ttl(r, ttl);
return r;
}
@ -4108,7 +4217,7 @@ static mdns_result_t * _mdns_search_result_add_ptr(mdns_search_once_t * search,
return NULL;
}
r->tcpip_if = tcpip_if;
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
r->ip_protocol = ip_protocol;
r->ttl = ttl;
r->next = search->result;
@ -4127,7 +4236,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t *search, const char *
{
mdns_result_t * r = search->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(hostname, r->hostname)) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(hostname, r->hostname)) {
_mdns_result_update_ttl(r, ttl);
return;
}
@ -4152,7 +4261,7 @@ static void _mdns_search_result_add_srv(mdns_search_once_t *search, const char *
r->service_type = strdup(search->service);
r->proto = strdup(search->proto);
r->port = port;
r->tcpip_if = tcpip_if;
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
r->ip_protocol = ip_protocol;
r->ttl = ttl;
r->next = search->result;
@ -4170,7 +4279,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t *search, mdns_txt_ite
{
mdns_result_t * r = search->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol) {
if (r->txt) {
goto free_txt;
}
@ -4193,7 +4302,7 @@ static void _mdns_search_result_add_txt(mdns_search_once_t *search, mdns_txt_ite
r->txt = txt;
r->txt_value_len = txt_value_len;
r->txt_count = txt_count;
r->tcpip_if = tcpip_if;
r->esp_netif = _mdns_get_esp_netif(tcpip_if);
r->ip_protocol = ip_protocol;
r->ttl = ttl;
r->next = search->result;
@ -4238,7 +4347,7 @@ static mdns_search_once_t * _mdns_search_find_from(mdns_search_once_t * s, mdns_
}
r = s->result;
while (r) {
if (r->tcpip_if == tcpip_if && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(name->host, r->hostname)) {
if (r->esp_netif == _mdns_get_esp_netif(tcpip_if) && r->ip_protocol == ip_protocol && !_str_null_or_empty(r->hostname) && !strcasecmp(name->host, r->hostname)) {
return s;
}
r = r->next;
@ -4311,7 +4420,7 @@ static mdns_tx_packet_t * _mdns_create_search_packet(mdns_search_once_t * search
r = search->result;
while (r) {
//full record on the same interface is available
if (r->tcpip_if != tcpip_if || r->ip_protocol != ip_protocol || r->instance_name == NULL || r->hostname == NULL || r->addr == NULL) {
if (r->esp_netif != _mdns_get_esp_netif(tcpip_if) || r->ip_protocol != ip_protocol || r->instance_name == NULL || r->hostname == NULL || r->addr == NULL) {
r = r->next;
continue;
}
@ -4375,7 +4484,7 @@ static void _mdns_search_send(mdns_search_once_t * search)
}
uint8_t i, j;
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_search_send_pcb(search, (mdns_if_t)i, (mdns_ip_protocol_t)j);
}
@ -4525,8 +4634,7 @@ static void _mdns_execute_action(mdns_action_t * action)
switch(action->type) {
case ACTION_SYSTEM_EVENT:
_mdns_handle_system_event(action->data.sys_event.event_base,
action->data.sys_event.event_id, action->data.sys_event.interface);
perform_event_action(action->data.sys_event.interface, action->data.sys_event.event_action);
break;
case ACTION_HOSTNAME_SET:
_mdns_send_bye_all_pcbs_no_instance(true);
@ -4939,35 +5047,113 @@ static esp_err_t _mdns_service_task_stop(void)
return ESP_OK;
}
/*
* Public Methods
* */
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
static esp_err_t mdns_post_custom_action_tcpip_if(mdns_if_t mdns_if, mdns_event_actions_t event_action)
{
if (!_mdns_server) {
return;
if (!_mdns_server || mdns_if >= MDNS_MAX_INTERFACES) {
return ESP_ERR_INVALID_STATE;
}
mdns_action_t * action = (mdns_action_t *)calloc(1, sizeof(mdns_action_t));
if (!action) {
HOOK_MALLOC_FAILED;
return;
return ESP_ERR_NO_MEM;
}
action->type = ACTION_SYSTEM_EVENT;
action->data.sys_event.event_base = event_base;
action->data.sys_event.event_id = event_id;
if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) {
ip_event_got_ip6_t* event = (ip_event_got_ip6_t*) event_data;
action->data.sys_event.interface = event->esp_netif;
}
action->data.sys_event.event_action = event_action;
action->data.sys_event.interface = mdns_if;
if (xQueueSend(_mdns_server->action_queue, &action, (TickType_t)0) != pdPASS) {
free(action);
}
return ESP_OK;
}
static inline void set_default_duplicated_interfaces(void)
{
mdns_if_t wifi_sta_if = MDNS_MAX_INTERFACES;
mdns_if_t eth_if = MDNS_MAX_INTERFACES;
for (mdns_if_t i=0; i<MDNS_MAX_INTERFACES; i++) {
if (s_esp_netifs[i].predefined && s_esp_netifs[i].predef_if == MDNS_IF_STA) {
wifi_sta_if = i;
}
if (s_esp_netifs[i].predefined && s_esp_netifs[i].predef_if == MDNS_IF_ETH) {
eth_if = i;
}
}
if (wifi_sta_if != MDNS_MAX_INTERFACES && eth_if != MDNS_MAX_INTERFACES) {
s_esp_netifs[wifi_sta_if].duplicate = eth_if;
s_esp_netifs[eth_if].duplicate = wifi_sta_if;
}
}
static inline void unregister_predefined_handlers(void)
{
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event);
#endif
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event);
#endif
#if defined(CONFIG_ETH_ENABLED) && CONFIG_MDNS_PREDEF_NETIF_ETH
esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event);
#endif
}
/*
* Public Methods
* */
esp_err_t mdns_netif_action(esp_netif_t *esp_netif, mdns_event_actions_t event_action)
{
return mdns_post_custom_action_tcpip_if(_mdns_get_if_from_esp_netif(esp_netif), event_action);
}
esp_err_t mdns_register_netif(esp_netif_t *esp_netif)
{
if (!_mdns_server) {
return ESP_ERR_INVALID_STATE;
}
esp_err_t err = ESP_ERR_NO_MEM;
MDNS_SERVICE_LOCK();
for (mdns_if_t i=0; i<MDNS_MAX_INTERFACES; ++i) {
if (s_esp_netifs[i].netif == esp_netif) {
MDNS_SERVICE_UNLOCK();
return ESP_ERR_INVALID_STATE;
}
}
for (mdns_if_t i=0; i<MDNS_MAX_INTERFACES; ++i) {
if (!s_esp_netifs[i].predefined && s_esp_netifs[i].netif == NULL) {
s_esp_netifs[i].netif = esp_netif;
err = ESP_OK;
break;
}
}
MDNS_SERVICE_UNLOCK();
return err;
}
esp_err_t mdns_unregister_netif(esp_netif_t *esp_netif)
{
if (!_mdns_server) {
return ESP_ERR_INVALID_STATE;
}
esp_err_t err = ESP_ERR_NOT_FOUND;
MDNS_SERVICE_LOCK();
for (mdns_if_t i=0; i<MDNS_MAX_INTERFACES; ++i) {
if (!s_esp_netifs[i].predefined && s_esp_netifs[i].netif == esp_netif) {
s_esp_netifs[i].netif = NULL;
err = ESP_OK;
break;
}
}
MDNS_SERVICE_UNLOCK();
return err;
}
esp_err_t mdns_init(void)
{
esp_err_t err = ESP_OK;
@ -4983,7 +5169,9 @@ esp_err_t mdns_init(void)
}
memset((uint8_t*)_mdns_server, 0, sizeof(mdns_server_t));
// zero-out local copy of netifs to initiate a fresh search by interface key whenever a netif ptr is needed
memset(s_esp_netifs, 0, sizeof(s_esp_netifs));
for (mdns_if_t i = 0; i < MDNS_MAX_INTERFACES; ++i) {
s_esp_netifs[i].netif = NULL;
}
_mdns_server->lock = xSemaphoreCreateMutex();
if (!_mdns_server->lock) {
@ -4996,24 +5184,34 @@ esp_err_t mdns_init(void)
err = ESP_ERR_NO_MEM;
goto free_lock;
}
if ((err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
goto free_event_handlers;
}
if ((err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
goto free_event_handlers;
}
#if CONFIG_ETH_ENABLED
if ((err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)) != ESP_OK) {
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP
if ((err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event, NULL)) != ESP_OK) {
goto free_event_handlers;
}
#endif
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH
if ((err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event, NULL)) != ESP_OK) {
goto free_event_handlers;
}
#endif
#if defined(CONFIG_ETH_ENABLED) && CONFIG_MDNS_PREDEF_NETIF_ETH
if ((err = esp_event_handler_register(ETH_EVENT, ESP_EVENT_ANY_ID, mdns_preset_if_handle_system_event, NULL)) != ESP_OK) {
goto free_event_handlers;
}
#endif
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH
set_default_duplicated_interfaces();
#endif
uint8_t i;
#if CONFIG_LWIP_IPV6
esp_ip6_addr_t tmp_addr6;
#endif
esp_netif_ip_info_t if_ip_info;
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
#if CONFIG_LWIP_IPV6
if (!esp_netif_get_ip6_linklocal(_mdns_get_esp_netif(i), &tmp_addr6) && !_ipv6_address_is_zero(tmp_addr6)) {
_mdns_enable_pcb(i, MDNS_IP_PROTOCOL_V6);
@ -5033,15 +5231,14 @@ esp_err_t mdns_init(void)
return ESP_OK;
free_all_and_disable_pcbs:
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V6);
_mdns_disable_pcb(i, MDNS_IP_PROTOCOL_V4);
s_esp_netifs[i].duplicate = MDNS_MAX_INTERFACES;
}
#if CONFIG_MDNS_PREDEF_NETIF_STA || CONFIG_MDNS_PREDEF_NETIF_AP || CONFIG_MDNS_PREDEF_NETIF_ETH
free_event_handlers:
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler);
#if CONFIG_ETH_ENABLED
esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler);
unregister_predefined_handlers();
#endif
vQueueDelete(_mdns_server->action_queue);
free_lock:
@ -5060,16 +5257,12 @@ void mdns_free(void)
}
// Unregister handlers before destroying the mdns internals to avoid receiving async events while deinit
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler);
esp_event_handler_unregister(IP_EVENT, ESP_EVENT_ANY_ID, &event_handler);
#if CONFIG_ETH_ENABLED
esp_event_handler_unregister(ETH_EVENT, ESP_EVENT_ANY_ID, &event_handler);
#endif
unregister_predefined_handlers();
mdns_service_remove_all();
free_delegated_hostnames();
_mdns_service_task_stop();
for (i=0; i<MDNS_IF_MAX; i++) {
for (i=0; i<MDNS_MAX_INTERFACES; i++) {
for (j=0; j<MDNS_IP_PROTOCOL_MAX; j++) {
_mdns_pcb_deinit(i, j);
}

Wyświetl plik

@ -1,23 +1,14 @@
// 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.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
#include "esp_console.h"
#include "argtable3/argtable3.h"
#include "mdns.h"
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
static void mdns_print_results(mdns_result_t * results)
@ -26,7 +17,7 @@ static void mdns_print_results(mdns_result_t * results)
mdns_ip_addr_t * a = NULL;
int i = 1;
while (r) {
printf("%d: Interface: %s, Type: %s\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol]);
printf("%d: Interface: %s, Type: %s\n", i++, esp_netif_get_ifkey(r->esp_netif), ip_protocol_str[r->ip_protocol]);
if (r->instance_name) {
printf(" PTR : %s\n", r->instance_name);
}

Wyświetl plik

@ -134,7 +134,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
continue;
}
packet->tcpip_if = MDNS_IF_MAX;
packet->tcpip_if = MDNS_MAX_INTERFACES;
packet->pb = this_pb;
packet->src_port = rport;
#if CONFIG_LWIP_IPV6
@ -164,7 +164,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
//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_IF_MAX; i++) {
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 ()) {
@ -198,7 +198,7 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
*/
static bool _udp_pcb_is_in_use(void){
int i, p;
for (i=0; i<MDNS_IF_MAX; i++) {
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;

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -101,7 +101,7 @@ esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
}
}
for (int i=0; i<MDNS_IF_MAX; i++) {
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
@ -247,7 +247,7 @@ void sock_recv_task(void* arg)
fd_set rfds;
FD_ZERO(&rfds);
int max_sock = -1;
for (int i=0; i<MDNS_IF_MAX; i++) {
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) {
@ -267,7 +267,7 @@ void sock_recv_task(void* arg)
ESP_LOGE(TAG, "Select failed. errno=%d: %s", errno, strerror(errno));
break;
} else if (s > 0) {
for (int tcpip_if=0; tcpip_if<MDNS_IF_MAX; tcpip_if++) {
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) {

Wyświetl plik

@ -41,6 +41,27 @@
* 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
@ -150,6 +171,8 @@
#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,
@ -384,7 +407,7 @@ typedef struct mdns_search_once_s {
typedef struct mdns_server_s {
struct {
mdns_pcb_t pcbs[MDNS_IP_PROTOCOL_MAX];
} interfaces[MDNS_IF_MAX];
} interfaces[MDNS_MAX_INTERFACES];
const char * hostname;
const char * instance;
mdns_srv_item_t * services;
@ -404,9 +427,8 @@ typedef struct {
} hostname_set;
char * instance;
struct {
esp_event_base_t event_base;
int32_t event_id;
esp_netif_t* interface;
mdns_if_t interface;
mdns_event_actions_t event_action;
} sys_event;
struct {
mdns_srv_item_t * service;

Wyświetl plik

@ -284,6 +284,7 @@
#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

Wyświetl plik

@ -34,8 +34,10 @@ 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)
{
_mdns_server->interfaces[MDNS_IF_STA].pcbs[MDNS_IP_PROTOCOL_V4].state = PCB_RUNNING; // mark the PCB running to exercise mdns in fully operational mode
_mdns_server->interfaces[MDNS_IF_STA].pcbs[MDNS_IP_PROTOCOL_V6].state = PCB_RUNNING;
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);

Wyświetl plik

@ -48,4 +48,13 @@ menu "Example Configuration"
help
Set the GPIO number used as mDNS test button
config MDNS_ADD_CUSTOM_NETIF
bool "Add user netif to mdns service"
default n
help
If enabled, we try to add a custom netif to mdns service.
Note that for using with common connection example code, we have to disable
all predefined interfaces in mdns component setup (since we're adding one
of the default interfaces)
endmenu

Wyświetl plik

@ -83,9 +83,6 @@ static void initialise_mdns(void)
free(hostname);
}
/* these strings match tcpip_adapter_if_t enumeration */
static const char * if_str[] = {"STA", "AP", "ETH", "MAX"};
/* these strings match mdns_ip_protocol_t enumeration */
static const char * ip_protocol_str[] = {"V4", "V6", "MAX"};
@ -95,7 +92,7 @@ static void mdns_print_results(mdns_result_t *results)
mdns_ip_addr_t *a = NULL;
int i = 1, t;
while (r) {
printf("%d: Interface: %s, Type: %s, TTL: %u\n", i++, if_str[r->tcpip_if], ip_protocol_str[r->ip_protocol],
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);
@ -269,6 +266,18 @@ void app_main(void)
*/
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);
}

Wyświetl plik

@ -13,10 +13,6 @@ import ttfw_idf
from tiny_test_fw import DUT
from tiny_test_fw.Utility import console_log
stop_mdns_server = Event()
esp_answered = Event()
esp_delegated_answered = Event()
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')
@ -34,7 +30,7 @@ def get_dns_answer_to_mdns(tester_host):
arr.type = dpkt.dns.DNS_A
arr.name = tester_host
arr.ip = socket.inet_aton('127.0.0.1')
dns. an.append(arr)
dns.an.append(arr)
console_log('Created answer to mdns query: {} '.format(dns.__repr__()))
return dns.pack()
@ -52,8 +48,7 @@ def get_dns_answer_to_mdns_lwip(tester_host, id):
return dns.pack()
def mdns_server(esp_host):
global esp_answered
def mdns_server(esp_host, events):
UDP_IP = '0.0.0.0'
UDP_PORT = 5353
MCAST_GRP = '224.0.0.251'
@ -64,19 +59,19 @@ def mdns_server(esp_host):
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))
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 stop_mdns_server.is_set():
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 esp_answered.is_set():
sock.sendto(get_dns_query_for_esp(esp_host), (MCAST_GRP,UDP_PORT))
if not esp_delegated_answered.is_set():
sock.sendto(get_dns_query_for_esp(esp_host + '-delegated'), (MCAST_GRP,UDP_PORT))
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:
@ -86,7 +81,7 @@ def mdns_server(esp_host):
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))
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)
@ -94,19 +89,17 @@ def mdns_server(esp_host):
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__()))
esp_answered.set()
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__()))
esp_delegated_answered.set()
events['esp_delegated_answered'].set()
except socket.timeout:
break
except dpkt.UnpackError:
continue
@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1')
def test_examples_protocol_mdns(env, extra_data):
global stop_mdns_server
def test_examples_protocol_mdns(env, config):
"""
steps: |
1. obtain IP address + init mdns example
@ -114,7 +107,7 @@ def test_examples_protocol_mdns(env, extra_data):
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='eth_kit')
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)
@ -123,7 +116,9 @@ def test_examples_protocol_mdns(env, extra_data):
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_responder = Thread(target=mdns_server, args=(str(specific_host),))
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))
@ -132,9 +127,9 @@ def test_examples_protocol_mdns(env, extra_data):
try:
# 3. check the mdns name is accessible
mdns_responder.start()
if not esp_answered.wait(timeout=30):
if not mdns_server_events['esp_answered'].wait(timeout=30):
raise ValueError('Test has failed: did not receive mdns answer within timeout')
if not esp_delegated_answered.wait(timeout=30):
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)
@ -148,9 +143,24 @@ def test_examples_protocol_mdns(env, extra_data):
raise ValueError('Test has failed: Incorrectly resolved DUT hostname using dig'
"Output should've contained DUT's IP address:{}".format(ip_address))
finally:
stop_mdns_server.set()
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()
test_examples_protocol_mdns_default()

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -1133,7 +1133,6 @@ components/mdns/host_test/components/freertos_linux/queue_unique_ptr.cpp
components/mdns/host_test/components/freertos_linux/queue_unique_ptr.hpp
components/mdns/host_test/main/main.c
components/mdns/include/mdns_console.h
components/mdns/mdns_console.c
components/mdns/mdns_networking_lwip.c
components/mdns/private_include/mdns_networking.h
components/mdns/test/test_mdns.c