mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-21 17:16:29 +08:00
feat(lwip): update lwip component from idf
This commit is contained in:
@ -217,6 +217,7 @@ coap_free_endpoint(coap_endpoint_t *ep) {
|
||||
/* define struct in6_pktinfo and struct in_pktinfo if not available
|
||||
FIXME: check with configure
|
||||
*/
|
||||
#if 0 //update lwip and have conflict. Later will update COAP.
|
||||
struct in6_pktinfo {
|
||||
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
|
||||
unsigned int ipi6_ifindex; /* send/recv interface index */
|
||||
@ -228,6 +229,7 @@ struct in_pktinfo {
|
||||
struct in_addr ipi_addr;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WITH_POSIX) && !defined(SOL_IP)
|
||||
/* Solaris expects level IPPROTO_IP for ancillary data. */
|
||||
|
@ -26,7 +26,7 @@
|
||||
#define HAVE_MALLOC
|
||||
#define HAVE_ARPA_INET_H
|
||||
|
||||
#define IP_PKTINFO IP_MULTICAST_IF
|
||||
//#define IP_PKTINFO IP_MULTICAST_IF
|
||||
#define IPV6_PKTINFO IPV6_V6ONLY
|
||||
|
||||
#define PACKAGE_NAME "libcoap-posix"
|
||||
|
@ -49,6 +49,8 @@ extern int wifi_nvs_init(void);
|
||||
extern esp_err_t esp_pthread_init(void);
|
||||
extern void phy_get_bb_evm(void);
|
||||
extern void uart_div_modify(uint8_t uart_no, uint16_t DivLatchValue);
|
||||
/*Only for calling esp_wifi_set_ps can compile successfully */
|
||||
uint32_t LwipTimOutLim = 0;
|
||||
|
||||
static inline int should_load(uint32_t load_addr)
|
||||
{
|
||||
|
@ -40,7 +40,7 @@
|
||||
#define ESP_TASKD_EVENT_PRIO (ESP_TASK_PRIO_MAX - 5)
|
||||
#define ESP_TASKD_EVENT_STACK (CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE)
|
||||
#define ESP_TASK_TCPIP_PRIO (ESP_TASK_PRIO_MAX - 7)
|
||||
#define ESP_TASK_TCPIP_STACK (CONFIG_LWIP_TCPIP_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE)
|
||||
#define ESP_TASK_TCPIP_STACK (CONFIG_LWIP_TCPIP_TASK_STACK_SIZE)
|
||||
#define ESP_TASK_MAIN_PRIO (ESP_TASK_PRIO_MIN + 1)
|
||||
#define ESP_TASK_MAIN_STACK (CONFIG_ESP_MAIN_TASK_STACK_SIZE + TASK_EXTRA_STACK_SIZE)
|
||||
|
||||
|
@ -16,6 +16,10 @@ config FREERTOS_ENABLE_REENT
|
||||
|
||||
The configuration will enable newlib.
|
||||
|
||||
config FREERTOS_NO_AFFINITY
|
||||
hex
|
||||
default 0x7FFFFFFF
|
||||
|
||||
config FREERTOS_HZ
|
||||
int "Tick rate (Hz)"
|
||||
range 1 1000
|
||||
|
@ -1,13 +1,15 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
set(include_dirs
|
||||
include/apps
|
||||
include/apps/sntp
|
||||
lwip/src/include
|
||||
port/esp32/include
|
||||
port/esp32/include/arch
|
||||
port/${target}/include
|
||||
port/${target}/include/arch
|
||||
)
|
||||
|
||||
set(srcs
|
||||
"apps/dhcpserver/dhcpserver.c"
|
||||
"apps/multi-threads/sockets_mt.c"
|
||||
"apps/ping/esp_ping.c"
|
||||
"apps/ping/ping.c"
|
||||
"apps/ping/ping_sock.c"
|
||||
@ -85,12 +87,16 @@ set(srcs
|
||||
"lwip/src/netif/ppp/upap.c"
|
||||
"lwip/src/netif/ppp/utils.c"
|
||||
"lwip/src/netif/ppp/vj.c"
|
||||
"port/esp32/vfs_lwip.c"
|
||||
"port/esp32/debug/lwip_debug.c"
|
||||
"port/esp32/freertos/sys_arch.c"
|
||||
"port/esp32/netif/dhcp_state.c"
|
||||
"port/esp32/netif/nettestif.c"
|
||||
"port/esp32/netif/wlanif.c")
|
||||
"port/${target}/vfs_lwip.c"
|
||||
"port/${target}/debug/lwip_debug.c"
|
||||
"port/${target}/freertos/sys_arch.c"
|
||||
"port/${target}/netif/dhcp_state.c"
|
||||
"port/${target}/netif/wlanif.c")
|
||||
|
||||
if(CONFIG_IDF_TARGET_ESP32)
|
||||
list(APPEND srcs
|
||||
"port/${target}/netif/nettestif.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_LWIP_PPP_SUPPORT)
|
||||
list(APPEND srcs
|
||||
@ -130,11 +136,15 @@ if(CONFIG_ETH_ENABLED)
|
||||
list(APPEND srcs "port/esp32/netif/ethernetif.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_LWIP_SOCKET_MULTITHREAD)
|
||||
set(COMPONENT_OBJEXCLUDE lwip/src/api/sockets.c)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "${include_dirs}"
|
||||
LDFRAGMENTS linker.lf
|
||||
REQUIRES vfs esp_wifi
|
||||
PRIV_REQUIRES ${priv_requires} esp_eth tcpip_adapter nvs_flash)
|
||||
REQUIRES vfs
|
||||
PRIV_REQUIRES ${priv_requires} tcpip_adapter nvs_flash)
|
||||
|
||||
# lots of LWIP source files evaluate macros that check address of stack variables
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-address)
|
||||
|
@ -124,6 +124,24 @@ menu "LWIP"
|
||||
help
|
||||
Enabling this option allows LWIP statistics
|
||||
|
||||
config LWIP_SOCKET_MULTITHREAD
|
||||
bool "LWIP socket supports multithread"
|
||||
default y
|
||||
help
|
||||
Enable the option can enable LWIP socket multithread and all
|
||||
function will be thread safe.
|
||||
|
||||
config SET_SOLINGER_DEFAULT
|
||||
bool "set socket SO_LINGER default"
|
||||
default y
|
||||
depends on LWIP_SOCKET_MULTITHREAD
|
||||
help
|
||||
The function is only used by socket multi-thread.
|
||||
|
||||
Enable this option can set the target socket to enable the "SO_LINGER" and config timeout to be "0" when it is created.
|
||||
It means that if close the socket, all send queue will be dropped, so heap memory can be collected immediately,
|
||||
but some packets which are waiting to be sent will lost.
|
||||
|
||||
config LWIP_ETHARP_TRUST_IP_MAC
|
||||
bool "Enable LWIP ARP trust"
|
||||
default n
|
||||
@ -484,7 +502,7 @@ menu "LWIP"
|
||||
|
||||
config LWIP_TCPIP_TASK_STACK_SIZE
|
||||
int "TCP/IP Task Stack Size"
|
||||
default 3072
|
||||
default 2048
|
||||
# for high log levels, tcpip_adapter API calls can end up
|
||||
# a few calls deep and logging there can trigger a stack overflow
|
||||
range 2048 65536 if LOG_DEFAULT_LEVEL < 4
|
||||
@ -593,6 +611,12 @@ menu "LWIP"
|
||||
|
||||
endmenu # LWIP RAW API
|
||||
|
||||
config LWIP_IPV6
|
||||
bool "Enable IPv6"
|
||||
default n
|
||||
help
|
||||
Enable IPV6
|
||||
|
||||
menu "SNTP"
|
||||
|
||||
config LWIP_DHCP_MAX_NTP_SERVERS
|
||||
|
826
components/lwip/apps/multi-threads/sockets_mt.c
Normal file
826
components/lwip/apps/multi-threads/sockets_mt.c
Normal file
@ -0,0 +1,826 @@
|
||||
// Copyright 2018-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.
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#ifdef SOCKETS_MT
|
||||
|
||||
#define SOCKETS_MT_DISABLE_SHUTDOWN
|
||||
|
||||
#include "lwip/priv/api_msg.h"
|
||||
|
||||
/* disable all LWIP socket API when compiling LWIP raw socket */
|
||||
|
||||
#undef lwip_accept
|
||||
#undef lwip_bind
|
||||
#undef lwip_shutdown
|
||||
#undef lwip_getpeername
|
||||
#undef lwip_getsockname
|
||||
#undef lwip_setsockopt
|
||||
#undef lwip_getsockopt
|
||||
#undef lwip_close
|
||||
#undef lwip_connect
|
||||
#undef lwip_listen
|
||||
#undef lwip_recv
|
||||
#undef lwip_recvfrom
|
||||
#undef lwip_send
|
||||
#undef lwip_sendmsg
|
||||
#undef lwip_sendto
|
||||
#undef lwip_socket
|
||||
#undef lwip_select
|
||||
#undef lwip_ioctlsocket
|
||||
|
||||
#define lwip_accept lwip_accept_esp
|
||||
#define lwip_bind lwip_bind_esp
|
||||
#define lwip_shutdown lwip_shutdown_esp
|
||||
#define lwip_getpeername lwip_getpeername_esp
|
||||
#define lwip_getsockname lwip_getsockname_esp
|
||||
#define lwip_setsockopt lwip_setsockopt_esp
|
||||
#define lwip_getsockopt lwip_getsockopt_esp
|
||||
#define lwip_close lwip_closesocket_esp
|
||||
#define lwip_connect lwip_connect_esp
|
||||
#define lwip_listen lwip_listen_esp
|
||||
#define lwip_recv lwip_recv_esp
|
||||
#define lwip_recvfrom lwip_recvfrom_esp
|
||||
#define lwip_send lwip_send_esp
|
||||
#define lwip_sendmsg lwip_sendmsg_esp
|
||||
#define lwip_sendto lwip_sendto_esp
|
||||
#define lwip_socket lwip_socket_esp
|
||||
#define lwip_select lwip_select_esp
|
||||
#define lwip_ioctlsocket lwip_ioctl_esp
|
||||
|
||||
#undef lwip_read
|
||||
#undef lwip_write
|
||||
#undef lwip_writev
|
||||
#undef lwip_close
|
||||
#undef closesocket
|
||||
#undef lwip_fcntl
|
||||
#undef lwip_ioctl
|
||||
|
||||
#define lwip_read lwip_read_esp
|
||||
#define lwip_write lwip_write_esp
|
||||
#define lwip_writev lwip_writev_esp
|
||||
#define lwip_close lwip_close_esp
|
||||
#define lwip_fcntl lwip_fcntl_esp
|
||||
#define lwip_ioctl lwip_ioctl_esp
|
||||
|
||||
#include "../../lwip/src/api/sockets.c"
|
||||
|
||||
/* disable macros to enable LWIP function */
|
||||
|
||||
#undef lwip_accept
|
||||
#undef lwip_bind
|
||||
#undef lwip_shutdown
|
||||
#undef lwip_getpeername
|
||||
#undef lwip_getsockname
|
||||
#undef lwip_setsockopt
|
||||
#undef lwip_getsockopt
|
||||
#undef lwip_close
|
||||
#undef lwip_connect
|
||||
#undef lwip_listen
|
||||
#undef lwip_recv
|
||||
#undef lwip_recvfrom
|
||||
#undef lwip_send
|
||||
#undef lwip_sendmsg
|
||||
#undef lwip_sendto
|
||||
#undef lwip_socket
|
||||
#undef lwip_select
|
||||
#undef lwip_ioctlsocket
|
||||
|
||||
#undef lwip_read
|
||||
#undef lwip_write
|
||||
#undef lwip_writev
|
||||
#undef lwip_close
|
||||
#undef closesocket
|
||||
#undef lwip_fcntl
|
||||
#undef lwip_ioctl
|
||||
|
||||
/********************************************************************/
|
||||
#define LWIP_SYNC_MT_SLEEP_MS 10
|
||||
|
||||
#define SOCK_MT_DEBUG_LEVEL 255
|
||||
|
||||
typedef struct socket_conn_sync {
|
||||
struct tcpip_api_call_data call;
|
||||
struct netconn *conn;
|
||||
} socket_conn_sync_t;
|
||||
|
||||
typedef int (*lwip_io_mt_fn)(int, int );
|
||||
|
||||
/* Use about 2 bit */
|
||||
#define SOCK_MT_STATE_SOCK 0
|
||||
#define SOCK_MT_STATE_ACCEPT 1
|
||||
#define SOCK_MT_STATE_CONNECT 2
|
||||
#define SOCK_MT_STATE_SEND 3
|
||||
#define SOCK_MT_STATE_ILL 4
|
||||
|
||||
#define SOCK_MT_LOCK_SEND (1 << 0)
|
||||
#define SOCK_MT_LOCK_RECV (1 << 1)
|
||||
#define SOCK_MT_LOCK_IOCTL (1 << 2)
|
||||
|
||||
#define SOCK_MT_LOCK_MIN SOCK_MT_LOCK_SEND
|
||||
#define SOCK_MT_LOCK_MAX SOCK_MT_LOCK_IOCTL
|
||||
|
||||
#define SOCK_MT_SELECT_RECV (1 << 0)
|
||||
#define SOCK_MT_SELECT_SEND (1 << 1)
|
||||
|
||||
typedef struct _sock_mt {
|
||||
uint8_t opened : 1;
|
||||
uint8_t state : 2;
|
||||
uint8_t select : 2;
|
||||
uint8_t lock : 3;
|
||||
} sock_mt_t;
|
||||
|
||||
#if (SOCK_MT_DEBUG_LEVEL < 16)
|
||||
#define SOCK_MT_DEBUG(level, ...) \
|
||||
if (level >= SOCK_MT_DEBUG_LEVEL) \
|
||||
printf(__VA_ARGS__);
|
||||
#else
|
||||
#define SOCK_MT_DEBUG(level, ...)
|
||||
#endif
|
||||
|
||||
#define SOCK_MT_ENTER_CHECK(s, l, st) \
|
||||
{ \
|
||||
if (_sock_lock(s, l) != ERR_OK) \
|
||||
return -1; \
|
||||
if (st != SOCK_MT_STATE_ILL) \
|
||||
_sock_set_state(s, st); \
|
||||
}
|
||||
|
||||
#define SOCK_MT_EXIT_CHECK(s, l, st) \
|
||||
{ \
|
||||
if (st != SOCK_MT_STATE_ILL) \
|
||||
_sock_set_state(s, SOCK_MT_STATE_SOCK); \
|
||||
if (_sock_unlock(s, l) != ERR_OK) \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
static volatile sock_mt_t DRAM_ATTR sockets_mt[NUM_SOCKETS];
|
||||
|
||||
static inline void _sock_mt_init(int s)
|
||||
{
|
||||
memset((void *)&sockets_mt[s - LWIP_SOCKET_OFFSET], 0, sizeof(sock_mt_t));
|
||||
}
|
||||
|
||||
static inline int _sock_is_opened(int s)
|
||||
{
|
||||
return sockets_mt[s - LWIP_SOCKET_OFFSET].opened != 0;
|
||||
}
|
||||
|
||||
static inline void _sock_set_open(int s, int opened)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].opened = opened;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static inline void _sock_set_state(int s, int state)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].state = state;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static inline int _sock_get_state(int s)
|
||||
{
|
||||
return sockets_mt[s - LWIP_SOCKET_OFFSET].state;
|
||||
}
|
||||
|
||||
static inline int _sock_get_select(int s, int select)
|
||||
{
|
||||
return sockets_mt[s - LWIP_SOCKET_OFFSET].select & select;
|
||||
}
|
||||
|
||||
static int inline _sock_is_lock(int s, int l)
|
||||
{
|
||||
return sockets_mt[s - LWIP_SOCKET_OFFSET].lock & l;
|
||||
}
|
||||
|
||||
static int inline _sock_next_lock(int lock)
|
||||
{
|
||||
return lock << 1;
|
||||
}
|
||||
|
||||
static void inline _sock_set_select(int s, int select)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].select |= select;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static void inline _sock_reset_select(int s, int select)
|
||||
{
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].select &= ~select;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
}
|
||||
|
||||
static int _sock_try_lock(int s, int l)
|
||||
{
|
||||
int ret = ERR_OK;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
if (!_sock_is_opened(s)) {
|
||||
ret = ERR_CLSD;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (sockets_mt[s - LWIP_SOCKET_OFFSET].lock & l) {
|
||||
ret = ERR_INPROGRESS;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].lock |= l;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sock_lock(int s, int l)
|
||||
{
|
||||
int ret = ERR_OK;
|
||||
if (tryget_socket_unconn_nouse(s) == NULL)
|
||||
return -1;
|
||||
|
||||
SOCK_MT_DEBUG(1, "s %d l %d enter ", s, l);
|
||||
|
||||
while (1) {
|
||||
ret = _sock_try_lock(s, l);
|
||||
|
||||
if (ret != ERR_INPROGRESS)
|
||||
break;
|
||||
|
||||
vTaskDelay(1);
|
||||
}
|
||||
|
||||
SOCK_MT_DEBUG(1, "OK %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _sock_unlock(int s, int l)
|
||||
{
|
||||
int ret = 0;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
SOCK_MT_DEBUG(1, "s %d l %d exit ", s, l);
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
sockets_mt[s - LWIP_SOCKET_OFFSET].lock &= ~l;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
if (!_sock_is_opened(s)) {
|
||||
ret = ERR_CLSD;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
exit:
|
||||
SOCK_MT_DEBUG(1, "OK %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lwip_enter_mt_select(int s, fd_set *read_set, fd_set *write_set)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s > NUM_SOCKETS + LWIP_SOCKET_OFFSET || s < LWIP_SOCKET_OFFSET)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < s; i++) {
|
||||
if(FD_ISSET(i, read_set) || FD_ISSET(i, write_set))
|
||||
if (tryget_socket_unconn_nouse(i) == NULL)
|
||||
goto failed1;
|
||||
|
||||
if (FD_ISSET(i, read_set)) {
|
||||
err_t err;
|
||||
|
||||
_sock_set_select(i, SOCK_MT_SELECT_RECV);
|
||||
err = _sock_lock(i, SOCK_MT_LOCK_RECV);
|
||||
if (err != ERR_OK) {
|
||||
goto failed2;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(i, write_set)) {
|
||||
err_t err;
|
||||
|
||||
_sock_set_select(i, SOCK_MT_SELECT_SEND);
|
||||
err = _sock_lock(i, SOCK_MT_LOCK_SEND);
|
||||
if (err != ERR_OK) {
|
||||
goto failed3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
failed3:
|
||||
_sock_unlock(i, SOCK_MT_LOCK_SEND);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_SEND);
|
||||
failed2:
|
||||
if (FD_ISSET(i, read_set)) {
|
||||
_sock_unlock(i, SOCK_MT_LOCK_RECV);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_RECV);
|
||||
}
|
||||
failed1:
|
||||
for (i--; i >=0; i--) {
|
||||
if (FD_ISSET(i, read_set) ) {
|
||||
_sock_unlock(i, SOCK_MT_LOCK_RECV);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_RECV);
|
||||
}
|
||||
|
||||
if (FD_ISSET(i, write_set)) {
|
||||
_sock_unlock(i, SOCK_MT_LOCK_SEND);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_SEND);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void lwip_exit_mt_select(int s, fd_set *read_set, fd_set *write_set)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s; i++) {
|
||||
if (FD_ISSET(i, read_set)) {
|
||||
_sock_unlock(i, SOCK_MT_LOCK_RECV);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_RECV);
|
||||
}
|
||||
|
||||
if (FD_ISSET(i, write_set)) {
|
||||
_sock_unlock(i, SOCK_MT_LOCK_SEND);
|
||||
_sock_reset_select(i, SOCK_MT_SELECT_SEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static err_t lwip_do_sync_accept(struct tcpip_api_call_data *call)
|
||||
{
|
||||
socket_conn_sync_t *sync = (socket_conn_sync_t *)call;
|
||||
struct netconn *conn = sync->conn;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (sys_mbox_valid(&conn->acceptmbox))
|
||||
sys_mbox_trypost(&conn->acceptmbox, NULL);
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t lwip_do_sync_send(struct tcpip_api_call_data *call)
|
||||
{
|
||||
socket_conn_sync_t *sync = (socket_conn_sync_t *)call;
|
||||
struct netconn *conn = sync->conn;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (conn->current_msg) {
|
||||
conn->current_msg->err = ERR_OK;
|
||||
if (sys_sem_valid(conn->current_msg->op_completed_sem))
|
||||
sys_sem_signal(conn->current_msg->op_completed_sem);
|
||||
conn->current_msg = NULL;
|
||||
}
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t lwip_do_sync_recv_state(struct tcpip_api_call_data *call)
|
||||
{
|
||||
socket_conn_sync_t *sync = (socket_conn_sync_t *)call;
|
||||
struct netconn *conn = sync->conn;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
SOCK_MT_DEBUG(1, "sync recv %d\n", conn->socket);
|
||||
if (sys_mbox_valid(&conn->recvmbox))
|
||||
sys_mbox_trypost(&conn->recvmbox, NULL);
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static err_t lwip_do_sync_select_state(struct tcpip_api_call_data *call)
|
||||
{
|
||||
socket_conn_sync_t *sync = (socket_conn_sync_t *)call;
|
||||
struct netconn *conn = sync->conn;
|
||||
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
event_callback(conn, NETCONN_EVT_ERROR, 0);
|
||||
conn->state = NETCONN_NONE;
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static void lwip_sync_state_mt(int s)
|
||||
{
|
||||
struct lwip_sock *sock = tryget_socket_unconn_nouse(s);
|
||||
int state = _sock_get_state(s);
|
||||
socket_conn_sync_t sync = {
|
||||
.conn = sock->conn,
|
||||
};
|
||||
|
||||
SOCK_MT_DEBUG(1, "sync state %d\n", state);
|
||||
|
||||
switch (state) {
|
||||
case SOCK_MT_STATE_ACCEPT :
|
||||
tcpip_api_call(lwip_do_sync_accept, &sync.call);
|
||||
break;
|
||||
case SOCK_MT_STATE_CONNECT:
|
||||
case SOCK_MT_STATE_SEND :
|
||||
tcpip_api_call(lwip_do_sync_send, &sync.call);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void lwip_sync_recv_mt(int s)
|
||||
{
|
||||
struct lwip_sock *sock = tryget_socket_unconn_nouse(s);
|
||||
socket_conn_sync_t sync = {
|
||||
.conn = sock->conn,
|
||||
};
|
||||
|
||||
tcpip_api_call(lwip_do_sync_recv_state, &sync.call);
|
||||
}
|
||||
|
||||
static void lwip_sync_select_mt(int s)
|
||||
{
|
||||
struct lwip_sock *sock = tryget_socket_unconn_nouse(s);
|
||||
socket_conn_sync_t sync = {
|
||||
.conn = sock->conn,
|
||||
};
|
||||
|
||||
tcpip_api_call(lwip_do_sync_select_state, &sync.call);
|
||||
}
|
||||
|
||||
static void lwip_sync_mt(int s, int how)
|
||||
{
|
||||
int lock = SOCK_MT_LOCK_MIN;
|
||||
|
||||
do {
|
||||
if (_sock_is_lock(s, lock)) {
|
||||
int need_wait = 0;
|
||||
|
||||
if (!_sock_get_select(s, SOCK_MT_SELECT_RECV | SOCK_MT_SELECT_SEND)) {
|
||||
switch (lock) {
|
||||
case SOCK_MT_LOCK_SEND:
|
||||
lwip_sync_state_mt(s);
|
||||
need_wait = 1;
|
||||
break;
|
||||
case SOCK_MT_LOCK_RECV:
|
||||
lwip_sync_recv_mt(s);
|
||||
need_wait = 1;
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
lwip_sync_select_mt(s);
|
||||
need_wait = 1;
|
||||
}
|
||||
|
||||
if (need_wait)
|
||||
sys_delay_ms(LWIP_SYNC_MT_SLEEP_MS);
|
||||
} else
|
||||
lock = _sock_next_lock(lock);
|
||||
} while (lock < SOCK_MT_LOCK_MAX);
|
||||
}
|
||||
|
||||
#if SET_SOLINGER_DEFAULT
|
||||
#if LWIP_SO_LINGER
|
||||
static void lwip_socket_set_so_link(int s, int linger)
|
||||
{
|
||||
struct lwip_sock *sock = tryget_socket_unconn_nouse(s);
|
||||
|
||||
if (sock) {
|
||||
/*
|
||||
* linker:
|
||||
* -1: nothing
|
||||
* 0: free sent_buf immediately
|
||||
*/
|
||||
sock->conn->linger = linger;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error "LWIP_SO_LINGER must be enable"
|
||||
#endif /* LWIP_SO_LINGER */
|
||||
#else /* SET_SOLINGER_DEFAULT */
|
||||
#define lwip_socket_set_so_link(_s, _linger)
|
||||
#endif /* SET_SOLINGER_DEFAULT */
|
||||
|
||||
int lwip_socket(int domain, int type, int protocol)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = lwip_socket_esp(domain, type, protocol);
|
||||
if (s < 0)
|
||||
return -1;
|
||||
|
||||
lwip_socket_set_so_link(s, 0);
|
||||
_sock_mt_init(s);
|
||||
_sock_set_open(s, 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_bind_esp(s, name, namelen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_CONNECT);
|
||||
|
||||
ret = lwip_connect_esp(s, name, namelen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_CONNECT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_listen(int s, int backlog)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL);
|
||||
|
||||
lwip_socket_set_so_link(s, -1);
|
||||
|
||||
ret = lwip_listen_esp(s, backlog);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ACCEPT)
|
||||
|
||||
lwip_socket_set_so_link(s, -1);
|
||||
|
||||
ret = lwip_accept_esp(s, addr, addrlen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_ACCEPT);
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
lwip_socket_set_so_link(ret, 0);
|
||||
_sock_mt_init(ret);
|
||||
_sock_set_open(ret, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_getpeername_esp(s, name, namelen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_getsockname_esp(s, name, namelen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_setsockopt_esp(s, level, optname, optval, optlen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (tryget_socket_unconn_nouse(s) == NULL)
|
||||
return -1;
|
||||
|
||||
if (optname == SO_ERROR) {
|
||||
int retval = 0;
|
||||
|
||||
if (!_sock_is_opened(s))
|
||||
retval = ENOTCONN;
|
||||
|
||||
if (retval) {
|
||||
*(int *)optval = retval;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_getsockopt_esp(s, level, optname, optval, optlen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_ioctl(int s, long cmd, void *argp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL)
|
||||
|
||||
ret = lwip_ioctl_esp(s, cmd, argp);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
const struct sockaddr *to, socklen_t tolen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND);
|
||||
|
||||
ret = lwip_sendto_esp(s, data, size, flags, to, tolen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_send(int s, const void *data, size_t size, int flags)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND);
|
||||
|
||||
ret = lwip_send_esp(s, data, size, flags);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_SEND, SOCK_MT_STATE_SEND);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_recvfrom(int s, void *mem, size_t len, int flags,
|
||||
struct sockaddr *from, socklen_t *fromlen)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_RECV, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_recvfrom_esp(s, mem, len, flags, from, fromlen);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_RECV, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_recv(int s, void *mem, size_t len, int flags)
|
||||
{
|
||||
return lwip_recvfrom(s, mem, len, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
int lwip_read(int s, void *mem, size_t len)
|
||||
{
|
||||
return lwip_recvfrom(s, mem, len, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int lwip_write(int s, const void *data, size_t size)
|
||||
{
|
||||
return lwip_send(s, data, size, 0);
|
||||
}
|
||||
|
||||
int lwip_fcntl(int s, int cmd, int val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
SOCK_MT_ENTER_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
ret = lwip_fcntl_esp(s, cmd, val);
|
||||
|
||||
SOCK_MT_EXIT_CHECK(s, SOCK_MT_LOCK_IOCTL, SOCK_MT_STATE_ILL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_shutdown(int s, int how)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lwip_close(int s)
|
||||
{
|
||||
int ret;
|
||||
SYS_ARCH_DECL_PROTECT(lev);
|
||||
|
||||
if (tryget_socket_unconn_nouse(s) == NULL)
|
||||
return -1;
|
||||
|
||||
SYS_ARCH_PROTECT(lev);
|
||||
if (_sock_is_opened(s)) {
|
||||
_sock_set_open(s, 0);
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
} else {
|
||||
SYS_ARCH_UNPROTECT(lev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
lwip_sync_mt(s, SHUT_RDWR);
|
||||
|
||||
ret = lwip_close_esp(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset,
|
||||
fd_set *exceptset, struct timeval *timeout)
|
||||
{
|
||||
int ret;
|
||||
fd_set read_set, write_set;
|
||||
|
||||
if (readset)
|
||||
MEMCPY(&read_set, readset, sizeof(fd_set));
|
||||
else
|
||||
FD_ZERO(&read_set);
|
||||
|
||||
if (writeset)
|
||||
MEMCPY(&write_set, writeset, sizeof(fd_set));
|
||||
else
|
||||
FD_ZERO(&write_set);
|
||||
|
||||
ret = lwip_enter_mt_select(maxfdp1, &read_set, &write_set);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = lwip_select_esp(maxfdp1, readset, writeset, exceptset, timeout);
|
||||
|
||||
lwip_exit_mt_select(maxfdp1, &read_set, &write_set);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
@ -112,13 +112,15 @@ static int esp_ping_receive(esp_ping_t *ep)
|
||||
struct sockaddr_in *from4 = (struct sockaddr_in *)&from;
|
||||
inet_addr_to_ip4addr(ip_2_ip4(&ep->recv_addr), &from4->sin_addr);
|
||||
IP_SET_TYPE_VAL(ep->recv_addr, IPADDR_TYPE_V4);
|
||||
} else {
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
else {
|
||||
// IPv6
|
||||
struct sockaddr_in6 *from6 = (struct sockaddr_in6 *)&from;
|
||||
inet6_addr_to_ip6addr(ip_2_ip6(&ep->recv_addr), &from6->sin6_addr);
|
||||
IP_SET_TYPE_VAL(ep->recv_addr, IPADDR_TYPE_V6);
|
||||
}
|
||||
|
||||
#endif
|
||||
// Currently we only process IPv4
|
||||
if (IP_IS_V4_VAL(ep->recv_addr)) {
|
||||
struct ip_hdr *iphdr = (struct ip_hdr *)buf;
|
||||
@ -236,12 +238,18 @@ esp_err_t esp_ping_new_session(const esp_ping_config_t *config, const esp_ping_c
|
||||
d[i] = 'A' + i;
|
||||
}
|
||||
|
||||
/* create socket */
|
||||
if (IP_IS_V4(&config->target_addr) || ip6_addr_isipv4mappedipv6(ip_2_ip6(&config->target_addr))) {
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
if (IP_IS_V4(&config->target_addr) || ip6_addr_isipv4mappedipv6(ip_2_ip6(&config->target_addr))) {
|
||||
ep->sock = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
|
||||
} else {
|
||||
ep->sock = socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6);
|
||||
}
|
||||
#else
|
||||
if (IP_IS_V4(&config->target_addr)) {
|
||||
ep->sock = socket(AF_INET, SOCK_RAW, IP_PROTO_ICMP);
|
||||
} else {
|
||||
ep->sock = socket(AF_INET6, SOCK_RAW, IP6_NEXTH_ICMP6);
|
||||
}
|
||||
#endif
|
||||
|
||||
PING_CHECK(ep->sock > 0, "create socket failed: %d", err, ESP_FAIL, ep->sock);
|
||||
|
||||
struct timeval timeout;
|
||||
@ -259,11 +267,13 @@ esp_err_t esp_ping_new_session(const esp_ping_config_t *config, const esp_ping_c
|
||||
to4->sin_family = AF_INET;
|
||||
inet_addr_from_ip4addr(&to4->sin_addr, ip_2_ip4(&config->target_addr));
|
||||
}
|
||||
#if LWIP_IPV6
|
||||
if (IP_IS_V6(&config->target_addr)) {
|
||||
struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ep->target_addr;
|
||||
to6->sin6_family = AF_INET6;
|
||||
inet6_addr_from_ip6addr(&to6->sin6_addr, ip_2_ip6(&config->target_addr));
|
||||
}
|
||||
#endif
|
||||
/* return ping handle to user */
|
||||
*hdl_out = (esp_ping_handle_t)ep;
|
||||
return ESP_OK;
|
||||
|
@ -7,8 +7,8 @@ COMPONENT_ADD_INCLUDEDIRS := \
|
||||
include/apps \
|
||||
include/apps/sntp \
|
||||
lwip/src/include \
|
||||
port/esp32/include \
|
||||
port/esp32/include/arch
|
||||
port/esp8266/include \
|
||||
port/esp8266/include/arch
|
||||
|
||||
COMPONENT_SRCDIRS := \
|
||||
apps/dhcpserver \
|
||||
@ -21,15 +21,21 @@ COMPONENT_SRCDIRS := \
|
||||
lwip/src/core/ipv4 \
|
||||
lwip/src/core/ipv6 \
|
||||
lwip/src/netif \
|
||||
port/esp32 \
|
||||
port/esp32/freertos \
|
||||
port/esp32/netif \
|
||||
port/esp32/debug
|
||||
port/esp8266 \
|
||||
port/esp8266/freertos \
|
||||
port/esp8266/netif \
|
||||
port/esp8266/debug
|
||||
|
||||
ifndef CONFIG_IDF_TARGET_ESP32
|
||||
COMPONENT_OBJEXCLUDE := port/esp32/netif/ethernetif.o
|
||||
COMPONENT_OBJEXCLUDE := port/esp8266/netif/ethernetif.o
|
||||
endif
|
||||
|
||||
ifdef CONFIG_LWIP_SOCKET_MULTITHREAD
|
||||
COMPONENT_SRCDIRS += apps/multi-threads
|
||||
COMPONENT_OBJEXCLUDE += lwip/src/api/sockets.o
|
||||
endif
|
||||
|
||||
|
||||
ifdef CONFIG_LWIP_PPP_SUPPORT
|
||||
COMPONENT_SRCDIRS += lwip/src/netif/ppp lwip/src/netif/ppp/polarssl
|
||||
endif
|
||||
|
@ -77,6 +77,11 @@ typedef struct {
|
||||
* @brief Default ping configuration
|
||||
*
|
||||
*/
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
#define PING_TARGET_ADDR ip_addr_any_type
|
||||
#else
|
||||
#define PING_TARGET_ADDR ip_addr_any
|
||||
#endif
|
||||
#define ESP_PING_DEFAULT_CONFIG() \
|
||||
{ \
|
||||
.count = 5, \
|
||||
@ -84,7 +89,7 @@ typedef struct {
|
||||
.timeout_ms = 1000, \
|
||||
.data_size = 56, \
|
||||
.tos = 0, \
|
||||
.target_addr = ip_addr_any_type, \
|
||||
.target_addr = PING_TARGET_ADDR, \
|
||||
.task_stack_size = 2048, \
|
||||
.task_prio = 2, \
|
||||
}
|
||||
|
@ -1,87 +1,4 @@
|
||||
[mapping:lwip]
|
||||
archive: liblwip.a
|
||||
entries:
|
||||
if LWIP_IRAM_OPTIMIZATION = y:
|
||||
sockets:get_socket (noflash_text)
|
||||
sockets:tryget_socket (noflash_text)
|
||||
sockets:tryget_socket_unconn (noflash_text)
|
||||
sockets:sock_inc_used (noflash_text)
|
||||
sockets:tryget_socket_unconn_nouse (noflash_text)
|
||||
sockets:tryget_socket_unconn_locked (noflash_text)
|
||||
sockets:done_socket (noflash_text)
|
||||
sockets:lwip_recvfrom (noflash_text)
|
||||
sockets:lwip_recv_tcp (noflash_text)
|
||||
sockets:lwip_recv_tcp_from (noflash_text)
|
||||
sockets:lwip_recvfrom_udp_raw (noflash_text)
|
||||
sockets:lwip_send (noflash_text)
|
||||
sockets:lwip_sendto (noflash_text)
|
||||
sockets:event_callback (noflash_text)
|
||||
sockets:lwip_select (noflash_text)
|
||||
sockets:select_check_waiters (noflash_text)
|
||||
api_lib:netconn_apimsg (noflash_text)
|
||||
api_lib:netconn_recv_data (noflash_text)
|
||||
api_lib:netconn_tcp_recvd_msg (noflash_text)
|
||||
api_lib:netconn_tcp_recvd (noflash_text)
|
||||
api_lib:netconn_recv_data_tcp (noflash_text)
|
||||
api_lib:netconn_recv_tcp_pbuf_flags (noflash_text)
|
||||
api_lib:netconn_recv_udp_raw_netbuf_flags (noflash_text)
|
||||
api_lib:netconn_recv (noflash_text)
|
||||
api_lib:netconn_sendto (noflash_text)
|
||||
api_lib:netconn_send (noflash_text)
|
||||
api_lib:netconn_write_partly (noflash_text)
|
||||
api_lib:netconn_write_vectors_partly (noflash_text)
|
||||
api_msg:lwip_netconn_do_send (noflash_text)
|
||||
api_msg:lwip_netconn_do_write (noflash_text)
|
||||
netbuf:netbuf_alloc (noflash_text)
|
||||
netbuf:netbuf_free (noflash_text)
|
||||
tcpip:tcpip_thread (noflash_text)
|
||||
tcpip:tcpip_thread_handle_msg (noflash_text)
|
||||
tcpip:tcpip_inpkt (noflash_text)
|
||||
tcpip:tcpip_input (noflash_text)
|
||||
tcpip:tcpip_callback (noflash_text)
|
||||
tcpip:tcpip_try_callback (noflash_text)
|
||||
tcpip:tcpip_send_msg_wait_sem (noflash_text)
|
||||
inet_chksum:inet_cksum_pseudo_base (noflash_text)
|
||||
inet_chksum:inet_chksum_pseudo (noflash_text)
|
||||
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)
|
||||
ip4:ip4_output_if (noflash_text)
|
||||
ip4:ip4_output_if_opt (noflash_text)
|
||||
ip4:ip4_output_if_src (noflash_text)
|
||||
ip4:ip4_output_if_opt_src (noflash_text)
|
||||
ip4:ip4_output (noflash_text)
|
||||
pbuf:pbuf_alloc (noflash_text)
|
||||
pbuf:pbuf_add_header_impl (noflash_text)
|
||||
pbuf:pbuf_add_header (noflash_text)
|
||||
pbuf:pbuf_remove_header (noflash_text)
|
||||
pbuf:pbuf_header_impl (noflash_text)
|
||||
pbuf:pbuf_header (noflash_text)
|
||||
pbuf:pbuf_free (noflash_text)
|
||||
timeouts:sys_timeouts_mbox_fetch (noflash_text)
|
||||
udp:udp_input_local_match (noflash_text)
|
||||
udp:udp_input (noflash_text)
|
||||
udp:udp_send (noflash_text)
|
||||
udp:udp_sendto (noflash_text)
|
||||
udp:udp_sendto_if (noflash_text)
|
||||
udp:udp_sendto_if_src (noflash_text)
|
||||
ethernet:ethernet_input (noflash_text)
|
||||
ethernet:ethernet_output (noflash_text)
|
||||
sys_arch:sys_mutex_lock (noflash_text)
|
||||
sys_arch:sys_mutex_unlock (noflash_text)
|
||||
sys_arch:sys_sem_signal (noflash_text)
|
||||
sys_arch:sys_arch_sem_wait (noflash_text)
|
||||
sys_arch:sys_mbox_post (noflash_text)
|
||||
sys_arch:sys_mbox_trypost (noflash_text)
|
||||
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)
|
||||
else:
|
||||
|
||||
* (default)
|
||||
* (iram_bss)
|
||||
|
@ -1,245 +0,0 @@
|
||||
/**
|
||||
* @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>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "netif/wlanif.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tcpip_adapter.h"
|
||||
|
||||
|
||||
/**
|
||||
* In this function, the hardware should be initialized.
|
||||
* Called from ethernetif_init().
|
||||
*
|
||||
* @param netif the already initialized lwip network interface structure
|
||||
* for this ethernetif
|
||||
*/
|
||||
static void
|
||||
low_level_init(struct netif *netif)
|
||||
{
|
||||
/* set MAC hardware address length */
|
||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
|
||||
/* set MAC hardware address */
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1500;
|
||||
|
||||
/* device capabilities */
|
||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
|
||||
|
||||
#if ESP_LWIP
|
||||
#if LWIP_IGMP
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !ESP_L2_TO_L3_COPY
|
||||
netif->l2_buffer_free_notify = esp_wifi_internal_free_rx_buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @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
|
||||
* dropped because of memory failure (except for the TCP timers).
|
||||
*/
|
||||
static err_t ESP_IRAM_ATTR
|
||||
low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
wifi_interface_t wifi_if = tcpip_adapter_get_esp_if(netif);
|
||||
struct pbuf *q = p;
|
||||
err_t ret;
|
||||
|
||||
if (wifi_if >= ESP_IF_MAX) {
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
if(q->next == NULL) {
|
||||
ret = esp_wifi_internal_tx(wifi_if, 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_wifi_internal_tx(wifi_if, q->payload, q->len);
|
||||
pbuf_free(q);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ESP_IRAM_ATTR
|
||||
wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb)
|
||||
{
|
||||
struct pbuf *p;
|
||||
|
||||
if(!buffer || !netif_is_up(netif)) {
|
||||
if (eb) {
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if (ESP_L2_TO_L3_COPY == 1)
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
|
||||
if (p == NULL) {
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return;
|
||||
}
|
||||
p->l2_owner = NULL;
|
||||
memcpy(p->payload, buffer, len);
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
#else
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_REF);
|
||||
if (p == NULL){
|
||||
esp_wifi_internal_free_rx_buffer(eb);
|
||||
return;
|
||||
}
|
||||
p->payload = buffer;
|
||||
p->l2_owner = netif;
|
||||
p->l2_buf = eb;
|
||||
#endif
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (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
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other err_t on error
|
||||
*/
|
||||
err_t
|
||||
wlanif_init(struct netif *netif)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
|
||||
#if ESP_LWIP
|
||||
netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
|
||||
#else
|
||||
netif->hostname = "lwip";
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
/*
|
||||
* Initialize the snmp variables and counters inside the struct netif.
|
||||
* The last argument should be replaced with your link speed, in units
|
||||
* of bits per second.
|
||||
*/
|
||||
NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100);
|
||||
|
||||
/* We directly use etharp_output() here to save a function call.
|
||||
* You can instead declare your own function an call etharp_output()
|
||||
* from it if you have to do some checks before sending (e.g. if link
|
||||
* is available...) */
|
||||
netif->output = etharp_output;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
|
||||
/* initialize the hardware */
|
||||
low_level_init(netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t wlanif_init_sta(struct netif *netif) {
|
||||
netif->name[0] = 's';
|
||||
netif->name[1] = 't';
|
||||
return wlanif_init(netif);
|
||||
}
|
||||
|
||||
err_t wlanif_init_ap(struct netif *netif) {
|
||||
netif->name[0] = 'a';
|
||||
netif->name[1] = 'p';
|
||||
return wlanif_init(netif);
|
||||
}
|
||||
|
||||
|
@ -23,10 +23,14 @@
|
||||
#include "lwip/memp.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#if LWIP_IPV4 && LWIP_IPV6
|
||||
#define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s type=%d ip=%x", (info), (ip).type, (ip).u_addr.ip4.addr)
|
||||
#else
|
||||
#define DBG_LWIP_IP_SHOW(info, ip) ESP_LWIP_LOGI("%s ip=%x", (info), (ip).addr)
|
||||
#endif
|
||||
#define DBG_LWIP_IP_PCB_SHOW(pcb) \
|
||||
DBG_LWIP_IP_SHOW("local ip", (pcb)->local_ip);\
|
||||
DBG_LWIP_IP_SHOW("remote ip", (pcb)->local_ip);\
|
||||
DBG_LWIP_IP_SHOW("remote ip", (pcb)->remote_ip);\
|
||||
ESP_LWIP_LOGI("so_options=%x, tos=%d ttl=%d", (pcb)->so_options, (pcb)->tos, (pcb)->ttl)
|
||||
|
||||
#define DBG_LWIP_SEG_SHOW(seg) while(seg) { ESP_LWIP_LOGI("\tseg=%p next=%p pbuf=%p flags=%x", (seg), (seg)->next, (seg)->p, (seg)->flags); (seg)=(seg)->next;}
|
||||
@ -186,11 +190,13 @@ void dbg_lwip_stats_show(void)
|
||||
LINK_STATS_DISPLAY();
|
||||
MEM_STATS_DISPLAY();
|
||||
SYS_STATS_DISPLAY();
|
||||
#if LWIP_IPV6
|
||||
IP6_STATS_DISPLAY();
|
||||
ICMP6_STATS_DISPLAY();
|
||||
IP6_FRAG_STATS_DISPLAY();
|
||||
MLD6_STATS_DISPLAY();
|
||||
ND6_STATS_DISPLAY();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if (ESP_STATS_MEM == 1)
|
@ -41,10 +41,12 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include "esp_task.h"
|
||||
#include "esp_libc.h"
|
||||
#include "esp_system.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "sntp.h"
|
||||
#include "netif/dhcp_state.h"
|
||||
#include "driver/soc.h"
|
||||
|
||||
/* Enable all Espressif-only options */
|
||||
|
||||
@ -100,6 +102,16 @@
|
||||
*/
|
||||
#define MEM_ALIGNMENT 4
|
||||
|
||||
#define mem_clib_free(s) heap_caps_free(s)
|
||||
#define mem_clib_malloc(s) heap_caps_malloc(s, MALLOC_CAP_8BIT)
|
||||
#define mem_clib_calloc(n, s) heap_caps_calloc(n, s, MALLOC_CAP_8BIT)
|
||||
|
||||
/**
|
||||
* @brief System
|
||||
*/
|
||||
#define SYS_ARCH_DECL_PROTECT(_lev) esp_irqflag_t _lev
|
||||
#define SYS_ARCH_PROTECT(_lev) _lev = soc_save_local_irq()
|
||||
#define SYS_ARCH_UNPROTECT(_lev) soc_restore_local_irq(_lev)
|
||||
/*
|
||||
------------------------------------------------
|
||||
---------- Internal Memory Pool Sizes ----------
|
||||
@ -386,6 +398,13 @@
|
||||
---------- Pbuf options ----------
|
||||
----------------------------------
|
||||
*/
|
||||
/**
|
||||
* PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated
|
||||
* for an additional encapsulation header before ethernet headers (e.g. 802.11)
|
||||
*/
|
||||
#define PBUF_LINK_ENCAPSULATION_HLEN 36u
|
||||
|
||||
#define LWIP_SUPPORT_CUSTOM_PBUF 1
|
||||
|
||||
/*
|
||||
------------------------------------------------
|
||||
@ -548,6 +567,13 @@
|
||||
*/
|
||||
#define LWIP_SO_RCVBUF CONFIG_LWIP_SO_RCVBUF
|
||||
|
||||
/**
|
||||
* LWIP_SO_LINGER==1: Enable SO_LINGER processing.
|
||||
*/
|
||||
#define LWIP_SO_LINGER 1
|
||||
|
||||
#define SET_SOLINGER_DEFAULT CONFIG_SET_SOLINGER_DEFAULT
|
||||
|
||||
/**
|
||||
* SO_REUSE==1: Enable SO_REUSEADDR option.
|
||||
* This option is set via menuconfig.
|
||||
@ -668,7 +694,7 @@
|
||||
/**
|
||||
* LWIP_IPV6==1: Enable IPv6
|
||||
*/
|
||||
#define LWIP_IPV6 1
|
||||
#define LWIP_IPV6 CONFIG_LWIP_IPV6
|
||||
|
||||
/*
|
||||
---------------------------------------
|
||||
@ -766,7 +792,9 @@
|
||||
#define LWIP_SOCKET_OFFSET (FD_SETSIZE - CONFIG_LWIP_MAX_SOCKETS)
|
||||
|
||||
/* Enable all Espressif-only options */
|
||||
|
||||
#ifdef CONFIG_LWIP_SOCKET_MULTITHREAD
|
||||
#define SOCKETS_MT
|
||||
#endif
|
||||
#define ESP_LWIP 1
|
||||
#define ESP_LWIP_ARP 1
|
||||
#define ESP_PER_SOC_TCP_WND 0
|
||||
@ -774,7 +802,7 @@
|
||||
#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF
|
||||
#define ESP_DHCP 1
|
||||
#define ESP_DNS 1
|
||||
#define ESP_IPV6_AUTOCONFIG 1
|
||||
#define ESP_IPV6_AUTOCONFIG LWIP_IPV6
|
||||
#define ESP_PERF 0
|
||||
#define ESP_RANDOM_TCP_PORT 1
|
||||
#define ESP_IP4_ATON 1
|
||||
@ -793,7 +821,7 @@
|
||||
#define ESP_AUTO_IP 1
|
||||
#define ESP_PBUF 1
|
||||
#define ESP_PPP 1
|
||||
#define ESP_IPV6 1
|
||||
#define ESP_IPV6 LWIP_IPV6
|
||||
#define ESP_SOCKET 1
|
||||
#define ESP_LWIP_SELECT 1
|
||||
|
||||
@ -820,6 +848,16 @@
|
||||
#define LWIP_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_DEBUG LWIP_DBG_OFF
|
||||
|
||||
#define ESP_TCP_TXRX_PBUF_DEBUG LWIP_DBG_OFF
|
||||
#define LWIP_SEND_DATA_TO_WIFI 1
|
||||
#define LWIP_RESEND_DATA_TO_WIFI_WHEN_WIFI_SEND_FAILED 2
|
||||
#define LWIP_RECV_DATA_FROM_WIFI 3
|
||||
#define LWIP_RETRY_DATA_WHEN_RECV_ACK_TIMEOUT 4
|
||||
#define LWIP_FETCH_DATA_AT_TCPIP_THREAD 5
|
||||
#define WIFI_SEND_DATA_FAILED 6
|
||||
|
||||
void tcp_print_status(int status, void* p, uint32_t tmp1, uint32_t tmp2, uint32_t tmp3);
|
||||
|
||||
#define CHECKSUM_CHECK_UDP 0
|
||||
#define CHECKSUM_CHECK_IP 0
|
||||
|
@ -16,24 +16,6 @@
|
||||
#ifndef _WLAN_LWIP_IF_H_
|
||||
#define _WLAN_LWIP_IF_H_
|
||||
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#include "esp_private/wifi.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t wlanif_init_ap(struct netif *netif);
|
||||
err_t wlanif_init_sta(struct netif *netif);
|
||||
|
||||
void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb);
|
||||
|
||||
wifi_interface_t wifi_get_interface(void *dev);
|
||||
|
||||
void netif_reg_addr_change_cb(void* cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
@ -31,6 +31,7 @@ static const char *interface_key[] = {"IF_STA", "IF_AP", "IF_ETH", "IF_TEST"};
|
||||
_Static_assert(sizeof(interface_key) / sizeof(char*) == TCPIP_ADAPTER_IF_MAX,
|
||||
"Number interface keys differs from number of interfaces");
|
||||
|
||||
typedef nvs_handle nvs_handle_t;
|
||||
bool dhcp_ip_addr_restore(void *netif)
|
||||
{
|
||||
nvs_handle_t nvs;
|
629
components/lwip/port/esp8266/netif/wlanif.c
Normal file
629
components/lwip/port/esp8266/netif/wlanif.c
Normal file
@ -0,0 +1,629 @@
|
||||
/**
|
||||
* @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>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "esp_libc.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_aio.h"
|
||||
#include "tcpip_adapter.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#include "esp8266/eagle_soc.h"
|
||||
|
||||
int ieee80211_output_pbuf(esp_aio_t *aio);
|
||||
int8_t wifi_get_netif(uint8_t fd);
|
||||
void wifi_station_set_default_hostname(uint8_t* hwaddr);
|
||||
|
||||
#define IFNAME0 'e'
|
||||
#define IFNAME1 'n'
|
||||
|
||||
#if ESP_TCP
|
||||
typedef struct pbuf_send_list {
|
||||
struct pbuf_send_list* next;
|
||||
struct pbuf* p;
|
||||
int aiofd;
|
||||
int err_cnt;
|
||||
} pbuf_send_list_t;
|
||||
|
||||
static pbuf_send_list_t* pbuf_list_head = NULL;
|
||||
static int pbuf_send_list_num = 0;
|
||||
#endif
|
||||
static int low_level_send_cb(esp_aio_t* aio);
|
||||
|
||||
#if ESP_TCP_TXRX_PBUF_DEBUG
|
||||
void tcp_print_status(int status, void* buf, uint32_t tmp1, uint32_t tmp2, uint32_t tmp3)
|
||||
{
|
||||
struct pbuf* p = (struct pbuf*)buf;
|
||||
if (p->tot_len < 50) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t i;
|
||||
|
||||
i = *((unsigned char*)p->payload + 12);
|
||||
|
||||
if (i == 0x08) { /*ipv4*/
|
||||
i = *((unsigned char*)p->payload + 13);
|
||||
|
||||
if (i == 0) {
|
||||
i = *((unsigned char*)p->payload + 23);
|
||||
|
||||
if (i == 0x06) { /*tcp*/
|
||||
i = *((unsigned char*)p->payload + 16);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 17);
|
||||
|
||||
if (i >= 40) { /*tcp data*/
|
||||
uint32_t len, seq, ack, srcport, destport, flags;
|
||||
wifi_tx_status_t *tx_result = (wifi_tx_status_t *)(&tmp1);
|
||||
len = i;
|
||||
i = *((unsigned char*)p->payload + 38);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 39);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 40);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 41);
|
||||
seq = i;
|
||||
i = *((unsigned char*)p->payload + 42);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 43);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 44);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 45);
|
||||
ack = i;
|
||||
i = *((unsigned char*)p->payload + 34);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 35);
|
||||
srcport = i;
|
||||
i = *((unsigned char*)p->payload + 36);
|
||||
i <<= 8;
|
||||
i += *((unsigned char*)p->payload + 37);
|
||||
destport = i;
|
||||
flags = *((unsigned char *)p->payload+47);
|
||||
|
||||
switch (status) {
|
||||
case LWIP_SEND_DATA_TO_WIFI:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ Tx - L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n", len, seq, ack, srcport, destport, flags));
|
||||
break;
|
||||
|
||||
case LWIP_RESEND_DATA_TO_WIFI_WHEN_WIFI_SEND_FAILED:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ Cache Tx - L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n", len, seq, ack, srcport, destport, flags));
|
||||
break;
|
||||
|
||||
case LWIP_RECV_DATA_FROM_WIFI:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ WiFi Rx - L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n", len, seq, ack, srcport, destport, flags));
|
||||
break;
|
||||
|
||||
case LWIP_RETRY_DATA_WHEN_RECV_ACK_TIMEOUT:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ TCP RTY - rtime:%d, rto:%d, L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n", tmp1, tmp2, len, seq, ack, srcport, destport, flags));
|
||||
return;
|
||||
|
||||
case LWIP_FETCH_DATA_AT_TCPIP_THREAD:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ eth Rx - L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n", len, seq, ack, srcport, destport, flags));
|
||||
break;
|
||||
|
||||
case WIFI_SEND_DATA_FAILED:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ WiFi Tx Fail - result:%d, src:%d, lrc:%d, rate:%d, L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x\n",\
|
||||
tx_result->wifi_tx_result, tx_result->wifi_tx_src, tx_result->wifi_tx_lrc, tx_result->wifi_tx_rate, len, seq, ack, srcport, destport, flags));
|
||||
break;
|
||||
|
||||
default:
|
||||
LWIP_DEBUGF(ESP_TCP_TXRX_PBUF_DEBUG, ("@@ status:%d, L:%u, S:%u, A:%u, SP:%u, DP:%u, F:%x, tmp1:%d, tmp2:%d, tmp3:%d\n",\
|
||||
status, len, seq, ack, srcport, destport, flags, tmp1, tmp2, tmp3));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ESP_TCP
|
||||
static inline bool check_pbuf_to_insert(struct pbuf* p)
|
||||
{
|
||||
uint8_t* buf = (uint8_t*)p->payload;
|
||||
|
||||
/*Check if pbuf is tcp ip*/
|
||||
if (buf[12] == 0x08 && buf[13] == 0x00 && buf[23] == 0x06) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void insert_to_list(int fd, struct pbuf* p)
|
||||
{
|
||||
pbuf_send_list_t* tmp_pbuf_list1;
|
||||
pbuf_send_list_t* tmp_pbuf_list2;
|
||||
|
||||
if (pbuf_send_list_num > (TCP_SND_QUEUELEN * MEMP_NUM_TCP_PCB + MEMP_NUM_TCP_PCB)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!check_pbuf_to_insert(p)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Insert %p,%d\n", p, pbuf_send_list_num));
|
||||
|
||||
if (pbuf_list_head == NULL) {
|
||||
tmp_pbuf_list1 = (pbuf_send_list_t*)malloc(sizeof(pbuf_send_list_t));
|
||||
|
||||
if (!tmp_pbuf_list1) {
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("no memory malloc pbuf list error\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pbuf_ref(p);
|
||||
tmp_pbuf_list1->aiofd = fd;
|
||||
tmp_pbuf_list1->p = p;
|
||||
tmp_pbuf_list1->next = NULL;
|
||||
tmp_pbuf_list1->err_cnt = 0;
|
||||
pbuf_list_head = tmp_pbuf_list1;
|
||||
pbuf_send_list_num++;
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_pbuf_list1 = pbuf_list_head;
|
||||
tmp_pbuf_list2 = tmp_pbuf_list1;
|
||||
|
||||
while (tmp_pbuf_list1 != NULL) {
|
||||
if (tmp_pbuf_list1->p == p) {
|
||||
tmp_pbuf_list1->err_cnt ++;
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_pbuf_list2 = tmp_pbuf_list1;
|
||||
tmp_pbuf_list1 = tmp_pbuf_list2->next;
|
||||
}
|
||||
|
||||
tmp_pbuf_list1 = (pbuf_send_list_t*)malloc(sizeof(pbuf_send_list_t));
|
||||
|
||||
if (!tmp_pbuf_list1) {
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("no memory malloc pbuf list error\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
pbuf_ref(p);
|
||||
tmp_pbuf_list1->aiofd = fd;
|
||||
tmp_pbuf_list1->p = p;
|
||||
tmp_pbuf_list1->next = NULL;
|
||||
tmp_pbuf_list1->err_cnt = 0;
|
||||
tmp_pbuf_list2->next = tmp_pbuf_list1;
|
||||
pbuf_send_list_num++;
|
||||
}
|
||||
|
||||
void send_from_list()
|
||||
{
|
||||
pbuf_send_list_t* tmp_pbuf_list1;
|
||||
|
||||
while (pbuf_list_head != NULL) {
|
||||
if (pbuf_list_head->p->ref == 1) {
|
||||
tmp_pbuf_list1 = pbuf_list_head->next;
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n", pbuf_list_head->p, pbuf_send_list_num));
|
||||
pbuf_free(pbuf_list_head->p);
|
||||
free(pbuf_list_head);
|
||||
pbuf_send_list_num--;
|
||||
pbuf_list_head = tmp_pbuf_list1;
|
||||
} else {
|
||||
esp_aio_t aio;
|
||||
esp_err_t err;
|
||||
aio.fd = (int)pbuf_list_head->aiofd;
|
||||
aio.pbuf = pbuf_list_head->p->payload;
|
||||
aio.len = pbuf_list_head->p->len;
|
||||
aio.cb = low_level_send_cb;
|
||||
aio.arg = pbuf_list_head->p;
|
||||
aio.ret = 0;
|
||||
|
||||
err = ieee80211_output_pbuf(aio);
|
||||
|
||||
#if ESP_TCP_TXRX_PBUF_DEBUG
|
||||
tcp_print_status(LWIP_RESEND_DATA_TO_WIFI_WHEN_WIFI_SEND_FAILED, (void*)pbuf_list_head->p, 0 ,0, 0);
|
||||
#endif
|
||||
tmp_pbuf_list1 = pbuf_list_head->next;
|
||||
|
||||
if (err == ERR_MEM) {
|
||||
pbuf_list_head->err_cnt++;
|
||||
|
||||
if (pbuf_list_head->err_cnt >= 3) {
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n", pbuf_list_head->p, pbuf_send_list_num));
|
||||
pbuf_free(pbuf_list_head->p);
|
||||
free(pbuf_list_head);
|
||||
pbuf_send_list_num--;
|
||||
pbuf_list_head = tmp_pbuf_list1;
|
||||
}
|
||||
|
||||
return;
|
||||
} else if (err == ERR_OK) {
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n", pbuf_list_head->p, pbuf_send_list_num));
|
||||
free(pbuf_list_head);
|
||||
pbuf_send_list_num--;
|
||||
pbuf_list_head = tmp_pbuf_list1;
|
||||
} else {
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Delete %p,%d\n", pbuf_list_head->p, pbuf_send_list_num));
|
||||
pbuf_free(pbuf_list_head->p);
|
||||
free(pbuf_list_head);
|
||||
pbuf_send_list_num--;
|
||||
pbuf_list_head = tmp_pbuf_list1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* In this function, the hardware should be initialized.
|
||||
* Called from ethernetif_init().
|
||||
*
|
||||
* @param netif the already initialized lwip network interface structure
|
||||
* for this ethernetif
|
||||
*/
|
||||
static void low_level_init(struct netif* netif)
|
||||
{
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_init: netif is NULL\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* set MAC hardware address length */
|
||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
|
||||
/* maximum transfer unit */
|
||||
netif->mtu = 1500;
|
||||
|
||||
/* device capabilities */
|
||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
|
||||
|
||||
#if LWIP_IGMP
|
||||
netif->flags |= NETIF_FLAG_IGMP;
|
||||
#endif
|
||||
/* Do whatever else is needed to initialize interface. */
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief LWIP low-level AI/O sending callback function, it is to free pbuf
|
||||
*
|
||||
* @param aio AI/O control block pointer
|
||||
*
|
||||
* @return 0 meaning successs
|
||||
*/
|
||||
static int low_level_send_cb(esp_aio_t* aio)
|
||||
{
|
||||
struct pbuf* pbuf = aio->arg;
|
||||
|
||||
#if ESP_TCP_TXRX_PBUF_DEBUG
|
||||
wifi_tx_status_t* status = (wifi_tx_status_t*) & (aio->ret);
|
||||
if (TX_STATUS_SUCCESS != status->wifi_tx_result) {
|
||||
uint8_t* buf = (uint8_t*)pbuf->payload;
|
||||
|
||||
/*Check if pbuf is tcp ip*/
|
||||
if (buf[12] == 0x08 && buf[13] == 0x00 && buf[23] == 0x06) {
|
||||
tcp_print_status(WIFI_SEND_DATA_FAILED, (void*)pbuf, aio->ret ,0, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ESP_TCP
|
||||
wifi_tx_status_t* status = (wifi_tx_status_t*) & (aio->ret);
|
||||
|
||||
if ((TX_STATUS_SUCCESS != status->wifi_tx_result) && check_pbuf_to_insert(pbuf)) {
|
||||
uint8_t* buf = (uint8_t*)pbuf->payload;
|
||||
struct eth_hdr ethhdr;
|
||||
|
||||
if (*(buf - 17) & 0x01) { //From DS
|
||||
memcpy(ðhdr.dest, buf - 2, ETH_HWADDR_LEN);
|
||||
memcpy(ðhdr.src, buf - 2 - ETH_HWADDR_LEN, ETH_HWADDR_LEN);
|
||||
} else if (*(buf - 17) & 0x02) { //To DS
|
||||
memcpy(ðhdr.dest, buf - 2 - ETH_HWADDR_LEN - ETH_HWADDR_LEN, ETH_HWADDR_LEN);
|
||||
memcpy(ðhdr.src, buf - 2, 6);
|
||||
} else {
|
||||
pbuf_free(pbuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(buf, ðhdr, (ETH_HWADDR_LEN + ETH_HWADDR_LEN));
|
||||
LWIP_DEBUGF(PBUF_CACHE_DEBUG, ("Send packet fail: result:%d, LRC:%d, SRC:%d, RATE:%d",
|
||||
status->wifi_tx_result, status->wifi_tx_lrc, status->wifi_tx_src, status->wifi_tx_rate));
|
||||
insert_to_list(aio->fd, aio->arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
pbuf_free(pbuf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief transform custom pbuf to LWIP core pbuf, LWIP may use input custom pbuf
|
||||
* to send ARP data directly
|
||||
*
|
||||
* @param pbuf LWIP pbuf pointer
|
||||
*
|
||||
* @return LWIP pbuf pointer which it not "PBUF_FLAG_IS_CUSTOM" attribute
|
||||
*/
|
||||
static inline struct pbuf* ethernetif_transform_pbuf(struct pbuf* pbuf)
|
||||
{
|
||||
struct pbuf* p;
|
||||
|
||||
if (!(pbuf->flags & PBUF_FLAG_IS_CUSTOM) && IS_DRAM(pbuf->payload)) {
|
||||
/*
|
||||
* Add ref to pbuf to avoid it to be freed by upper layer.
|
||||
*/
|
||||
pbuf_ref(pbuf);
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
p = pbuf_alloc(PBUF_RAW, pbuf->len, PBUF_RAM);
|
||||
|
||||
if (!p) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (IS_IRAM(p->payload)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: data in IRAM\n"));
|
||||
pbuf_free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(p->payload, pbuf->payload, pbuf->len);
|
||||
|
||||
/*
|
||||
* The input pbuf(named "pbuf") should not be freed, becasue it will be
|
||||
* freed by upper layer.
|
||||
*
|
||||
* The output pbuf(named "p") should not be freed either, becasue it will
|
||||
* be freed at callback function "low_level_send_cb".
|
||||
*/
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function should do the actual transmission of the packet. The packet is
|
||||
* contained in the pbuf that is passed to the function. This pbuf
|
||||
* might be chained.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @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 int8_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
|
||||
* dropped because of memory failure (except for the TCP timers).
|
||||
*/
|
||||
|
||||
static int8_t low_level_output(struct netif* netif, struct pbuf* p)
|
||||
{
|
||||
esp_aio_t aio;
|
||||
int8_t err = ERR_OK;
|
||||
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: netif is NULL\n"));
|
||||
return ERR_ARG;
|
||||
}
|
||||
|
||||
if (!netif_is_up(netif)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: netif is not up\n"));
|
||||
return ERR_RTE;
|
||||
}
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */
|
||||
#endif
|
||||
|
||||
p = ethernetif_transform_pbuf(p);
|
||||
|
||||
if (!p) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("low_level_output: lack memory\n"));
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
aio.fd = (int)netif->state;
|
||||
aio.pbuf = p->payload;
|
||||
aio.len = p->len;
|
||||
aio.cb = low_level_send_cb;
|
||||
aio.arg = p;
|
||||
aio.ret = 0;
|
||||
|
||||
#if ESP_TCP_TXRX_PBUF_DEBUG
|
||||
tcp_print_status(LWIP_SEND_DATA_TO_WIFI, (void*)p, 0 ,0, 0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* we use "SOCK_RAW" to create socket, so all input/output datas include full ethernet
|
||||
* header, meaning we should not pass target low-level address here.
|
||||
*/
|
||||
err = ieee80211_output_pbuf(&aio);
|
||||
if (err != ERR_OK) {
|
||||
if (err == ERR_MEM) {
|
||||
#if ESP_TCP
|
||||
insert_to_list(aio.fd, p);
|
||||
#endif
|
||||
err = ERR_OK;
|
||||
}
|
||||
|
||||
pbuf_free(p);
|
||||
}
|
||||
|
||||
// signal that packet should be sent();
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
|
||||
#endif
|
||||
|
||||
#if LWIP_STATS
|
||||
LINK_STATS_INC(link.xmit);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ethernetif_input(struct netif* netif, struct pbuf* p)
|
||||
{
|
||||
struct eth_hdr* ethhdr;
|
||||
|
||||
if (p == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: pbuf is NULL\n"));
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (p->payload == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: payload is NULL\n"));
|
||||
pbuf_free(p);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: netif is NULL\n"));
|
||||
pbuf_free(p);
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
if (!(netif->flags & NETIF_FLAG_LINK_UP)) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: netif is not up\n"));
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
/* points to packet payload, which starts with an Ethernet header */
|
||||
ethhdr = p->payload;
|
||||
|
||||
switch (htons(ethhdr->type)) {
|
||||
/* IP or ARP packet? */
|
||||
case ETHTYPE_IP:
|
||||
case ETHTYPE_IPV6:
|
||||
case ETHTYPE_ARP:
|
||||
#if PPPOE_SUPPORT
|
||||
|
||||
/* PPPoE packet? */
|
||||
case ETHTYPE_PPPOEDISC:
|
||||
case ETHTYPE_PPPOE:
|
||||
#endif /* PPPOE_SUPPORT */
|
||||
|
||||
/* full packet send to tcpip_thread to process */
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
pbuf_free(p);
|
||||
p = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
_exit:
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* actual setup of the hardware.
|
||||
*
|
||||
* This function should be passed as a parameter to netif_add().
|
||||
*
|
||||
* @param netif the lwip network interface structure for this ethernetif
|
||||
* @return ERR_OK if the loopif is initialized
|
||||
* ERR_MEM if private data couldn't be allocated
|
||||
* any other int8_t on error
|
||||
*/
|
||||
int8_t ethernetif_init(struct netif* netif)
|
||||
{
|
||||
if (netif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: netif is NULL\n"));
|
||||
}
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
|
||||
#if ESP_LWIP
|
||||
netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
|
||||
#else
|
||||
netif->hostname = "lwip";
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
/*
|
||||
* Initialize the snmp variables and counters inside the struct netif.
|
||||
* The last argument should be replaced with your link speed, in units
|
||||
* of bits per second.
|
||||
*/
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
/* We directly use etharp_output() here to save a function call.
|
||||
* You can instead declare your own function an call etharp_output()
|
||||
* from it if you have to do some checks before sending (e.g. if link
|
||||
* is available...) */
|
||||
netif->output = etharp_output;
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
|
||||
/* initialize the hardware */
|
||||
low_level_init(netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
@ -21,35 +21,28 @@
|
||||
#include "esp_vfs.h"
|
||||
#include "esp_vfs_dev.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp8266/uart_struct.h"
|
||||
#include "lwip/sockets.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
_Static_assert(MAX_FDS >= CONFIG_LWIP_MAX_SOCKETS, "MAX_FDS < CONFIG_LWIP_MAX_SOCKETS");
|
||||
|
||||
static void lwip_stop_socket_select(void *sem)
|
||||
static void lwip_stop_socket_select()
|
||||
{
|
||||
sys_sem_signal(sem); //socket_select will return
|
||||
sys_sem_signal(sys_thread_sem_get()); //socket_select will return
|
||||
}
|
||||
|
||||
static void lwip_stop_socket_select_isr(void *sem, BaseType_t *woken)
|
||||
static void lwip_stop_socket_select_isr(BaseType_t *woken)
|
||||
{
|
||||
if (sys_sem_signal_isr(sem) && woken) {
|
||||
if (sys_sem_signal_isr(sys_thread_sem_get()) && woken) {
|
||||
*woken = pdTRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void *lwip_get_socket_select_semaphore(void)
|
||||
static int lwip_fcntl_r_wrapper(int fd, int cmd, va_list args)
|
||||
{
|
||||
/* Calling this from the same process as select() will ensure that the semaphore won't be allocated from
|
||||
* ISR (lwip_stop_socket_select_isr).
|
||||
*/
|
||||
return (void *) sys_thread_sem_get();
|
||||
}
|
||||
|
||||
static int lwip_fcntl_r_wrapper(int fd, int cmd, int arg)
|
||||
{
|
||||
return lwip_fcntl(fd, cmd, arg);
|
||||
return lwip_fcntl(fd, cmd, va_arg(args, int));
|
||||
}
|
||||
|
||||
static int lwip_ioctl_r_wrapper(int fd, int cmd, va_list args)
|
||||
@ -69,7 +62,6 @@ void esp_vfs_lwip_sockets_register(void)
|
||||
.fcntl = &lwip_fcntl_r_wrapper,
|
||||
.ioctl = &lwip_ioctl_r_wrapper,
|
||||
.socket_select = &lwip_select,
|
||||
.get_socket_select_semaphore = &lwip_get_socket_select_semaphore,
|
||||
.stop_socket_select = &lwip_stop_socket_select,
|
||||
.stop_socket_select_isr = &lwip_stop_socket_select_isr,
|
||||
};
|
@ -142,5 +142,5 @@
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "task.h"
|
||||
#include "driver/soc.h"
|
||||
|
||||
#include "limits.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#ifdef CONFIG_ESP8266_TIME_SYSCALL_USE_FRC1
|
||||
@ -35,6 +36,20 @@
|
||||
|
||||
static uint64_t s_boot_time;
|
||||
|
||||
#if defined(WITH_RTC) || defined(WITH_FRC)
|
||||
// stores the start time of the slew
|
||||
static uint64_t adjtime_start = 0;
|
||||
// is how many microseconds total to slew
|
||||
static int64_t adjtime_total_correction = 0;
|
||||
#define ADJTIME_CORRECTION_FACTOR 6
|
||||
static uint64_t get_time_since_boot(void);
|
||||
#endif
|
||||
// Offset between FRC timer and the RTC.
|
||||
// Initialized after reset or light sleep.
|
||||
#if defined(WITH_RTC) && defined(WITH_FRC)
|
||||
uint64_t s_microseconds_offset;
|
||||
#endif
|
||||
|
||||
static inline void set_boot_time(uint64_t time_us)
|
||||
{
|
||||
esp_irqflag_t flag;
|
||||
@ -56,6 +71,103 @@ static inline uint64_t get_boot_time()
|
||||
return result;
|
||||
}
|
||||
|
||||
// This function gradually changes boot_time to the correction value and immediately updates it.
|
||||
static uint64_t adjust_boot_time(void)
|
||||
{
|
||||
uint64_t boot_time = get_boot_time();
|
||||
if ((boot_time == 0) || (get_time_since_boot() < adjtime_start)) {
|
||||
adjtime_start = 0;
|
||||
}
|
||||
if (adjtime_start > 0) {
|
||||
uint64_t since_boot = get_time_since_boot();
|
||||
// If to call this function once per second, then (since_boot - adjtime_start) will be 1_000_000 (1 second),
|
||||
// and the correction will be equal to (1_000_000us >> 6) = 15_625 us.
|
||||
// The minimum possible correction step can be (64us >> 6) = 1us.
|
||||
// Example: if the time error is 1 second, then it will be compensate for 1 sec / 0,015625 = 64 seconds.
|
||||
int64_t correction = (since_boot >> ADJTIME_CORRECTION_FACTOR) - (adjtime_start >> ADJTIME_CORRECTION_FACTOR);
|
||||
if (correction > 0) {
|
||||
adjtime_start = since_boot;
|
||||
if (adjtime_total_correction < 0) {
|
||||
if ((adjtime_total_correction + correction) >= 0) {
|
||||
boot_time = boot_time + adjtime_total_correction;
|
||||
adjtime_start = 0;
|
||||
} else {
|
||||
adjtime_total_correction += correction;
|
||||
boot_time -= correction;
|
||||
}
|
||||
} else {
|
||||
if ((adjtime_total_correction - correction) <= 0) {
|
||||
boot_time = boot_time + adjtime_total_correction;
|
||||
adjtime_start = 0;
|
||||
} else {
|
||||
adjtime_total_correction -= correction;
|
||||
boot_time += correction;
|
||||
}
|
||||
}
|
||||
set_boot_time(boot_time);
|
||||
}
|
||||
}
|
||||
return boot_time;
|
||||
}
|
||||
|
||||
#if defined( WITH_FRC ) || defined( WITH_RTC )
|
||||
static uint64_t get_time_since_boot(void)
|
||||
{
|
||||
uint64_t microseconds = 0;
|
||||
#ifdef WITH_FRC
|
||||
#ifdef WITH_RTC
|
||||
microseconds = s_microseconds_offset + esp_timer_get_time();
|
||||
#else
|
||||
microseconds = esp_timer_get_time();
|
||||
#endif // WITH_RTC
|
||||
#elif defined(WITH_RTC)
|
||||
microseconds = get_rtc_time_us();
|
||||
#endif // WITH_FRC
|
||||
return microseconds;
|
||||
}
|
||||
#endif // defined( WITH_FRC ) || defined( WITH_RTC
|
||||
|
||||
int adjtime(const struct timeval *delta, struct timeval *outdelta)
|
||||
{
|
||||
#if defined( WITH_FRC ) || defined( WITH_RTC )
|
||||
esp_irqflag_t flag;
|
||||
if(delta != NULL){
|
||||
int64_t sec = delta->tv_sec;
|
||||
int64_t usec = delta->tv_usec;
|
||||
if(llabs(sec) > ((INT_MAX / 1000000L) - 1L)) {
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
* If adjusting the system clock by adjtime () is already done during the second call adjtime (),
|
||||
* and the delta of the second call is not NULL, the earlier tuning is stopped,
|
||||
* but the already completed part of the adjustment is not canceled.
|
||||
*/
|
||||
flag = soc_save_local_irq();
|
||||
// If correction is already in progress (adjtime_start != 0), then apply accumulated corrections.
|
||||
adjust_boot_time();
|
||||
adjtime_start = get_time_since_boot();
|
||||
adjtime_total_correction = sec * 1000000L + usec;
|
||||
soc_restore_local_irq(flag);
|
||||
}
|
||||
if(outdelta != NULL){
|
||||
flag = soc_save_local_irq();
|
||||
adjust_boot_time();
|
||||
if (adjtime_start != 0) {
|
||||
outdelta->tv_sec = adjtime_total_correction / 1000000L;
|
||||
outdelta->tv_usec = adjtime_total_correction % 1000000L;
|
||||
} else {
|
||||
outdelta->tv_sec = 0;
|
||||
outdelta->tv_usec = 0;
|
||||
}
|
||||
soc_restore_local_irq(flag);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
int _gettimeofday_r(struct _reent* r, struct timeval* tv, void* tz)
|
||||
{
|
||||
(void) tz;
|
||||
|
@ -2,6 +2,7 @@ menu "PThreads"
|
||||
|
||||
config ENABLE_PTHREAD
|
||||
bool "Enable Pthread"
|
||||
default y
|
||||
help
|
||||
Enable this option and then pthread is to be used.
|
||||
|
||||
|
@ -127,11 +127,12 @@ typedef struct {
|
||||
#define ESP_ERR_TCPIP_ADAPTER_NO_MEM ESP_ERR_TCPIP_ADAPTER_BASE + 0x06
|
||||
#define ESP_ERR_TCPIP_ADAPTER_DHCP_NOT_STOPPED ESP_ERR_TCPIP_ADAPTER_BASE + 0x07
|
||||
|
||||
/* TODO: add Ethernet interface */
|
||||
/* @brief On-chip network interfaces */
|
||||
typedef enum {
|
||||
TCPIP_ADAPTER_IF_STA = 0, /**< TCP-IP adatpter station interface */
|
||||
TCPIP_ADAPTER_IF_AP, /**< TCP-IP adatpter soft-AP interface */
|
||||
TCPIP_ADAPTER_IF_ETH, /**< TCP-IP adatpter ethernet interface */
|
||||
TCPIP_ADAPTER_IF_STA = 0, /**< Wi-Fi STA (station) interface */
|
||||
TCPIP_ADAPTER_IF_AP, /**< Wi-Fi soft-AP interface */
|
||||
TCPIP_ADAPTER_IF_ETH, /**< Ethernet interface */
|
||||
TCPIP_ADAPTER_IF_TEST, /**< tcpip stack test interface */
|
||||
TCPIP_ADAPTER_IF_MAX
|
||||
} tcpip_adapter_if_t;
|
||||
|
||||
@ -660,6 +661,15 @@ esp_err_t tcpip_adapter_set_default_wifi_handlers();
|
||||
*/
|
||||
esp_err_t tcpip_adapter_clear_default_wifi_handlers();
|
||||
|
||||
/**
|
||||
* @brief Search nefit index through netif interface
|
||||
* @param[in] tcpip_if Interface to search for netif index
|
||||
* @return
|
||||
* - netif_index on success
|
||||
* - -1 if an invalid parameter is supplied
|
||||
*/
|
||||
int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1223,28 +1223,6 @@ esp_err_t tcpip_adapter_get_netif(tcpip_adapter_if_t tcpip_if, void ** netif)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
struct netif* ip4_route_src_hook(const ip4_addr_t* dest, const ip4_addr_t* src)
|
||||
{
|
||||
extern struct netif *netif_list;
|
||||
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;
|
||||
}
|
||||
|
||||
bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if)
|
||||
{
|
||||
if (esp_netif[tcpip_if] != NULL && netif_is_up(esp_netif[tcpip_if])) {
|
||||
@ -1254,4 +1232,12 @@ bool tcpip_adapter_is_netif_up(tcpip_adapter_if_t tcpip_if)
|
||||
}
|
||||
}
|
||||
|
||||
int tcpip_adapter_get_netif_index(tcpip_adapter_if_t tcpip_if)
|
||||
{
|
||||
if (tcpip_if >= TCPIP_ADAPTER_IF_MAX || esp_netif[tcpip_if] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return netif_get_index(esp_netif[tcpip_if]);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TCPIP_LWIP */
|
||||
|
@ -2,14 +2,14 @@ menu "Virtual file system"
|
||||
|
||||
config USING_ESP_VFS
|
||||
bool "Using espressif VFS"
|
||||
default n
|
||||
default y
|
||||
help
|
||||
Enable this option, espressif VFS can be used. Users can use APIs like "open", "read", "write"
|
||||
and so on to operate I/O device which is registered.
|
||||
|
||||
config SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||
bool "Suppress select() related debug outputs"
|
||||
default y
|
||||
default n
|
||||
depends on USING_ESP_VFS
|
||||
help
|
||||
Select() related functions might produce an unconveniently lot of
|
||||
@ -19,7 +19,7 @@ config SUPPRESS_SELECT_DEBUG_OUTPUT
|
||||
|
||||
config SUPPORT_TERMIOS
|
||||
bool "Add support for termios.h"
|
||||
default y
|
||||
default n
|
||||
depends on USING_ESP_VFS
|
||||
help
|
||||
Disabling this option can save memory when the support for termios.h is not required.
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "esp_err.h"
|
||||
@ -27,6 +28,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/poll.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
@ -379,6 +381,21 @@ void esp_vfs_select_triggered(SemaphoreHandle_t *signal_sem);
|
||||
*/
|
||||
void esp_vfs_select_triggered_isr(SemaphoreHandle_t *signal_sem, BaseType_t *woken);
|
||||
|
||||
/**
|
||||
* @brief Implements the VFS layer for synchronous I/O multiplexing by poll()
|
||||
*
|
||||
* The implementation is based on esp_vfs_select. The parameters and return values are compatible with POSIX poll().
|
||||
*
|
||||
* @param fds Pointer to the array containing file descriptors and events poll() should consider.
|
||||
* @param nfds Number of items in the array fds.
|
||||
* @param timeout Poll() should wait at least timeout milliseconds. If the value is 0 then it should return
|
||||
* immediately. If the value is -1 then it should wait (block) until the event occurs.
|
||||
*
|
||||
* @return A positive return value indicates the number of file descriptors that have been selected. The 0
|
||||
* return value indicates a timed-out poll. -1 is return on failure and errno is set accordingly.
|
||||
*
|
||||
*/
|
||||
int esp_vfs_poll(struct pollfd *fds, int nfds, int timeout);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -1096,3 +1096,80 @@ int tcsendbreak(int fd, int duration)
|
||||
return ret;
|
||||
}
|
||||
#endif // CONFIG_SUPPORT_TERMIOS
|
||||
|
||||
int esp_vfs_poll(struct pollfd *fds, int nfds, int timeout)
|
||||
{
|
||||
struct timeval tv = {
|
||||
// timeout is in milliseconds
|
||||
.tv_sec = timeout / 1000,
|
||||
.tv_usec = (timeout % 1000) * 1000,
|
||||
};
|
||||
int max_fd = -1;
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
fd_set errorfds;
|
||||
struct _reent* r = __getreent();
|
||||
int ret = 0;
|
||||
|
||||
if (fds == NULL) {
|
||||
__errno_r(r) = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_ZERO(&writefds);
|
||||
FD_ZERO(&errorfds);
|
||||
|
||||
for (int i = 0; i < nfds; ++i) {
|
||||
fds[i].revents = 0;
|
||||
|
||||
if (fds[i].fd < 0) {
|
||||
// revents should remain 0 and events ignored (according to the documentation of poll()).
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fds[i].fd >= MAX_FDS) {
|
||||
fds[i].revents |= POLLNVAL;
|
||||
++ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fds[i].events & (POLLIN | POLLRDNORM | POLLRDBAND | POLLPRI)) {
|
||||
FD_SET(fds[i].fd, &readfds);
|
||||
FD_SET(fds[i].fd, &errorfds);
|
||||
max_fd = MAX(max_fd, fds[i].fd);
|
||||
}
|
||||
|
||||
if (fds[i].events & (POLLOUT | POLLWRNORM | POLLWRBAND)) {
|
||||
FD_SET(fds[i].fd, &writefds);
|
||||
FD_SET(fds[i].fd, &errorfds);
|
||||
max_fd = MAX(max_fd, fds[i].fd);
|
||||
}
|
||||
}
|
||||
|
||||
const int select_ret = esp_vfs_select(max_fd + 1, &readfds, &writefds, &errorfds, timeout < 0 ? NULL: &tv);
|
||||
|
||||
if (select_ret > 0) {
|
||||
ret += select_ret;
|
||||
|
||||
for (int i = 0; i < nfds; ++i) {
|
||||
if (FD_ISSET(fds[i].fd, &readfds)) {
|
||||
fds[i].revents |= POLLIN;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fds[i].fd, &writefds)) {
|
||||
fds[i].revents |= POLLOUT;
|
||||
}
|
||||
|
||||
if (FD_ISSET(fds[i].fd, &errorfds)) {
|
||||
fds[i].revents |= POLLERR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = select_ret;
|
||||
// keeping the errno from select()
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ static void openssl_client_task(void* p)
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
|
||||
int socket;
|
||||
int sockfd;
|
||||
struct sockaddr_in sock_addr;
|
||||
struct hostent* entry = NULL;
|
||||
int recv_bytes = 0;
|
||||
@ -108,9 +108,9 @@ static void openssl_client_task(void* p)
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
|
||||
printf("create socket ......");
|
||||
socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (socket < 0) {
|
||||
if (sockfd < 0) {
|
||||
printf("failed\n");
|
||||
goto failed3;
|
||||
}
|
||||
@ -122,7 +122,7 @@ static void openssl_client_task(void* p)
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_addr.s_addr = 0;
|
||||
sock_addr.sin_port = htons(OPENSSL_CLIENT_LOCAL_TCP_PORT);
|
||||
ret = bind(socket, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||
ret = bind(sockfd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||
|
||||
if (ret) {
|
||||
printf("failed\n");
|
||||
@ -136,7 +136,7 @@ static void openssl_client_task(void* p)
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_addr.s_addr = ((struct in_addr*)(entry->h_addr))->s_addr;
|
||||
sock_addr.sin_port = htons(CONFIG_TARGET_PORT_NUMBER);
|
||||
ret = connect(socket, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||
ret = connect(sockfd, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
|
||||
|
||||
if (ret) {
|
||||
printf("failed\n");
|
||||
@ -155,7 +155,7 @@ static void openssl_client_task(void* p)
|
||||
|
||||
printf("OK\n");
|
||||
|
||||
SSL_set_fd(ssl, socket);
|
||||
SSL_set_fd(ssl, sockfd);
|
||||
|
||||
printf("SSL connected to %s port %d ......", CONFIG_TARGET_DOMAIN, CONFIG_TARGET_PORT_NUMBER);
|
||||
ret = SSL_connect(ssl);
|
||||
@ -198,7 +198,7 @@ failed7:
|
||||
failed6:
|
||||
failed5:
|
||||
failed4:
|
||||
close(socket);
|
||||
close(sockfd);
|
||||
failed3:
|
||||
failed2:
|
||||
SSL_CTX_free(ctx);
|
||||
|
@ -46,7 +46,7 @@ static void openssl_task(void *p)
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
|
||||
int socket;
|
||||
int sockfd;
|
||||
struct sockaddr_in sock_addr;
|
||||
struct hostent *entry = NULL;
|
||||
|
||||
@ -80,9 +80,9 @@ static void openssl_task(void *p)
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
ESP_LOGI(TAG, "create socket ......");
|
||||
socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (socket < 0) {
|
||||
if (sockfd < 0) {
|
||||
ESP_LOGI(TAG, "failed");
|
||||
goto failed2;
|
||||
}
|
||||
@ -94,7 +94,7 @@ static void openssl_task(void *p)
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_addr.s_addr = 0;
|
||||
sock_addr.sin_port = htons(OPENSSL_DEMO_LOCAL_TCP_PORT);
|
||||
ret = bind(socket, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
|
||||
ret = bind(sockfd, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
|
||||
|
||||
if (ret) {
|
||||
ESP_LOGI(TAG, "failed");
|
||||
@ -108,7 +108,7 @@ static void openssl_task(void *p)
|
||||
sock_addr.sin_family = AF_INET;
|
||||
sock_addr.sin_addr.s_addr = ((struct in_addr *)(entry->h_addr))->s_addr;
|
||||
sock_addr.sin_port = htons(OPENSSL_DEMO_TARGET_TCP_PORT);
|
||||
ret = connect(socket, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
|
||||
ret = connect(sockfd, (struct sockaddr *)&sock_addr, sizeof(sock_addr));
|
||||
|
||||
if (ret) {
|
||||
ESP_LOGI(TAG, "failed\n");
|
||||
@ -127,7 +127,7 @@ static void openssl_task(void *p)
|
||||
|
||||
ESP_LOGI(TAG, "OK");
|
||||
|
||||
SSL_set_fd(ssl, socket);
|
||||
SSL_set_fd(ssl, sockfd);
|
||||
|
||||
ESP_LOGI(TAG, "SSL connected to %s port %d ......", OPENSSL_DEMO_TARGET_NAME, OPENSSL_DEMO_TARGET_TCP_PORT);
|
||||
ret = SSL_connect(ssl);
|
||||
@ -169,7 +169,7 @@ failed6:
|
||||
failed5:
|
||||
failed4:
|
||||
failed3:
|
||||
close(socket);
|
||||
close(sockfd);
|
||||
failed2:
|
||||
SSL_CTX_free(ctx);
|
||||
failed1:
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "protocol_examples_common.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "tcpip_adapter.h"
|
||||
|
||||
#include "lwip/err.h"
|
||||
#include "lwip/sockets.h"
|
||||
@ -161,9 +162,10 @@ err:
|
||||
static int create_multicast_ipv6_socket()
|
||||
{
|
||||
struct sockaddr_in6 saddr = { 0 };
|
||||
int netif_index;
|
||||
struct in6_addr if_inaddr = { 0 };
|
||||
struct ip6_addr if_ipaddr = { 0 };
|
||||
struct ip6_mreq v6imreq = { 0 };
|
||||
struct ipv6_mreq v6imreq = { 0 };
|
||||
int sock = -1;
|
||||
int err = 0;
|
||||
|
||||
@ -201,9 +203,14 @@ static int create_multicast_ipv6_socket()
|
||||
}
|
||||
#endif
|
||||
|
||||
// search for netif index
|
||||
netif_index = tcpip_adapter_get_netif_index(TCPIP_ADAPTER_IF_STA);
|
||||
if(netif_index < 0) {
|
||||
ESP_LOGE(V6TAG, "Failed to get netif index");
|
||||
goto err;
|
||||
}
|
||||
// Assign the multicast source interface, via its IP
|
||||
err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &if_inaddr,
|
||||
sizeof(struct in6_addr));
|
||||
err = setsockopt(sock, IPPROTO_IPV6, IPV6_MULTICAST_IF, &netif_index,sizeof(uint8_t));
|
||||
if (err < 0) {
|
||||
ESP_LOGE(V6TAG, "Failed to set IPV6_MULTICAST_IF. Error %d", errno);
|
||||
goto err;
|
||||
@ -231,13 +238,6 @@ static int create_multicast_ipv6_socket()
|
||||
|
||||
// this is also a listening socket, so add it to the multicast
|
||||
// group for listening...
|
||||
|
||||
// Configure source interface
|
||||
#if USE_DEFAULT_IF
|
||||
v6imreq.imr_interface.s_addr = IPADDR_ANY;
|
||||
#else
|
||||
inet6_addr_from_ip6addr(&v6imreq.ipv6mr_interface, &if_ipaddr);
|
||||
#endif
|
||||
#ifdef CONFIG_EXAMPLE_IPV6
|
||||
// Configure multicast address to listen to
|
||||
err = inet6_aton(MULTICAST_IPV6_ADDR, &v6imreq.ipv6mr_multiaddr);
|
||||
@ -251,9 +251,10 @@ static int create_multicast_ipv6_socket()
|
||||
if (!ip6_addr_ismulticast(&multi_addr)) {
|
||||
ESP_LOGW(V6TAG, "Configured IPV6 multicast address '%s' is not a valid multicast address. This will probably not work.", MULTICAST_IPV6_ADDR);
|
||||
}
|
||||
|
||||
// Configure source interface
|
||||
v6imreq.ipv6mr_interface = (unsigned int)netif_index;
|
||||
err = setsockopt(sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
|
||||
&v6imreq, sizeof(struct ip6_mreq));
|
||||
&v6imreq, sizeof(struct ipv6_mreq));
|
||||
if (err < 0) {
|
||||
ESP_LOGE(V6TAG, "Failed to set IPV6_ADD_MEMBERSHIP. Error %d", errno);
|
||||
goto err;
|
||||
|
Reference in New Issue
Block a user