feat(lwip): update lwip component according to IDF

commit ID: 79a5b0b5
This commit is contained in:
yuanjm
2020-07-16 20:23:43 +08:00
parent da3362ecab
commit ef2c714c06
23 changed files with 613 additions and 435 deletions

View File

@ -41,9 +41,7 @@
#include "lwip/stats.h"
#include "esp_log.h"
/* This is the number of threads that can be started with sys_thread_new() */
#define SYS_THREAD_MAX 4
#define TAG "lwip_arch"
static const char* TAG = "lwip_arch";
static sys_mutex_t g_lwip_protect_mutex = NULL;
@ -51,160 +49,167 @@ static pthread_key_t sys_thread_sem_key;
static void sys_thread_sem_free(void* data);
#if !LWIP_COMPAT_MUTEX
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
/**
* @brief Create a new mutex
*
* @param pxMutex pointer of the mutex to create
* @return ERR_OK on success, ERR_MEM when out of memory
*/
err_t
sys_mutex_new(sys_mutex_t *pxMutex)
{
err_t xReturn = ERR_MEM;
*pxMutex = xSemaphoreCreateMutex();
if (*pxMutex != NULL) {
xReturn = ERR_OK;
if (*pxMutex == NULL) {
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_new: out of mem\r\n"));
return ERR_MEM;
}
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_new: m=%p\n", *pxMutex));
return xReturn;
return ERR_OK;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void ESP_IRAM_ATTR
/**
* @brief Lock a mutex
*
* @param pxMutex pointer of mutex to lock
*/
void
sys_mutex_lock(sys_mutex_t *pxMutex)
{
while (xSemaphoreTake(*pxMutex, portMAX_DELAY) != pdPASS);
BaseType_t ret = xSemaphoreTake(*pxMutex, portMAX_DELAY);
LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
}
err_t
sys_mutex_trylock(sys_mutex_t *pxMutex)
{
if (xSemaphoreTake(*pxMutex, 0) == pdPASS) return 0;
else return -1;
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void ESP_IRAM_ATTR
/**
* @brief Unlock a mutex
*
* @param pxMutex pointer of mutex to unlock
*/
void
sys_mutex_unlock(sys_mutex_t *pxMutex)
{
xSemaphoreGive(*pxMutex);
BaseType_t ret = xSemaphoreGive(*pxMutex);
LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
}
/** Delete a semaphore
* @param mutex the mutex to delete */
/**
* @brief Delete a mutex
*
* @param pxMutex pointer of mutex to delete
*/
void
sys_mutex_free(sys_mutex_t *pxMutex)
{
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_mutex_free: m=%p\n", *pxMutex));
vQueueDelete(*pxMutex);
vSemaphoreDelete(*pxMutex);
*pxMutex = NULL;
}
#endif
/*-----------------------------------------------------------------------------------*/
// Creates and returns a new semaphore. The "count" argument specifies
// the initial state of the semaphore. TBD finish and test
#endif /* !LWIP_COMPAT_MUTEX */
/**
* @brief Creates a new semaphore
*
* @param sem pointer of the semaphore
* @param count initial state of the semaphore
* @return err_t
*/
err_t
sys_sem_new(sys_sem_t *sem, u8_t count)
{
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary(*sem);
LWIP_ASSERT("initial_count invalid (neither 0 nor 1)",
(count == 0) || (count == 1));
if ((*sem) != NULL) {
if (count == 0) { // Means it can't be taken
xSemaphoreTake(*sem, 1);
}
xReturn = ERR_OK;
} else {
; // TBD need assert
*sem = xSemaphoreCreateBinary();
if (*sem == NULL) {
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("sys_sem_new: out of mem\r\n"));
return ERR_MEM;
}
return xReturn;
if (count == 1) {
BaseType_t ret = xSemaphoreGive(*sem);
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
}
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore
void ESP_IRAM_ATTR
/**
* @brief Signals a semaphore
*
* @param sem pointer of the semaphore
*/
void
sys_sem_signal(sys_sem_t *sem)
{
xSemaphoreGive(*sem);
BaseType_t ret = xSemaphoreGive(*sem);
/* queue full is OK, this is a signal only... */
LWIP_ASSERT("sys_sem_signal: sane return value",
(ret == pdTRUE) || (ret == errQUEUE_FULL));
}
/*-----------------------------------------------------------------------------------*/
// Signals a semaphore (from ISR)
int sys_sem_signal_isr(sys_sem_t *sem)
int
sys_sem_signal_isr(sys_sem_t *sem)
{
BaseType_t woken = pdFALSE;
xSemaphoreGiveFromISR(*sem, &woken);
return woken == pdTRUE;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread while waiting for the semaphore to be
signaled. If the "timeout" argument is non-zero, the thread should
only be blocked for the specified time (measured in
milliseconds).
If the timeout argument is non-zero, the return value is the number of
milliseconds spent waiting for the semaphore to be signaled. If the
semaphore wasn't signaled within the specified time, the return value is
SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
(i.e., it was already signaled), the function may return zero.
Notice that lwIP implements a function with a similar name,
sys_sem_wait(), that uses the sys_arch_sem_wait() function.
*/
u32_t ESP_IRAM_ATTR
/**
* @brief Wait for a semaphore to be signaled
*
* @param sem pointer of the semaphore
* @param timeout if zero, will wait infinitely, or will wait for milliseconds specify by this argument
* @return SYS_ARCH_TIMEOUT when timeout, 0 otherwise
*/
u32_t
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
portTickType StartTime, EndTime, Elapsed;
unsigned long ulReturn;
BaseType_t ret;
StartTime = xTaskGetTickCount();
if (timeout != 0) {
if (xSemaphoreTake(*sem, timeout / portTICK_PERIOD_MS) == pdTRUE) {
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
if (Elapsed == 0) {
Elapsed = 1;
}
ulReturn = Elapsed;
} else {
ulReturn = SYS_ARCH_TIMEOUT;
if (!timeout) {
/* wait infinite */
ret = xSemaphoreTake(*sem, portMAX_DELAY);
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
} else {
TickType_t timeout_ticks = timeout / portTICK_RATE_MS;
ret = xSemaphoreTake(*sem, timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
return SYS_ARCH_TIMEOUT;
}
} else { // must block without a timeout
while (xSemaphoreTake(*sem, portMAX_DELAY) != pdTRUE);
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
if (Elapsed == 0) {
Elapsed = 1;
}
ulReturn = Elapsed;
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
}
return ulReturn ; // return time blocked
return 0;
}
/*-----------------------------------------------------------------------------------*/
// Deallocates a semaphore
/**
* @brief Delete a semaphore
*
* @param sem pointer of the semaphore to delete
*/
void
sys_sem_free(sys_sem_t *sem)
{
vSemaphoreDelete(*sem);
*sem = NULL;
}
/*-----------------------------------------------------------------------------------*/
// Creates an empty mailbox.
/**
* @brief Create an empty mailbox.
*
* @param mbox pointer of the mailbox
* @param size size of the mailbox
* @return ERR_OK on success, ERR_MEM when out of memory
*/
err_t
sys_mbox_new(sys_mbox_t *mbox, int size)
{
@ -217,7 +222,7 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
(*mbox)->os_mbox = xQueueCreate(size, sizeof(void *));
if ((*mbox)->os_mbox == NULL) {
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new *mbox->os_mbox\n"));
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("fail to new (*mbox)->os_mbox\n"));
free(*mbox);
return ERR_MEM;
}
@ -230,21 +235,32 @@ sys_mbox_new(sys_mbox_t *mbox, int size)
return ERR_OK;
}
/*-----------------------------------------------------------------------------------*/
// Posts the "msg" to the mailbox.
void ESP_IRAM_ATTR
/**
* @brief Send message to mailbox
*
* @param mbox pointer of the mailbox
* @param msg pointer of the message to send
*/
void
sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
while (xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY) != pdTRUE);
BaseType_t ret = xQueueSendToBack((*mbox)->os_mbox, &msg, portMAX_DELAY);
LWIP_ASSERT("mbox post failed", ret == pdTRUE);
}
/*-----------------------------------------------------------------------------------*/
err_t ESP_IRAM_ATTR
/**
* @brief Try to post a message to mailbox
*
* @param mbox pointer of the mailbox
* @param msg pointer of the message to send
* @return ERR_OK on success, ERR_MEM when mailbox is full
*/
err_t
sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
err_t xReturn;
if (xQueueSend((*mbox)->os_mbox, &msg, (portTickType)0) == pdPASS) {
if (xQueueSend((*mbox)->os_mbox, &msg, 0) == pdTRUE) {
xReturn = ERR_OK;
} else {
LWIP_DEBUGF(ESP_THREAD_SAFE_DEBUG, ("trypost mbox=%p fail\n", (*mbox)->os_mbox));
@ -254,83 +270,95 @@ sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
return xReturn;
}
/*-----------------------------------------------------------------------------------*/
/*
Blocks the thread until a message arrives in the mailbox, but does
not block the thread longer than "timeout" milliseconds (similar to
the sys_arch_sem_wait() function). The "msg" argument is a result
parameter that is set by the function (i.e., by doing "*msg =
ptr"). The "msg" parameter maybe NULL to indicate that the message
should be dropped.
/**
* @brief Try to post a message to mailbox from ISR
*
* @param mbox pointer of the mailbox
* @param msg pointer of the message to send
* @return ERR_OK on success
* ERR_MEM when mailbox is full
* ERR_NEED_SCHED when high priority task wakes up
*/
err_t
sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
The return values are the same as for the sys_arch_sem_wait() function:
Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
timeout.
ret = xQueueSendFromISR((*mbox)->os_mbox, &msg, &xHigherPriorityTaskWoken);
if (ret == pdTRUE) {
if (xHigherPriorityTaskWoken == pdTRUE) {
return ERR_NEED_SCHED;
}
return ERR_OK;
} else {
LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
return ERR_MEM;
}
}
Note that a function with a similar name, sys_mbox_fetch(), is
implemented by lwIP.
*/
u32_t ESP_IRAM_ATTR
/**
* @brief Fetch message from mailbox
*
* @param mbox pointer of mailbox
* @param msg pointer of the received message, could be NULL to indicate the message should be dropped
* @param timeout if zero, will wait infinitely; or will wait milliseconds specify by this argument
* @return SYS_ARCH_TIMEOUT when timeout, 0 otherwise
*/
u32_t
sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
void *dummyptr;
portTickType StartTime, EndTime, Elapsed;
unsigned long ulReturn;
BaseType_t ret;
void *msg_dummy;
StartTime = xTaskGetTickCount();
if (msg == NULL) {
msg = &dummyptr;
}
if (*mbox == NULL){
*msg = NULL;
return -1;
msg = &msg_dummy;
}
if (timeout == 0) {
timeout = portMAX_DELAY;
/* wait infinite */
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), portMAX_DELAY);
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
} else {
timeout = timeout / portTICK_PERIOD_MS;
}
*msg = NULL;
if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), timeout)) {
EndTime = xTaskGetTickCount();
Elapsed = (EndTime - StartTime) * portTICK_PERIOD_MS;
if (Elapsed == 0) {
Elapsed = 1;
TickType_t timeout_ticks = timeout / portTICK_RATE_MS;
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
ulReturn = Elapsed;
} else { // timed out blocking for message
ulReturn = SYS_ARCH_TIMEOUT;
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
}
return ulReturn ; // return time blocked TBD test
return 0;
}
/*-----------------------------------------------------------------------------------*/
/**
* @brief try to fetch message from mailbox
*
* @param mbox pointer of mailbox
* @param msg pointer of the received message
* @return SYS_MBOX_EMPTY if mailbox is empty, 1 otherwise
*/
u32_t
sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
void *pvDummy;
unsigned long ulReturn;
BaseType_t ret;
void *msg_dummy;
if (msg == NULL) {
msg = &pvDummy;
msg = &msg_dummy;
}
if (pdTRUE == xQueueReceive((*mbox)->os_mbox, &(*msg), 0)) {
ulReturn = ERR_OK;
} else {
ulReturn = SYS_MBOX_EMPTY;
ret = xQueueReceive((*mbox)->os_mbox, &(*msg), 0);
if (ret == errQUEUE_EMPTY) {
*msg = NULL;
return SYS_MBOX_EMPTY;
}
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
return ulReturn;
return 0;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_set_owner(sys_mbox_t *mbox, void* owner)
{
@ -340,112 +368,128 @@ sys_mbox_set_owner(sys_mbox_t *mbox, void* owner)
}
}
/*
Deallocates a mailbox. If there are messages still present in the
mailbox when the mailbox is deallocated, it is an indication of a
programming error in lwIP and the developer should be notified.
*/
/**
* @brief Delete a mailbox
*
* @param mbox pointer of the mailbox to delete
*/
void
sys_mbox_free(sys_mbox_t *mbox)
{
if ( (NULL == mbox) || (NULL == *mbox) ) {
return;
if ((NULL == mbox) || (NULL == *mbox)) {
return;
}
UBaseType_t msgs_waiting = uxQueueMessagesWaiting((*mbox)->os_mbox);
LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
vQueueDelete((*mbox)->os_mbox);
free(*mbox);
*mbox = NULL;
}
/*-----------------------------------------------------------------------------------*/
/*
Starts a new thread with priority "prio" that will begin its execution in the
function "thread()". The "arg" argument will be passed as an argument to the
thread() function. The id of the new thread is returned. Both the id and
the priority are system dependent.
*/
/**
* @brief Create a new thread
*
* @param name thread name
* @param thread thread function
* @param arg thread arguments
* @param stacksize stacksize of the thread
* @param prio priority of the thread
* @return thread ID
*/
sys_thread_t
sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
{
xTaskHandle created_task;
portBASE_TYPE result;
TaskHandle_t rtos_task;
BaseType_t ret;
result = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &created_task,
/* LwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the
thread function without adaption here. */
ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task,
CONFIG_LWIP_TCPIP_TASK_AFFINITY);
if (result != pdPASS) {
if (ret != pdTRUE) {
return NULL;
}
return created_task;
return (sys_thread_t)rtos_task;
}
/*-----------------------------------------------------------------------------------*/
// Initialize sys arch
/**
* @brief Initialize the sys_arch layer
*
*/
void
sys_init(void)
{
if (!g_lwip_protect_mutex) {
if (ERR_OK != sys_mutex_new(&g_lwip_protect_mutex)) {
ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n");
ESP_LOGE(TAG, "sys_init: failed to init lwip protect mutex\n");
}
}
// Create the pthreads key for the per-thread semaphore storage
pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free);
// Create the pthreads key for the per-thread semaphore storage
pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free);
esp_vfs_lwip_sockets_register();
esp_vfs_lwip_sockets_register();
}
/*-----------------------------------------------------------------------------------*/
/**
* @brief Get system ticks
*
* @return system tick counts
*/
u32_t
sys_jiffies(void)
{
return xTaskGetTickCount();
}
/*-----------------------------------------------------------------------------------*/
/**
* @brief Get current time, in miliseconds
*
* @return current time
*/
u32_t
sys_now(void)
{
return (xTaskGetTickCount()*portTICK_PERIOD_MS);
return xTaskGetTickCount() * portTICK_PERIOD_MS;
}
/*
This optional function does a "fast" critical region protection and returns
the previous protection level. This function is only called during very short
critical regions. An embedded system which supports ISR-based drivers might
want to implement this function by disabling interrupts. Task-based systems
might want to implement this by using a mutex or disabling tasking. This
function should support recursive calls from the same task or interrupt. In
other words, sys_arch_protect() could be called while already protected. In
that case the return value indicates that it is already protected.
sys_arch_protect() is only required if your port is supporting an operating
system.
*/
/**
* @brief Protect critical region
*
* @note This function is only called during very short critical regions.
*
* @return previous protection level
*/
sys_prot_t
sys_arch_protect(void)
{
if (!g_lwip_protect_mutex) {
sys_mutex_new(&g_lwip_protect_mutex);
}
sys_mutex_lock(&g_lwip_protect_mutex);
return (sys_prot_t) 1;
}
/*-----------------------------------------------------------------------------------*/
/*
This optional function does a "fast" set of critical region protection to the
value specified by pval. See the documentation for sys_arch_protect() for
more information. This function is only required if your port is supporting
an operating system.
*/
/**
* @brief Unprotect critical region
*
* @param pval protection level
*/
void
sys_arch_unprotect(sys_prot_t pval)
{
LWIP_UNUSED_ARG(pval);
sys_mutex_unlock(&g_lwip_protect_mutex);
}
/*
* get per thread semphore
* get per thread semaphore
*/
sys_sem_t* sys_thread_sem_get(void)
sys_sem_t*
sys_thread_sem_get(void)
{
sys_sem_t *sem = pthread_getspecific(sys_thread_sem_key);
@ -456,7 +500,8 @@ sys_sem_t* sys_thread_sem_get(void)
return sem;
}
static void sys_thread_sem_free(void* data) // destructor for TLS semaphore
static void
sys_thread_sem_free(void* data) // destructor for TLS semaphore
{
sys_sem_t *sem = (sys_sem_t*)(data);
@ -471,7 +516,8 @@ static void sys_thread_sem_free(void* data) // destructor for TLS semaphore
}
}
sys_sem_t* sys_thread_sem_init(void)
sys_sem_t*
sys_thread_sem_init(void)
{
sys_sem_t *sem = (sys_sem_t*)mem_malloc(sizeof(sys_sem_t*));
@ -491,7 +537,8 @@ sys_sem_t* sys_thread_sem_init(void)
return sem;
}
void sys_thread_sem_deinit(void)
void
sys_thread_sem_deinit(void)
{
sys_sem_t *sem = pthread_getspecific(sys_thread_sem_key);
if (sem != NULL) {
@ -500,9 +547,8 @@ void sys_thread_sem_deinit(void)
}
}
void sys_delay_ms(uint32_t ms)
void
sys_delay_ms(uint32_t ms)
{
vTaskDelay(ms / portTICK_PERIOD_MS);
}

View File

@ -45,6 +45,10 @@
#define BYTE_ORDER LITTLE_ENDIAN
#endif // BYTE_ORDER
#ifndef CONFIG_LWIP_ESP_LWIP_ASSERT
#define LWIP_NOASSERT 1
#endif
typedef uint8_t u8_t;
typedef int8_t s8_t;
typedef uint16_t u16_t;

View File

@ -29,7 +29,7 @@
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef __SYS_ARCH_H__
#define __SYS_ARCH_H__
@ -44,15 +44,22 @@ extern "C" {
#endif
typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_t;
typedef xTaskHandle sys_thread_t;
typedef SemaphoreHandle_t sys_sem_t;
typedef SemaphoreHandle_t sys_mutex_t;
typedef TaskHandle_t sys_thread_t;
typedef struct sys_mbox_s {
xQueueHandle os_mbox;
QueueHandle_t os_mbox;
void *owner;
}* sys_mbox_t;
/** This is returned by _fromisr() sys functions to tell the outermost function
* that a higher priority task was woken and the scheduler needs to be invoked.
*/
#define ERR_NEED_SCHED 123
void sys_delay_ms(uint32_t ms);
#define sys_msleep(ms) sys_delay_ms(ms)
#define LWIP_COMPAT_MUTEX 0
@ -64,7 +71,7 @@ typedef struct sys_mbox_s {
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
/* Define the sys_mbox_set_invalid() to empty to support lock-free mbox in ESP LWIP.
*
*
* The basic idea about the lock-free mbox is that the mbox should always be valid unless
* no socket APIs are using the socket and the socket is closed. ESP LWIP achieves this by
* following two changes to official LWIP:
@ -72,9 +79,9 @@ typedef struct sys_mbox_s {
* no one is using the socket.
* 2. Define the sys_mbox_set_invalid() to empty if the mbox is not actually freed.
* The second change is necessary. Consider a common scenario: the application task calls
* The second change is necessary. Consider a common scenario: the application task calls
* recv() to receive packets from the socket, the sys_mbox_valid() returns true. Because there
* is no lock for the mbox, the LWIP CORE can call sys_mbox_set_invalid() to set the mbox at
* is no lock for the mbox, the LWIP CORE can call sys_mbox_set_invalid() to set the mbox at
* anytime and the thread-safe issue may happen.
*
* However, if the sys_mbox_set_invalid() is not called after sys_mbox_free(), e.g. in netconn_alloc(),

View File

@ -15,6 +15,6 @@
#ifndef INET_H_
#define INET_H_
#include "../../../lwip/src/include/lwip/inet.h"
#include "lwip/inet.h"
#endif /* INET_H_ */

View File

@ -169,18 +169,32 @@
--------------------------------
*/
/**
* IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that
* IP_REASSEMBLY==1: Reassemble incoming fragmented IP4 packets. Note that
* this option does not affect outgoing packet sizes, which can be controlled
* via IP_FRAG.
*/
#define IP_REASSEMBLY CONFIG_LWIP_IP_REASSEMBLY
#define IP_REASSEMBLY CONFIG_LWIP_IP4_REASSEMBLY
/**
* IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note
* LWIP_IPV6_REASS==1: reassemble incoming IP6 packets that fragmented. Note that
* this option does not affect outgoing packet sizes, which can be controlled
* via LWIP_IPV6_FRAG.
*/
#define LWIP_IPV6_REASS CONFIG_LWIP_IP6_REASSEMBLY
/**
* IP_FRAG==1: Fragment outgoing IP4 packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#define IP_FRAG CONFIG_LWIP_IP_FRAG
#define IP_FRAG CONFIG_LWIP_IP4_FRAG
/**
* LWIP_IPV6_FRAG==1: Fragment outgoing IP6 packets if their size exceeds MTU. Note
* that this option does not affect incoming packet sizes, which can be
* controlled via IP_REASSEMBLY.
*/
#define LWIP_IPV6_FRAG CONFIG_LWIP_IP6_FRAG
/**
* IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally)
@ -197,6 +211,20 @@
*/
#define IP_REASS_MAX_PBUFS 10
/**
* IP_FORWARD==1: Enables the ability to forward IP packets across network
* interfaces. If you are going to run lwIP on a device with only one network
* interface, define this to 0.
*/
#define IP_FORWARD CONFIG_LWIP_IP_FORWARD
/**
* IP_NAPT==1: Enables IPv4 Network Address and Port Translation.
* Note that both CONFIG_LWIP_IP_FORWARD and CONFIG_LWIP_L2_TO_L3_COPY options
* need to be enabled in system configuration for the NAPT to work on ESP platform
*/
#define IP_NAPT CONFIG_LWIP_IPV4_NAPT
/*
----------------------------------
---------- ICMP options ----------
@ -323,6 +351,11 @@
*/
#define TCP_QUEUE_OOSEQ CONFIG_LWIP_TCP_QUEUE_OOSEQ
/**
* LWIP_TCP_SACK_OUT==1: TCP will support sending selective acknowledgements (SACKs).
*/
#define LWIP_TCP_SACK_OUT CONFIG_LWIP_TCP_SACK_OUT
/**
* ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES==1: Keep TCP connection when IP changed
* scenario happens: 192.168.0.2 -> 0.0.0.0 -> 192.168.0.2 or 192.168.0.2 -> 0.0.0.0
@ -393,6 +426,12 @@
#define TCP_RCV_SCALE CONFIG_LWIP_TCP_RCV_SCALE
#endif
/**
* LWIP_TCP_RTO_TIME: TCP rto time.
* Default is 3 second.
*/
#define LWIP_TCP_RTO_TIME CONFIG_LWIP_TCP_RTO_TIME
/*
----------------------------------
---------- Pbuf options ----------
@ -562,6 +601,11 @@
*/
#define LWIP_TCP_KEEPALIVE 1
/**
* LWIP_SO_LINGER==1: Enable SO_LINGER processing.
*/
#define LWIP_SO_LINGER CONFIG_LWIP_SO_LINGER
/**
* LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
*/
@ -625,6 +669,14 @@
#if PPP_SUPPORT
/**
* PPP_IPV6_SUPPORT == 1: Enable IPV6 support for local link
* between modem and lwIP stack.
* Some modems do not support IPV6 addressing in local link and
* the only option available is to disable IPV6 address negotiation.
*/
#define PPP_IPV6_SUPPORT CONFIG_LWIP_PPP_ENABLE_IPV6
/**
* PPP_NOTIFY_PHASE==1: Support PPP notify phase.
*/
@ -667,6 +719,8 @@
#if PPP_DEBUG_ON
#define PPP_DEBUG LWIP_DBG_ON
#define PRINTPKT_SUPPORT 1
#define PPP_PROTOCOLNAME 1
#else
#define PPP_DEBUG LWIP_DBG_OFF
#endif
@ -793,7 +847,6 @@
#define ESP_THREAD_SAFE_DEBUG LWIP_DBG_OFF
#define ESP_DHCP 1
#define ESP_DNS 1
#define ESP_IPV6_AUTOCONFIG LWIP_IPV6
#define ESP_PERF 0
#define ESP_RANDOM_TCP_PORT 1
#define ESP_IP4_ATON 1
@ -817,6 +870,10 @@
#define ESP_LWIP_SELECT 1
#define ESP_LWIP_LOCK 1
#ifdef CONFIG_LWIP_IPV6_AUTOCONFIG
#define ESP_IPV6_AUTOCONFIG CONFIG_LWIP_IPV6_AUTOCONFIG
#endif
#ifdef ESP_IRAM_ATTR
#undef ESP_IRAM_ATTR
#endif
@ -873,7 +930,10 @@ void tcp_print_status(int status, void* p, uint32_t tmp1, uint32_t tmp2, uint32_
*/
#define SNTP_SERVER_DNS 1
#define SNTP_UPDATE_DELAY CONFIG_LWIP_SNTP_UPDATE_DELAY
// It disables a check of SNTP_UPDATE_DELAY it is done in sntp_set_sync_interval
#define SNTP_SUPPRESS_DELAY_CHECK
#define SNTP_UPDATE_DELAY (sntp_get_sync_interval())
#define SNTP_SET_SYSTEM_TIME_US(sec, us) \
do { \

View File

@ -1,4 +1,5 @@
// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
// Copyright 2020 Francesco Giancane <francesco.giancane@accenture.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@ -12,22 +13,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef _NETINET_TCP_H
#define _NETINET_TCP_H
#ifndef _NETTEST_LWIP_IF_H_
#define _NETTEST_LWIP_IF_H_
#include "lwip/tcp.h"
#include "lwip/err.h"
#ifdef __cplusplus
extern "C" {
#endif
err_t nettestif_init(struct netif *netif);
void nettestif_input(void *buffer, u16_t len);
#ifdef __cplusplus
}
#endif
#endif /* _NETTEST_LWIP_IF_H_ */
#endif /* _NETINET_TCP_H */

View File

@ -1,105 +0,0 @@
#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"
static struct netif *g_last_netif = NULL;
err_t nettestif_output(struct netif *netif, struct pbuf *p)
{
int i;
char *dat = p->payload;
/* output the packet to stdout */
printf("\nPacketOut:[");
for (i=0; i<p->len; i++) {
printf("%02x", *dat++);
}
printf("]\n");
return ERR_OK;
}
err_t nettestif_init(struct netif *netif)
{
g_last_netif = netif;
netif->hostname = CONFIG_LWIP_LOCAL_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 = nettestif_output;
/* 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
return ERR_OK;
}
void nettestif_input(void *buffer, u16_t len)
{
struct pbuf *p;
if (g_last_netif == NULL) {
printf("error!");
return;
}
printf("simul in: %d\n", len);
if (len==0) return;
p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM);
p->l2_owner = NULL;
memcpy(p->payload, buffer, len);
/* full packet send to tcpip_thread to process
* on success - the packet is processed and deallocated in tcpip stack
* on failure - log error and deallocate the packet
*/
if (g_last_netif->input(p, g_last_netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
}

View File

@ -319,12 +319,17 @@ static void low_level_init(struct netif* netif)
/* 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
#if LWIP_IPV6_AUTOCONFIG
netif->ip6_autoconfig_enabled = 1;
#endif /* LWIP_IPV6_AUTOCONFIG */
#endif
#if ESP_IPV6
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif->flags |= NETIF_FLAG_MLD6;
#endif
#endif
/* Do whatever else is needed to initialize interface. */
}
@ -593,7 +598,9 @@ int8_t ethernetif_init(struct netif* netif)
/* Initialize interface hostname */
#if ESP_LWIP
netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
if (tcpip_adapter_get_hostname(tcpip_adapter_get_esp_if(netif), &netif->hostname) != ESP_OK) {
netif->hostname = CONFIG_LWIP_LOCAL_HOSTNAME;
}
#else
netif->hostname = "lwip";
#endif