mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-16 04:22:22 +00:00
Merge branch 'feature/lwip_rework_patches' into 'master'
lw-IP: Reworked patches Closes IDFGH-6197 See merge request espressif/esp-idf!17388
This commit is contained in:
@@ -1,79 +1,73 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "nvs.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "esp_interface.h"
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_net_stack.h"
|
||||
#include "netif/dhcp_state.h"
|
||||
|
||||
#define DHCP_NAMESPACE "dhcp_state"
|
||||
#define IF_KEY_SIZE 3
|
||||
|
||||
// DHCP_Client has to be enabled for this netif
|
||||
#define VALID_NETIF_ID(netif) (ESP_NETIF_DHCP_CLIENT&esp_netif_get_flags(netif))
|
||||
/*
|
||||
* As a NVS key, use string representation of the interface index number
|
||||
*/
|
||||
static inline char *gen_if_key(struct netif *netif, char *name)
|
||||
{
|
||||
lwip_itoa(name, IF_KEY_SIZE, netif->num);
|
||||
return name;
|
||||
}
|
||||
|
||||
bool dhcp_ip_addr_restore(void *netif)
|
||||
bool dhcp_ip_addr_restore(struct netif *netif)
|
||||
{
|
||||
nvs_handle_t nvs;
|
||||
char if_key[IF_KEY_SIZE];
|
||||
bool err = false;
|
||||
struct netif *net = (struct netif *)netif;
|
||||
struct dhcp *dhcp = netif_dhcp_data(net);
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
if (netif == NULL) {
|
||||
return false;
|
||||
}
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
|
||||
if(VALID_NETIF_ID(esp_netif)) {
|
||||
uint32_t *ip_addr = &dhcp->offered_ip_addr.addr;
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) {
|
||||
if (nvs_get_u32(nvs, esp_netif_get_ifkey(esp_netif), ip_addr) == ESP_OK) {
|
||||
err = true;
|
||||
}
|
||||
nvs_close(nvs);
|
||||
uint32_t *ip_addr = &dhcp->offered_ip_addr.addr;
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) {
|
||||
if (nvs_get_u32(nvs, gen_if_key(netif, if_key), ip_addr) == ESP_OK) {
|
||||
err = true;
|
||||
}
|
||||
nvs_close(nvs);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void dhcp_ip_addr_store(void *netif)
|
||||
void dhcp_ip_addr_store(struct netif *netif)
|
||||
{
|
||||
nvs_handle_t nvs;
|
||||
struct netif *net = (struct netif *)netif;
|
||||
struct dhcp *dhcp = netif_dhcp_data(net);
|
||||
char if_key[IF_KEY_SIZE];
|
||||
if (netif == NULL) {
|
||||
return;
|
||||
}
|
||||
struct dhcp *dhcp = netif_dhcp_data(netif);
|
||||
uint32_t ip_addr = dhcp->offered_ip_addr.addr;
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
|
||||
if(VALID_NETIF_ID(esp_netif)) {
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
|
||||
nvs_set_u32(nvs,esp_netif_get_ifkey(esp_netif), ip_addr);
|
||||
nvs_commit(nvs);
|
||||
nvs_close(nvs);
|
||||
}
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
|
||||
nvs_set_u32(nvs, gen_if_key(netif, if_key), ip_addr);
|
||||
nvs_commit(nvs);
|
||||
nvs_close(nvs);
|
||||
}
|
||||
}
|
||||
|
||||
void dhcp_ip_addr_erase(void *esp_netif)
|
||||
void dhcp_ip_addr_erase(struct netif *netif)
|
||||
{
|
||||
nvs_handle_t nvs;
|
||||
|
||||
if(VALID_NETIF_ID(esp_netif)) {
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
|
||||
nvs_erase_key(nvs, esp_netif_get_ifkey(esp_netif));
|
||||
nvs_commit(nvs);
|
||||
nvs_close(nvs);
|
||||
}
|
||||
char if_key[IF_KEY_SIZE];
|
||||
if (netif == NULL) {
|
||||
return;
|
||||
}
|
||||
if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
|
||||
nvs_erase_key(nvs, gen_if_key(netif, if_key));
|
||||
nvs_commit(nvs);
|
||||
nvs_close(nvs);
|
||||
}
|
||||
}
|
||||
|
||||
58
components/lwip/port/esp32/netif/esp_pbuf_ref.c
Normal file
58
components/lwip/port/esp32/netif/esp_pbuf_ref.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
/**
|
||||
* @file esp_pbuf reference
|
||||
* This file handles lwip custom pbufs interfacing with esp_netif
|
||||
* and the L2 free function esp_netif_free_rx_buffer()
|
||||
*/
|
||||
|
||||
#include "netif/esp_pbuf_ref.h"
|
||||
#include "esp_netif_net_stack.h"
|
||||
#include "lwip/mem.h"
|
||||
|
||||
/**
|
||||
* @brief Specific pbuf structure for pbufs allocated by ESP netif
|
||||
* of PBUF_REF type
|
||||
*/
|
||||
typedef struct esp_custom_pbuf
|
||||
{
|
||||
struct pbuf_custom p;
|
||||
esp_netif_t *esp_netif;
|
||||
void* l2_buf;
|
||||
} esp_custom_pbuf_t;
|
||||
|
||||
/**
|
||||
* @brief Free custom pbuf containing the L2 layer buffer allocated in the driver
|
||||
*
|
||||
* @param pbuf Custom pbuf holding the packet passed to lwip input
|
||||
* @note This function called as a custom_free_function() upon pbuf_free()
|
||||
*/
|
||||
static void esp_pbuf_free(struct pbuf *pbuf)
|
||||
{
|
||||
esp_custom_pbuf_t* esp_pbuf = (esp_custom_pbuf_t*)pbuf;
|
||||
esp_netif_free_rx_buffer(esp_pbuf->esp_netif, esp_pbuf->l2_buf);
|
||||
mem_free(pbuf);
|
||||
}
|
||||
|
||||
|
||||
struct pbuf* esp_pbuf_allocate(esp_netif_t *esp_netif, void *buffer, size_t len, void *l2_buff)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
esp_custom_pbuf_t* esp_pbuf = mem_malloc(sizeof(esp_custom_pbuf_t));
|
||||
if (esp_pbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
esp_pbuf->p.custom_free_function = esp_pbuf_free;
|
||||
esp_pbuf->esp_netif = esp_netif;
|
||||
esp_pbuf->l2_buf = l2_buff;
|
||||
p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &esp_pbuf->p, buffer, len);
|
||||
if (p == NULL) {
|
||||
mem_free(esp_pbuf);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
@@ -52,22 +52,12 @@
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_net_stack.h"
|
||||
#include "esp_compiler.h"
|
||||
#include "netif/esp_pbuf_ref.h"
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 'e'
|
||||
#define IFNAME1 'n'
|
||||
|
||||
/**
|
||||
* @brief Free resources allocated in L2 layer
|
||||
*
|
||||
* @param buf memory alloc in L2 layer
|
||||
* @note this function is also the callback when invoke pbuf_free
|
||||
*/
|
||||
static void ethernet_free_rx_buf_l2(struct netif *netif, void *buf)
|
||||
{
|
||||
free(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* In this function, the hardware should be initialized.
|
||||
* Invoked by ethernetif_init().
|
||||
@@ -126,11 +116,6 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p)
|
||||
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
|
||||
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
#if ESP_LWIP
|
||||
/* This pbuf RAM was not allocated on layer2, no extra free operation needed in pbuf_free */
|
||||
q->l2_owner = NULL;
|
||||
q->l2_buf = NULL;
|
||||
#endif
|
||||
pbuf_copy(q, p);
|
||||
} else {
|
||||
return ERR_MEM;
|
||||
@@ -155,33 +140,30 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p)
|
||||
* interface. Then the type of the received packet is determined and
|
||||
* the appropriate input function is called.
|
||||
*
|
||||
* @param netif lwip network interface structure for this ethernetif
|
||||
* @param h lwip network interface structure (struct netif) for this ethernetif
|
||||
* @param buffer ethernet buffer
|
||||
* @param len length of buffer
|
||||
* @param l2_buff Placeholder for a separate L2 buffer. Unused for ethernet interface
|
||||
*/
|
||||
void ethernetif_input(void *h, void *buffer, size_t len, void *eb)
|
||||
void ethernetif_input(void *h, void *buffer, size_t len, void *l2_buff)
|
||||
{
|
||||
struct netif *netif = h;
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
struct pbuf *p;
|
||||
|
||||
if (unlikely(buffer == NULL || !netif_is_up(netif))) {
|
||||
if (buffer) {
|
||||
ethernet_free_rx_buf_l2(netif, buffer);
|
||||
esp_netif_free_rx_buffer(esp_netif, buffer);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* acquire new pbuf, type: PBUF_REF */
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
|
||||
/* allocate custom pbuf to hold */
|
||||
p = esp_pbuf_allocate(esp_netif, buffer, len, buffer);
|
||||
if (p == NULL) {
|
||||
ethernet_free_rx_buf_l2(netif, buffer);
|
||||
esp_netif_free_rx_buffer(esp_netif, buffer);
|
||||
return;
|
||||
}
|
||||
p->payload = buffer;
|
||||
#if ESP_LWIP
|
||||
p->l2_owner = netif;
|
||||
p->l2_buf = buffer;
|
||||
#endif
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
@@ -234,7 +216,6 @@ err_t ethernetif_init(struct netif *netif)
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = ethernet_low_level_output;
|
||||
netif->l2_buffer_free_notify = ethernet_free_rx_buf_l2;
|
||||
|
||||
ethernet_low_level_init(netif);
|
||||
|
||||
|
||||
@@ -37,11 +37,6 @@ static err_t openthread_output_ip6(struct netif *netif, struct pbuf *p, const st
|
||||
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
|
||||
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
#if ESP_LWIP
|
||||
/* This pbuf RAM was not allocated on layer2, no extra free operation needed in pbuf_free */
|
||||
q->l2_owner = NULL;
|
||||
q->l2_buf = NULL;
|
||||
#endif
|
||||
pbuf_copy(q, p);
|
||||
} else {
|
||||
return ERR_MEM;
|
||||
@@ -84,10 +79,6 @@ void openthread_netif_input(void *h, void *buffer, size_t len, void *eb)
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("Failed to read OpenThread message\n"));
|
||||
}
|
||||
|
||||
#if ESP_LWIP
|
||||
p->l2_owner = NULL;
|
||||
p->l2_buf = NULL;
|
||||
#endif
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("openthread_netif_input: IP input error\n"));
|
||||
@@ -135,7 +126,6 @@ err_t openthread_netif_init(struct netif *netif)
|
||||
netif->output = NULL;
|
||||
netif->output_ip6 = openthread_output_ip6;
|
||||
netif->mld_mac_filter = openthread_netif_multicast_handler;
|
||||
netif->l2_buffer_free_notify = NULL;
|
||||
netif_set_link_up(netif);
|
||||
|
||||
return ERR_OK;
|
||||
|
||||
@@ -1,38 +1,13 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2001-2004 Swedish Institute of Computer Science
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* SPDX-FileContributor: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* Ethernet Interface Skeleton
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
* Ethernet Interface Skeleton used for WiFi
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -46,6 +21,7 @@
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/wlanif.h"
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@@ -53,27 +29,24 @@
|
||||
#include "esp_netif.h"
|
||||
#include "esp_netif_net_stack.h"
|
||||
#include "esp_compiler.h"
|
||||
#include "netif/esp_pbuf_ref.h"
|
||||
|
||||
#ifndef CONFIG_LWIP_L2_TO_L3_COPY
|
||||
/**
|
||||
* @brief Free resources allocated in L2 layer
|
||||
*
|
||||
* @param buf memory alloc in L2 layer
|
||||
* @note this function is also the callback when invoke pbuf_free
|
||||
*/
|
||||
static void lwip_netif_wifi_free_rx_buffer(struct netif *netif, void *buf)
|
||||
|
||||
typedef struct wifi_custom_pbuf
|
||||
{
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
esp_netif_free_rx_buffer(esp_netif, buf);
|
||||
}
|
||||
#endif
|
||||
struct pbuf_custom p;
|
||||
void* l2_buf;
|
||||
} wifi_custom_pbuf_t;
|
||||
|
||||
static struct netif *s_wifi_netifs[2] = { NULL };
|
||||
|
||||
|
||||
/**
|
||||
* In this function, the hardware should be initialized.
|
||||
* Called from ethernetif_init().
|
||||
* Called from wlanif_input().
|
||||
*
|
||||
* @param netif the already initialized lwip network interface structure
|
||||
* for this ethernetif
|
||||
* for this wlanif
|
||||
*/
|
||||
static void
|
||||
low_level_init(struct netif *netif)
|
||||
@@ -102,9 +75,145 @@ low_level_init(struct netif *netif)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_LWIP_L2_TO_L3_COPY
|
||||
netif->l2_buffer_free_notify = lwip_netif_wifi_free_rx_buffer;
|
||||
}
|
||||
|
||||
err_t set_wifi_netif(int wifi_inx, void* netif)
|
||||
{
|
||||
if (wifi_inx < 2) {
|
||||
s_wifi_netifs[wifi_inx] = netif;
|
||||
return ERR_OK;
|
||||
}
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
|
||||
static void wifi_pbuf_free(struct pbuf *p)
|
||||
{
|
||||
wifi_custom_pbuf_t* wifi_pbuf = (wifi_custom_pbuf_t*)p;
|
||||
if (wifi_pbuf) {
|
||||
esp_wifi_internal_free_rx_buffer(wifi_pbuf->l2_buf);
|
||||
}
|
||||
mem_free(wifi_pbuf);
|
||||
}
|
||||
|
||||
static inline struct pbuf* wifi_pbuf_allocate(struct netif *netif, void *buffer, size_t len, void *l2_buff)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
wifi_custom_pbuf_t* esp_pbuf = mem_malloc(sizeof(wifi_custom_pbuf_t));
|
||||
|
||||
if (esp_pbuf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
esp_pbuf->p.custom_free_function = wifi_pbuf_free;
|
||||
esp_pbuf->l2_buf = l2_buff;
|
||||
p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &esp_pbuf->p, buffer, len);
|
||||
if (p == NULL) {
|
||||
mem_free(esp_pbuf);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *l2_buff)
|
||||
{
|
||||
struct netif * netif = s_wifi_netifs[0];
|
||||
struct pbuf *p;
|
||||
|
||||
if(unlikely(!buffer || !netif_is_up(netif))) {
|
||||
if (l2_buff) {
|
||||
esp_wifi_internal_free_rx_buffer(l2_buff);
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
p = wifi_pbuf_allocate(netif, buffer, len, l2_buff);
|
||||
if (p == NULL) {
|
||||
esp_wifi_internal_free_rx_buffer(l2_buff);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *l2_buff)
|
||||
{
|
||||
struct netif * netif = s_wifi_netifs[1];
|
||||
struct pbuf *p;
|
||||
|
||||
if(unlikely(!buffer || !netif_is_up(netif))) {
|
||||
if (l2_buff) {
|
||||
esp_wifi_internal_free_rx_buffer(l2_buff);
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
p = wifi_pbuf_allocate(netif, buffer, len, l2_buff);
|
||||
if (p == NULL) {
|
||||
esp_wifi_internal_free_rx_buffer(l2_buff);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function low_level_input() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface. Then the type of the received packet is determined and
|
||||
* the appropriate input function is called.
|
||||
*
|
||||
* @param h lwip network interface structure (struct netif) for this ethernetif
|
||||
* @param buffer wlan buffer
|
||||
* @param len length of buffer
|
||||
* @param l2_buff wlan's L2 buffer pointer
|
||||
*/
|
||||
void
|
||||
wlanif_input(void *h, void *buffer, size_t len, void* l2_buff)
|
||||
{
|
||||
struct netif * netif = h;
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
struct pbuf *p;
|
||||
|
||||
if(unlikely(!buffer || !netif_is_up(netif))) {
|
||||
if (l2_buff) {
|
||||
esp_netif_free_rx_buffer(esp_netif, l2_buff);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_L2_TO_L3_COPY
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
esp_netif_free_rx_buffer(esp_netif, l2_buff);
|
||||
return;
|
||||
}
|
||||
memcpy(p->payload, buffer, len);
|
||||
esp_netif_free_rx_buffer(esp_netif, l2_buff);
|
||||
#else
|
||||
p = esp_pbuf_allocate(esp_netif, buffer, len, l2_buff);
|
||||
if (p == NULL) {
|
||||
esp_netif_free_rx_buffer(esp_netif, l2_buff);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,41 +221,66 @@ low_level_init(struct netif *netif)
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @param netif the lwip network interface structure for this wlanif
|
||||
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
|
||||
* @return ERR_OK if the packet could be sent
|
||||
* an err_t value if the packet couldn't be sent
|
||||
*
|
||||
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
|
||||
* strange results. You might consider waiting for space in the DMA queue
|
||||
* to become availale since the stack doesn't retry to send a packet
|
||||
* to become available since the stack doesn't retry to send a packet
|
||||
* dropped because of memory failure (except for the TCP timers).
|
||||
*/
|
||||
static err_t
|
||||
low_level_output(struct netif *netif, struct pbuf *p)
|
||||
sta_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
if (esp_netif == NULL) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
struct pbuf *q = p;
|
||||
esp_err_t ret;
|
||||
|
||||
if(q->next == NULL) {
|
||||
ret = esp_netif_transmit_wrap(esp_netif, q->payload, q->len, q);
|
||||
ret = esp_wifi_internal_tx(WIFI_IF_STA, q->payload, q->len);
|
||||
|
||||
} else {
|
||||
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
|
||||
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
q->l2_owner = NULL;
|
||||
pbuf_copy(q, p);
|
||||
} else {
|
||||
return ERR_MEM;
|
||||
}
|
||||
ret = esp_netif_transmit_wrap(esp_netif, q->payload, q->len, q);
|
||||
ret = esp_wifi_internal_tx(WIFI_IF_STA, q->payload, q->len);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
if (ret == ESP_OK) {
|
||||
return ERR_OK;
|
||||
} else if (ret == ESP_ERR_NO_MEM) {
|
||||
return ERR_MEM;
|
||||
} else if (ret == ESP_ERR_INVALID_ARG) {
|
||||
return ERR_ARG;
|
||||
} else {
|
||||
return ERR_IF;
|
||||
}
|
||||
}
|
||||
|
||||
static err_t
|
||||
ap_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct pbuf *q = p;
|
||||
esp_err_t ret;
|
||||
|
||||
if(q->next == NULL) {
|
||||
ret = esp_wifi_internal_tx(WIFI_IF_AP, q->payload, q->len);
|
||||
|
||||
} else {
|
||||
LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug"));
|
||||
q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM);
|
||||
if (q != NULL) {
|
||||
pbuf_copy(q, p);
|
||||
} else {
|
||||
return ERR_MEM;
|
||||
}
|
||||
ret = esp_wifi_internal_tx(WIFI_IF_AP, q->payload, q->len);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
@@ -161,57 +295,6 @@ low_level_output(struct netif *netif, struct pbuf *p)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should be called when a packet is ready to be read
|
||||
* from the interface. It uses the function low_level_input() that
|
||||
* should handle the actual reception of bytes from the network
|
||||
* interface. Then the type of the received packet is determined and
|
||||
* the appropriate input function is called.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
*/
|
||||
void
|
||||
wlanif_input(void *h, void *buffer, size_t len, void* eb)
|
||||
{
|
||||
struct netif * netif = h;
|
||||
esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif);
|
||||
struct pbuf *p;
|
||||
|
||||
if(unlikely(!buffer || !netif_is_up(netif))) {
|
||||
if (eb) {
|
||||
esp_netif_free_rx_buffer(esp_netif, eb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_LWIP_L2_TO_L3_COPY
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
esp_netif_free_rx_buffer(esp_netif, eb);
|
||||
return;
|
||||
}
|
||||
p->l2_owner = NULL;
|
||||
memcpy(p->payload, buffer, len);
|
||||
esp_netif_free_rx_buffer(esp_netif, eb);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
|
||||
if (p == NULL){
|
||||
esp_netif_free_rx_buffer(esp_netif, eb);
|
||||
return;
|
||||
}
|
||||
p->payload = buffer;
|
||||
p->l2_owner = netif;
|
||||
p->l2_buf = eb;
|
||||
#endif /* CONFIG_LWIP_L2_TO_L3_COPY */
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (unlikely(netif->input(p, netif) != ERR_OK)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called at the beginning of the program to set up the
|
||||
* network interface. It calls the function low_level_init() to do the
|
||||
@@ -219,7 +302,7 @@ wlanif_input(void *h, void *buffer, size_t len, void* eb)
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @param netif the lwip network interface structure for this wlanif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
@@ -257,7 +340,6 @@ wlanif_init(struct netif *netif)
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
|
||||
/* initialize the hardware */
|
||||
low_level_init(netif);
|
||||
@@ -268,11 +350,13 @@ wlanif_init(struct netif *netif)
|
||||
err_t wlanif_init_sta(struct netif *netif) {
|
||||
netif->name[0] = 's';
|
||||
netif->name[1] = 't';
|
||||
netif->linkoutput = sta_output;
|
||||
return wlanif_init(netif);
|
||||
}
|
||||
|
||||
err_t wlanif_init_ap(struct netif *netif) {
|
||||
netif->name[0] = 'a';
|
||||
netif->name[1] = 'p';
|
||||
netif->linkoutput = ap_output;
|
||||
return wlanif_init(netif);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user