| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * MDNS Server Networking | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include "mdns_networking.h"
 | 
					
						
							| 
									
										
										
										
											2018-12-07 20:43:13 +01:00
										 |  |  | #include "esp_log.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern mdns_server_t * _mdns_server; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * MDNS Server Networking | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-12-07 20:43:13 +01:00
										 |  |  | static const char *TAG = "MDNS_Networking"; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | static struct udp_pcb * _pcb_main = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static esp_err_t _udp_pcb_main_init() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     _pcb_main->mcast_ttl = 1; | 
					
						
							|  |  |  |     _pcb_main->remote_port = MDNS_SERVICE_PORT; | 
					
						
							|  |  |  |     ip_addr_copy(_pcb_main->remote_ip, ip_addr_any_type); | 
					
						
							|  |  |  |     udp_recv(_pcb_main, &_udp_recv, _mdns_server); | 
					
						
							|  |  |  |     return ESP_OK; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Low level UDP PCB Free | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void _udp_pcb_main_deinit() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static esp_err_t _udp_join_group(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, bool join) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct netif * netif = NULL; | 
					
						
							|  |  |  |     void * nif = NULL; | 
					
						
							| 
									
										
										
										
											2018-10-22 16:45:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!tcpip_adapter_is_netif_up(tcpip_if)) { | 
					
						
							|  |  |  |         // Network interface went down before event propagated, skipping IGMP config
 | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     esp_err_t err = tcpip_adapter_get_netif(tcpip_if, &nif); | 
					
						
							|  |  |  |     if (err) { | 
					
						
							|  |  |  |         return ESP_ERR_INVALID_ARG; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     netif = (struct netif *)nif; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ip_protocol == MDNS_IP_PROTOCOL_V4) { | 
					
						
							|  |  |  |         ip_addr_t multicast_addr; | 
					
						
							|  |  |  |         IP_ADDR4(&multicast_addr, 224, 0, 0, 251); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if(join){ | 
					
						
							|  |  |  |             if (igmp_joingroup_netif(netif, (const struct ip4_addr *)&multicast_addr.u_addr.ip4)) { | 
					
						
							|  |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (igmp_leavegroup_netif(netif, (const struct ip4_addr *)&multicast_addr.u_addr.ip4)) { | 
					
						
							|  |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         ip_addr_t multicast_addr = IPADDR6_INIT(0x000002ff, 0, 0, 0xfb000000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if(join){ | 
					
						
							|  |  |  |             if (mld6_joingroup_netif(netif, &(multicast_addr.u_addr.ip6))) { | 
					
						
							|  |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (mld6_leavegroup_netif(netif, &(multicast_addr.u_addr.ip6))) { | 
					
						
							|  |  |  |                 return ESP_ERR_INVALID_STATE; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         packet->tcpip_if = TCPIP_ADAPTER_IF_MAX; | 
					
						
							|  |  |  |         packet->pb = this_pb; | 
					
						
							|  |  |  |         packet->src_port = rport; | 
					
						
							|  |  |  |         memcpy(&packet->src, raddr, sizeof(ip_addr_t)); | 
					
						
							|  |  |  |         packet->dest.type = packet->src.type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             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); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         packet->multicast = ip_addr_ismulticast(&(packet->dest)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         //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; | 
					
						
							|  |  |  |         void * nif = NULL; | 
					
						
							|  |  |  |         struct udp_pcb * pcb = NULL; | 
					
						
							|  |  |  |         for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) { | 
					
						
							|  |  |  |             pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb; | 
					
						
							|  |  |  |             tcpip_adapter_get_netif (i, &nif); | 
					
						
							|  |  |  |             netif = (struct netif *)nif; | 
					
						
							|  |  |  |             if (pcb && netif && netif == ip_current_input_netif ()) { | 
					
						
							|  |  |  |                 if (packet->src.type == IPADDR_TYPE_V4) { | 
					
						
							|  |  |  |                     if ((packet->src.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr) != (netif->ip_addr.u_addr.ip4.addr & netif->netmask.u_addr.ip4.addr)) { | 
					
						
							|  |  |  |                         //packet source is not in the same subnet
 | 
					
						
							|  |  |  |                         pcb = NULL; | 
					
						
							|  |  |  |                         break; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 packet->tcpip_if = i; | 
					
						
							|  |  |  |                 break; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             pcb = NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!pcb || !_mdns_server || !_mdns_server->action_queue | 
					
						
							|  |  |  |           || _mdns_send_rx_action(packet) != ESP_OK) { | 
					
						
							|  |  |  |             pbuf_free(this_pb); | 
					
						
							|  |  |  |             free(packet); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Check if any of the interfaces is up | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static bool _udp_pcb_is_in_use(){ | 
					
						
							|  |  |  |     int i, p; | 
					
						
							|  |  |  |     for (i=0; i<TCPIP_ADAPTER_IF_MAX; i++) { | 
					
						
							|  |  |  |         for (p=0; p<MDNS_IP_PROTOCOL_MAX; p++) { | 
					
						
							|  |  |  |             if(_mdns_server->interfaces[i].pcbs[p].pcb){ | 
					
						
							|  |  |  |                 return true; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * @brief  Stop PCB Main code | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void _udp_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!_mdns_server) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     mdns_pcb_t * _pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol]; | 
					
						
							|  |  |  |     if (_pcb->pcb) { | 
					
						
							|  |  |  |         free(_pcb->probe_services); | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |         _pcb->state = PCB_OFF; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |         _pcb->pcb = NULL; | 
					
						
							|  |  |  |         _pcb->probe_ip = false; | 
					
						
							|  |  |  |         _pcb->probe_services = NULL; | 
					
						
							|  |  |  |         _pcb->probe_services_len = 0; | 
					
						
							|  |  |  |         _pcb->probe_running = false; | 
					
						
							|  |  |  |         _pcb->failed_probes = 0; | 
					
						
							| 
									
										
										
										
											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
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  | static esp_err_t _udp_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) { | 
					
						
							| 
									
										
										
										
											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
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-13 12:01:11 +02:00
										 |  |  |     _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = _pcb_main; | 
					
						
							|  |  |  |     _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     tcpip_adapter_if_t tcpip_if; | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | esp_err_t _mdns_pcb_init(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | esp_err_t _mdns_pcb_deinit(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     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; | 
					
						
							|  |  |  |     mdns_pcb_t * _pcb = &_mdns_server->interfaces[msg->tcpip_if].pcbs[msg->ip_protocol]; | 
					
						
							|  |  |  |     esp_err_t err = tcpip_adapter_get_netif(msg->tcpip_if, &nif); | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     if (err) { | 
					
						
							| 
									
										
										
										
											2019-02-15 15:59:11 +01:00
										 |  |  |         pbuf_free(msg->pbt); | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |         msg->err = err; | 
					
						
							|  |  |  |         return err; | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif); | 
					
						
							|  |  |  |     pbuf_free(msg->pbt); | 
					
						
							|  |  |  |     msg->err = err; | 
					
						
							|  |  |  |     return err; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-05-04 16:42:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  | size_t _mdns_udp_pcb_write(tcpip_adapter_if_t tcpip_if, mdns_ip_protocol_t ip_protocol, const ip_addr_t *ip, uint16_t port, uint8_t * data, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											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); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-14 11:23:19 +01:00
										 |  |  |     mdns_api_call_t msg = { | 
					
						
							|  |  |  |         .tcpip_if = tcpip_if, | 
					
						
							|  |  |  |         .ip_protocol = ip_protocol, | 
					
						
							|  |  |  |         .pbt = pbt, | 
					
						
							|  |  |  |         .ip = ip, | 
					
						
							|  |  |  |         .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; | 
					
						
							|  |  |  | } |