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:
David Čermák 2022-06-03 15:26:55 +08:00
commit 46e599c56d
37 changed files with 1114 additions and 339 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -19,10 +19,9 @@
# endif // CONFIG_COMPILER_RTTI
//
// LWIP compatibility inet and address macros/functions
// Use system sockets
//
# define LWIP_COMPAT_SOCKET_INET 1
# define LWIP_COMPAT_SOCKET_ADDR 1
# include "sys/socket.h"
//
// Specific ASIO feature flags

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -40,6 +40,11 @@ static esp_err_t eth_input_to_netif(esp_eth_handle_t eth_handle, uint8_t *buffer
return esp_netif_receive((esp_netif_t *)priv, buffer, length, NULL);
}
static void eth_l2_free(void *h, void* buffer)
{
free(buffer);
}
static esp_err_t esp_eth_post_attach(esp_netif_t *esp_netif, void *args)
{
uint8_t eth_mac[6];
@ -52,7 +57,7 @@ static esp_err_t esp_eth_post_attach(esp_netif_t *esp_netif, void *args)
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = netif_glue->eth_driver,
.transmit = esp_eth_transmit,
.driver_free_rx_buffer = NULL
.driver_free_rx_buffer = eth_l2_free
};
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));

View File

@ -28,6 +28,7 @@ menu "ESP NETIF Adapter"
help
Dummy implementation of esp-netif functionality which connects driver transmit
to receive function. This option is for testing purpose only
endchoice
config ESP_NETIF_L2_TAP

View File

@ -15,7 +15,7 @@
#include "esp_netif_private.h"
#include "esp_random.h"
#if CONFIG_ESP_NETIF_TCPIP_LWIP
#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP)
#include "lwip/tcpip.h"
#include "lwip/dhcp.h"
@ -25,6 +25,7 @@
#include "lwip/nd6.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/netif.h"
#include "lwip/etharp.h"
#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */
#include "lwip/dns.h"
#endif
@ -37,7 +38,7 @@
#include "esp_netif_lwip_slip.h"
#include "dhcpserver/dhcpserver.h"
#include "dhcpserver/dhcpserver_options.h"
#include "netif/dhcp_state.h"
#include "esp_event.h"
#include "esp_log.h"
@ -47,6 +48,8 @@
#define ESP_NETIF_HOSTNAME_MAX_SIZE 32
#define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED)
/**
* @brief lwip thread safe tcpip function utility macros
*/
@ -98,6 +101,75 @@ static const char *TAG = "esp_netif_lwip";
static bool tcpip_initialized = false;
static esp_netif_t *s_last_default_esp_netif = NULL;
static bool s_is_last_default_esp_netif_overridden = false;
static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL };
static void esp_netif_internal_dhcpc_cb(struct netif *netif);
#if LWIP_IPV6
static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index);
#endif /* LWIP_IPV6 */
static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args)
{
if (reason & DHCP_CB_CHANGE) {
esp_netif_internal_dhcpc_cb(netif);
}
#if LWIP_IPV6
if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) {
s8_t addr_idx = args->ipv6_addr_state_changed.addr_index;
if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) {
/* address is valid -> call the callback function */
esp_netif_internal_nd6_cb(netif, addr_idx);
}
}
#endif /* #if LWIP_IPV6 */
}
static void set_lwip_netif_callback(void)
{
if (netif_callback.callback_fn == NULL ) {
netif_add_ext_callback(&netif_callback, netif_callback_fn);
}
}
static void remove_lwip_netif_callback(void)
{
netif_remove_ext_callback(&netif_callback);
memset(&netif_callback, 0, sizeof(netif_callback));
}
static void dns_clear_servers(bool keep_fallback)
{
u8_t numdns = 0;
for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) {
if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) {
continue;
}
dns_setserver(numdns, NULL);
}
}
#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL
static void netif_send_garp(void *arg)
{
struct netif *netif = arg;
etharp_gratuitous(netif);
sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
}
static void netif_set_garp_flag(struct netif *netif)
{
sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif);
}
static void netif_unset_garp_flag(struct netif *netif)
{
sys_untimeout(netif_send_garp, netif);
}
#endif // CONFIG_LWIP_GARP_TMR_INTERVAL
#if !LWIP_TCPIP_CORE_LOCKING
static sys_sem_t api_sync_sem = NULL;
@ -490,7 +562,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
// Create parent esp-netif object
esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj));
if (!esp_netif) {
ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct esp_netif_obj),
ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct esp_netif_obj),
esp_get_free_heap_size());
return NULL;
}
@ -498,7 +570,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
// Create ip info
esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t),
ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t),
esp_get_free_heap_size());
free(esp_netif);
return NULL;
@ -508,7 +580,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
// creating another ip info (to store old ip)
ip_info = calloc(1, sizeof(esp_netif_ip_info_t));
if (!ip_info) {
ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t),
ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t),
esp_get_free_heap_size());
free(esp_netif->ip_info);
free(esp_netif);
@ -519,7 +591,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
// Create underlying lwip netif
struct netif * lwip_netif = calloc(1, sizeof(struct netif));
if (!lwip_netif) {
ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct netif),
ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct netif),
esp_get_free_heap_size());
free(esp_netif->ip_info_old);
free(esp_netif->ip_info);
@ -552,6 +624,8 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config)
return NULL;
}
set_lwip_netif_callback();
return esp_netif;
}
@ -562,6 +636,15 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif)
netif_set_down(esp_netif->lwip_netif);
}
netif_remove(esp_netif->lwip_netif);
#if ESP_GRATUITOUS_ARP
if (esp_netif->flags & ESP_NETIF_FLAG_GARP) {
netif_unset_garp_flag(esp_netif->lwip_netif);
}
#endif
if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) {
dhcp_cleanup(esp_netif->lwip_netif);
}
}
}
@ -611,6 +694,9 @@ void esp_netif_destroy(esp_netif_t *esp_netif)
{
if (esp_netif) {
esp_netif_remove_from_list(esp_netif);
if (esp_netif_get_nr_of_ifs() == 0) {
remove_lwip_netif_callback();
}
free(esp_netif->ip_info);
free(esp_netif->ip_info_old);
free(esp_netif->if_key);
@ -742,6 +828,9 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg)
ESP_ERROR_CHECK(esp_netif_lwip_add(esp_netif));
#if ESP_IPV6_AUTOCONFIG
esp_netif->lwip_netif->ip6_autoconfig_enabled = 1;
#endif
if (esp_netif->flags&ESP_NETIF_FLAG_GARP) {
#if ESP_GRATUITOUS_ARP
netif_set_garp_flag(esp_netif->lwip_netif);
@ -923,12 +1012,12 @@ esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, vo
return ESP_OK;
}
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
//
// DHCP:
//
static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif);
static void esp_netif_dhcpc_cb(struct netif *netif)
static void esp_netif_internal_dhcpc_cb(struct netif *netif)
{
if (!netif) {
ESP_LOGD(TAG, "null netif=%p", netif);
@ -941,7 +1030,6 @@ static void esp_netif_dhcpc_cb(struct netif *netif)
esp_netif_ip_info_t *ip_info = esp_netif->ip_info;
esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info_old;
if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4) ) {
//check whether IP is changed
@ -972,6 +1060,9 @@ static void esp_netif_dhcpc_cb(struct netif *netif)
if (ESP_OK != ret) {
ESP_LOGE(TAG, "dhcpc cb: failed to post got ip event (%x)", ret);
}
#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
dhcp_ip_addr_store(netif);
#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */
} else {
ESP_LOGD(TAG, "if%p ip unchanged", esp_netif);
}
@ -1074,7 +1165,9 @@ static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg)
ESP_LOGD(TAG, "dhcp client stop successfully");
esp_netif->dhcpc_status = ESP_NETIF_DHCP_STOPPED;
LWIP_DHCP_IP_ADDR_ERASE(esp_netif);
#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
dhcp_ip_addr_erase(esp_netif->lwip_netif);
#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */
return ESP_OK;
}
@ -1122,8 +1215,6 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg)
return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED;
}
dhcp_set_cb(p_netif, esp_netif_dhcpc_cb);
esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED;
return ESP_OK;
} else {
@ -1624,11 +1715,11 @@ esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr)
}
static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index)
static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index)
{
ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, p_netif);
if (!p_netif) {
ESP_LOGD(TAG, "esp_netif_nd6_cb called with null p_netif");
ESP_LOGD(TAG, "esp_netif_internal_nd6_cb called with null p_netif");
return;
}
@ -1661,7 +1752,6 @@ static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg)
struct netif *p_netif = esp_netif->lwip_netif;
if (p_netif != NULL && netif_is_up(p_netif)) {
netif_create_ip6_linklocal_address(p_netif, 1);
nd6_set_cb(p_netif, esp_netif_nd6_cb);
return ESP_OK;
} else {
return ESP_FAIL;

View File

@ -8,7 +8,7 @@
#include "esp_netif_lwip_internal.h"
#include "esp_netif_lwip_ppp.h"
#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP
#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP)
#include "netif/wlanif.h"
#include "netif/ethernetif.h"

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -12,7 +12,7 @@
#include "lwip/netif.h"
#include "dhcpserver/dhcpserver.h"
#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP
#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP)
struct esp_netif_netstack_lwip_vanilla_config {
err_t (*init_fn)(struct netif*);

View File

@ -36,6 +36,29 @@ typedef struct lwip_peer2peer_ctx {
ppp_pcb *ppp;
} lwip_peer2peer_ctx_t;
#if PPP_SUPPORT && PPP_AUTH_SUPPORT
typedef struct {
struct tcpip_api_call_data call;
ppp_pcb *ppp;
u8_t authtype;
const char *user;
const char *passwd;
} set_auth_msg_t;
static err_t pppapi_do_ppp_set_auth(struct tcpip_api_call_data *m)
{
set_auth_msg_t *msg = (set_auth_msg_t *)m;
ppp_set_auth(msg->ppp, msg->authtype, msg->user, msg->passwd);
return ERR_OK;
}
static void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd)
{
set_auth_msg_t msg = { .ppp = pcb, .authtype = authtype, .user = user, .passwd = passwd};
tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call);
}
#endif // PPP_SUPPORT && PPP_AUTH_SUPPORT
/**
* @brief lwip callback from PPP client used here to produce PPP error related events,
* as well as some IP events

View File

@ -1,22 +1,12 @@
// Copyright 2019 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
// 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.
/*
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _ESP_NETIF_LWIP_PPP_H_
#define _ESP_NETIF_LWIP_PPP_H_
#if CONFIG_ESP_NETIF_TCPIP_LWIP
/**
* @brief Creates new PPP related structure
*
@ -77,7 +67,5 @@ esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related);
*/
void esp_netif_ppp_set_default_netif(netif_related_data_t *netif_related);
#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */
#endif // _ESP_NETIF_LWIP_PPP_H_

View File

@ -5,6 +5,8 @@
*/
#include "esp_wifi.h"
#include "esp_netif.h"
#include "esp_netif_net_stack.h"
#include "netif/wlanif.h"
#include "esp_log.h"
#include "esp_private/wifi.h"
#include "esp_wifi_netif.h"
@ -24,28 +26,6 @@ typedef struct wifi_netif_driver {
static const char* TAG = "wifi_netif";
/**
* @brief Local storage for netif handles and callbacks for specific wifi interfaces
*/
static esp_netif_receive_t s_wifi_rxcbs[MAX_WIFI_IFS] = { NULL };
static esp_netif_t *s_wifi_netifs[MAX_WIFI_IFS] = { NULL };
/**
* @brief WiFi netif driver IO functions, a thin glue layer
* to the original wifi interface API
*/
static esp_err_t wifi_sta_receive(void *buffer, uint16_t len, void *eb)
{
return s_wifi_rxcbs[WIFI_IF_STA](s_wifi_netifs[WIFI_IF_STA], buffer, len, eb);
}
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
static esp_err_t wifi_ap_receive(void *buffer, uint16_t len, void *eb)
{
return s_wifi_rxcbs[WIFI_IF_AP](s_wifi_netifs[WIFI_IF_AP], buffer, len, eb);
}
#endif
static void wifi_free(void *h, void* buffer)
{
if (buffer) {
@ -88,7 +68,6 @@ void esp_wifi_destroy_if_driver(wifi_netif_driver_t h)
if (h) {
esp_wifi_internal_reg_rxcb(h->wifi_if, NULL); // ignore the potential error
// as the wifi might have been already uninitialized
s_wifi_netifs[h->wifi_if] = NULL;
}
free(h);
}
@ -129,7 +108,6 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t
return ESP_ERR_INVALID_ARG;
}
wifi_interface_t wifi_interface = ifx->wifi_if;
s_wifi_rxcbs[wifi_interface] = fn;
wifi_rxcb_t rxcb = NULL;
esp_err_t ret;
@ -137,12 +115,12 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t
{
case WIFI_IF_STA:
rxcb = wifi_sta_receive;
rxcb = wifi_rxcb_sta;
break;
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
case WIFI_IF_AP:
rxcb = wifi_ap_receive;
rxcb = wifi_rxcb_ap;
break;
#endif
@ -155,10 +133,10 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t
return ESP_ERR_NOT_SUPPORTED;
}
s_wifi_netifs[wifi_interface] = ifx->base.netif;
if ((ret = esp_wifi_internal_reg_rxcb(wifi_interface, rxcb)) != ESP_OK) {
ESP_LOGE(TAG, "esp_wifi_internal_reg_rxcb for if=%d failed with %d", wifi_interface, ret);
return ESP_ERR_INVALID_STATE;
}
set_wifi_netif(wifi_interface, esp_netif_get_netif_impl(arg));
return ESP_OK;
}

View File

@ -1,4 +1,5 @@
set(include_dirs
include
include/apps
include/apps/sntp
lwip/src/include
@ -85,7 +86,9 @@ set(srcs
"port/esp32/hooks/lwip_default_hooks.c"
"port/esp32/debug/lwip_debug.c"
"port/esp32/freertos/sys_arch.c"
"port/esp32/netif/wlanif.c")
"port/esp32/sockets_ext.c"
"port/esp32/netif/wlanif.c"
"port/esp32/netif/esp_pbuf_ref.c")
if(CONFIG_LWIP_PPP_SUPPORT)
list(APPEND srcs
@ -159,15 +162,10 @@ idf_component_register(SRCS "${srcs}"
# lots of LWIP source files evaluate macros that check address of stack variables
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-address)
set_source_files_properties(
lwip/src/netif/ppp/ppp.c
PROPERTIES COMPILE_FLAGS
-Wno-uninitialized
)
set_source_files_properties(
lwip/src/netif/ppp/pppos.c
PROPERTIES COMPILE_FLAGS
-Wno-implicit-fallthrough
-Wno-type-limits
)
# "comparison is always false due to limited range of data type" warning
# when setting CONFIG_LWIP_TCP_WND_DEFAULT to 65535

View File

@ -17,7 +17,7 @@
#include "dhcpserver/dhcpserver.h"
#include "dhcpserver/dhcpserver_options.h"
#if ESP_DHCP
#if ESP_DHCPS
#define BOOTP_BROADCAST 0x8000
@ -1419,4 +1419,4 @@ err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver)
}
return ERR_ARG;
}
#endif // ESP_DHCP
#endif // ESP_DHCPS

View File

@ -0,0 +1,27 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stddef.h>
#include_next "lwip/netdb.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop)
{ return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); }
static inline struct hostent *gethostbyname(const char *name)
{ return lwip_gethostbyname(name); }
static inline void freeaddrinfo(struct addrinfo *ai)
{ lwip_freeaddrinfo(ai); }
static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
{ return lwip_getaddrinfo(nodename, servname, hints, res); }
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,56 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include_next "lwip/sockets.h"
#include "sdkconfig.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen)
{ return lwip_accept(s,addr,addrlen); }
static inline int bind(int s,const struct sockaddr *name, socklen_t namelen)
{ return lwip_bind(s,name,namelen); }
static inline int shutdown(int s,int how)
{ return lwip_shutdown(s,how); }
static inline int getpeername(int s,struct sockaddr *name,socklen_t *namelen)
{ return lwip_getpeername(s,name,namelen); }
static inline int getsockname(int s,struct sockaddr *name,socklen_t *namelen)
{ return lwip_getsockname(s,name,namelen); }
static inline int setsockopt(int s,int level,int optname,const void *opval,socklen_t optlen)
{ return lwip_setsockopt(s,level,optname,opval,optlen); }
static inline int getsockopt(int s,int level,int optname,void *opval,socklen_t *optlen)
{ return lwip_getsockopt(s,level,optname,opval,optlen); }
static inline int closesocket(int s)
{ return lwip_close(s); }
static inline int connect(int s,const struct sockaddr *name,socklen_t namelen)
{ return lwip_connect(s,name,namelen); }
static inline int listen(int s,int backlog)
{ return lwip_listen(s,backlog); }
static inline ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{ return lwip_recvmsg(sockfd, msg, flags); }
static inline ssize_t recv(int s,void *mem,size_t len,int flags)
{ return lwip_recv(s,mem,len,flags); }
static inline ssize_t recvfrom(int s,void *mem,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen)
{ return lwip_recvfrom(s,mem,len,flags,from,fromlen); }
static inline ssize_t send(int s,const void *dataptr,size_t size,int flags)
{ return lwip_send(s,dataptr,size,flags); }
static inline ssize_t sendmsg(int s,const struct msghdr *message,int flags)
{ return lwip_sendmsg(s,message,flags); }
static inline ssize_t sendto(int s,const void *dataptr,size_t size,int flags,const struct sockaddr *to,socklen_t tolen)
{ return lwip_sendto(s,dataptr,size,flags,to,tolen); }
static inline int socket(int domain,int type,int protocol)
{ return lwip_socket(domain,type,protocol); }
static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
{ return lwip_inet_ntop(af, src, dst, size); }
static inline int inet_pton(int af, const char *src, void *dst)
{ return lwip_inet_pton(af, src, dst); }
#ifdef __cplusplus
}
#endif

View File

@ -46,7 +46,6 @@ entries:
etharp:etharp_output_to_arp_index (noflash_text)
etharp:etharp_output (noflash_text)
ip4_addr:ip4_addr_isbroadcast_u32 (noflash_text)
ip4:ip4_route_src_hook (noflash_text)
ip4:ip4_route_src (noflash_text)
ip4:ip4_route (noflash_text)
ip4:ip4_input (noflash_text)
@ -62,6 +61,8 @@ entries:
pbuf:pbuf_header_impl (noflash_text)
pbuf:pbuf_header (noflash_text)
pbuf:pbuf_free (noflash_text)
pbuf:pbuf_alloced_custom (noflash_text)
pbuf:pbuf_init_alloced_pbuf (noflash_text)
udp:udp_input_local_match (noflash_text)
udp:udp_input (noflash_text)
udp:udp_send (noflash_text)
@ -79,8 +80,12 @@ entries:
sys_arch:sys_arch_mbox_fetch (noflash_text)
ethernetif:ethernet_low_level_output (noflash_text)
ethernetif:ethernetif_input (noflash_text)
wlanif:low_level_output (noflash_text)
wlanif:wlanif_input (noflash_text)
wlanif:sta_output (noflash_text)
wlanif:ap_output (noflash_text)
wlanif:wifi_rxcb_sta (noflash_text)
wlanif:wifi_rxcb_ap (noflash_text)
wlanif:wifi_pbuf_free (noflash_text)
lwip_default_hooks:ip4_route_src_hook (noflash_text)
if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y:
* (extram_bss)

@ -1 +1 @@
Subproject commit 76303df2386902e0d7873be4217f1d9d1b50f982
Subproject commit 2e7efc486e6d90dfe8a6f058682375870c05071f

View File

@ -53,6 +53,7 @@ static sys_mutex_t g_lwip_protect_mutex = NULL;
static pthread_key_t sys_thread_sem_key;
static void sys_thread_sem_free(void* data);
sys_thread_t g_lwip_task;
#if !LWIP_COMPAT_MUTEX
@ -427,6 +428,11 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize
ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task,
CONFIG_LWIP_TCPIP_TASK_AFFINITY);
g_lwip_task = rtos_task;
LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n",
(u32_t)g_lwip_task,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE));
if (ret != pdTRUE) {
return NULL;
}

View File

@ -5,6 +5,10 @@
*/
#include "lwip_default_hooks.h"
#include "lwip/prot/dhcp.h"
#include "lwip/dhcp.h"
#include "lwip/prot/iana.h"
#include <string.h>
#define __weak __attribute__((weak))
@ -50,3 +54,219 @@ int __weak lwip_hook_ip6_input(struct pbuf *p, struct netif *inp)
return 0;
}
#endif
#ifdef LWIP_HOOK_IP4_ROUTE_SRC
#if ESP_IP4_ROUTE
#include "lwip/netif.h"
bool ip4_netif_exist(const ip4_addr_t *src, const ip4_addr_t *dest)
{
struct netif *netif = NULL;
for (netif = netif_list; netif != NULL; netif = netif->next) {
/* is the netif up, does it have a link and a valid address? */
if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
/* source netif and dest netif match? */
if (ip4_addr_netcmp(src, netif_ip4_addr(netif), netif_ip4_netmask(netif)) || ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) {
/* return false when both netif don't match */
return true;
}
}
}
return false;
}
/**
* Source based IPv4 routing hook function.
*/
struct netif *
ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest)
{
struct netif *netif = NULL;
/* destination IP is broadcast IP? */
if ((src != NULL) && !ip4_addr_isany(src)) {
/* iterate through netifs */
for (netif = netif_list; netif != NULL; netif = netif->next) {
/* is the netif up, does it have a link and a valid address? */
if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) {
/* source IP matches? */
if (ip4_addr_cmp(src, netif_ip4_addr(netif))) {
/* return netif on which to forward IP packet */
return netif;
}
}
}
}
return netif;
}
#endif
#endif /* LWIP_HOOK_IP4_ROUTE_SRC */
#define LWIP_DHCP_ENABLE_MTU_UPDATE 1
#define LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
#define LWIP_DHCP_ENABLE_CLIENT_ID !ESP_DHCP_DISABLE_CLIENT_ID
#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS
#define DHCP_OPTION_VSI 43
#define DHCP_OPTION_VCI 60
#define DHCP_OPTION_VSI_MAX 16
static u8_t vendor_class_len = 0;
static char *vendor_class_buf = NULL;
static u32_t dhcp_option_vsi[DHCP_OPTION_VSI_MAX] = {0};
void dhcp_free_vendor_class_identifier(void)
{
mem_free(vendor_class_buf);
}
int dhcp_get_vendor_specific_information(uint8_t len, char * str)
{
u8_t copy_len = 0;
if (len == 0 || str == NULL) {
return ERR_ARG;
}
copy_len = LWIP_MIN(len, sizeof(dhcp_option_vsi));
memcpy(str, dhcp_option_vsi, copy_len);
return ERR_OK;
}
int dhcp_set_vendor_class_identifier(uint8_t len, const char * str)
{
if (len == 0 || str == NULL) {
return ERR_ARG;
}
if (vendor_class_buf && vendor_class_len != len) {
mem_free(vendor_class_buf);
vendor_class_buf = NULL;
}
if (!vendor_class_buf) {
vendor_class_buf = (char *)mem_malloc(len + 1);
if (vendor_class_buf == NULL) {
return ERR_MEM;
}
vendor_class_len = len;
}
memcpy(vendor_class_buf, str, len);
return ERR_OK;
}
#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */
void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset)
{
LWIP_UNUSED_ARG(dhcp);
LWIP_UNUSED_ARG(state);
LWIP_UNUSED_ARG(option);
LWIP_UNUSED_ARG(len);
LWIP_UNUSED_ARG(p);
LWIP_UNUSED_ARG(offset);
#if LWIP_DHCP_ENABLE_MTU_UPDATE
if ((option == DHCP_OPTION_MTU) &&
(state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING ||
state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING)) {
u32_t mtu = 0;
struct netif *netif;
LWIP_ERROR("dhcp_parse_extra_opts(): MTU option's len != 2", len == 2, return;);
LWIP_ERROR("dhcp_parse_extra_opts(): extracting MTU option failed",
pbuf_copy_partial(p, &mtu, 2, offset) == 2, return;);
mtu = lwip_htons((u16_t)mtu);
NETIF_FOREACH(netif) {
/* find the netif related to this dhcp */
if (dhcp == netif_dhcp_data(netif)) {
if (mtu < netif->mtu) {
netif->mtu = mtu;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_parse_extra_opts(): Negotiated netif MTU is %d\n", netif->mtu));
}
return;
}
}
} /* DHCP_OPTION_MTU */
#endif /* LWIP_DHCP_ENABLE_MTU_UPDATE */
#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS
if ((option == DHCP_OPTION_VSI) &&
(state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING ||
state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING || state == DHCP_STATE_SELECTING)) {
u8_t n;
u32_t value;
u16_t copy_len;
for (n = 0; n < DHCP_OPTION_VSI_MAX && len > 0; n++) {
copy_len = LWIP_MIN(len, 4);
LWIP_ERROR("dhcp_parse_extra_opts(): extracting VSI option failed",
pbuf_copy_partial(p, &value, copy_len, offset) == copy_len, return;);
dhcp_option_vsi[n] = lwip_htonl(value);
len -= copy_len;
}
} /* DHCP_OPTION_VSI */
#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */
}
void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len)
{
LWIP_UNUSED_ARG(netif);
LWIP_UNUSED_ARG(state);
LWIP_UNUSED_ARG(msg_out);
LWIP_UNUSED_ARG(options_out_len);
#if LWIP_DHCP_ENABLE_CLIENT_ID
if (state == DHCP_STATE_RENEWING || state == DHCP_STATE_REBINDING ||
state == DHCP_STATE_REBOOTING || state == DHCP_STATE_OFF ||
state == DHCP_STATE_REQUESTING || state == DHCP_STATE_BACKING_OFF || state == DHCP_STATE_SELECTING) {
size_t i;
u8_t *options = msg_out->options + *options_out_len;
LWIP_ERROR("dhcp_append(client_id): options_out_len + 3 + netif->hwaddr_len <= DHCP_OPTIONS_LEN",
*options_out_len + 3U + netif->hwaddr_len <= DHCP_OPTIONS_LEN, return;);
*options_out_len = *options_out_len + netif->hwaddr_len + 3;
*options++ = DHCP_OPTION_CLIENT_ID;
*options++ = netif->hwaddr_len + 1; /* option size */
*options++ = LWIP_IANA_HWTYPE_ETHERNET;
for (i = 0; i < netif->hwaddr_len; i++) {
*options++ = netif->hwaddr[i];
}
}
#endif /* LWIP_DHCP_ENABLE_CLIENT_ID */
#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS
if (state == DHCP_STATE_RENEWING || state == DHCP_STATE_REBINDING ||
state == DHCP_STATE_REBOOTING || state == DHCP_STATE_OFF ||
state == DHCP_STATE_REQUESTING || state == DHCP_STATE_BACKING_OFF || state == DHCP_STATE_SELECTING) {
size_t i;
const char *p = NULL;
u8_t len = 0;
if (vendor_class_buf && vendor_class_len) {
p = vendor_class_buf;
len = vendor_class_len;
} else {
#if LWIP_NETIF_HOSTNAME
size_t namelen;
if (netif->hostname != NULL && (namelen = strlen(netif->hostname)) < 0xff) {
p = netif->hostname;
len = (u8_t)namelen;
}
#endif /* LWIP_NETIF_HOSTNAME */
}
LWIP_ERROR("dhcp_append(vci): options_out_len + 3 + vci_size <= DHCP_OPTIONS_LEN",
*options_out_len + 3U + len <= DHCP_OPTIONS_LEN, return;);
if (p) {
u8_t *options = msg_out->options + *options_out_len;
*options_out_len = *options_out_len + len + 3;
*options++ = DHCP_OPTION_VCI;
*options++ = len;
for (i = 0; i < len; i ++) {
*options++ = p[i];
}
}
return;
}
#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */
}

View File

@ -4,12 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _LWIP_DEFAULT_HOOKS_H_
#define _LWIP_DEFAULT_HOOKS_H_
#ifndef LWIP_ESP_DEFAULT_HOOKS_H_
#define LWIP_ESP_DEFAULT_HOOKS_H_
#include "lwip/ip_addr.h"
#include "lwip/arch.h"
#include "lwip/err.h"
#include "lwip/pbuf.h"
#include "netif/dhcp_state.h"
#ifdef ESP_IDF_LWIP_HOOK_FILENAME
#include ESP_IDF_LWIP_HOOK_FILENAME
@ -53,8 +54,22 @@ int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp);
#define LWIP_HOOK_IP6_INPUT lwip_hook_ip6_input
#endif /* CONFIG_LWIP_HOOK_IP6_INPUT_CUSTIOM... */
struct netif *
ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest);
struct dhcp;
struct netif;
struct dhcp_msg;
void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset);
void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len);
int dhcp_set_vendor_class_identifier(uint8_t len, const char * str);
int dhcp_get_vendor_specific_information(uint8_t len, char * str);
void dhcp_free_vendor_class_identifier(void);
#ifdef __cplusplus
}
#endif
#endif /* _LWIP_DEFAULT_HOOKS_H_ */
#endif /* LWIP_ESP_DEFAULT_HOOKS_H_ */

View File

@ -16,15 +16,20 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/select.h>
#include "netif/dhcp_state.h"
#include "sntp/sntp_get_set_time.h"
#include <sys/poll.h>
#ifdef __linux__
#include "esp32_mock.h"
#else
#include "esp_task.h"
#include "esp_random.h"
#endif // __linux__
#include "sdkconfig.h"
#include "sntp/sntp_get_set_time.h"
#include "sockets_ext.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
-----------------------------------------------
@ -302,13 +307,19 @@
* is restored after reset/power-up.
*/
#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP
#define LWIP_DHCP_IP_ADDR_RESTORE() dhcp_ip_addr_restore(netif)
#define LWIP_DHCP_IP_ADDR_STORE() dhcp_ip_addr_store(netif)
#define LWIP_DHCP_IP_ADDR_ERASE(esp_netif) dhcp_ip_addr_erase(esp_netif)
/*
* Make the post-init hook check if we could restore the previously bound address
* - if yes reset the state to bound and mark result as ERR_OK (which skips discovery state)
* - if no, return false to continue normally to the discovery state
*/
#define LWIP_HOOK_DHCP_POST_INIT(netif, result) \
(dhcp_ip_addr_restore(netif) ? ( dhcp_set_state(dhcp, DHCP_STATE_BOUND), \
dhcp_network_changed(netif), \
(result) = ERR_OK , \
true ) : \
false)
#else
#define LWIP_DHCP_IP_ADDR_RESTORE() 0
#define LWIP_DHCP_IP_ADDR_STORE()
#define LWIP_DHCP_IP_ADDR_ERASE(esp_netif)
#define LWIP_HOOK_DHCP_PRE_DISCOVERY(netif, result) (false)
#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */
/**
@ -327,6 +338,38 @@
*/
#define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID
#define DHCP_DEFINE_CUSTOM_TIMEOUTS 1
#define DHCP_COARSE_TIMER_SECS (1)
#define DHCP_NEXT_TIMEOUT_THRESHOLD (3)
/* Since for embedded devices it's not that hard to miss a discover packet, so lower
* the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s.
*/
#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) (( (tries) < 6 ? 1 << (tries) : 60) * 250)
static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
{
uint32_t timeout = lease;
if (timeout == 0) {
timeout = min;
}
return timeout;
}
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) \
timeout_from_offered((dhcp)->offered_t0_lease, 120)
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) \
timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ )
#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \
timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ )
#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \
do { LWIP_UNUSED_ARG(msg); \
dhcp_parse_extra_opts(dhcp, state, option, len, pbuf, offset); \
} while(0)
#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) \
dhcp_append_extra_opts(netif, state, msg, options_len_ptr);
/*
------------------------------------
---------- AUTOIP options ----------
@ -589,6 +632,15 @@
#define LWIP_NETIF_STATUS_CALLBACK 0
#endif
/**
* LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function
* for several netif related event that supports multiple subscribers.
*
* This ext-callback is used by ESP-NETIF with lwip-orig (upstream version)
* to provide netif related events on IP4/IP6 address/status changes
*/
#define LWIP_NETIF_EXT_STATUS_CALLBACK 1
/**
* LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data
* to be sent into one single pbuf. This is for compatibility with DMA-enabled
@ -790,7 +842,7 @@
* While this helps code completion, it might conflict with existing libraries.
* (only used if you use sockets.c)
*/
#define LWIP_COMPAT_SOCKETS 1
#define LWIP_COMPAT_SOCKETS 0
/**
* LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names.
@ -1111,6 +1163,11 @@
#endif
#define LWIP_HOOK_FILENAME "lwip_default_hooks.h"
#define LWIP_HOOK_IP4_ROUTE_SRC ip4_route_src_hook
#define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) \
lwip_getsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false
#define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) \
lwip_setsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false
/*
---------------------------------------
@ -1311,6 +1368,8 @@
#ifdef CONFIG_LWIP_TIMERS_ONDEMAND
#define ESP_LWIP_IGMP_TIMERS_ONDEMAND 1
#define ESP_LWIP_MLD6_TIMERS_ONDEMAND 1
#define LWIP_NUM_SYS_TIMEOUT_INTERNAL_WOUT_IGMP_MLD6 (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS)))
#define MEMP_NUM_SYS_TIMEOUT LWIP_NUM_SYS_TIMEOUT_INTERNAL_WOUT_IGMP_MLD6
#else
#define ESP_LWIP_IGMP_TIMERS_ONDEMAND 0
#define ESP_LWIP_MLD6_TIMERS_ONDEMAND 0
@ -1346,7 +1405,7 @@
#define ESP_LWIP_SELECT 1
#define ESP_LWIP_LOCK 1
#define ESP_THREAD_PROTECTION 1
#define ESP_IP_FORWARD 1
#define LWIP_SUPPORT_CUSTOM_PBUF 1
/*
-----------------------------------------
@ -1365,4 +1424,29 @@
#endif /* CONFIG_LWIP_DHCPS */
#if LWIP_NETCONN_SEM_PER_THREAD
#if ESP_THREAD_SAFE
#define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem_get()
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_thread_sem_init()
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_thread_sem_deinit()
#endif
#endif
/**
* If CONFIG_ALLOC_MEMORY_IN_SPIRAM_FIRST is enabled, Try to
* allocate memory for lwip in SPIRAM firstly. If failed, try to allocate
* internal memory then.
*/
#if CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP
#define mem_clib_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#define mem_clib_calloc(n, size) heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL)
#else /* !CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP */
#define mem_clib_malloc malloc
#define mem_clib_calloc calloc
#endif /* CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP */
#ifdef __cplusplus
}
#endif
#endif /* LWIP_HDR_ESP_LWIPOPTS_H */

View File

@ -4,24 +4,24 @@
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _DHCP_STATE_H_
#define _DHCP_STATE_H_
#ifndef LWIP_ESP_DHCP_STATE_H
#define LWIP_ESP_DHCP_STATE_H
#include <stdbool.h>
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
bool dhcp_ip_addr_restore(void *netif);
bool dhcp_ip_addr_restore(struct netif *netif);
void dhcp_ip_addr_store(void *netif);
void dhcp_ip_addr_store(struct netif *netif);
void dhcp_ip_addr_erase(void *esp_netif);
void dhcp_ip_addr_erase(struct netif *netif);
#ifdef __cplusplus
}
#endif
#endif /* _DHCP_STATE_H_ */
#endif /* LWIP_ESP_DHCP_STATE_H */

View File

@ -0,0 +1,32 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file esp_pbuf reference interface file
*/
#ifndef __LWIP_ESP_PBUF_REF_H__
#define __LWIP_ESP_PBUF_REF_H__
#include <stddef.h>
#include "lwip/pbuf.h"
#include "esp_netif.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Allocate custom pbuf containing pointer to a private l2-free function
*
* @note pbuf_free() will deallocate this custom pbuf and call the driver assigned free function
*/
struct pbuf* esp_pbuf_allocate(esp_netif_t *esp_netif, void *buffer, size_t len, void *l2_buff);
#ifdef __cplusplus
}
#endif
#endif //__LWIP_ESP_PBUF_REF_H__

View File

@ -1,16 +1,8 @@
// Copyright 2015-2016 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
// 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.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _WLAN_LWIP_IF_H_
@ -19,13 +11,19 @@
#include "esp_wifi.h"
#include "lwip/err.h"
#include "lwip/netif.h"
#ifdef __cplusplus
extern "C" {
#endif
err_t wlanif_init_ap(struct netif *netif);
err_t wlanif_init_sta(struct netif *netif);
err_t set_wifi_netif(int wifi_inx, void* netif);
esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *l2_buff);
esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *l2_buff);
void wlanif_input(void *netif, void *buffer, size_t len, void* eb);
err_t wlanif_init(struct netif *netif);

View File

@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define IPV6_MULTICAST_IF 0x300
#define IPV6_MULTICAST_HOPS 0x301
#define IPV6_MULTICAST_LOOP 0x302
struct lwip_sock;
bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, uint32_t optlen, int *err);
bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err);
#ifdef __cplusplus
}
#endif

View File

@ -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);
}
}

View 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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "lwip/sockets.h"
#include "lwip/priv/sockets_priv.h"
#include "lwip/api.h"
#include "lwip/sys.h"
#include "lwip/tcp.h"
#include "lwip/raw.h"
#include "lwip/udp.h"
#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \
if (((optlen) < sizeof(opttype)) || ((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { *err=EINVAL; goto exit; } }while(0)
#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \
if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { *err=ENOPROTOOPT; goto exit; } } while(0)
bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, socklen_t optlen, int *err)
{
#if LWIP_IPV6
if (level != IPPROTO_IPV6)
#endif /* LWIP_IPV6 */
{
return false;
}
#if LWIP_IPV6
switch (optname) {
default:
return false;
case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this takes an IP not an index */
{
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
udp_set_multicast_netif_index(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval));
}
break;
case IPV6_MULTICAST_HOPS:
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval));
break;
case IPV6_MULTICAST_LOOP:
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP);
if (*(const u8_t*)optval) {
udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP);
} else {
udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP);
}
break;
}
exit:
return true;
#endif /* LWIP_IPV6 */
}
bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err)
{
#if LWIP_IPV6
if (level != IPPROTO_IPV6)
#endif /* LWIP_IPV6 */
{
return false;
}
#if LWIP_IPV6
switch (optname) {
default:
return false;
case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this returns an IP not an index */
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
*err = ENOPROTOOPT;
goto exit;
}
*(u8_t*)optval = udp_get_multicast_netif_index(sock->conn->pcb.udp);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IPV6_MULTICAST_IF) = 0x%"X32_F"\n",
*(u32_t *)optval));
break;
case IPV6_MULTICAST_HOPS:
printf("IPV6_MULTICAST_HOPS\n");
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) {
*err = ENOPROTOOPT;
goto exit;
}
*(u8_t*)optval = udp_get_multicast_ttl(sock->conn->pcb.udp);
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n",
*(int *)optval));
break;
case IPV6_MULTICAST_LOOP:
LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t);
if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_MULTICAST_LOOP) != 0) {
*(u8_t*)optval = 1;
} else {
*(u8_t*)optval = 0;
}
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n",
*(int *)optval));
break;
}
exit:
return true;
#endif /* LWIP_IPV6 */
}

View File

@ -1,16 +1,8 @@
// Copyright 2017 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
//
// 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.
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <stdbool.h>
@ -32,6 +24,15 @@ _Static_assert(MAX_FDS >= CONFIG_LWIP_MAX_SOCKETS, "MAX_FDS < CONFIG_LWIP_MAX_SO
#ifdef CONFIG_VFS_SUPPORT_SELECT
/**
* @brief This function is implemented only in FreeRTOS port (ingroup sys_sem)
* and has no official API counterpart in lwip's sys.h declarations
* Signals a semaphore from ISR
* @param sem the semaphore to signal
* @return 1 if the signal has caused a high-prio task to unblock (pxHigherPriorityTaskWoken)
*/
int sys_sem_signal_isr(sys_sem_t *sem);
static void lwip_stop_socket_select(void *sem)
{
sys_sem_signal(sem); //socket_select will return

View File

@ -301,3 +301,11 @@ uint32_t esp_random(void)
// Preparation for injecting favorable random numbers
return g_random_numbers[g_random_numbers_cnt++ % 8];
}
void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset)
{
}
void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len)
{
}

View File

@ -1 +1,2 @@
CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=n
CONFIG_FREERTOS_SMP=n

View File

@ -12,7 +12,8 @@
struct ifreq ifr; \
ifr.ifr_name[0] = 'l'; \
ifr.ifr_name[1] = 'o'; \
ifr.ifr_name[2] = '\0';
ifr.ifr_name[2] = '0'; \
ifr.ifr_name[3] = '\0';
static void tcp_transport_keepalive_test(esp_transport_handle_t transport_under_test, bool async, esp_transport_keep_alive_t *config)

View File

@ -8,7 +8,7 @@ The behaviour of the example is:
* Listens to specified multicast addresses (one IPV4 and/or one IPV6).
* Print any UDP packets received as ASCII text.
* If no packets are received it will periodicially (after 2.5 seconds) send its own plaintext packet(s) to the multicast address(es).
* If no packets are received it will periodically (after 2.5 seconds) send its own plaintext packet(s) to the multicast address(es).
## Configuration

View File

@ -417,8 +417,12 @@ static void mcast_example_task(void *pvParameters)
#ifdef CONFIG_EXAMPLE_IPV4_ONLY
hints.ai_family = AF_INET; // For an IPv4 socket
#else
#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP // Resolving IPv4 mapped IPv6 addresses is supported only in the official TCPIP_LWIP stack (esp-lwip)
hints.ai_family = AF_INET6; // For an IPv4 socket with V4 mapped addresses
hints.ai_flags |= AI_V4MAPPED;
#endif // CONFIG_ESP_NETIF_TCPIP_LWIP
#endif
int err = getaddrinfo(CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR,
NULL,

View File

@ -475,7 +475,6 @@ components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c
components/esp_netif/include/esp_netif_ppp.h
components/esp_netif/include/esp_netif_slip.h
components/esp_netif/loopback/esp_netif_loopback.c
components/esp_netif/lwip/esp_netif_lwip_ppp.h
components/esp_netif/lwip/esp_netif_lwip_slip.c
components/esp_netif/lwip/esp_netif_lwip_slip.h
components/esp_netif/private_include/esp_netif_private.h
@ -956,16 +955,12 @@ components/lwip/port/esp32/include/debug/lwip_debug.h
components/lwip/port/esp32/include/netdb.h
components/lwip/port/esp32/include/netif/ethernetif.h
components/lwip/port/esp32/include/netif/openthreadif.h
components/lwip/port/esp32/include/netif/wlanif.h
components/lwip/port/esp32/include/netinet/in.h
components/lwip/port/esp32/include/netinet/tcp.h
components/lwip/port/esp32/include/sntp/sntp_get_set_time.h
components/lwip/port/esp32/include/sys/socket.h
components/lwip/port/esp32/netif/dhcp_state.c
components/lwip/port/esp32/netif/ethernetif.c
components/lwip/port/esp32/netif/wlanif.c
components/lwip/port/esp32/no_vfs_syscalls.c
components/lwip/port/esp32/vfs_lwip.c
components/lwip/test_afl_host/dhcp_di.h
components/lwip/test_afl_host/dhcpserver_di.h
components/lwip/test_afl_host/dns_di.h

View File

@ -28,7 +28,11 @@ components/esp32/include/esp32/cache_err_int.h
components/driver/include/driver/sdmmc_defs.h
components/driver/include/driver/sdmmc_types.h
# LWIP: sockets.h uses #include_next<>, which doesn't work correctly with the checker
# memp_std.h is supposed to be included multiple times with different settings
components/lwip/lwip/src/include/lwip/priv/memp_std.h
components/lwip/include/lwip/sockets.h
components/lwip/lwip/src/include/lwip/prot/nd6.h
components/esp_phy/esp32/include/phy_init_data.h
@ -101,8 +105,6 @@ components/esp_common/include/esp_compiler.h
### To be fixed: headers that rely on implicit inclusion
#
components/lwip/lwip/src/include/lwip/prot/nd6.h
components/lwip/port/esp32/include/netif/dhcp_state.h
components/soc/src/esp32/rtc_clk_common.h
components/esp_rom/include/esp32/rom/sha.h
components/esp_rom/include/esp32/rom/secure_boot.h
@ -142,6 +144,5 @@ components/fatfs/diskio/diskio_sdmmc.h
components/openssl/include/openssl/ssl.h
components/ulp/include/ulp_common.h
components/ulp/include/esp32s2/ulp_riscv.h
components/lwip/include/apps/sntp/sntp.h
components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h
components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h