| 
									
										
										
										
											2022-10-11 16:31:57 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-02-15 15:41:46 +01:00
										 |  |  |  * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD | 
					
						
							| 
									
										
										
										
											2022-10-11 16:31:57 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |  * SPDX-License-Identifier: Apache-2.0 | 
					
						
							| 
									
										
										
										
											2022-10-11 16:31:57 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * MDNS Server Networking | 
					
						
							| 
									
										
										
										
											2020-11-10 18:40:01 +11:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2018-12-07 20:43:13 +01:00
										 |  |  | #include "esp_log.h"
 | 
					
						
							| 
									
										
										
										
											2021-06-29 10:02:44 +02:00
										 |  |  | #include "lwip/ip_addr.h"
 | 
					
						
							|  |  |  | #include "lwip/pbuf.h"
 | 
					
						
							|  |  |  | #include "lwip/igmp.h"
 | 
					
						
							|  |  |  | #include "lwip/udp.h"
 | 
					
						
							|  |  |  | #include "lwip/mld6.h"
 | 
					
						
							|  |  |  | #include "lwip/priv/tcpip_priv.h"
 | 
					
						
							|  |  |  | #include "esp_system.h"
 | 
					
						
							|  |  |  | #include "esp_event.h"
 | 
					
						
							|  |  |  | #include "mdns_networking.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | #include "esp_netif_net_stack.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * MDNS Server Networking | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  | enum interface_protocol { | 
					
						
							|  |  |  |     PROTO_IPV4 = 1 << MDNS_IP_PROTOCOL_V4, | 
					
						
							|  |  |  |     PROTO_IPV6 = 1 << MDNS_IP_PROTOCOL_V6 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct interfaces { | 
					
						
							|  |  |  |     bool ready; | 
					
						
							|  |  |  |     int proto; | 
					
						
							|  |  |  | } interfaces_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static interfaces_t s_interfaces[MDNS_MAX_INTERFACES]; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | static struct udp_pcb *_pcb_main = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  | static const char *TAG = "mdns_networking"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Low level UDP PCB Initialize | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | static esp_err_t _udp_pcb_main_init(void) | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (_pcb_main) { | 
					
						
							|  |  |  |         return ESP_OK; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _pcb_main = udp_new(); | 
					
						
							|  |  |  |     if (!_pcb_main) { | 
					
						
							|  |  |  |         return ESP_ERR_NO_MEM; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (udp_bind(_pcb_main, IP_ANY_TYPE, MDNS_SERVICE_PORT) != 0) { | 
					
						
							|  |  |  |         udp_remove(_pcb_main); | 
					
						
							|  |  |  |         _pcb_main = NULL; | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-12-28 17:37:03 +01:00
										 |  |  |     _pcb_main->mcast_ttl = 255; | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     _pcb_main->remote_port = MDNS_SERVICE_PORT; | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |     ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE)); | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     udp_recv(_pcb_main, &_udp_recv, NULL); | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Low level UDP PCB Free | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | static void _udp_pcb_main_deinit(void) | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (_pcb_main) { | 
					
						
							|  |  |  |         udp_recv(_pcb_main, NULL, NULL); | 
					
						
							|  |  |  |         udp_disconnect(_pcb_main); | 
					
						
							|  |  |  |         udp_remove(_pcb_main); | 
					
						
							|  |  |  |         _pcb_main = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Low level UDP Multicast membership control | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | static esp_err_t _udp_join_group(mdns_if_t if_inx, mdns_ip_protocol_t ip_protocol, bool join) | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     struct netif *netif = NULL; | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |     esp_netif_t *tcpip_if = _mdns_get_esp_netif(if_inx); | 
					
						
							| 
									
										
										
										
											2018-10-22 16:45:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |     if (!esp_netif_is_netif_up(tcpip_if)) { | 
					
						
							| 
									
										
										
										
											2018-10-22 16:45:42 +02:00
										 |  |  |         // Network interface went down before event propagated, skipping IGMP config
 | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |     netif = esp_netif_get_netif_impl(tcpip_if); | 
					
						
							|  |  |  |     assert(netif); | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #if LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     if (ip_protocol == MDNS_IP_PROTOCOL_V4) { | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |         ip4_addr_t multicast_addr; | 
					
						
							|  |  |  |         IP4_ADDR(&multicast_addr, 224, 0, 0, 251); | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (join) { | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |             if (igmp_joingroup_netif(netif, &multicast_addr)) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |             if (igmp_leavegroup_netif(netif, &multicast_addr)) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #endif // LWIP_IPV4
 | 
					
						
							|  |  |  | #if LWIP_IPV6
 | 
					
						
							|  |  |  |     if (ip_protocol == MDNS_IP_PROTOCOL_V6) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |         ip_addr_t multicast_addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (join) { | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  |             if (mld6_joingroup_netif(netif, ip_2_ip6(&multicast_addr))) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  |             if (mld6_leavegroup_netif(netif, ip_2_ip6(&multicast_addr))) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #endif // LWIP_IPV6
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  the receive callback of the raw udp api. Packets are received here | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint8_t i; | 
					
						
							|  |  |  |     while (pb != NULL) { | 
					
						
							|  |  |  |         struct pbuf *this_pb = pb; | 
					
						
							|  |  |  |         pb = pb->next; | 
					
						
							|  |  |  |         this_pb->next = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         mdns_rx_packet_t *packet = (mdns_rx_packet_t *)malloc(sizeof(mdns_rx_packet_t)); | 
					
						
							|  |  |  |         if (!packet) { | 
					
						
							| 
									
										
										
										
											2018-12-07 20:43:13 +01:00
										 |  |  |             HOOK_MALLOC_FAILED; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |             //missed packet - no memory
 | 
					
						
							|  |  |  |             pbuf_free(this_pb); | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-14 16:14:21 +01:00
										 |  |  |         packet->tcpip_if = MDNS_MAX_INTERFACES; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         packet->pb = this_pb; | 
					
						
							|  |  |  |         packet->src_port = rport; | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #if LWIP_IPV4 && LWIP_IPV6
 | 
					
						
							| 
									
										
										
										
											2020-11-06 10:32:00 +01:00
										 |  |  |         packet->src.type = raddr->type; | 
					
						
							|  |  |  |         memcpy(&packet->src.u_addr, &raddr->u_addr, sizeof(raddr->u_addr)); | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #elif LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |         packet->src.type = IPADDR_TYPE_V4; | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  |         packet->src.u_addr.ip4.addr = raddr->addr; | 
					
						
							|  |  |  | #elif LWIP_IPV6
 | 
					
						
							|  |  |  |         packet->src.type = IPADDR_TYPE_V6; | 
					
						
							|  |  |  |         memcpy(&packet->src.u_addr.ip6, raddr, sizeof(ip_addr_t)); | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         packet->dest.type = packet->src.type; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #if LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         if (packet->src.type == IPADDR_TYPE_V4) { | 
					
						
							|  |  |  |             packet->ip_protocol = MDNS_IP_PROTOCOL_V4; | 
					
						
							|  |  |  |             struct ip_hdr *iphdr = (struct ip_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP_HLEN); | 
					
						
							|  |  |  |             packet->dest.u_addr.ip4.addr = iphdr->dest.addr; | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |             packet->multicast = ip4_addr_ismulticast(&(packet->dest.u_addr.ip4)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #endif // LWIP_IPV4
 | 
					
						
							|  |  |  | #if LWIP_IPV6
 | 
					
						
							|  |  |  |         if (packet->src.type == IPADDR_TYPE_V6) { | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |             packet->ip_protocol = MDNS_IP_PROTOCOL_V6; | 
					
						
							|  |  |  |             struct ip6_hdr *ip6hdr = (struct ip6_hdr *)(((uint8_t *)(packet->pb->payload)) - UDP_HLEN - IP6_HLEN); | 
					
						
							|  |  |  |             memcpy(&packet->dest.u_addr.ip6.addr, (uint8_t *)ip6hdr->dest.addr, 16); | 
					
						
							| 
									
										
										
										
											2021-01-18 19:14:51 +08:00
										 |  |  |             packet->multicast = ip6_addr_ismulticast(&(packet->dest.u_addr.ip6)); | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #endif // LWIP_IPV6
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         //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; | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |         bool found = false; | 
					
						
							| 
									
										
										
										
											2021-12-14 16:14:21 +01:00
										 |  |  |         for (i = 0; i < MDNS_MAX_INTERFACES; i++) { | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |             netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i)); | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |             if (s_interfaces[i].proto && netif && netif == ip_current_input_netif ()) { | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #if LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |                 if (packet->src.type == IPADDR_TYPE_V4) { | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  |                     if ((packet->src.u_addr.ip4.addr & ip_2_ip4(&netif->netmask)->addr) != (ip_2_ip4(&netif->ip_addr)->addr & ip_2_ip4(&netif->netmask)->addr)) { | 
					
						
							|  |  |  |                         //packet source is not in the same subnet
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #endif // LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |                 packet->tcpip_if = i; | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |                 found = true; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |         if (!found || _mdns_send_rx_action(packet) != ESP_OK) { | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |             pbuf_free(this_pb); | 
					
						
							|  |  |  |             free(packet); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  | bool mdns_is_netif_ready(mdns_if_t netif, mdns_ip_protocol_t ip_proto) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s_interfaces[netif].ready && | 
					
						
							|  |  |  |            s_interfaces[netif].proto & (ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Check if any of the interfaces is up | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-07-16 16:33:30 +07:00
										 |  |  | static bool _udp_pcb_is_in_use(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     int i, p; | 
					
						
							| 
									
										
										
										
											2021-12-14 16:14:21 +01:00
										 |  |  |     for (i = 0; i < MDNS_MAX_INTERFACES; i++) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |         for (p = 0; p < MDNS_IP_PROTOCOL_MAX; p++) { | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |             if (mdns_is_netif_ready(i, p)) { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Stop PCB Main code | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6); | 
					
						
							|  |  |  |     if (s_interfaces[tcpip_if].proto == 0) { | 
					
						
							|  |  |  |         s_interfaces[tcpip_if].ready = false; | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |         _udp_join_group(tcpip_if, ip_protocol, false); | 
					
						
							|  |  |  |         if (!_udp_pcb_is_in_use()) { | 
					
						
							|  |  |  |             _udp_pcb_main_deinit(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |  * @brief  Start PCB Main code | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     if (mdns_is_netif_ready(tcpip_if, ip_protocol)) { | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     esp_err_t err = _udp_join_group(tcpip_if, ip_protocol, true); | 
					
						
							|  |  |  |     if (err) { | 
					
						
							|  |  |  |         return err; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     err = _udp_pcb_main_init(); | 
					
						
							|  |  |  |     if (err) { | 
					
						
							|  |  |  |         return err; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6); | 
					
						
							|  |  |  |     s_interfaces[tcpip_if].ready = true; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2018-09-06 19:43:08 +08:00
										 |  |  |     struct tcpip_api_call_data call; | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |     mdns_if_t tcpip_if; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     mdns_ip_protocol_t ip_protocol; | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     struct pbuf *pbt; | 
					
						
							|  |  |  |     const ip_addr_t *ip; | 
					
						
							|  |  |  |     uint16_t port; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     esp_err_t err; | 
					
						
							|  |  |  | } mdns_api_call_t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Start PCB from LwIP thread | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-09-06 19:43:08 +08:00
										 |  |  | static err_t _mdns_pcb_init_api(struct tcpip_api_call_data *api_call_msg) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg; | 
					
						
							|  |  |  |     msg->err = _udp_pcb_init(msg->tcpip_if, msg->ip_protocol); | 
					
						
							|  |  |  |     return msg->err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Stop PCB from LwIP thread | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-09-06 19:43:08 +08:00
										 |  |  | static err_t _mdns_pcb_deinit_api(struct tcpip_api_call_data *api_call_msg) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg; | 
					
						
							|  |  |  |     _udp_pcb_deinit(msg->tcpip_if, msg->ip_protocol); | 
					
						
							|  |  |  |     msg->err = ESP_OK; | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Non-static functions below are | 
					
						
							|  |  |  |  *  - _mdns prefixed | 
					
						
							|  |  |  |  *  - commented in mdns_networking.h header | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     mdns_api_call_t msg = { | 
					
						
							|  |  |  |         .tcpip_if = tcpip_if, | 
					
						
							|  |  |  |         .ip_protocol = ip_protocol | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     tcpip_api_call(_mdns_pcb_init_api, &msg.call); | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     return msg.err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     mdns_api_call_t msg = { | 
					
						
							|  |  |  |         .tcpip_if = tcpip_if, | 
					
						
							|  |  |  |         .ip_protocol = ip_protocol | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     tcpip_api_call(_mdns_pcb_deinit_api, &msg.call); | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     return msg.err; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  | static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     void *nif = NULL; | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg; | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |     nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if)); | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     if (!nif || !mdns_is_netif_ready(msg->tcpip_if, msg->ip_protocol) || _pcb_main == NULL) { | 
					
						
							| 
									
										
										
										
											2019-02-15 15:59:11 +01:00
										 |  |  |         pbuf_free(msg->pbt); | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  |         msg->err = ERR_IF; | 
					
						
							|  |  |  |         return ERR_IF; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-08-08 16:39:13 +02:00
										 |  |  |     esp_err_t err = udp_sendto_if (_pcb_main, msg->pbt, msg->ip, msg->port, (struct netif *)nif); | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     pbuf_free(msg->pbt); | 
					
						
							|  |  |  |     msg->err = err; | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-31 19:06:54 +02:00
										 |  |  | size_t _mdns_udp_pcb_write(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const esp_ip_addr_t *ip, uint16_t port, uint8_t *data, size_t len) | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     struct pbuf *pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); | 
					
						
							|  |  |  |     if (pbt == NULL) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     memcpy((uint8_t *)pbt->payload, data, len); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-07 19:59:16 +08:00
										 |  |  |     ip_addr_t ip_add_copy; | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #if LWIP_IPV6 && LWIP_IPV4
 | 
					
						
							| 
									
										
										
										
											2022-07-07 19:59:16 +08:00
										 |  |  |     ip_add_copy.type = ip->type; | 
					
						
							| 
									
										
										
										
											2022-09-02 16:13:17 +05:30
										 |  |  |     memcpy(&(ip_add_copy.u_addr), &(ip->u_addr), sizeof(ip_add_copy.u_addr)); | 
					
						
							| 
									
										
										
										
											2023-11-03 17:45:57 +08:00
										 |  |  | #elif LWIP_IPV4
 | 
					
						
							|  |  |  |     ip_add_copy.addr = ip->u_addr.ip4.addr; | 
					
						
							|  |  |  | #elif LWIP_IPV6
 | 
					
						
							|  |  |  | #if LWIP_IPV6_SCOPES
 | 
					
						
							|  |  |  |     ip_add_copy.zone = ip->u_addr.ip6.zone; | 
					
						
							|  |  |  | #endif // LWIP_IPV6_SCOPES
 | 
					
						
							|  |  |  |     memcpy(ip_add_copy.addr, ip->u_addr.ip6.addr, sizeof(ip_add_copy.addr)); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-07-07 19:59:16 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     mdns_api_call_t msg = { | 
					
						
							|  |  |  |         .tcpip_if = tcpip_if, | 
					
						
							|  |  |  |         .ip_protocol = ip_protocol, | 
					
						
							|  |  |  |         .pbt = pbt, | 
					
						
							| 
									
										
										
										
											2022-07-07 19:59:16 +08:00
										 |  |  |         .ip = &ip_add_copy, | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |         .port = port | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     tcpip_api_call(_mdns_udp_pcb_write_api, &msg.call); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (msg.err) { | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return len; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-06-29 10:02:44 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void *_mdns_get_packet_data(mdns_rx_packet_t *packet) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return packet->pb->payload; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t _mdns_get_packet_len(mdns_rx_packet_t *packet) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return packet->pb->len; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void _mdns_packet_free(mdns_rx_packet_t *packet) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     pbuf_free(packet->pb); | 
					
						
							|  |  |  |     free(packet); | 
					
						
							|  |  |  | } |