mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-06-26 09:51:34 +02:00
feat(mdns): Decouple main module from mdns-networking
Removed sharing the data via the global variable `_mdns_server`, added API `mdns_is_netif_ready()`
This commit is contained in:
@ -1358,7 +1358,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
|||||||
} else if (answer->type == MDNS_TYPE_A) {
|
} else if (answer->type == MDNS_TYPE_A) {
|
||||||
if (answer->host == &_mdns_self_host) {
|
if (answer->host == &_mdns_self_host) {
|
||||||
esp_netif_ip_info_t if_ip_info;
|
esp_netif_ip_info_t if_ip_info;
|
||||||
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
|
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V4) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].state != PCB_DUP) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
|
if (esp_netif_get_ip_info(_mdns_get_esp_netif(tcpip_if), &if_ip_info)) {
|
||||||
@ -1387,8 +1387,7 @@ static uint8_t _mdns_append_answer(uint8_t *packet, uint16_t *index, mdns_out_an
|
|||||||
if (answer->host == &_mdns_self_host) {
|
if (answer->host == &_mdns_self_host) {
|
||||||
struct esp_ip6_addr if_ip6s[NETIF_IPV6_MAX_NUMS];
|
struct esp_ip6_addr if_ip6s[NETIF_IPV6_MAX_NUMS];
|
||||||
uint8_t count = 0;
|
uint8_t count = 0;
|
||||||
if (!_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb &&
|
if (!mdns_is_netif_ready(tcpip_if, MDNS_IP_PROTOCOL_V6) && _mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].state != PCB_DUP) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
count = esp_netif_get_all_ip6(_mdns_get_esp_netif(tcpip_if), if_ip6s);
|
count = esp_netif_get_all_ip6(_mdns_get_esp_netif(tcpip_if), if_ip6s);
|
||||||
@ -2275,7 +2274,7 @@ static void _mdns_send_bye(mdns_srv_item_t **services, size_t len, bool include_
|
|||||||
|
|
||||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||||
if (_mdns_server->interfaces[i].pcbs[j].pcb && _mdns_server->interfaces[i].pcbs[j].state == PCB_RUNNING) {
|
if (mdns_is_netif_ready(i, j) && _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);
|
_mdns_pcb_send_bye((mdns_if_t)i, (mdns_ip_protocol_t)j, services, len, include_ip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2289,7 +2288,7 @@ static void _mdns_announce_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
|
|||||||
{
|
{
|
||||||
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
|
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
|
||||||
size_t i;
|
size_t i;
|
||||||
if (_pcb->pcb) {
|
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
|
||||||
if (PCB_STATE_IS_PROBING(_pcb)) {
|
if (PCB_STATE_IS_PROBING(_pcb)) {
|
||||||
_mdns_init_pcb_probe(tcpip_if, ip_protocol, services, len, include_ip);
|
_mdns_init_pcb_probe(tcpip_if, ip_protocol, services, len, include_ip);
|
||||||
} else if (PCB_STATE_IS_ANNOUNCING(_pcb)) {
|
} else if (PCB_STATE_IS_ANNOUNCING(_pcb)) {
|
||||||
@ -2333,7 +2332,7 @@ static void _mdns_probe_all_pcbs(mdns_srv_item_t **services, size_t len, bool pr
|
|||||||
uint8_t i, j;
|
uint8_t i, j;
|
||||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||||
if (_mdns_server->interfaces[i].pcbs[j].pcb) {
|
if (mdns_is_netif_ready(i, j)) {
|
||||||
mdns_pcb_t *_pcb = &_mdns_server->interfaces[i].pcbs[j];
|
mdns_pcb_t *_pcb = &_mdns_server->interfaces[i].pcbs[j];
|
||||||
if (clear_old_probe) {
|
if (clear_old_probe) {
|
||||||
free(_pcb->probe_services);
|
free(_pcb->probe_services);
|
||||||
@ -2628,7 +2627,7 @@ static void _mdns_remove_scheduled_service_packets(mdns_service_t *service)
|
|||||||
|
|
||||||
|
|
||||||
mdns_pcb_t *_pcb = &_mdns_server->interfaces[q->tcpip_if].pcbs[q->ip_protocol];
|
mdns_pcb_t *_pcb = &_mdns_server->interfaces[q->tcpip_if].pcbs[q->ip_protocol];
|
||||||
if (_pcb->pcb) {
|
if (mdns_is_netif_ready(q->tcpip_if, q->ip_protocol)) {
|
||||||
if (PCB_STATE_IS_PROBING(_pcb)) {
|
if (PCB_STATE_IS_PROBING(_pcb)) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
//check if we are probing this service
|
//check if we are probing this service
|
||||||
@ -2829,6 +2828,22 @@ static int _mdns_check_txt_collision(mdns_service_t *service, const uint8_t *dat
|
|||||||
return 0;//same
|
return 0;//same
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static esp_err_t mdns_pcb_deinit_local(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_proto)
|
||||||
|
{
|
||||||
|
esp_err_t err = _mdns_pcb_deinit(tcpip_if, ip_proto);
|
||||||
|
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_proto];
|
||||||
|
if (_pcb == NULL || err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
free(_pcb->probe_services);
|
||||||
|
_pcb->state = PCB_OFF;
|
||||||
|
_pcb->probe_ip = false;
|
||||||
|
_pcb->probe_services = NULL;
|
||||||
|
_pcb->probe_services_len = 0;
|
||||||
|
_pcb->probe_running = false;
|
||||||
|
_pcb->failed_probes = 0;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Set interface as duplicate if another is found on the same subnet
|
* @brief Set interface as duplicate if another is found on the same subnet
|
||||||
*/
|
*/
|
||||||
@ -2840,11 +2855,11 @@ static void _mdns_dup_interface(mdns_if_t tcpip_if)
|
|||||||
return; // no other interface found
|
return; // no other interface found
|
||||||
}
|
}
|
||||||
for (i = 0; i < MDNS_IP_PROTOCOL_MAX; i++) {
|
for (i = 0; i < MDNS_IP_PROTOCOL_MAX; i++) {
|
||||||
if (_mdns_server->interfaces[other_if].pcbs[i].pcb) {
|
if (mdns_is_netif_ready(other_if, i)) {
|
||||||
//stop this interface and mark as dup
|
//stop this interface and mark as dup
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[i].pcb) {
|
if (mdns_is_netif_ready(tcpip_if, i)) {
|
||||||
_mdns_clear_pcb_tx_queue_head(tcpip_if, i);
|
_mdns_clear_pcb_tx_queue_head(tcpip_if, i);
|
||||||
_mdns_pcb_deinit(tcpip_if, i);
|
mdns_pcb_deinit_local(tcpip_if, i);
|
||||||
}
|
}
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[i].state = PCB_DUP;
|
_mdns_server->interfaces[tcpip_if].pcbs[i].state = PCB_DUP;
|
||||||
_mdns_announce_pcb(other_if, i, NULL, 0, true);
|
_mdns_announce_pcb(other_if, i, NULL, 0, true);
|
||||||
@ -3984,8 +3999,9 @@ clear_rx_packet:
|
|||||||
*/
|
*/
|
||||||
void _mdns_enable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
void _mdns_enable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
if (!_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
|
if (!mdns_is_netif_ready(tcpip_if, ip_protocol)) {
|
||||||
if (_mdns_pcb_init(tcpip_if, ip_protocol)) {
|
if (_mdns_pcb_init(tcpip_if, ip_protocol)) {
|
||||||
|
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3999,9 +4015,9 @@ void _mdns_disable_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
|||||||
{
|
{
|
||||||
_mdns_clean_netif_ptr(tcpip_if);
|
_mdns_clean_netif_ptr(tcpip_if);
|
||||||
|
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
|
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
|
||||||
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
|
_mdns_clear_pcb_tx_queue_head(tcpip_if, ip_protocol);
|
||||||
_mdns_pcb_deinit(tcpip_if, ip_protocol);
|
mdns_pcb_deinit_local(tcpip_if, ip_protocol);
|
||||||
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
|
mdns_if_t other_if = _mdns_get_other_if (tcpip_if);
|
||||||
if (other_if != MDNS_MAX_INTERFACES && _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_server->interfaces[other_if].pcbs[ip_protocol].state = PCB_OFF;
|
||||||
@ -4669,7 +4685,7 @@ static mdns_tx_packet_t *_mdns_create_search_packet(mdns_search_once_t *search,
|
|||||||
static void _mdns_search_send_pcb(mdns_search_once_t *search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
static void _mdns_search_send_pcb(mdns_search_once_t *search, mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
mdns_tx_packet_t *packet = NULL;
|
mdns_tx_packet_t *packet = NULL;
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
|
if (mdns_is_netif_ready(tcpip_if, ip_protocol) && _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].state > PCB_INIT) {
|
||||||
packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol);
|
packet = _mdns_create_search_packet(search, tcpip_if, ip_protocol);
|
||||||
if (!packet) {
|
if (!packet) {
|
||||||
return;
|
return;
|
||||||
@ -5483,7 +5499,7 @@ void mdns_free(void)
|
|||||||
_mdns_service_task_stop();
|
_mdns_service_task_stop();
|
||||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
for (j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||||
_mdns_pcb_deinit(i, j);
|
mdns_pcb_deinit_local(i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free((char *)_mdns_server->hostname);
|
free((char *)_mdns_server->hostname);
|
||||||
|
@ -21,16 +21,26 @@
|
|||||||
#include "mdns_networking.h"
|
#include "mdns_networking.h"
|
||||||
#include "esp_netif_net_stack.h"
|
#include "esp_netif_net_stack.h"
|
||||||
|
|
||||||
extern mdns_server_t *_mdns_server;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MDNS Server Networking
|
* MDNS Server Networking
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static const char *TAG = "mdns_networking";
|
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];
|
||||||
|
|
||||||
static struct udp_pcb *_pcb_main = NULL;
|
static struct udp_pcb *_pcb_main = NULL;
|
||||||
|
|
||||||
|
static const char *TAG = "mdns_networking";
|
||||||
|
|
||||||
static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport);
|
static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip_addr_t *raddr, uint16_t rport);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -53,7 +63,7 @@ static esp_err_t _udp_pcb_main_init(void)
|
|||||||
_pcb_main->mcast_ttl = 255;
|
_pcb_main->mcast_ttl = 255;
|
||||||
_pcb_main->remote_port = MDNS_SERVICE_PORT;
|
_pcb_main->remote_port = MDNS_SERVICE_PORT;
|
||||||
ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE));
|
ip_addr_copy(_pcb_main->remote_ip, *(IP_ANY_TYPE));
|
||||||
udp_recv(_pcb_main, &_udp_recv, _mdns_server);
|
udp_recv(_pcb_main, &_udp_recv, NULL);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,29 +178,26 @@ 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)
|
//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 netif *netif = NULL;
|
||||||
struct udp_pcb *pcb = NULL;
|
bool found = false;
|
||||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
pcb = _mdns_server->interfaces[i].pcbs[packet->ip_protocol].pcb;
|
|
||||||
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
|
netif = esp_netif_get_netif_impl(_mdns_get_esp_netif(i));
|
||||||
if (pcb && netif && netif == ip_current_input_netif ()) {
|
if (s_interfaces[i].proto && netif && netif == ip_current_input_netif ()) {
|
||||||
if (packet->src.type == IPADDR_TYPE_V4) {
|
if (packet->src.type == IPADDR_TYPE_V4) {
|
||||||
#if CONFIG_LWIP_IPV6
|
#if CONFIG_LWIP_IPV6
|
||||||
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)) {
|
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)) {
|
||||||
#else
|
#else
|
||||||
if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
|
if ((packet->src.u_addr.ip4.addr & netif->netmask.addr) != (netif->ip_addr.addr & netif->netmask.addr)) {
|
||||||
#endif //packet source is not in the same subnet
|
#endif //packet source is not in the same subnet
|
||||||
pcb = NULL;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
packet->tcpip_if = i;
|
packet->tcpip_if = i;
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pcb = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pcb || !_mdns_server || !_mdns_server->action_queue
|
if (!found || _mdns_send_rx_action(packet) != ESP_OK) {
|
||||||
|| _mdns_send_rx_action(packet) != ESP_OK) {
|
|
||||||
pbuf_free(this_pb);
|
pbuf_free(this_pb);
|
||||||
free(packet);
|
free(packet);
|
||||||
}
|
}
|
||||||
@ -198,6 +205,12 @@ static void _udp_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb, const ip
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if any of the interfaces is up
|
* @brief Check if any of the interfaces is up
|
||||||
*/
|
*/
|
||||||
@ -206,7 +219,7 @@ static bool _udp_pcb_is_in_use(void)
|
|||||||
int i, p;
|
int i, p;
|
||||||
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (p = 0; p < MDNS_IP_PROTOCOL_MAX; p++) {
|
for (p = 0; p < MDNS_IP_PROTOCOL_MAX; p++) {
|
||||||
if (_mdns_server->interfaces[i].pcbs[p].pcb) {
|
if (mdns_is_netif_ready(i, p)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,19 +232,9 @@ static bool _udp_pcb_is_in_use(void)
|
|||||||
*/
|
*/
|
||||||
static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
if (!_mdns_server) {
|
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
return;
|
if (s_interfaces[tcpip_if].proto == 0) {
|
||||||
}
|
s_interfaces[tcpip_if].ready = false;
|
||||||
mdns_pcb_t *_pcb = &_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol];
|
|
||||||
if (_pcb->pcb) {
|
|
||||||
free(_pcb->probe_services);
|
|
||||||
_pcb->state = PCB_OFF;
|
|
||||||
_pcb->pcb = NULL;
|
|
||||||
_pcb->probe_ip = false;
|
|
||||||
_pcb->probe_services = NULL;
|
|
||||||
_pcb->probe_services_len = 0;
|
|
||||||
_pcb->probe_running = false;
|
|
||||||
_pcb->failed_probes = 0;
|
|
||||||
_udp_join_group(tcpip_if, ip_protocol, false);
|
_udp_join_group(tcpip_if, ip_protocol, false);
|
||||||
if (!_udp_pcb_is_in_use()) {
|
if (!_udp_pcb_is_in_use()) {
|
||||||
_udp_pcb_main_deinit();
|
_udp_pcb_main_deinit();
|
||||||
@ -244,7 +247,7 @@ static void _udp_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
|||||||
*/
|
*/
|
||||||
static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
if (!_mdns_server || _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
|
if (mdns_is_netif_ready(tcpip_if, ip_protocol)) {
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,9 +260,9 @@ static esp_err_t _udp_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protoco
|
|||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
|
s_interfaces[tcpip_if].ready = true;
|
||||||
|
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = _pcb_main;
|
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,14 +326,13 @@ static err_t _mdns_udp_pcb_write_api(struct tcpip_api_call_data *api_call_msg)
|
|||||||
{
|
{
|
||||||
void *nif = NULL;
|
void *nif = NULL;
|
||||||
mdns_api_call_t *msg = (mdns_api_call_t *)api_call_msg;
|
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];
|
|
||||||
nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
|
nif = esp_netif_get_netif_impl(_mdns_get_esp_netif(msg->tcpip_if));
|
||||||
if (!nif) {
|
if (!nif || !mdns_is_netif_ready(msg->tcpip_if, msg->ip_protocol) || _pcb_main == NULL) {
|
||||||
pbuf_free(msg->pbt);
|
pbuf_free(msg->pbt);
|
||||||
msg->err = ERR_IF;
|
msg->err = ERR_IF;
|
||||||
return ERR_IF;
|
return ERR_IF;
|
||||||
}
|
}
|
||||||
esp_err_t err = udp_sendto_if (_pcb->pcb, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
|
esp_err_t err = udp_sendto_if (_pcb_main, msg->pbt, msg->ip, msg->port, (struct netif *)nif);
|
||||||
pbuf_free(msg->pbt);
|
pbuf_free(msg->pbt);
|
||||||
msg->err = err;
|
msg->err = err;
|
||||||
return err;
|
return err;
|
||||||
|
@ -27,7 +27,17 @@
|
|||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern mdns_server_t *_mdns_server;
|
enum interface_protocol {
|
||||||
|
PROTO_IPV4 = 1 << MDNS_IP_PROTOCOL_V4,
|
||||||
|
PROTO_IPV6 = 1 << MDNS_IP_PROTOCOL_V6
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct interfaces {
|
||||||
|
int sock;
|
||||||
|
int proto;
|
||||||
|
} interfaces_t;
|
||||||
|
|
||||||
|
static interfaces_t s_interfaces[MDNS_MAX_INTERFACES];
|
||||||
|
|
||||||
static const char *TAG = "mdns_networking";
|
static const char *TAG = "mdns_networking";
|
||||||
static bool s_run_sock_recv_task = false;
|
static bool s_run_sock_recv_task = false;
|
||||||
@ -52,23 +62,9 @@ static void delete_socket(int sock)
|
|||||||
close(sock);
|
close(sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct udp_pcb *sock_to_pcb(int sock)
|
bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
if (sock < 0) {
|
return s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
// Note: sock=0 is a valid descriptor, so save it as +1 ("1" is a valid pointer)
|
|
||||||
intptr_t sock_plus_one = sock + 1;
|
|
||||||
return (struct udp_pcb *)sock_plus_one;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pcb_to_sock(struct udp_pcb *pcb)
|
|
||||||
{
|
|
||||||
if (pcb == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
intptr_t sock_plus_one = (intptr_t)pcb;
|
|
||||||
return sock_plus_one - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *_mdns_get_packet_data(mdns_rx_packet_t *packet)
|
void *_mdns_get_packet_data(mdns_rx_packet_t *packet)
|
||||||
@ -90,26 +86,20 @@ void _mdns_packet_free(mdns_rx_packet_t *packet)
|
|||||||
|
|
||||||
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
esp_err_t _mdns_pcb_deinit(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
struct udp_pcb *pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
|
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = NULL;
|
if (s_interfaces[tcpip_if].proto == 0) {
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb == NULL &&
|
// if the interface for both protocols uninitialized, close the interface socket
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb == NULL) {
|
if (s_interfaces[tcpip_if].sock >= 0) {
|
||||||
// if the interface for both protocol uninitialized, close the interface socket
|
delete_socket(s_interfaces[tcpip_if].sock);
|
||||||
int sock = pcb_to_sock(pcb);
|
|
||||||
if (sock >= 0) {
|
|
||||||
delete_socket(sock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
if (s_interfaces[i].sock >= 0) {
|
||||||
if (_mdns_server->interfaces[i].pcbs[j].pcb)
|
// If any of the interfaces initialized
|
||||||
// If any of the interfaces/protocol initialized
|
|
||||||
{
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// no interface alive, stop the rx task
|
// no interface alive, stop the rx task
|
||||||
s_run_sock_recv_task = false;
|
s_run_sock_recv_task = false;
|
||||||
@ -191,7 +181,10 @@ static inline size_t espaddr_to_inet(const esp_ip_addr_t *addr, const uint16_t p
|
|||||||
|
|
||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb);
|
if (!(s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int sock = s_interfaces[tcpip_if].sock;
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -250,14 +243,12 @@ void sock_recv_task(void *arg)
|
|||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
int max_sock = -1;
|
int max_sock = -1;
|
||||||
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||||
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
int sock = s_interfaces[i].sock;
|
||||||
int sock = pcb_to_sock(_mdns_server->interfaces[i].pcbs[j].pcb);
|
|
||||||
if (sock >= 0) {
|
if (sock >= 0) {
|
||||||
FD_SET(sock, &rfds);
|
FD_SET(sock, &rfds);
|
||||||
max_sock = MAX(max_sock, sock);
|
max_sock = MAX(max_sock, sock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (max_sock < 0) {
|
if (max_sock < 0) {
|
||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
ESP_LOGI(TAG, "No sock!");
|
ESP_LOGI(TAG, "No sock!");
|
||||||
@ -270,11 +261,7 @@ void sock_recv_task(void *arg)
|
|||||||
break;
|
break;
|
||||||
} else if (s > 0) {
|
} else if (s > 0) {
|
||||||
for (int tcpip_if = 0; tcpip_if < MDNS_MAX_INTERFACES; tcpip_if++) {
|
for (int tcpip_if = 0; tcpip_if < MDNS_MAX_INTERFACES; tcpip_if++) {
|
||||||
// Both protocols share once socket
|
int sock = s_interfaces[tcpip_if].sock;
|
||||||
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb);
|
|
||||||
if (sock < 0) {
|
|
||||||
sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb);
|
|
||||||
}
|
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -323,7 +310,7 @@ void sock_recv_task(void *arg)
|
|||||||
packet->dest.type = packet->src.type;
|
packet->dest.type = packet->src.type;
|
||||||
packet->ip_protocol =
|
packet->ip_protocol =
|
||||||
packet->src.type == ESP_IPADDR_TYPE_V4 ? MDNS_IP_PROTOCOL_V4 : MDNS_IP_PROTOCOL_V6;
|
packet->src.type == ESP_IPADDR_TYPE_V4 ? MDNS_IP_PROTOCOL_V4 : MDNS_IP_PROTOCOL_V6;
|
||||||
if (!_mdns_server || !_mdns_server->action_queue || _mdns_send_rx_action(packet) != ESP_OK) {
|
if (_mdns_send_rx_action(packet) != ESP_OK) {
|
||||||
ESP_LOGE(TAG, "_mdns_send_rx_action failed!");
|
ESP_LOGE(TAG, "_mdns_send_rx_action failed!");
|
||||||
free(packet->pb->payload);
|
free(packet->pb->payload);
|
||||||
free(packet->pb);
|
free(packet->pb);
|
||||||
@ -339,46 +326,52 @@ void sock_recv_task(void *arg)
|
|||||||
static void mdns_networking_init(void)
|
static void mdns_networking_init(void)
|
||||||
{
|
{
|
||||||
if (s_run_sock_recv_task == false) {
|
if (s_run_sock_recv_task == false) {
|
||||||
|
for (int i = 0; i < sizeof(s_interfaces) / sizeof(s_interfaces[0]); ++i) {
|
||||||
|
s_interfaces[i].sock = -1;
|
||||||
|
s_interfaces[i].proto = 0;
|
||||||
|
}
|
||||||
s_run_sock_recv_task = true;
|
s_run_sock_recv_task = true;
|
||||||
xTaskCreate( sock_recv_task, "mdns recv task", 3 * 1024, NULL, 5, NULL );
|
xTaskCreate( sock_recv_task, "mdns recv task", 3 * 1024, NULL, 5, NULL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct udp_pcb *create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
static bool create_pcb(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb) {
|
if (s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6)) {
|
||||||
return _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
|
return true;
|
||||||
}
|
}
|
||||||
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
|
int sock = s_interfaces[tcpip_if].sock;
|
||||||
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
|
esp_netif_t *netif = _mdns_get_esp_netif(tcpip_if);
|
||||||
if (_mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb) {
|
if (sock >= 0) {
|
||||||
struct udp_pcb *other_pcb = _mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb;
|
mdns_ip_protocol_t other_ip_proto = ip_protocol == MDNS_IP_PROTOCOL_V4 ? MDNS_IP_PROTOCOL_V6 : MDNS_IP_PROTOCOL_V4;
|
||||||
int err = join_mdns_multicast_group(pcb_to_sock(other_pcb), netif, ip_protocol);
|
int err = join_mdns_multicast_group(sock, netif, other_ip_proto);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
|
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
return other_pcb;
|
s_interfaces[tcpip_if].proto |= (other_ip_proto == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
int sock = create_socket(netif);
|
sock = create_socket(netif);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
ESP_LOGE(TAG, "Failed to create the socket!");
|
ESP_LOGE(TAG, "Failed to create the socket!");
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
|
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
|
ESP_LOGE(TAG, "Failed to add ipv6 multicast group for protocol %d", ip_protocol);
|
||||||
}
|
}
|
||||||
return sock_to_pcb(sock);
|
s_interfaces[tcpip_if].proto |= (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
esp_err_t _mdns_pcb_init(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
|
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = create_pcb(tcpip_if, ip_protocol);
|
|
||||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].failed_probes = 0;
|
|
||||||
|
|
||||||
mdns_networking_init();
|
mdns_networking_init();
|
||||||
|
ESP_LOGI(TAG, "_mdns_pcb_init(tcpip_if=%d, ip_protocol=%d)", tcpip_if, ip_protocol);
|
||||||
|
if (!create_pcb(tcpip_if, ip_protocol)) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t *packet);
|
esp_err_t _mdns_send_rx_action(mdns_rx_packet_t *packet);
|
||||||
|
|
||||||
|
bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start PCB
|
* @brief Start PCB
|
||||||
*/
|
*/
|
||||||
|
@ -347,7 +347,6 @@ typedef struct mdns_tx_packet_s {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
mdns_pcb_state_t state;
|
mdns_pcb_state_t state;
|
||||||
struct udp_pcb *pcb;
|
|
||||||
mdns_srv_item_t **probe_services;
|
mdns_srv_item_t **probe_services;
|
||||||
uint8_t probe_services_len;
|
uint8_t probe_services_len;
|
||||||
uint8_t probe_ip;
|
uint8_t probe_ip;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
*/
|
*/
|
||||||
@ -24,3 +24,8 @@ static inline void _mdns_packet_free(mdns_rx_packet_t *packet)
|
|||||||
free(packet->pb);
|
free(packet->pb);
|
||||||
free(packet);
|
free(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool mdns_is_netif_ready(mdns_if_t tcpip_if, mdns_ip_protocol_t ip_protocol)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user