Use LwIP IPC for low-level API calls
This commit is contained in:
parent
ff6a3b1a11
commit
713964fe9e
1 changed files with 182 additions and 116 deletions
|
@ -23,6 +23,8 @@
|
|||
#include "lwip/pbuf.h"
|
||||
#include "lwip/igmp.h"
|
||||
#include "lwip/udp.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "esp_wifi.h"
|
||||
#endif
|
||||
|
||||
|
@ -154,6 +156,14 @@ struct mdns_server_s {
|
|||
} 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_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
|
||||
*
|
||||
|
@ -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 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) {
|
||||
return err;
|
||||
mdns_api_call_t msg = {
|
||||
.server = server,
|
||||
};
|
||||
tcpip_api_call(_mdns_server_init_api, (struct tcpip_api_call*)&msg);
|
||||
return msg.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 (igmp_joingroup((const struct ip4_addr *)&multicast_if_addr.u_addr.ip4, (const struct ip4_addr *)&laddr.u_addr.ip4)) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
if (server->pcb) {
|
||||
udp_recv(server->pcb, NULL, NULL);
|
||||
udp_disconnect(server->pcb);
|
||||
udp_remove(server->pcb);
|
||||
server->pcb = NULL;
|
||||
}
|
||||
|
||||
struct udp_pcb * pcb = udp_new();
|
||||
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;
|
||||
msg->err = ESP_OK;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -254,16 +301,39 @@ esp_err_t _mdns_server_init(mdns_server_t * server)
|
|||
*/
|
||||
esp_err_t _mdns_server_deinit(mdns_server_t * server)
|
||||
{
|
||||
if (server->pcb) {
|
||||
udp_recv(server->pcb, NULL, NULL);
|
||||
udp_disconnect(server->pcb);
|
||||
udp_remove(server->pcb);
|
||||
server->pcb = NULL;
|
||||
}
|
||||
return ESP_OK;
|
||||
mdns_api_call_t msg = {
|
||||
.server = server,
|
||||
};
|
||||
tcpip_api_call(_mdns_server_deinit_api, (struct tcpip_api_call*)&msg);
|
||||
return msg.err;
|
||||
}
|
||||
#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
|
||||
*
|
||||
|
@ -273,22 +343,18 @@ esp_err_t _mdns_server_deinit(mdns_server_t * server)
|
|||
*
|
||||
* @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
|
||||
struct pbuf* pbt = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
|
||||
if (pbt == NULL) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t* dst = (uint8_t *)pbt->payload;
|
||||
memcpy(dst, data, len);
|
||||
err_t err = udp_sendto(server->pcb, pbt, &(server->pcb->remote_ip), server->pcb->remote_port);
|
||||
pbuf_free(pbt);
|
||||
if (err) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
mdns_api_call_t msg = {
|
||||
.server = server,
|
||||
.data = data,
|
||||
.len = len,
|
||||
};
|
||||
tcpip_api_call(_mdns_server_write_api, (struct tcpip_api_call*)&msg);
|
||||
return msg.len;
|
||||
#else
|
||||
return len;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue