mirror of
https://github.com/espressif/esp-protocols.git
synced 2025-07-22 23:07:28 +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:
@ -27,7 +27,17 @@
|
||||
#include <net/if.h>
|
||||
#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 bool s_run_sock_recv_task = false;
|
||||
@ -52,23 +62,9 @@ static void delete_socket(int 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 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;
|
||||
return s_interfaces[tcpip_if].proto & (ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||
}
|
||||
|
||||
void *_mdns_get_packet_data(mdns_rx_packet_t *packet)
|
||||
@ -90,24 +86,18 @@ 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)
|
||||
{
|
||||
struct udp_pcb *pcb = _mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb;
|
||||
_mdns_server->interfaces[tcpip_if].pcbs[ip_protocol].pcb = NULL;
|
||||
if (_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb == NULL &&
|
||||
_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb == NULL) {
|
||||
// if the interface for both protocol uninitialized, close the interface socket
|
||||
int sock = pcb_to_sock(pcb);
|
||||
if (sock >= 0) {
|
||||
delete_socket(sock);
|
||||
s_interfaces[tcpip_if].proto &= ~(ip_protocol == MDNS_IP_PROTOCOL_V4 ? PROTO_IPV4 : PROTO_IPV6);
|
||||
if (s_interfaces[tcpip_if].proto == 0) {
|
||||
// if the interface for both protocols uninitialized, close the interface socket
|
||||
if (s_interfaces[tcpip_if].sock >= 0) {
|
||||
delete_socket(s_interfaces[tcpip_if].sock);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||
if (_mdns_server->interfaces[i].pcbs[j].pcb)
|
||||
// If any of the interfaces/protocol initialized
|
||||
{
|
||||
return ESP_OK;
|
||||
}
|
||||
if (s_interfaces[i].sock >= 0) {
|
||||
// If any of the interfaces initialized
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
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) {
|
||||
return 0;
|
||||
}
|
||||
@ -250,12 +243,10 @@ void sock_recv_task(void *arg)
|
||||
FD_ZERO(&rfds);
|
||||
int max_sock = -1;
|
||||
for (int i = 0; i < MDNS_MAX_INTERFACES; i++) {
|
||||
for (int j = 0; j < MDNS_IP_PROTOCOL_MAX; j++) {
|
||||
int sock = pcb_to_sock(_mdns_server->interfaces[i].pcbs[j].pcb);
|
||||
if (sock >= 0) {
|
||||
FD_SET(sock, &rfds);
|
||||
max_sock = MAX(max_sock, sock);
|
||||
}
|
||||
int sock = s_interfaces[i].sock;
|
||||
if (sock >= 0) {
|
||||
FD_SET(sock, &rfds);
|
||||
max_sock = MAX(max_sock, sock);
|
||||
}
|
||||
}
|
||||
if (max_sock < 0) {
|
||||
@ -270,11 +261,7 @@ void sock_recv_task(void *arg)
|
||||
break;
|
||||
} else if (s > 0) {
|
||||
for (int tcpip_if = 0; tcpip_if < MDNS_MAX_INTERFACES; tcpip_if++) {
|
||||
// Both protocols share once socket
|
||||
int sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V4].pcb);
|
||||
if (sock < 0) {
|
||||
sock = pcb_to_sock(_mdns_server->interfaces[tcpip_if].pcbs[MDNS_IP_PROTOCOL_V6].pcb);
|
||||
}
|
||||
int sock = s_interfaces[tcpip_if].sock;
|
||||
if (sock < 0) {
|
||||
continue;
|
||||
}
|
||||
@ -323,7 +310,7 @@ void sock_recv_task(void *arg)
|
||||
packet->dest.type = packet->src.type;
|
||||
packet->ip_protocol =
|
||||
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!");
|
||||
free(packet->pb->payload);
|
||||
free(packet->pb);
|
||||
@ -339,46 +326,52 @@ void sock_recv_task(void *arg)
|
||||
static void mdns_networking_init(void)
|
||||
{
|
||||
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;
|
||||
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) {
|
||||
return _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 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);
|
||||
if (_mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb) {
|
||||
struct udp_pcb *other_pcb = _mdns_server->interfaces[tcpip_if].pcbs[other_ip_proto].pcb;
|
||||
int err = join_mdns_multicast_group(pcb_to_sock(other_pcb), netif, ip_protocol);
|
||||
if (sock >= 0) {
|
||||
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(sock, netif, other_ip_proto);
|
||||
if (err < 0) {
|
||||
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) {
|
||||
ESP_LOGE(TAG, "Failed to create the socket!");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
int err = join_mdns_multicast_group(sock, netif, ip_protocol);
|
||||
if (err < 0) {
|
||||
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_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();
|
||||
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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user