Merge branch 'bugfix/mdns_tcpip_threadsafe' into 'master'
mdns: Use LwIP IPC for low-level API calls See merge request !925
This commit is contained in:
commit
ef60d73fe4
1 changed files with 182 additions and 116 deletions
|
@ -23,6 +23,8 @@
|
||||||
#include "lwip/pbuf.h"
|
#include "lwip/pbuf.h"
|
||||||
#include "lwip/igmp.h"
|
#include "lwip/igmp.h"
|
||||||
#include "lwip/udp.h"
|
#include "lwip/udp.h"
|
||||||
|
#include "lwip/tcpip.h"
|
||||||
|
#include "lwip/priv/tcpip_priv.h"
|
||||||
#include "esp_wifi.h"
|
#include "esp_wifi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -154,6 +156,14 @@ struct mdns_server_s {
|
||||||
} search;
|
} search;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct tcpip_api_call call;
|
||||||
|
mdns_server_t *server;
|
||||||
|
uint8_t *data;
|
||||||
|
size_t len;
|
||||||
|
esp_err_t err;
|
||||||
|
} mdns_api_call_t;
|
||||||
|
|
||||||
#define MDNS_MUTEX_LOCK() xSemaphoreTake(server->lock, portMAX_DELAY)
|
#define MDNS_MUTEX_LOCK() xSemaphoreTake(server->lock, portMAX_DELAY)
|
||||||
#define MDNS_MUTEX_UNLOCK() xSemaphoreGive(server->lock)
|
#define MDNS_MUTEX_UNLOCK() xSemaphoreGive(server->lock)
|
||||||
|
|
||||||
|
@ -195,6 +205,56 @@ static void _mdns_server_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief init the network of MDNS server (called in tcpip thread context)
|
||||||
|
*/
|
||||||
|
static err_t _mdns_server_init_api(struct tcpip_api_call *api_call_msg)
|
||||||
|
{
|
||||||
|
mdns_api_call_t *msg = (mdns_api_call_t*)api_call_msg;
|
||||||
|
mdns_server_t *server = msg->server;
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
|
||||||
|
tcpip_adapter_ip_info_t if_ip_info;
|
||||||
|
err = tcpip_adapter_get_ip_info(server->tcpip_if, &if_ip_info);
|
||||||
|
if (err) {
|
||||||
|
msg->err = err;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_addr_t laddr;
|
||||||
|
IP_ADDR4(&laddr, 224, 0, 0, 251);
|
||||||
|
|
||||||
|
ip_addr_t multicast_if_addr = IPADDR4_INIT(if_ip_info.ip.addr);
|
||||||
|
|
||||||
|
if (igmp_joingroup((const struct ip4_addr *)&multicast_if_addr.u_addr.ip4, (const struct ip4_addr *)&laddr.u_addr.ip4)) {
|
||||||
|
msg->err = ESP_ERR_INVALID_STATE;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udp_pcb * pcb = udp_new();
|
||||||
|
if (!pcb) {
|
||||||
|
msg->err = ESP_ERR_NO_MEM;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb->remote_port = MDNS_SERVICE_PORT;
|
||||||
|
|
||||||
|
if (udp_bind(pcb, &multicast_if_addr, pcb->remote_port) != 0) {
|
||||||
|
udp_remove(pcb);
|
||||||
|
msg->err = ESP_ERR_INVALID_STATE;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcb->mcast_ttl = 1;
|
||||||
|
ip_addr_copy(pcb->multicast_ip, multicast_if_addr);
|
||||||
|
ip_addr_copy(pcb->remote_ip, laddr);
|
||||||
|
|
||||||
|
server->pcb = pcb;
|
||||||
|
udp_recv(pcb, &_mdns_server_recv, server);
|
||||||
|
msg->err = err;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief init the network of MDNS server
|
* @brief init the network of MDNS server
|
||||||
*
|
*
|
||||||
|
@ -207,42 +267,29 @@ static void _mdns_server_recv(void *arg, struct udp_pcb *upcb, struct pbuf *pb,
|
||||||
*/
|
*/
|
||||||
esp_err_t _mdns_server_init(mdns_server_t * server)
|
esp_err_t _mdns_server_init(mdns_server_t * server)
|
||||||
{
|
{
|
||||||
esp_err_t err = ESP_OK;
|
mdns_api_call_t msg = {
|
||||||
|
.server = server,
|
||||||
tcpip_adapter_ip_info_t if_ip_info;
|
};
|
||||||
err = tcpip_adapter_get_ip_info(server->tcpip_if, &if_ip_info);
|
tcpip_api_call(_mdns_server_init_api, (struct tcpip_api_call*)&msg);
|
||||||
if (err) {
|
return msg.err;
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ip_addr_t laddr;
|
/**
|
||||||
IP_ADDR4(&laddr, 224, 0, 0, 251);
|
* @brief stop the network of MDNS server (called in tcpip thread context)
|
||||||
|
*/
|
||||||
|
static err_t _mdns_server_deinit_api(struct tcpip_api_call *api_call_msg)
|
||||||
|
{
|
||||||
|
mdns_api_call_t *msg = (mdns_api_call_t*)api_call_msg;
|
||||||
|
mdns_server_t *server = msg->server;
|
||||||
|
|
||||||
ip_addr_t multicast_if_addr = IPADDR4_INIT(if_ip_info.ip.addr);
|
if (server->pcb) {
|
||||||
|
udp_recv(server->pcb, NULL, NULL);
|
||||||
if (igmp_joingroup((const struct ip4_addr *)&multicast_if_addr.u_addr.ip4, (const struct ip4_addr *)&laddr.u_addr.ip4)) {
|
udp_disconnect(server->pcb);
|
||||||
return ESP_ERR_INVALID_STATE;
|
udp_remove(server->pcb);
|
||||||
|
server->pcb = NULL;
|
||||||
}
|
}
|
||||||
|
msg->err = ESP_OK;
|
||||||
struct udp_pcb * pcb = udp_new();
|
return ERR_OK;
|
||||||
if (!pcb) {
|
|
||||||
return ESP_ERR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcb->remote_port = MDNS_SERVICE_PORT;
|
|
||||||
|
|
||||||
if (udp_bind(pcb, &multicast_if_addr, pcb->remote_port) != 0) {
|
|
||||||
udp_remove(pcb);
|
|
||||||
return ESP_ERR_INVALID_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
pcb->mcast_ttl = 1;
|
|
||||||
ip_addr_copy(pcb->multicast_ip, multicast_if_addr);
|
|
||||||
ip_addr_copy(pcb->remote_ip, laddr);
|
|
||||||
|
|
||||||
server->pcb = pcb;
|
|
||||||
udp_recv(pcb, &_mdns_server_recv, server);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,16 +301,39 @@ esp_err_t _mdns_server_init(mdns_server_t * server)
|
||||||
*/
|
*/
|
||||||
esp_err_t _mdns_server_deinit(mdns_server_t * server)
|
esp_err_t _mdns_server_deinit(mdns_server_t * server)
|
||||||
{
|
{
|
||||||
if (server->pcb) {
|
mdns_api_call_t msg = {
|
||||||
udp_recv(server->pcb, NULL, NULL);
|
.server = server,
|
||||||
udp_disconnect(server->pcb);
|
};
|
||||||
udp_remove(server->pcb);
|
tcpip_api_call(_mdns_server_deinit_api, (struct tcpip_api_call*)&msg);
|
||||||
server->pcb = NULL;
|
return msg.err;
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief send packet over UDP (called in tcpip thread context)
|
||||||
|
*/
|
||||||
|
static err_t _mdns_server_write_api(struct tcpip_api_call *api_call_msg)
|
||||||
|
{
|
||||||
|
mdns_api_call_t *msg = (mdns_api_call_t*)api_call_msg;
|
||||||
|
mdns_server_t *server = msg->server;
|
||||||
|
|
||||||
|
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, msg->len, PBUF_RAM);
|
||||||
|
if (pbt == NULL) {
|
||||||
|
msg->len = 0;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
uint8_t* dst = (uint8_t *)pbt->payload;
|
||||||
|
memcpy(dst, msg->data, msg->len);
|
||||||
|
err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port);
|
||||||
|
pbuf_free(pbt);
|
||||||
|
if (err) {
|
||||||
|
msg->len = 0;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief send packet over UDP
|
* @brief send packet over UDP
|
||||||
*
|
*
|
||||||
|
@ -273,22 +343,18 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server)
|
||||||
*
|
*
|
||||||
* @return length of sent packet or 0 on error
|
* @return length of sent packet or 0 on error
|
||||||
*/
|
*/
|
||||||
static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len)
|
static size_t _mdns_server_write(mdns_server_t * server, uint8_t * data, size_t len) {
|
||||||
{
|
|
||||||
#ifndef MDNS_TEST_MODE
|
#ifndef MDNS_TEST_MODE
|
||||||
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
mdns_api_call_t msg = {
|
||||||
if (pbt == NULL) {
|
.server = server,
|
||||||
return 0;
|
.data = data,
|
||||||
}
|
.len = len,
|
||||||
uint8_t* dst = (uint8_t *)pbt->payload;
|
};
|
||||||
memcpy(dst, data, len);
|
tcpip_api_call(_mdns_server_write_api, (struct tcpip_api_call*)&msg);
|
||||||
err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port);
|
return msg.len;
|
||||||
pbuf_free(pbt);
|
#else
|
||||||
if (err) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return len;
|
return len;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue