From f23d3fc404a594b84ed82da6ba8556b372c83d88 Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Mon, 23 Apr 2018 17:07:36 +0800 Subject: [PATCH] feat(lwip): LWIP and tcpip adapter using esp_socket to read/write low-level data --- components/lwip/port/netif/ethernetif.c | 43 +++++-- components/tcpip_adapter/tcpip_adapter_wifi.c | 118 +++++++++++++++++- 2 files changed, 146 insertions(+), 15 deletions(-) diff --git a/components/lwip/port/netif/ethernetif.c b/components/lwip/port/netif/ethernetif.c index c2abca8b..28dbc4c2 100644 --- a/components/lwip/port/netif/ethernetif.c +++ b/components/lwip/port/netif/ethernetif.c @@ -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; diff --git a/components/tcpip_adapter/tcpip_adapter_wifi.c b/components/tcpip_adapter/tcpip_adapter_wifi.c index 3542f6a0..cde1eccb 100644 --- a/components/tcpip_adapter/tcpip_adapter_wifi.c +++ b/components/tcpip_adapter/tcpip_adapter_wifi.c @@ -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) {