diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 216be7f9ee..0c90e514d7 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -309,6 +309,7 @@ example_test_001A: example_test_001B: extends: .example_test_esp32_template + parallel: 2 tags: - ESP32 - Example_EthKitV1 diff --git a/components/mdns/Kconfig b/components/mdns/Kconfig index 5607afac84..def0d850d6 100644 --- a/components/mdns/Kconfig +++ b/components/mdns/Kconfig @@ -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 diff --git a/components/mdns/include/mdns.h b/components/mdns/include/mdns.h index 55de0dbab7..7f81d0af82 100644 --- a/components/mdns/include/mdns.h +++ b/components/mdns/include/mdns.h @@ -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 diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 8b47b3c35a..15b32e3388 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -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 "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; iinterfaces[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; iinterfaces[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; iinterfaces[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; itype == 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; itype) { 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; ilock = 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; iaction_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 #include #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); } diff --git a/components/mdns/mdns_networking_lwip.c b/components/mdns/mdns_networking_lwip.c index 5f7a6673fb..370661d122 100644 --- a/components/mdns/mdns_networking_lwip.c +++ b/components/mdns/mdns_networking_lwip.c @@ -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; iinterfaces[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; iinterfaces[i].pcbs[p].pcb){ return true; diff --git a/components/mdns/mdns_networking_socket.c b/components/mdns/mdns_networking_socket.c index 45ad83dec3..0f393cbc09 100644 --- a/components/mdns/mdns_networking_socket.c +++ b/components/mdns/mdns_networking_socket.c @@ -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; iinterfaces[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; iinterfaces[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_ifinterfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb); if (sock < 0) { diff --git a/components/mdns/private_include/mdns_private.h b/components/mdns/private_include/mdns_private.h index 44535747f1..bf1d6d8bff 100644 --- a/components/mdns/private_include/mdns_private.h +++ b/components/mdns/private_include/mdns_private.h @@ -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; diff --git a/components/mdns/test_afl_fuzz_host/sdkconfig.h b/components/mdns/test_afl_fuzz_host/sdkconfig.h index d17d4f5e8f..fe207b001e 100644 --- a/components/mdns/test_afl_fuzz_host/sdkconfig.h +++ b/components/mdns/test_afl_fuzz_host/sdkconfig.h @@ -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 diff --git a/components/mdns/test_afl_fuzz_host/test.c b/components/mdns/test_afl_fuzz_host/test.c index b48d904e3f..568c7eee19 100644 --- a/components/mdns/test_afl_fuzz_host/test.c +++ b/components/mdns/test_afl_fuzz_host/test.c @@ -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; iinterfaces[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); diff --git a/examples/protocols/mdns/main/Kconfig.projbuild b/examples/protocols/mdns/main/Kconfig.projbuild index bc4b1a055c..b66e6f867a 100644 --- a/examples/protocols/mdns/main/Kconfig.projbuild +++ b/examples/protocols/mdns/main/Kconfig.projbuild @@ -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 diff --git a/examples/protocols/mdns/main/mdns_example_main.c b/examples/protocols/mdns/main/mdns_example_main.c index c1db88ba09..da0cbe53b1 100644 --- a/examples/protocols/mdns/main/mdns_example_main.c +++ b/examples/protocols/mdns/main/mdns_example_main.c @@ -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); } diff --git a/examples/protocols/mdns/mdns_example_test.py b/examples/protocols/mdns/mdns_example_test.py index f067077182..83763634eb 100644 --- a/examples/protocols/mdns/mdns_example_test.py +++ b/examples/protocols/mdns/mdns_example_test.py @@ -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() diff --git a/examples/protocols/mdns/sdkconfig.ci.eth_custom_netif b/examples/protocols/mdns/sdkconfig.ci.eth_custom_netif new file mode 100644 index 0000000000..56499bd433 --- /dev/null +++ b/examples/protocols/mdns/sdkconfig.ci.eth_custom_netif @@ -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 diff --git a/examples/protocols/mdns/sdkconfig.ci.eth_kit b/examples/protocols/mdns/sdkconfig.ci.eth_def similarity index 100% rename from examples/protocols/mdns/sdkconfig.ci.eth_kit rename to examples/protocols/mdns/sdkconfig.ci.eth_def diff --git a/examples/protocols/mdns/sdkconfig.ci.eth_socket b/examples/protocols/mdns/sdkconfig.ci.eth_socket new file mode 100644 index 0000000000..5d92405260 --- /dev/null +++ b/examples/protocols/mdns/sdkconfig.ci.eth_socket @@ -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 diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 7afc65abf3..8e17c1eb0d 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -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