Use LwIP IPC for low-level API calls

This commit is contained in:
Eugene Zagidullin 2017-06-27 00:35:16 +03:00
parent ff6a3b1a11
commit 713964fe9e

View file

@ -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
}
/*