feat(lwip): LWIP and tcpip adapter using esp_socket to read/write low-level data

This commit is contained in:
Dong Heng
2018-04-23 17:07:36 +08:00
parent 39b77d4337
commit f23d3fc404
2 changed files with 146 additions and 15 deletions

View File

@@ -18,7 +18,7 @@
#include "esp_libc.h"
#include "esp_wifi.h"
#include "tcpip_adapter.h"
#include "esp_socket.h"
int8_t ieee80211_output_pbuf(uint8_t fd, uint8_t* dataptr, uint16_t datalen);
int8_t wifi_get_netif(uint8_t fd);
@@ -54,6 +54,22 @@ static void low_level_init(struct netif* netif)
/* Do whatever else is needed to initialize interface. */
}
/*
* @brief LWIP low-level AI/O sending callback function, it is to free pbuf
*
* @param aio AI/O control block pointer
*
* @return 0 meaning successs
*/
static int low_level_send_cb(esp_aio_t *aio)
{
struct pbuf *pbuf = aio->arg;
pbuf_free(pbuf);
return 0;
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
@@ -72,6 +88,7 @@ static void low_level_init(struct netif* netif)
static int8_t low_level_output(struct netif* netif, struct pbuf* p)
{
esp_aio_t aio;
int8_t err = ERR_OK;
if (netif == NULL) {
@@ -83,20 +100,20 @@ static int8_t low_level_output(struct netif* netif, struct pbuf* p)
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
#endif
uint8_t* outputbuf = (uint8_t*)os_malloc(p->len + 36);
if (outputbuf == NULL) {
TCPIP_ATAPTER_LOG("ERROR no memory\n");
return ERR_MEM;
}
pbuf_ref(p);
outputbuf += 36;
memcpy(outputbuf, p->payload, p->len);
aio.fd = (int)netif->state;
aio.pbuf = p->payload;
aio.len = p->len;
aio.cb = low_level_send_cb;
aio.arg = p;
aio.ret = 0;
if (netif == esp_netif[TCPIP_ADAPTER_IF_STA]) {
err = ieee80211_output_pbuf(TCPIP_ADAPTER_IF_STA, outputbuf, p->len);
} else {
err = ieee80211_output_pbuf(TCPIP_ADAPTER_IF_AP, outputbuf, p->len);
}
/*
* we use "SOCK_RAW" to create socket, so all input/output datas include full ethernet
* header, meaning we should not pass target low-level address here.
*/
err = esp_aio_sendto(&aio, NULL, 0);
if (err == ERR_MEM) {
err = ERR_OK;

View File

@@ -21,6 +21,16 @@
#include "esp_misc.h"
#include "tcpip_adapter.h"
#include "dhcpserver/dhcpserver.h"
#include "net/sockio.h"
#include "esp_socket.h"
struct tcpip_adapter_pbuf {
struct pbuf_custom pbuf;
void *base;
struct netif *netif;
};
/* Avoid warning. No header file has include these function */
err_t ethernetif_init(struct netif* netif);
@@ -86,6 +96,90 @@ static void tcpip_adapter_station_dhcp_start()
}
}
/*
* @brief LWIP custom pbuf callback function, it is to free custom pbuf
*
* @param p LWIP pbuf pointer
*
* @return none
*/
static void tcpip_adapter_free_pbuf(struct pbuf *p)
{
struct tcpip_adapter_pbuf *pa = (struct tcpip_adapter_pbuf *)p;
int s = (int)pa->netif->state;
esp_free_pbuf(s, pa->base);
os_free(pa);
}
/*
* @brief TCPIP adapter AI/O recieve callback function, it is to recieve input data
* and pass it to LWIP core
*
* @param aio AI/O control block pointer
*
* @return 0 if success or others if failed
*/
static int tcpip_adapter_recv_cb(struct esp_aio *aio)
{
struct pbuf *pbuf = NULL;
struct tcpip_adapter_pbuf *p;
struct netif *netif = (struct netif *)aio->arg;
extern void ethernetif_input(struct netif *netif, struct pbuf *p);
p = os_malloc(sizeof(struct tcpip_adapter_pbuf));
if (!p)
return -ENOMEM;
p->pbuf.custom_free_function = tcpip_adapter_free_pbuf;
p->base = (void *)aio->pbuf;
p->netif = netif;
// PBUF_RAW means payload = (char *)aio->pbuf + offset(=0)
pbuf = pbuf_alloced_custom(PBUF_RAW, aio->len, PBUF_REF, &p->pbuf, (void *)aio->pbuf, aio->len);
if (!pbuf)
return -ENOMEM;
ethernetif_input(netif, pbuf);
return 0;
}
/*
* @brief create a "esp_socket" and bind it to target net card
*
* @param name net card name pointer
* @param netif LWIP net interface pointer
*
* @return 0 if success or others if failed
*/
static int tcpip_adapter_bind_netcard(const char *name, struct netif *netif)
{
int s, ret;
s = esp_socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
if (s < 0) {
TCPIP_ATAPTER_LOG("create socket of (AF_PACKET, SOCK_RAW, ETH_P_ALL) error\n");
return -1;
}
ret = esp_ioctl(s, SIOCGIFINDEX, name);
if (ret) {
TCPIP_ATAPTER_LOG("bind socket %d to netcard %s error\n", s, name);
esp_close(s);
return -1;
}
ret = esp_aio_event(s, ESP_SOCKET_RECV_EVENT, tcpip_adapter_recv_cb, netif);
if (ret) {
TCPIP_ATAPTER_LOG("socket %d register receive callback function %p error\n", s, tcpip_adapter_recv_cb);
esp_close(s);
return -1;
}
return s;
}
void tcpip_adapter_start(uint8_t netif_index, bool authed)
{
if (!TCPIP_ADAPTER_IF_VALID(netif_index)) {
@@ -98,10 +192,20 @@ void tcpip_adapter_start(uint8_t netif_index, bool authed)
if (netif_index == TCPIP_ADAPTER_IF_STA) {
if (authed == 0) {
if (esp_netif[netif_index] == NULL) {
int s;
const char *netcard_name = "sta0";
esp_netif[netif_index] = (struct netif*)os_zalloc(sizeof(*esp_netif[netif_index]));
TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
TCPIP_ATAPTER_LOG("Add netif:%d\n", netif_index);
netif_add(esp_netif[netif_index], NULL, NULL, NULL, NULL, ethernetif_init, tcpip_input);
s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[netif_index]);
if (s < 0) {
TCPIP_ATAPTER_LOG("TCPIP adapter bind net card %s error\n", netcard_name);
return ;
}
netif_add(esp_netif[netif_index], NULL, NULL, NULL, (void *)s, ethernetif_init, tcpip_input);
}
} else {
if ((esp_netif[netif_index]->flags & NETIF_FLAG_DHCP) == 0) {
@@ -131,10 +235,20 @@ void tcpip_adapter_start(uint8_t netif_index, bool authed)
}
if (esp_netif[netif_index] == NULL) {
int s;
const char *netcard_name = "ap0";
TCPIP_ATAPTER_LOG("Malloc netif:%d\n", netif_index);
esp_netif[netif_index] = (struct netif*)os_zalloc(sizeof(*esp_netif[netif_index]));
s = tcpip_adapter_bind_netcard(netcard_name, esp_netif[netif_index]);
if (s < 0) {
TCPIP_ATAPTER_LOG("TCPIP adapter bind net card %s error\n", netcard_name);
return ;
}
netif_add(esp_netif[netif_index], &esp_ip[TCPIP_ADAPTER_IF_AP].ip,
&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, &esp_ip[TCPIP_ADAPTER_IF_AP].gw, NULL, ethernetif_init, tcpip_input);
&esp_ip[TCPIP_ADAPTER_IF_AP].netmask, &esp_ip[TCPIP_ADAPTER_IF_AP].gw, (void *)s, ethernetif_init, tcpip_input);
}
if (dhcps_flag) {