LwIP 2.2.1在STM32F407VET6平台 移植
This commit is contained in:
99
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/cc.h
vendored
Normal file
99
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/cc.h
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_ARCH_CC_H
|
||||
#define LWIP_ARCH_CC_H
|
||||
|
||||
/* see https://sourceforge.net/p/predef/wiki/OperatingSystems/ */
|
||||
#if defined __ANDROID__
|
||||
#define LWIP_UNIX_ANDROID
|
||||
#elif defined __linux__
|
||||
#define LWIP_UNIX_LINUX
|
||||
#elif defined __APPLE__
|
||||
#define LWIP_UNIX_MACH
|
||||
#elif defined __OpenBSD__
|
||||
#define LWIP_UNIX_OPENBSD
|
||||
#elif defined __FreeBSD__
|
||||
#define LWIP_UNIX_FREEBSD
|
||||
#elif defined __FreeBSD_kernel__ && __GLIBC__
|
||||
#define LWIP_UNIX_KFREEBSD
|
||||
#elif defined __CYGWIN__
|
||||
#define LWIP_UNIX_CYGWIN
|
||||
#elif defined __GNU__
|
||||
#define LWIP_UNIX_HURD
|
||||
#endif
|
||||
|
||||
#define LWIP_TIMEVAL_PRIVATE 0
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LWIP_ERRNO_INCLUDE <errno.h>
|
||||
|
||||
#if defined(LWIP_UNIX_LINUX) || defined(LWIP_UNIX_HURD) || defined(LWIP_UNIX_KFREEBSD)
|
||||
#define LWIP_ERRNO_STDINCLUDE 1
|
||||
#endif
|
||||
|
||||
extern unsigned int lwip_port_rand(void);
|
||||
#define LWIP_RAND() (lwip_port_rand())
|
||||
|
||||
/* different handling for unit test, normally not needed */
|
||||
#ifdef LWIP_NOASSERT_ON_ERROR
|
||||
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
|
||||
handler;}} while(0)
|
||||
#endif
|
||||
|
||||
#if defined(LWIP_UNIX_ANDROID) && defined(FD_SET)
|
||||
typedef __kernel_fd_set fd_set;
|
||||
#endif
|
||||
|
||||
#if defined(LWIP_UNIX_MACH)
|
||||
/* sys/types.h and signal.h bring in Darwin byte order macros. pull the
|
||||
header here and disable LwIP's version so that apps still can get
|
||||
the macros via LwIP headers and use system headers */
|
||||
#include <sys/types.h>
|
||||
#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS
|
||||
#endif
|
||||
|
||||
struct sio_status_s;
|
||||
typedef struct sio_status_s sio_status_t;
|
||||
#define sio_fd_t sio_status_t*
|
||||
#define __sio_fd_t_defined
|
||||
|
||||
typedef unsigned int sys_prot_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_ARCH_CC_H */
|
||||
71
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/perf.h
vendored
Normal file
71
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/perf.h
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_ARCH_PERF_H
|
||||
#define LWIP_ARCH_PERF_H
|
||||
|
||||
#include <sys/times.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef PERF
|
||||
#define PERF_START { \
|
||||
unsigned long __c1l, __c1h, __c2l, __c2h; \
|
||||
__asm__(".byte 0x0f, 0x31" : "=a" (__c1l), "=d" (__c1h))
|
||||
#define PERF_STOP(x) __asm__(".byte 0x0f, 0x31" : "=a" (__c2l), "=d" (__c2h)); \
|
||||
perf_print(__c1l, __c1h, __c2l, __c2h, x);}
|
||||
|
||||
/*#define PERF_START do { \
|
||||
struct tms __perf_start, __perf_end; \
|
||||
times(&__perf_start)
|
||||
#define PERF_STOP(x) times(&__perf_end); \
|
||||
perf_print_times(&__perf_start, &__perf_end, x);\
|
||||
} while(0)*/
|
||||
#else /* PERF */
|
||||
#define PERF_START /* null definition */
|
||||
#define PERF_STOP(x) /* null definition */
|
||||
#endif /* PERF */
|
||||
|
||||
void perf_print(unsigned long c1l, unsigned long c1h,
|
||||
unsigned long c2l, unsigned long c2h,
|
||||
char *key);
|
||||
|
||||
void perf_print_times(struct tms *start, struct tms *end, char *key);
|
||||
|
||||
void perf_init(char *fname);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_ARCH_PERF_H */
|
||||
98
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/sys_arch.h
vendored
Normal file
98
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/arch/sys_arch.h
vendored
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_ARCH_SYS_ARCH_H
|
||||
#define LWIP_ARCH_SYS_ARCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SYS_MBOX_NULL NULL
|
||||
#define SYS_SEM_NULL NULL
|
||||
|
||||
/*typedef u32_t sys_prot_t;*/
|
||||
|
||||
struct sys_sem;
|
||||
typedef struct sys_sem * sys_sem_t;
|
||||
#define sys_sem_valid(sem) (((sem) != NULL) && (*(sem) != NULL))
|
||||
#define sys_sem_valid_val(sem) ((sem) != NULL)
|
||||
#define sys_sem_set_invalid(sem) do { if((sem) != NULL) { *(sem) = NULL; }}while(0)
|
||||
#define sys_sem_set_invalid_val(sem) do { (sem) = NULL; }while(0)
|
||||
|
||||
struct sys_mutex;
|
||||
typedef struct sys_mutex * sys_mutex_t;
|
||||
#define sys_mutex_valid(mutex) sys_sem_valid(mutex)
|
||||
#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex)
|
||||
|
||||
struct sys_mbox;
|
||||
typedef struct sys_mbox * sys_mbox_t;
|
||||
#define sys_mbox_valid(mbox) sys_sem_valid(mbox)
|
||||
#define sys_mbox_valid_val(mbox) sys_sem_valid_val(mbox)
|
||||
#define sys_mbox_set_invalid(mbox) sys_sem_set_invalid(mbox)
|
||||
#define sys_mbox_set_invalid_val(mbox) sys_sem_set_invalid_val(mbox)
|
||||
|
||||
struct sys_thread;
|
||||
typedef struct sys_thread * sys_thread_t;
|
||||
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
sys_sem_t* sys_arch_netconn_sem_get(void);
|
||||
void sys_arch_netconn_sem_alloc(void);
|
||||
void sys_arch_netconn_sem_free(void);
|
||||
#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get()
|
||||
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
|
||||
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free()
|
||||
#endif /* #if LWIP_NETCONN_SEM_PER_THREAD */
|
||||
|
||||
#define LWIP_EXAMPLE_APP_ABORT() lwip_unix_keypressed()
|
||||
int lwip_unix_keypressed(void);
|
||||
|
||||
/*
|
||||
---------------------------------------
|
||||
---------- Threading options ----------
|
||||
---------------------------------------
|
||||
*/
|
||||
|
||||
void sys_mark_tcpip_thread(void);
|
||||
#define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread()
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
void sys_lock_tcpip_core(void);
|
||||
#define LOCK_TCPIP_CORE() sys_lock_tcpip_core()
|
||||
void sys_unlock_tcpip_core(void);
|
||||
#define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core()
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_ARCH_SYS_ARCH_H */
|
||||
62
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/fifo.h
vendored
Normal file
62
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/fifo.h
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef FIFO_H
|
||||
#define FIFO_H
|
||||
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** How many bytes in fifo */
|
||||
#define FIFOSIZE 2048
|
||||
|
||||
/** fifo data structure, this one is passed to all fifo functions */
|
||||
typedef struct fifo_t {
|
||||
u8_t data[FIFOSIZE+10]; /* data segment, +10 is a hack probably not needed.. FIXME! */
|
||||
int dataslot; /* index to next char to be read */
|
||||
int emptyslot; /* index to next empty slot */
|
||||
int len; /* len probably not needed, may be calculated from dataslot and emptyslot in conjunction with FIFOSIZE */
|
||||
|
||||
sys_sem_t sem; /* semaphore protecting simultaneous data manipulation */
|
||||
sys_sem_t getSem; /* sepaphore used to signal new data if getWaiting is set */
|
||||
u8_t getWaiting; /* flag used to indicate that fifoget is waiting for data. fifoput is supposed to clear */
|
||||
/* this flag prior to signaling the getSem semaphore */
|
||||
} fifo_t;
|
||||
|
||||
|
||||
/**
|
||||
* Get a character from fifo
|
||||
* Blocking call.
|
||||
* @param fifo pointer to fifo data structure
|
||||
* @return character read from fifo
|
||||
*/
|
||||
u8_t fifoGet(fifo_t * fifo);
|
||||
|
||||
/**
|
||||
* Get a character from fifo
|
||||
* Non blocking call.
|
||||
* @param fifo pointer to fifo data structure
|
||||
* @return character read from fifo, or < zero if non was available
|
||||
*/
|
||||
s16_t fifoGetNonBlock(fifo_t * fifo);
|
||||
|
||||
/**
|
||||
* fifoput is called by the signalhandler when new data has arrived (or some other event is indicated)
|
||||
* fifoput reads directly from the serialport and is thus highly dependent on unix arch at this moment
|
||||
* @param fifo pointer to fifo data structure
|
||||
* @param fd unix file descriptor
|
||||
*/
|
||||
void fifoPut(fifo_t * fifo, int fd);
|
||||
|
||||
/**
|
||||
* fifoinit initiate fifo
|
||||
* @param fifo pointer to fifo data structure, allocated by the user
|
||||
*/
|
||||
void fifoInit(fifo_t * fifo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
34
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/list.h
vendored
Normal file
34
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/list.h
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
|
||||
#ifndef LWIP_LIST_H
|
||||
#define LWIP_LIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct elem;
|
||||
|
||||
struct list {
|
||||
struct elem *first, *last;
|
||||
int size, elems;
|
||||
};
|
||||
|
||||
struct elem {
|
||||
struct elem *next;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct list *list_new(int size);
|
||||
int list_push(struct list *list, void *data);
|
||||
void *list_pop(struct list *list);
|
||||
void *list_first(struct list *list);
|
||||
int list_elems(struct list *list);
|
||||
void list_delete(struct list *list);
|
||||
int list_remove(struct list *list, void *elem);
|
||||
void list_map(struct list *list, void (* func)(void *arg));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/pcapif.h
vendored
Normal file
47
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/pcapif.h
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_PCAPIF_H
|
||||
#define LWIP_PCAPIF_H
|
||||
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t pcapif_init(struct netif *netif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_PCAPIF_H */
|
||||
68
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/sio.h
vendored
Normal file
68
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/sio.h
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef SIO_UNIX_H
|
||||
#define SIO_UNIX_H
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "netif/fifo.h"
|
||||
/*#include "netif/pppif.h"*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct sio_status_s {
|
||||
int fd;
|
||||
fifo_t myfifo;
|
||||
};
|
||||
|
||||
/* BAUDRATE is defined in sio.c as it is implementation specific */
|
||||
/** Baudrates */
|
||||
typedef enum sioBaudrates {
|
||||
SIO_BAUD_9600,
|
||||
SIO_BAUD_19200,
|
||||
SIO_BAUD_38400,
|
||||
SIO_BAUD_57600,
|
||||
SIO_BAUD_115200
|
||||
} sioBaudrates;
|
||||
|
||||
/**
|
||||
* Poll for a new character from incoming data stream
|
||||
* @param siostat siostatus struct, contains sio instance data, given by sio_open
|
||||
* @return char read from input stream, or < 0 if no char was available
|
||||
*/
|
||||
s16_t sio_poll(sio_status_t * siostat);
|
||||
|
||||
/**
|
||||
* Parse incoming characters until a string str is received, blocking call
|
||||
* @param str zero terminated string to expect
|
||||
* @param siostat siostatus struct, contains sio instance data, given by sio_open
|
||||
*/
|
||||
void sio_expect_string(u8_t *str, sio_status_t * siostat);
|
||||
|
||||
/**
|
||||
* Write a char to output data stream
|
||||
* @param str pointer to a zero terminated string
|
||||
* @param siostat siostatus struct, contains sio instance data, given by sio_open
|
||||
*/
|
||||
void sio_send_string(u8_t *str, sio_status_t * siostat);
|
||||
|
||||
/**
|
||||
* Flush outbuffer (send everything in buffer now), useful if some layer below is
|
||||
* holding on to data, waitng to fill a buffer
|
||||
* @param siostat siostatus struct, contains sio instance data, given by sio_open
|
||||
*/
|
||||
void sio_flush( sio_status_t * siostat );
|
||||
|
||||
/**
|
||||
* Change baudrate of port, may close and reopen port
|
||||
* @param baud new baudrate
|
||||
* @param siostat siostatus struct, contains sio instance data, given by sio_open
|
||||
*/
|
||||
void sio_change_baud( sioBaudrates baud, sio_status_t * siostat );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
51
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/tapif.h
vendored
Normal file
51
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/tapif.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_TAPIF_H
|
||||
#define LWIP_TAPIF_H
|
||||
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t tapif_init(struct netif *netif);
|
||||
void tapif_poll(struct netif *netif);
|
||||
#if NO_SYS
|
||||
int tapif_select(struct netif *netif);
|
||||
#endif /* NO_SYS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_TAPIF_H */
|
||||
51
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/vdeif.h
vendored
Normal file
51
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/include/netif/vdeif.h
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_VDEIF_H
|
||||
#define LWIP_VDEIF_H
|
||||
|
||||
#include "lwip/netif.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t vdeif_init(struct netif *netif);
|
||||
void vdeif_poll(struct netif *netif);
|
||||
#if NO_SYS
|
||||
int vdeif_select(struct netif *netif);
|
||||
#endif /* NO_SYS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_VDEIF_H */
|
||||
139
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/fifo.c
vendored
Normal file
139
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/fifo.c
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
|
||||
|
||||
/* ---------------------------------------------- */
|
||||
/* --- fifo 4 unix ------------------------------ */
|
||||
/* ---------------------------------------------- */
|
||||
#include "lwip/err.h"
|
||||
#include "netif/fifo.h"
|
||||
#include "lwip/debug.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/arch.h"
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef SIO_FIFO_DEBUG
|
||||
#define SIO_FIFO_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
u8_t fifoGet(fifo_t * fifo)
|
||||
{
|
||||
u8_t c;
|
||||
|
||||
sys_sem_wait(&fifo->sem); /* enter critical section */
|
||||
|
||||
if (fifo->dataslot == fifo->emptyslot)
|
||||
{
|
||||
fifo->getWaiting = TRUE; /* tell putFifo to signal us when data is available */
|
||||
sys_sem_signal(&fifo->sem); /* leave critical section (allow input from serial port..) */
|
||||
sys_sem_wait(&fifo->getSem); /* wait 4 data */
|
||||
sys_sem_wait(&fifo->sem); /* reenter critical section */
|
||||
}
|
||||
|
||||
c = fifo->data[fifo->dataslot++];
|
||||
fifo->len--;
|
||||
|
||||
if (fifo->dataslot == FIFOSIZE)
|
||||
{
|
||||
fifo->dataslot = 0;
|
||||
}
|
||||
sys_sem_signal(&fifo->sem); /* leave critical section */
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
s16_t fifoGetNonBlock(fifo_t * fifo)
|
||||
{
|
||||
u16_t c;
|
||||
|
||||
sys_sem_wait(&fifo->sem); /* enter critical section */
|
||||
|
||||
if (fifo->dataslot == fifo->emptyslot)
|
||||
{
|
||||
/* empty fifo */
|
||||
c = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = fifo->data[fifo->dataslot++];
|
||||
fifo->len--;
|
||||
|
||||
if (fifo->dataslot == FIFOSIZE)
|
||||
{
|
||||
fifo->dataslot = 0;
|
||||
}
|
||||
}
|
||||
sys_sem_signal(&fifo->sem); /* leave critical section */
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void fifoPut(fifo_t * fifo, int fd)
|
||||
{
|
||||
/* FIXME: mutex around struct data.. */
|
||||
int cnt=0;
|
||||
|
||||
sys_sem_wait(&fifo->sem ); /* enter critical */
|
||||
|
||||
LWIP_DEBUGF( SIO_FIFO_DEBUG,("fifoput: len%d dat%d empt%d --> ", fifo->len, fifo->dataslot, fifo->emptyslot ) );
|
||||
|
||||
if ( fifo->emptyslot < fifo->dataslot )
|
||||
{
|
||||
cnt = read( fd, &fifo->data[fifo->emptyslot], fifo->dataslot - fifo->emptyslot );
|
||||
}
|
||||
else
|
||||
{
|
||||
cnt = read( fd, &fifo->data[fifo->emptyslot], FIFOSIZE-fifo->emptyslot );
|
||||
}
|
||||
fifo->emptyslot += cnt;
|
||||
fifo->len += cnt;
|
||||
|
||||
LWIP_DEBUGF( SIO_FIFO_DEBUG,("len%d dat%d empt%d\n", fifo->len, fifo->dataslot, fifo->emptyslot ) );
|
||||
|
||||
if ( fifo->len > FIFOSIZE )
|
||||
{
|
||||
printf( "ERROR: fifo overrun detected len=%d, flushing\n", fifo->len );
|
||||
fifo->dataslot = 0;
|
||||
fifo->emptyslot = 0;
|
||||
fifo->len = 0;
|
||||
}
|
||||
|
||||
if ( fifo->emptyslot == FIFOSIZE )
|
||||
{
|
||||
fifo->emptyslot = 0;
|
||||
LWIP_DEBUGF( SIO_FIFO_DEBUG, ("(WRAP) ") );
|
||||
|
||||
sys_sem_signal(&fifo->sem ); /* leave critical */
|
||||
fifoPut( fifo, fd );
|
||||
return;
|
||||
}
|
||||
if ( fifo->getWaiting )
|
||||
{
|
||||
fifo->getWaiting = FALSE;
|
||||
sys_sem_signal(&fifo->getSem );
|
||||
}
|
||||
|
||||
sys_sem_signal(&fifo->sem ); /* leave critical */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void fifoInit(fifo_t * fifo)
|
||||
{
|
||||
fifo->dataslot = 0;
|
||||
fifo->emptyslot = 0;
|
||||
fifo->len = 0;
|
||||
if(sys_sem_new(&fifo->sem, 1) != ERR_OK) { /* critical section 1=free to enter */
|
||||
LWIP_ASSERT("Failed to create semaphore", 0);
|
||||
}
|
||||
if(sys_sem_new(&fifo->getSem, 0) != ERR_OK) { /* 0 = no one waiting */
|
||||
LWIP_ASSERT("Failed to create semaphore", 0);
|
||||
}
|
||||
fifo->getWaiting = FALSE;
|
||||
}
|
||||
152
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/list.c
vendored
Normal file
152
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/list.c
vendored
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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 <stdlib.h>
|
||||
#include <netif/list.h>
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
struct list *
|
||||
list_new(int size)
|
||||
{
|
||||
struct list *list;
|
||||
list = (struct list *)malloc(sizeof(struct list));
|
||||
list->first = list->last = NULL;
|
||||
list->size = size;
|
||||
list->elems = 0;
|
||||
return list;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
int
|
||||
list_push(struct list *list, void *data)
|
||||
{
|
||||
struct elem *elem;
|
||||
|
||||
if (list->elems < list->size) {
|
||||
elem = (struct elem *)malloc(sizeof(struct elem));
|
||||
elem->data = data;
|
||||
elem->next = NULL;
|
||||
if (list->last != NULL) {
|
||||
list->last->next = elem;
|
||||
}
|
||||
list->last = elem;
|
||||
if (list->first == NULL) {
|
||||
list->first = elem;
|
||||
}
|
||||
list->elems++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void *
|
||||
list_pop(struct list *list)
|
||||
{
|
||||
struct elem *elem;
|
||||
void *data;
|
||||
|
||||
if (list->elems > 0) {
|
||||
elem = list->first;
|
||||
if (elem == list->last) {
|
||||
list->last = elem->next;
|
||||
}
|
||||
list->first = elem->next;
|
||||
|
||||
list->elems--;
|
||||
|
||||
data = elem->data;
|
||||
free(elem);
|
||||
|
||||
return data;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void *
|
||||
list_first(struct list *list)
|
||||
{
|
||||
return list->first;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
int
|
||||
list_elems(struct list *list)
|
||||
{
|
||||
return list->elems;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
list_delete(struct list *list)
|
||||
{
|
||||
while (list_pop(list) != NULL);
|
||||
free(list);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
int
|
||||
list_remove(struct list *list, void *elem)
|
||||
{
|
||||
struct elem *e, *p;
|
||||
|
||||
p = NULL;
|
||||
for(e = list->first; e != NULL; e = e->next) {
|
||||
if (e->data == elem) {
|
||||
if (p != NULL) {
|
||||
p->next = e->next;
|
||||
} else {
|
||||
list->first = e->next;
|
||||
}
|
||||
if (list->last == e) {
|
||||
list->last = p;
|
||||
if (p != NULL) {
|
||||
p->next = NULL;
|
||||
}
|
||||
}
|
||||
free(e);
|
||||
list->elems--;
|
||||
return 1;
|
||||
}
|
||||
p = e;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
list_map(struct list *list, void (* func)(void *arg))
|
||||
{
|
||||
struct elem *e;
|
||||
|
||||
for(e = list->first; e != NULL; e = e->next) {
|
||||
func(e->data);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
207
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/pcapif.c
vendored
Normal file
207
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/pcapif.c
vendored
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef linux /* Apparently, this doesn't work under Linux. */
|
||||
|
||||
#include "lwip/debug.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "netif/etharp.h"
|
||||
|
||||
#include "lwip/stats.h"
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/sys.h"
|
||||
|
||||
#include "lwip/ip.h"
|
||||
|
||||
|
||||
struct pcapif {
|
||||
pcap_t *pd;
|
||||
sys_sem_t sem;
|
||||
u8_t pkt[2048];
|
||||
u32_t len;
|
||||
u32_t lasttime;
|
||||
struct pbuf *p;
|
||||
struct eth_addr *ethaddr;
|
||||
};
|
||||
|
||||
static char errbuf[PCAP_ERRBUF_SIZE];
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static err_t
|
||||
pcapif_output(struct netif *netif, struct pbuf *p,
|
||||
ip_addr_t *ipaddr)
|
||||
{
|
||||
return ERR_OK;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
timeout(void *arg)
|
||||
{
|
||||
struct netif *netif;
|
||||
struct pcapif *pcapif;
|
||||
struct pbuf *p;
|
||||
struct eth_hdr *ethhdr;
|
||||
|
||||
netif = (struct netif *)arg;
|
||||
pcapif = netif->state;
|
||||
ethhdr = (struct eth_hdr *)pcapif->pkt;
|
||||
|
||||
|
||||
if (lwip_htons(ethhdr->type) != ETHTYPE_IP ||
|
||||
ip_lookup(pcapif->pkt + 14, netif)) {
|
||||
|
||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||
p = pbuf_alloc(PBUF_LINK, pcapif->len, PBUF_POOL);
|
||||
|
||||
if (p != NULL) {
|
||||
pbuf_take(p, pcapif->pkt, pcapif->len);
|
||||
|
||||
ethhdr = p->payload;
|
||||
switch (lwip_htons(ethhdr->type)) {
|
||||
/* IP or ARP packet? */
|
||||
case ETHTYPE_IP:
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printf("ip_lookup dropped\n");
|
||||
}
|
||||
|
||||
sys_sem_signal(&pcapif->sem);
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
callback(u_char *arg, const struct pcap_pkthdr *hdr, const u_char *pkt)
|
||||
{
|
||||
struct netif *netif;
|
||||
struct pcapif *pcapif;
|
||||
u32_t time, lasttime;
|
||||
|
||||
netif = (struct netif *)arg;
|
||||
pcapif = netif->state;
|
||||
|
||||
pcapif->len = hdr->len;
|
||||
|
||||
bcopy(pkt, pcapif->pkt, hdr->len);
|
||||
|
||||
time = hdr->ts.tv_sec * 1000 + hdr->ts.tv_usec / 1000;
|
||||
|
||||
lasttime = pcapif->lasttime;
|
||||
pcapif->lasttime = time;
|
||||
|
||||
|
||||
if (lasttime == 0) {
|
||||
sys_timeout(1000, timeout, netif);
|
||||
} else {
|
||||
sys_timeout(time - lasttime, timeout, netif);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
pcapif_thread(void *arg)
|
||||
{
|
||||
struct netif *netif;
|
||||
struct pcapif *pcapif;
|
||||
netif = arg;
|
||||
pcapif = netif->state;
|
||||
|
||||
while (1) {
|
||||
pcap_loop(pcapif->pd, 1, callback, (u_char *)netif);
|
||||
sys_sem_wait(&pcapif->sem);
|
||||
if (pcapif->p != NULL) {
|
||||
netif->input(pcapif->p, netif);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
pcapif_init(struct netif *netif)
|
||||
{
|
||||
struct pcapif *p;
|
||||
|
||||
p = malloc(sizeof(struct pcapif));
|
||||
if (p == NULL)
|
||||
return ERR_MEM;
|
||||
netif->state = p;
|
||||
netif->name[0] = 'p';
|
||||
netif->name[1] = 'c';
|
||||
netif->output = pcapif_output;
|
||||
|
||||
p->pd = pcap_open_offline("pcapdump", errbuf);
|
||||
if (p->pd == NULL) {
|
||||
printf("pcapif_init: failed %s\n", errbuf);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
if(sys_sem_new(&p->sem, 0) != ERR_OK) {
|
||||
LWIP_ASSERT("Failed to create semaphore", 0);
|
||||
}
|
||||
p->p = NULL;
|
||||
p->lasttime = 0;
|
||||
|
||||
sys_thread_new("pcapif_thread", pcapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
||||
return ERR_OK;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
#endif /* linux */
|
||||
490
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/sio.c
vendored
Normal file
490
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/sio.c
vendored
Normal file
@ -0,0 +1,490 @@
|
||||
/* Author: Magnus Ivarsson <magnus.ivarsson@volvo.com> */
|
||||
|
||||
/* to get rid of implicit function declarations */
|
||||
#ifndef __FreeBSD__
|
||||
/* defining this on FreeBSD hides non-standard defines that sio.c depends on */
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/* build with Darwin C extensions not part of POSIX, i.e. FASYNC, SIGIO.
|
||||
we can't use LWIP_UNIX_MACH because extensions need to be turned
|
||||
on before any system headers (which are pulled in through cc.h)
|
||||
are included */
|
||||
#if defined(__APPLE__)
|
||||
#define _DARWIN_C_SOURCE
|
||||
#endif
|
||||
|
||||
#include "netif/sio.h"
|
||||
#include "netif/fifo.h"
|
||||
#include "lwip/debug.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/arch.h"
|
||||
#include "lwip/sio.h"
|
||||
#include "netif/ppp/ppp_opts.h"
|
||||
|
||||
/* Following #undefs are here to keep compiler from issuing warnings
|
||||
about them being double defined. (They are defined in lwip/inet.h
|
||||
as well as the Unix #includes below.) */
|
||||
#undef htonl
|
||||
#undef ntohl
|
||||
#undef htons
|
||||
#undef ntohs
|
||||
#undef HTONL
|
||||
#undef NTOHL
|
||||
#undef HTONS
|
||||
#undef NTOHS
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#if defined(LWIP_UNIX_OPENBSD) || defined(LWIP_UNIX_MACH)
|
||||
#include <util.h>
|
||||
#elif defined(LWIP_UNIX_FREEBSD)
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <termios.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/signal.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef LWIP_HAVE_SLIPIF
|
||||
#define LWIP_HAVE_SLIPIF 0
|
||||
#endif
|
||||
|
||||
#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF) && defined(LWIP_UNIX_LINUX)
|
||||
#include <pty.h>
|
||||
#endif
|
||||
|
||||
/*#define BAUDRATE B19200 */
|
||||
/*#define BAUDRATE B57600 */
|
||||
#define BAUDRATE B115200
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
/* for all of you who don't define SIO_DEBUG in debug.h */
|
||||
#ifndef SIO_DEBUG
|
||||
#define SIO_DEBUG 0
|
||||
#endif
|
||||
|
||||
|
||||
/* typedef struct siostruct_t */
|
||||
/* { */
|
||||
/* sio_status_t *sio; */
|
||||
/* } siostruct_t; */
|
||||
|
||||
/** array of ((siostruct*)netif->state)->sio structs */
|
||||
static sio_status_t statusar[4];
|
||||
|
||||
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
/* --private-functions----------------------------------------------------------------- */
|
||||
/**
|
||||
* Signal handler for ttyXX0 to indicate bytes received
|
||||
* one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
|
||||
*/
|
||||
static void signal_handler_IO_0( int status )
|
||||
{
|
||||
LWIP_UNUSED_ARG(status);
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 0\n"));
|
||||
fifoPut( &statusar[0].myfifo, statusar[0].fd );
|
||||
}
|
||||
|
||||
/**
|
||||
* Signal handler for ttyXX1 to indicate bytes received
|
||||
* one per interface is needed since we cannot send a instance number / pointer as callback argument (?)
|
||||
*/
|
||||
static void signal_handler_IO_1( int status )
|
||||
{
|
||||
LWIP_UNUSED_ARG(status);
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("SigHand: rxSignal channel 1\n"));
|
||||
fifoPut( &statusar[1].myfifo, statusar[1].fd );
|
||||
}
|
||||
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
|
||||
|
||||
/**
|
||||
* Initiation of serial device
|
||||
* @param device string with the device name and path, eg. "/dev/ttyS0"
|
||||
* @param devnum device number
|
||||
* @param siostat status
|
||||
* @return file handle to serial dev.
|
||||
*/
|
||||
static int sio_init( char * device, int devnum, sio_status_t * siostat )
|
||||
{
|
||||
struct termios oldtio,newtio;
|
||||
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
struct sigaction saio; /* definition of signal action */
|
||||
#endif
|
||||
int fd;
|
||||
LWIP_UNUSED_ARG(siostat);
|
||||
LWIP_UNUSED_ARG(devnum);
|
||||
|
||||
/* open the device to be non-blocking (read will return immediately) */
|
||||
fd = open( device, O_RDWR | O_NOCTTY | O_NONBLOCK );
|
||||
if ( fd < 0 )
|
||||
{
|
||||
perror( device );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
memset(&saio, 0, sizeof(struct sigaction));
|
||||
/* install the signal handler before making the device asynchronous */
|
||||
switch ( devnum )
|
||||
{
|
||||
case 0:
|
||||
LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_0\n") );
|
||||
saio.sa_handler = signal_handler_IO_0;
|
||||
break;
|
||||
case 1:
|
||||
LWIP_DEBUGF( SIO_DEBUG, ("sioinit, signal_handler_IO_1\n") );
|
||||
saio.sa_handler = signal_handler_IO_1;
|
||||
break;
|
||||
default:
|
||||
LWIP_DEBUGF( SIO_DEBUG,("sioinit, devnum not allowed\n") );
|
||||
break;
|
||||
}
|
||||
|
||||
sigaction( SIGIO,&saio,NULL );
|
||||
|
||||
/* allow the process to receive SIGIO */
|
||||
if ( fcntl( fd, F_SETOWN, getpid( ) ) != 0)
|
||||
{
|
||||
perror( device );
|
||||
exit( -1 );
|
||||
}
|
||||
/* Make the file descriptor asynchronous (the manual page says only
|
||||
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
|
||||
if ( fcntl( fd, F_SETFL, FASYNC ) != 0)
|
||||
{
|
||||
perror( device );
|
||||
exit( -1 );
|
||||
}
|
||||
#else
|
||||
if ( fcntl( fd, F_SETFL, 0 ) != 0)
|
||||
{
|
||||
perror( device );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
|
||||
|
||||
tcgetattr( fd,&oldtio ); /* save current port settings */
|
||||
/* set new port settings */
|
||||
/* see 'man termios' for further settings */
|
||||
memset(&newtio, 0, sizeof(newtio));
|
||||
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD | CRTSCTS;
|
||||
newtio.c_iflag = 0;
|
||||
newtio.c_oflag = 0;
|
||||
newtio.c_lflag = 0; /*ECHO; */
|
||||
newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
|
||||
newtio.c_cc[VTIME] = 0;
|
||||
|
||||
tcsetattr( fd,TCSANOW,&newtio );
|
||||
tcflush( fd, TCIOFLUSH );
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static void sio_speed( int fd, int speed )
|
||||
{
|
||||
struct termios oldtio,newtio;
|
||||
/* int fd; */
|
||||
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: baudcode:%d enter\n", fd, speed));
|
||||
|
||||
if ( fd < 0 )
|
||||
{
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: fd ERROR\n", fd));
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
tcgetattr( fd,&oldtio ); /* get current port settings */
|
||||
|
||||
/* set new port settings
|
||||
* see 'man termios' for further settings */
|
||||
memset(&newtio, 0, sizeof(newtio));
|
||||
newtio.c_cflag = speed | CS8 | CLOCAL | CREAD; /* | CRTSCTS; */
|
||||
newtio.c_iflag = 0;
|
||||
newtio.c_oflag = 0;
|
||||
newtio.c_lflag = 0; /*ECHO; */
|
||||
newtio.c_cc[VMIN] = 1; /* Read 1 byte at a time, no timer */
|
||||
newtio.c_cc[VTIME] = 0;
|
||||
|
||||
tcsetattr( fd,TCSANOW,&newtio );
|
||||
tcflush( fd, TCIOFLUSH );
|
||||
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_speed[%d]: leave\n", fd));
|
||||
}
|
||||
|
||||
/* --public-functions----------------------------------------------------------------------------- */
|
||||
void sio_send( u8_t c, sio_status_t * siostat )
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
|
||||
|
||||
if ( write( siostat->fd, &c, 1 ) <= 0 )
|
||||
{
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_send[%d]: write refused\n", siostat->fd));
|
||||
}
|
||||
}
|
||||
|
||||
void sio_send_string( u8_t *str, sio_status_t * siostat )
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
|
||||
int len = strlen( (const char *)str );
|
||||
|
||||
if ( write( siostat->fd, str, len ) <= 0 )
|
||||
{
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: write refused\n", siostat->fd));
|
||||
}
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_send_string[%d]: sent: %s\n", siostat->fd, str));
|
||||
}
|
||||
|
||||
|
||||
void sio_flush( sio_status_t * siostat )
|
||||
{
|
||||
LWIP_UNUSED_ARG(siostat);
|
||||
/* not implemented in unix as it is not needed */
|
||||
/*sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
|
||||
}
|
||||
|
||||
|
||||
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
/*u8_t sio_recv( struct netif * netif )*/
|
||||
u8_t sio_recv( sio_status_t * siostat )
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio; */
|
||||
return fifoGet( &(siostat->myfifo) );
|
||||
}
|
||||
|
||||
s16_t sio_poll(sio_status_t * siostat)
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
|
||||
return fifoGetNonBlock( &(siostat->myfifo) );
|
||||
}
|
||||
|
||||
|
||||
void sio_expect_string( u8_t *str, sio_status_t * siostat )
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
|
||||
u8_t c;
|
||||
int finger=0;
|
||||
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: %s\n", siostat->fd, str));
|
||||
while ( 1 )
|
||||
{
|
||||
c=fifoGet( &(siostat->myfifo) );
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("_%c", c));
|
||||
if ( c==str[finger] )
|
||||
{
|
||||
finger++;
|
||||
} else if ( finger > 0 )
|
||||
{
|
||||
/*it might fit in the beginning? */
|
||||
if ( str[0] == c )
|
||||
{
|
||||
finger = 1;
|
||||
}
|
||||
}
|
||||
if ( 0 == str[finger] )
|
||||
break; /* done, we have a match */
|
||||
}
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_expect_string[%d]: [match]\n", siostat->fd));
|
||||
}
|
||||
#endif /* ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
|
||||
|
||||
#if (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
u32_t sio_write(sio_status_t * siostat, const u8_t *buf, u32_t size)
|
||||
{
|
||||
ssize_t wsz = write( siostat->fd, buf, size );
|
||||
return wsz < 0 ? 0 : wsz;
|
||||
}
|
||||
|
||||
u32_t sio_read(sio_status_t * siostat, u8_t *buf, u32_t size)
|
||||
{
|
||||
ssize_t rsz = read( siostat->fd, buf, size );
|
||||
return rsz < 0 ? 0 : rsz;
|
||||
}
|
||||
|
||||
void sio_read_abort(sio_status_t * siostat)
|
||||
{
|
||||
LWIP_UNUSED_ARG(siostat);
|
||||
printf("sio_read_abort[%d]: not yet implemented for unix\n", siostat->fd);
|
||||
}
|
||||
#endif /* (PPP_SUPPORT || LWIP_HAVE_SLIPIF) */
|
||||
|
||||
sio_fd_t sio_open(u8_t devnum)
|
||||
{
|
||||
char dev[20];
|
||||
|
||||
/* would be nice with dynamic memory alloc */
|
||||
sio_status_t * siostate = &statusar[ devnum ];
|
||||
/* siostruct_t * tmp; */
|
||||
|
||||
|
||||
/* tmp = (siostruct_t*)(netif->state); */
|
||||
/* tmp->sio = siostate; */
|
||||
|
||||
/* tmp = (siostruct_t*)(netif->state); */
|
||||
|
||||
/* ((sio_status_t*)(tmp->sio))->fd = 0; */
|
||||
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: for devnum %d\n", devnum));
|
||||
|
||||
#if ! (PPP_SUPPORT || LWIP_HAVE_SLIPIF)
|
||||
fifoInit( &siostate->myfifo );
|
||||
#endif /* ! PPP_SUPPORT */
|
||||
|
||||
snprintf( dev, sizeof(dev), "/dev/ttyS%d", devnum );
|
||||
|
||||
if ( (devnum == 1) || (devnum == 0) )
|
||||
{
|
||||
if ( ( siostate->fd = sio_init( dev, devnum, siostate ) ) == 0 )
|
||||
{
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: ERROR opening serial device dev=%s\n", dev));
|
||||
abort( );
|
||||
return NULL;
|
||||
}
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: dev=%s open.\n", siostate->fd, dev));
|
||||
}
|
||||
#if PPP_SUPPORT
|
||||
else if (devnum == 2) {
|
||||
pid_t childpid;
|
||||
char name[256];
|
||||
childpid = forkpty(&siostate->fd, name, NULL, NULL);
|
||||
if(childpid < 0) {
|
||||
perror("forkpty");
|
||||
exit (1);
|
||||
}
|
||||
if(childpid == 0) {
|
||||
execl("/usr/sbin/pppd", "pppd",
|
||||
"ms-dns", "198.168.100.7",
|
||||
"local", "crtscts",
|
||||
"debug",
|
||||
#ifdef LWIP_PPP_CHAP_TEST
|
||||
"auth",
|
||||
"require-chap",
|
||||
"remotename", "lwip",
|
||||
#else
|
||||
"noauth",
|
||||
#endif
|
||||
#if LWIP_IPV6
|
||||
"+ipv6",
|
||||
#endif
|
||||
"192.168.1.1:192.168.1.2",
|
||||
NULL);
|
||||
perror("execl pppd");
|
||||
exit (1);
|
||||
} else {
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned pppd pid %d on %s\n",
|
||||
siostate->fd, childpid, name));
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
#if LWIP_HAVE_SLIPIF
|
||||
else if (devnum == 3) {
|
||||
pid_t childpid;
|
||||
/* create PTY pair */
|
||||
siostate->fd = posix_openpt(O_RDWR | O_NOCTTY);
|
||||
if (siostate->fd < 0) {
|
||||
perror("open pty master");
|
||||
exit (1);
|
||||
}
|
||||
if (grantpt(siostate->fd) != 0) {
|
||||
perror("grant pty master");
|
||||
exit (1);
|
||||
}
|
||||
if (unlockpt(siostate->fd) != 0) {
|
||||
perror("unlock pty master");
|
||||
exit (1);
|
||||
}
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: for %s\n",
|
||||
siostate->fd, ptsname(siostate->fd)));
|
||||
/* fork for slattach */
|
||||
childpid = fork();
|
||||
if(childpid < 0) {
|
||||
perror("fork");
|
||||
exit (1);
|
||||
}
|
||||
if(childpid == 0) {
|
||||
/* esteblish SLIP interface on host side connected to PTY slave */
|
||||
execl("/sbin/slattach", "slattach",
|
||||
"-d", "-v", "-L", "-p", "slip",
|
||||
ptsname(siostate->fd),
|
||||
NULL);
|
||||
perror("execl slattach");
|
||||
exit (1);
|
||||
} else {
|
||||
int ret;
|
||||
char buf[1024];
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: spawned slattach pid %d on %s\n",
|
||||
siostate->fd, childpid, ptsname(siostate->fd)));
|
||||
/* wait a moment for slattach startup */
|
||||
sleep(1);
|
||||
/* configure SLIP interface on host side as P2P interface */
|
||||
snprintf(buf, sizeof(buf),
|
||||
"/sbin/ifconfig sl0 mtu %d %s pointopoint %s up",
|
||||
SLIP_MAX_SIZE, "192.168.2.1", "192.168.2.2");
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open[%d]: system(\"%s\");\n", siostate->fd, buf));
|
||||
ret = system(buf);
|
||||
if (ret < 0) {
|
||||
perror("ifconfig failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_HAVE_SLIPIF */
|
||||
else
|
||||
{
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_open: device %s (%d) is not supported\n", dev, devnum));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return siostate;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void sio_change_baud( sioBaudrates baud, sio_status_t * siostat )
|
||||
{
|
||||
/* sio_status_t * siostat = ((siostruct_t*)netif->state)->sio;*/
|
||||
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]\n", siostat->fd));
|
||||
|
||||
switch ( baud )
|
||||
{
|
||||
case SIO_BAUD_9600:
|
||||
sio_speed( siostat->fd, B9600 );
|
||||
break;
|
||||
case SIO_BAUD_19200:
|
||||
sio_speed( siostat->fd, B19200 );
|
||||
break;
|
||||
case SIO_BAUD_38400:
|
||||
sio_speed( siostat->fd, B38400 );
|
||||
break;
|
||||
case SIO_BAUD_57600:
|
||||
sio_speed( siostat->fd, B57600 );
|
||||
break;
|
||||
case SIO_BAUD_115200:
|
||||
sio_speed( siostat->fd, B115200 );
|
||||
break;
|
||||
|
||||
default:
|
||||
LWIP_DEBUGF(SIO_DEBUG, ("sio_change_baud[%d]: Unknown baudrate, code:%d\n",
|
||||
siostat->fd, baud));
|
||||
break;
|
||||
}
|
||||
}
|
||||
432
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/tapif.c
vendored
Normal file
432
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/tapif.c
vendored
Normal file
@ -0,0 +1,432 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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 <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/debug.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
|
||||
#include "netif/tapif.h"
|
||||
|
||||
#define IFCONFIG_BIN "/sbin/ifconfig "
|
||||
|
||||
#if defined(LWIP_UNIX_LINUX)
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
/*
|
||||
* Creating a tap interface requires special privileges. If the interfaces
|
||||
* is created in advance with `tunctl -u <user>` it can be opened as a regular
|
||||
* user. The network must already be configured. If DEVTAP_IF is defined it
|
||||
* will be opened instead of creating a new tap device.
|
||||
*
|
||||
* You can also use PRECONFIGURED_TAPIF environment variable to do so.
|
||||
*/
|
||||
#ifndef DEVTAP_DEFAULT_IF
|
||||
#define DEVTAP_DEFAULT_IF "tap0"
|
||||
#endif
|
||||
#ifndef DEVTAP
|
||||
#define DEVTAP "/dev/net/tun"
|
||||
#endif
|
||||
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
|
||||
#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
|
||||
#elif defined(LWIP_UNIX_OPENBSD)
|
||||
#define DEVTAP "/dev/tun0"
|
||||
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
|
||||
#define IFCONFIG_ARGS "tun0 inet %d.%d.%d.%d " NETMASK_ARGS " link0"
|
||||
#else /* others */
|
||||
#define DEVTAP "/dev/tap0"
|
||||
#define NETMASK_ARGS "netmask %d.%d.%d.%d"
|
||||
#define IFCONFIG_ARGS "tap0 inet %d.%d.%d.%d " NETMASK_ARGS
|
||||
#endif
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 't'
|
||||
#define IFNAME1 'p'
|
||||
|
||||
#ifndef TAPIF_DEBUG
|
||||
#define TAPIF_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
struct tapif {
|
||||
/* Add whatever per-interface state that is needed here. */
|
||||
int fd;
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
static void tapif_input(struct netif *netif);
|
||||
#if !NO_SYS
|
||||
static void tapif_thread(void *arg);
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
low_level_init(struct netif *netif)
|
||||
{
|
||||
struct tapif *tapif;
|
||||
#if LWIP_IPV4
|
||||
int ret;
|
||||
char buf[1024];
|
||||
#endif /* LWIP_IPV4 */
|
||||
char *preconfigured_tapif = getenv("PRECONFIGURED_TAPIF");
|
||||
|
||||
tapif = (struct tapif *)netif->state;
|
||||
|
||||
/* Obtain MAC address from network interface. */
|
||||
|
||||
/* (We just fake an address...) */
|
||||
netif->hwaddr[0] = 0x02;
|
||||
netif->hwaddr[1] = 0x12;
|
||||
netif->hwaddr[2] = 0x34;
|
||||
netif->hwaddr[3] = 0x56;
|
||||
netif->hwaddr[4] = 0x78;
|
||||
netif->hwaddr[5] = 0xab;
|
||||
netif->hwaddr_len = 6;
|
||||
|
||||
/* device capabilities */
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
|
||||
|
||||
tapif->fd = open(DEVTAP, O_RDWR);
|
||||
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: fd %d\n", tapif->fd));
|
||||
if (tapif->fd == -1) {
|
||||
#ifdef LWIP_UNIX_LINUX
|
||||
perror("tapif_init: try running \"modprobe tun\" or rebuilding your kernel with CONFIG_TUN; cannot open "DEVTAP);
|
||||
#else /* LWIP_UNIX_LINUX */
|
||||
perror("tapif_init: cannot open "DEVTAP);
|
||||
#endif /* LWIP_UNIX_LINUX */
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef LWIP_UNIX_LINUX
|
||||
{
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
|
||||
if (preconfigured_tapif) {
|
||||
strncpy(ifr.ifr_name, preconfigured_tapif, sizeof(ifr.ifr_name) - 1);
|
||||
} else {
|
||||
strncpy(ifr.ifr_name, DEVTAP_DEFAULT_IF, sizeof(ifr.ifr_name) - 1);
|
||||
}
|
||||
ifr.ifr_name[sizeof(ifr.ifr_name)-1] = 0; /* ensure \0 termination */
|
||||
|
||||
ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
|
||||
if (ioctl(tapif->fd, TUNSETIFF, (void *) &ifr) < 0) {
|
||||
perror("tapif_init: "DEVTAP" ioctl TUNSETIFF");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif /* LWIP_UNIX_LINUX */
|
||||
|
||||
netif_set_link_up(netif);
|
||||
|
||||
if (preconfigured_tapif == NULL) {
|
||||
#if LWIP_IPV4
|
||||
snprintf(buf, 1024, IFCONFIG_BIN IFCONFIG_ARGS,
|
||||
ip4_addr1(netif_ip4_gw(netif)),
|
||||
ip4_addr2(netif_ip4_gw(netif)),
|
||||
ip4_addr3(netif_ip4_gw(netif)),
|
||||
ip4_addr4(netif_ip4_gw(netif))
|
||||
#ifdef NETMASK_ARGS
|
||||
,
|
||||
ip4_addr1(netif_ip4_netmask(netif)),
|
||||
ip4_addr2(netif_ip4_netmask(netif)),
|
||||
ip4_addr3(netif_ip4_netmask(netif)),
|
||||
ip4_addr4(netif_ip4_netmask(netif))
|
||||
#endif /* NETMASK_ARGS */
|
||||
);
|
||||
|
||||
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_init: system(\"%s\");\n", buf));
|
||||
ret = system(buf);
|
||||
if (ret < 0) {
|
||||
perror("ifconfig failed");
|
||||
exit(1);
|
||||
}
|
||||
if (ret != 0) {
|
||||
printf("ifconfig returned %d\n", ret);
|
||||
}
|
||||
#else /* LWIP_IPV4 */
|
||||
perror("todo: support IPv6 support for non-preconfigured tapif");
|
||||
exit(1);
|
||||
#endif /* LWIP_IPV4 */
|
||||
}
|
||||
|
||||
#if !NO_SYS
|
||||
sys_thread_new("tapif_thread", tapif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
||||
#endif /* !NO_SYS */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* low_level_output():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
static err_t
|
||||
low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct tapif *tapif = (struct tapif *)netif->state;
|
||||
char buf[1518]; /* max packet size including VLAN excluding CRC */
|
||||
ssize_t written;
|
||||
|
||||
#if 0
|
||||
if (((double)rand()/(double)RAND_MAX) < 0.2) {
|
||||
printf("drop output\n");
|
||||
return ERR_OK; /* ERR_OK because we simulate packet loss on cable */
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p->tot_len > sizeof(buf)) {
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
|
||||
perror("tapif: packet too large");
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/* initiate transfer(); */
|
||||
pbuf_copy_partial(p, buf, p->tot_len, 0);
|
||||
|
||||
/* signal that packet should be sent(); */
|
||||
written = write(tapif->fd, buf, p->tot_len);
|
||||
if (written < p->tot_len) {
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
|
||||
perror("tapif: write");
|
||||
return ERR_IF;
|
||||
} else {
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, (u32_t)written);
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* low_level_input():
|
||||
*
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static struct pbuf *
|
||||
low_level_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p;
|
||||
u16_t len;
|
||||
ssize_t readlen;
|
||||
char buf[1518]; /* max packet size including VLAN excluding CRC */
|
||||
struct tapif *tapif = (struct tapif *)netif->state;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len"
|
||||
variable. */
|
||||
readlen = read(tapif->fd, buf, sizeof(buf));
|
||||
if (readlen < 0) {
|
||||
perror("read returned -1");
|
||||
exit(1);
|
||||
}
|
||||
len = (u16_t)readlen;
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
|
||||
|
||||
#if 0
|
||||
if (((double)rand()/(double)RAND_MAX) < 0.2) {
|
||||
printf("drop\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||
if (p != NULL) {
|
||||
pbuf_take(p, buf, len);
|
||||
/* acknowledge that packet has been read(); */
|
||||
} else {
|
||||
/* drop packet(); */
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: could not allocate pbuf\n"));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* tapif_input():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
tapif_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p = low_level_input(netif);
|
||||
|
||||
if (p == NULL) {
|
||||
#if LINK_STATS
|
||||
LINK_STATS_INC(link.recv);
|
||||
#endif /* LINK_STATS */
|
||||
LWIP_DEBUGF(TAPIF_DEBUG, ("tapif_input: low_level_input returned NULL\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_input: netif input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* tapif_init():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
tapif_init(struct netif *netif)
|
||||
{
|
||||
struct tapif *tapif = (struct tapif *)mem_malloc(sizeof(struct tapif));
|
||||
|
||||
if (tapif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("tapif_init: out of memory for tapif\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
netif->state = tapif;
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_other, 100000000);
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
#if LWIP_IPV4
|
||||
netif->output = etharp_output;
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
netif->mtu = 1500;
|
||||
|
||||
low_level_init(netif);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
tapif_poll(struct netif *netif)
|
||||
{
|
||||
tapif_input(netif);
|
||||
}
|
||||
|
||||
#if NO_SYS
|
||||
|
||||
int
|
||||
tapif_select(struct netif *netif)
|
||||
{
|
||||
fd_set fdset;
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
struct tapif *tapif;
|
||||
u32_t msecs = sys_timeouts_sleeptime();
|
||||
|
||||
tapif = (struct tapif *)netif->state;
|
||||
|
||||
tv.tv_sec = msecs / 1000;
|
||||
tv.tv_usec = (msecs % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(tapif->fd, &fdset);
|
||||
|
||||
ret = select(tapif->fd + 1, &fdset, NULL, NULL, &tv);
|
||||
if (ret > 0) {
|
||||
tapif_input(netif);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* NO_SYS */
|
||||
|
||||
static void
|
||||
tapif_thread(void *arg)
|
||||
{
|
||||
struct netif *netif;
|
||||
struct tapif *tapif;
|
||||
fd_set fdset;
|
||||
int ret;
|
||||
|
||||
netif = (struct netif *)arg;
|
||||
tapif = (struct tapif *)netif->state;
|
||||
|
||||
while(1) {
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(tapif->fd, &fdset);
|
||||
|
||||
/* Wait for a packet to arrive. */
|
||||
ret = select(tapif->fd + 1, &fdset, NULL, NULL, NULL);
|
||||
|
||||
if(ret == 1) {
|
||||
/* Handle incoming packet. */
|
||||
tapif_input(netif);
|
||||
} else if(ret == -1) {
|
||||
perror("tapif_thread: select");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NO_SYS */
|
||||
344
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/vdeif.c
vendored
Normal file
344
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/netif/vdeif.c
vendored
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* VDE (virtual distributed ethernet) interface for ale4net
|
||||
* (based on tapif interface Adam Dunkels <adam@sics.se>)
|
||||
* 2005,2010,2011,2023 Renzo Davoli University of Bologna - Italy
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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 <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/debug.h"
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/ip.h"
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/timeouts.h"
|
||||
#include "netif/etharp.h"
|
||||
#include "lwip/ethip6.h"
|
||||
#include <libvdeplug.h>
|
||||
|
||||
#include "netif/vdeif.h"
|
||||
|
||||
/* Define those to better describe your network interface. */
|
||||
#define IFNAME0 'v'
|
||||
#define IFNAME1 'd'
|
||||
|
||||
#ifndef VDEIF_DEBUG
|
||||
#define VDEIF_DEBUG LWIP_DBG_OFF
|
||||
#endif
|
||||
|
||||
static char vdedescr[] = "lwip";
|
||||
|
||||
struct vdeif {
|
||||
VDECONN *vdeconn;
|
||||
};
|
||||
|
||||
/* Forward declarations. */
|
||||
static void vdeif_input(struct netif *netif);
|
||||
#if !NO_SYS
|
||||
static void vdeif_thread(void *arg);
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
low_level_init(struct netif *netif, char *vderl)
|
||||
{
|
||||
struct vdeif *vdeif;
|
||||
int randaddr;
|
||||
struct timeval now;
|
||||
|
||||
vdeif = (struct vdeif *)netif->state;
|
||||
gettimeofday(&now, NULL);
|
||||
srand(now.tv_sec + now.tv_usec);
|
||||
randaddr = rand();
|
||||
|
||||
/* Obtain MAC address from network interface. */
|
||||
|
||||
/* (We just fake an address...) */
|
||||
netif->hwaddr[0] = 0x02;
|
||||
netif->hwaddr[1] = 0x2;
|
||||
netif->hwaddr[2] = randaddr >> 24;
|
||||
netif->hwaddr[3] = randaddr >> 16;
|
||||
netif->hwaddr[4] = randaddr >> 8;
|
||||
netif->hwaddr[5] = randaddr;
|
||||
netif->hwaddr_len = 6;
|
||||
|
||||
/* device capabilities */
|
||||
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
|
||||
|
||||
vdeif->vdeconn = vde_open(vderl, vdedescr, NULL);
|
||||
LWIP_DEBUGF(VDEIF_DEBUG, ("vdeif_init: ok = %d\n", !!vdeif->vdeconn));
|
||||
if (vdeif->vdeconn == NULL) {
|
||||
perror("vdeif_init: cannot open vde net");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
netif_set_link_up(netif);
|
||||
|
||||
#if !NO_SYS
|
||||
sys_thread_new("vdeif_thread", vdeif_thread, netif, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO);
|
||||
#endif /* !NO_SYS */
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* low_level_output():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
static err_t
|
||||
low_level_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct vdeif *vdeif = (struct vdeif *)netif->state;
|
||||
char buf[1518]; /* max packet size including VLAN excluding CRC */
|
||||
ssize_t written;
|
||||
|
||||
if (p->tot_len > sizeof(buf)) {
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
|
||||
perror("vdeif: packet too large");
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/* initiate transfer(); */
|
||||
pbuf_copy_partial(p, buf, p->tot_len, 0);
|
||||
|
||||
/* signal that packet should be sent(); */
|
||||
written = vde_send(vdeif->vdeconn, buf, p->tot_len, 0);
|
||||
if (written < p->tot_len) {
|
||||
MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
|
||||
perror("vdeif: write");
|
||||
return ERR_IF;
|
||||
} else {
|
||||
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, (u32_t)written);
|
||||
return ERR_OK;
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* low_level_input():
|
||||
*
|
||||
* Should allocate a pbuf and transfer the bytes of the incoming
|
||||
* packet from the interface into the pbuf.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static struct pbuf *
|
||||
low_level_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p;
|
||||
u16_t len;
|
||||
ssize_t readlen;
|
||||
char buf[1518]; /* max packet size including VLAN excluding CRC */
|
||||
struct vdeif *vdeif = (struct vdeif *)netif->state;
|
||||
|
||||
/* Obtain the size of the packet and put it into the "len"
|
||||
variable. */
|
||||
readlen = vde_recv(vdeif->vdeconn, buf, sizeof(buf), 0);
|
||||
if (readlen < 0) {
|
||||
perror("read returned -1");
|
||||
exit(1);
|
||||
}
|
||||
len = (u16_t)readlen;
|
||||
|
||||
MIB2_STATS_NETIF_ADD(netif, ifinoctets, len);
|
||||
|
||||
/* We allocate a pbuf chain of pbufs from the pool. */
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
|
||||
if (p != NULL) {
|
||||
pbuf_take(p, buf, len);
|
||||
/* acknowledge that packet has been read(); */
|
||||
} else {
|
||||
/* drop packet(); */
|
||||
MIB2_STATS_NETIF_INC(netif, ifindiscards);
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_input: could not allocate pbuf\n"));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* vdeif_input():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
static void
|
||||
vdeif_input(struct netif *netif)
|
||||
{
|
||||
struct pbuf *p = low_level_input(netif);
|
||||
|
||||
if (p == NULL) {
|
||||
#if LINK_STATS
|
||||
LINK_STATS_INC(link.recv);
|
||||
#endif /* LINK_STATS */
|
||||
LWIP_DEBUGF(VDEIF_DEBUG, ("vdeif_input: low_level_input returned NULL\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_input: netif input error\n"));
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* vdeif_init():
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
err_t
|
||||
vdeif_init(struct netif *netif)
|
||||
{
|
||||
char *vderl = (char *) netif->state;
|
||||
struct vdeif *vdeif = (struct vdeif *)mem_malloc(sizeof(struct vdeif));
|
||||
|
||||
if (vdeif == NULL) {
|
||||
LWIP_DEBUGF(NETIF_DEBUG, ("vdeif_init: out of memory for vdeif\n"));
|
||||
return ERR_MEM;
|
||||
}
|
||||
netif->state = vdeif;
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_other, 100000000);
|
||||
|
||||
netif->name[0] = IFNAME0;
|
||||
netif->name[1] = IFNAME1;
|
||||
#if LWIP_IPV4
|
||||
netif->output = etharp_output;
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->linkoutput = low_level_output;
|
||||
netif->mtu = 1500;
|
||||
|
||||
low_level_init(netif, vderl);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
void
|
||||
vdeif_poll(struct netif *netif)
|
||||
{
|
||||
vdeif_input(netif);
|
||||
}
|
||||
|
||||
#if NO_SYS
|
||||
|
||||
int
|
||||
vdeif_select(struct netif *netif)
|
||||
{
|
||||
fd_set fdset;
|
||||
int ret;
|
||||
struct timeval tv;
|
||||
struct vdeif *vdeif;
|
||||
u32_t msecs = sys_timeouts_sleeptime();
|
||||
int datafd;
|
||||
|
||||
vdeif = (struct vdeif *)netif->state;
|
||||
datafd = vde_datafd(vdeif->vdeconn);
|
||||
|
||||
tv.tv_sec = msecs / 1000;
|
||||
tv.tv_usec = (msecs % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(datafd, &fdset);
|
||||
|
||||
ret = select(datafd + 1, &fdset, NULL, NULL, &tv);
|
||||
if (ret > 0) {
|
||||
vdeif_input(netif);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else /* NO_SYS */
|
||||
|
||||
static void
|
||||
vdeif_thread(void *arg)
|
||||
{
|
||||
struct netif *netif;
|
||||
struct vdeif *vdeif;
|
||||
fd_set fdset;
|
||||
int ret;
|
||||
int datafd;
|
||||
|
||||
netif = (struct netif *)arg;
|
||||
vdeif = (struct vdeif *)netif->state;
|
||||
datafd = vde_datafd(vdeif->vdeconn);
|
||||
|
||||
while(1) {
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(datafd, &fdset);
|
||||
|
||||
/* Wait for a packet to arrive. */
|
||||
ret = select(datafd + 1, &fdset, NULL, NULL, NULL);
|
||||
|
||||
if(ret == 1) {
|
||||
/* Handle incoming packet. */
|
||||
vdeif_input(netif);
|
||||
} else if(ret == -1) {
|
||||
perror("vdeif_thread: select");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NO_SYS */
|
||||
65
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/perf.c
vendored
Normal file
65
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/perf.c
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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 "arch/perf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static FILE *f;
|
||||
|
||||
void
|
||||
perf_print(unsigned long c1l, unsigned long c1h,
|
||||
unsigned long c2l, unsigned long c2h,
|
||||
char *key)
|
||||
{
|
||||
unsigned long sub_ms, sub_ls;
|
||||
|
||||
sub_ms = c2h - c1h;
|
||||
sub_ls = c2l - c1l;
|
||||
if (c2l < c1l) sub_ms--;
|
||||
fprintf(f, "%s: %.8lu%.8lu\n", key, sub_ms, sub_ls);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
perf_print_times(struct tms *start, struct tms *end, char *key)
|
||||
{
|
||||
fprintf(f, "%s: %lu\n", key, end->tms_stime - start->tms_stime);
|
||||
fflush(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
perf_init(char *fname)
|
||||
{
|
||||
f = fopen(fname, "w");
|
||||
}
|
||||
|
||||
840
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/sys_arch.c
vendored
Normal file
840
ThirdParty/lwip-2.2.1/contrib/ports/unix/port/sys_arch.c
vendored
Normal file
@ -0,0 +1,840 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 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>
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Wed Apr 17 16:05:29 EDT 2002 (James Roth)
|
||||
*
|
||||
* - Fixed an unlikely sys_thread_new() race condition.
|
||||
*
|
||||
* - Made current_thread() work with threads which where
|
||||
* not created with sys_thread_new(). This includes
|
||||
* the main thread and threads made with pthread_create().
|
||||
*
|
||||
* - Catch overflows where more than SYS_MBOX_SIZE messages
|
||||
* are waiting to be read. The sys_mbox_post() routine
|
||||
* will block until there is more room instead of just
|
||||
* leaking messages.
|
||||
*/
|
||||
#define _GNU_SOURCE /* pull in pthread_setname_np() on Linux */
|
||||
|
||||
#include "lwip/debug.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "lwip/def.h"
|
||||
|
||||
#ifdef LWIP_UNIX_MACH
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#endif
|
||||
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/tcpip.h"
|
||||
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
/* pthread key to *our* thread local storage entry */
|
||||
static pthread_key_t sys_thread_sem_key;
|
||||
#endif
|
||||
|
||||
/* Return code for an interrupted timed wait */
|
||||
#define SYS_ARCH_INTR 0xfffffffeUL
|
||||
|
||||
u32_t
|
||||
lwip_port_rand(void)
|
||||
{
|
||||
return (u32_t)rand();
|
||||
}
|
||||
|
||||
static void
|
||||
get_monotonic_time(struct timespec *ts)
|
||||
{
|
||||
#ifdef LWIP_UNIX_MACH
|
||||
/* darwin impl (no CLOCK_MONOTONIC) */
|
||||
u64_t t = mach_absolute_time();
|
||||
mach_timebase_info_data_t timebase_info = {0, 0};
|
||||
mach_timebase_info(&timebase_info);
|
||||
u64_t nano = (t * timebase_info.numer) / (timebase_info.denom);
|
||||
u64_t sec = nano/1000000000L;
|
||||
nano -= sec * 1000000000L;
|
||||
ts->tv_sec = sec;
|
||||
ts->tv_nsec = nano;
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, ts);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SYS_LIGHTWEIGHT_PROT
|
||||
static pthread_mutex_t lwprot_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_t lwprot_thread = (pthread_t)0xDEAD;
|
||||
static int lwprot_count = 0;
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
#if !NO_SYS
|
||||
|
||||
static struct sys_thread *threads = NULL;
|
||||
static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
struct sys_mbox_msg {
|
||||
struct sys_mbox_msg *next;
|
||||
void *msg;
|
||||
};
|
||||
|
||||
#define SYS_MBOX_SIZE 128
|
||||
|
||||
struct sys_mbox {
|
||||
int first, last;
|
||||
void *msgs[SYS_MBOX_SIZE];
|
||||
struct sys_sem *not_empty;
|
||||
struct sys_sem *not_full;
|
||||
struct sys_sem *mutex;
|
||||
int wait_send;
|
||||
};
|
||||
|
||||
struct sys_sem {
|
||||
unsigned int c;
|
||||
pthread_condattr_t condattr;
|
||||
pthread_cond_t cond;
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
struct sys_mutex {
|
||||
pthread_mutex_t mutex;
|
||||
};
|
||||
|
||||
struct sys_thread {
|
||||
struct sys_thread *next;
|
||||
pthread_t pthread;
|
||||
};
|
||||
|
||||
static struct sys_sem *sys_sem_new_internal(u8_t count);
|
||||
static void sys_sem_free_internal(struct sys_sem *sem);
|
||||
|
||||
static u32_t cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex,
|
||||
u32_t timeout);
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Threads */
|
||||
static struct sys_thread *
|
||||
introduce_thread(pthread_t id)
|
||||
{
|
||||
struct sys_thread *thread;
|
||||
|
||||
thread = (struct sys_thread *)malloc(sizeof(struct sys_thread));
|
||||
|
||||
if (thread != NULL) {
|
||||
pthread_mutex_lock(&threads_mutex);
|
||||
thread->next = threads;
|
||||
thread->pthread = id;
|
||||
threads = thread;
|
||||
pthread_mutex_unlock(&threads_mutex);
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
struct thread_wrapper_data
|
||||
{
|
||||
lwip_thread_fn function;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void *
|
||||
thread_wrapper(void *arg)
|
||||
{
|
||||
struct thread_wrapper_data *thread_data = (struct thread_wrapper_data *)arg;
|
||||
|
||||
thread_data->function(thread_data->arg);
|
||||
|
||||
/* we should never get here */
|
||||
free(arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sys_thread_t
|
||||
sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
|
||||
{
|
||||
int code;
|
||||
pthread_t tmp;
|
||||
struct sys_thread *st = NULL;
|
||||
struct thread_wrapper_data *thread_data;
|
||||
LWIP_UNUSED_ARG(name);
|
||||
LWIP_UNUSED_ARG(stacksize);
|
||||
LWIP_UNUSED_ARG(prio);
|
||||
|
||||
thread_data = (struct thread_wrapper_data *)malloc(sizeof(struct thread_wrapper_data));
|
||||
thread_data->arg = arg;
|
||||
thread_data->function = function;
|
||||
code = pthread_create(&tmp,
|
||||
NULL,
|
||||
thread_wrapper,
|
||||
thread_data);
|
||||
|
||||
#ifdef LWIP_UNIX_LINUX
|
||||
pthread_setname_np(tmp, name);
|
||||
#endif
|
||||
|
||||
if (0 == code) {
|
||||
st = introduce_thread(tmp);
|
||||
}
|
||||
|
||||
if (NULL == st) {
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_new: pthread_create %d, st = 0x%lx\n",
|
||||
code, (unsigned long)st));
|
||||
abort();
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
static pthread_t lwip_core_lock_holder_thread_id;
|
||||
void sys_lock_tcpip_core(void)
|
||||
{
|
||||
sys_mutex_lock(&lock_tcpip_core);
|
||||
lwip_core_lock_holder_thread_id = pthread_self();
|
||||
}
|
||||
|
||||
void sys_unlock_tcpip_core(void)
|
||||
{
|
||||
lwip_core_lock_holder_thread_id = 0;
|
||||
sys_mutex_unlock(&lock_tcpip_core);
|
||||
}
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
static pthread_t lwip_tcpip_thread_id;
|
||||
void sys_mark_tcpip_thread(void)
|
||||
{
|
||||
lwip_tcpip_thread_id = pthread_self();
|
||||
}
|
||||
|
||||
void sys_check_core_locking(void)
|
||||
{
|
||||
/* Embedded systems should check we are NOT in an interrupt context here */
|
||||
|
||||
if (lwip_tcpip_thread_id != 0) {
|
||||
pthread_t current_thread_id = pthread_self();
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
LWIP_ASSERT("Function called without core lock", current_thread_id == lwip_core_lock_holder_thread_id);
|
||||
#else /* LWIP_TCPIP_CORE_LOCKING */
|
||||
LWIP_ASSERT("Function called from wrong thread", current_thread_id == lwip_tcpip_thread_id);
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Mailbox */
|
||||
err_t
|
||||
sys_mbox_new(struct sys_mbox **mb, int size)
|
||||
{
|
||||
struct sys_mbox *mbox;
|
||||
LWIP_UNUSED_ARG(size);
|
||||
|
||||
mbox = (struct sys_mbox *)malloc(sizeof(struct sys_mbox));
|
||||
if (mbox == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
mbox->first = mbox->last = 0;
|
||||
mbox->not_empty = sys_sem_new_internal(0);
|
||||
mbox->not_full = sys_sem_new_internal(0);
|
||||
mbox->mutex = sys_sem_new_internal(1);
|
||||
mbox->wait_send = 0;
|
||||
|
||||
SYS_STATS_INC_USED(mbox);
|
||||
*mb = mbox;
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
void
|
||||
sys_mbox_free(struct sys_mbox **mb)
|
||||
{
|
||||
if ((mb != NULL) && (*mb != SYS_MBOX_NULL)) {
|
||||
struct sys_mbox *mbox = *mb;
|
||||
SYS_STATS_DEC(mbox.used);
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
|
||||
sys_sem_free_internal(mbox->not_empty);
|
||||
sys_sem_free_internal(mbox->not_full);
|
||||
sys_sem_free_internal(mbox->mutex);
|
||||
mbox->not_empty = mbox->not_full = mbox->mutex = NULL;
|
||||
/* LWIP_DEBUGF("sys_mbox_free: mbox 0x%lx\n", mbox); */
|
||||
free(mbox);
|
||||
}
|
||||
}
|
||||
|
||||
err_t
|
||||
sys_mbox_trypost(struct sys_mbox **mb, void *msg)
|
||||
{
|
||||
u8_t first;
|
||||
struct sys_mbox *mbox;
|
||||
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
|
||||
mbox = *mb;
|
||||
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_trypost: mbox %p msg %p\n",
|
||||
(void *)mbox, (void *)msg));
|
||||
|
||||
if ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
|
||||
|
||||
if (mbox->last == mbox->first) {
|
||||
first = 1;
|
||||
} else {
|
||||
first = 0;
|
||||
}
|
||||
|
||||
mbox->last++;
|
||||
|
||||
if (first) {
|
||||
sys_sem_signal(&mbox->not_empty);
|
||||
}
|
||||
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
err_t
|
||||
sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
|
||||
{
|
||||
return sys_mbox_trypost(q, msg);
|
||||
}
|
||||
|
||||
void
|
||||
sys_mbox_post(struct sys_mbox **mb, void *msg)
|
||||
{
|
||||
u8_t first;
|
||||
struct sys_mbox *mbox;
|
||||
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
|
||||
mbox = *mb;
|
||||
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg));
|
||||
|
||||
while ((mbox->last + 1) >= (mbox->first + SYS_MBOX_SIZE)) {
|
||||
mbox->wait_send++;
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
sys_arch_sem_wait(&mbox->not_full, 0);
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
mbox->wait_send--;
|
||||
}
|
||||
|
||||
mbox->msgs[mbox->last % SYS_MBOX_SIZE] = msg;
|
||||
|
||||
if (mbox->last == mbox->first) {
|
||||
first = 1;
|
||||
} else {
|
||||
first = 0;
|
||||
}
|
||||
|
||||
mbox->last++;
|
||||
|
||||
if (first) {
|
||||
sys_sem_signal(&mbox->not_empty);
|
||||
}
|
||||
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
}
|
||||
|
||||
u32_t
|
||||
sys_arch_mbox_tryfetch(struct sys_mbox **mb, void **msg)
|
||||
{
|
||||
struct sys_mbox *mbox;
|
||||
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
|
||||
mbox = *mb;
|
||||
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
|
||||
if (mbox->first == mbox->last) {
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
return SYS_MBOX_EMPTY;
|
||||
}
|
||||
|
||||
if (msg != NULL) {
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg));
|
||||
*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
|
||||
}
|
||||
else{
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox));
|
||||
}
|
||||
|
||||
mbox->first++;
|
||||
|
||||
if (mbox->wait_send) {
|
||||
sys_sem_signal(&mbox->not_full);
|
||||
}
|
||||
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32_t
|
||||
sys_arch_mbox_fetch(struct sys_mbox **mb, void **msg, u32_t timeout)
|
||||
{
|
||||
u32_t time_needed = 0;
|
||||
struct sys_mbox *mbox;
|
||||
LWIP_ASSERT("invalid mbox", (mb != NULL) && (*mb != NULL));
|
||||
mbox = *mb;
|
||||
|
||||
/* The mutex lock is quick so we don't bother with the timeout
|
||||
stuff here. */
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
|
||||
while (mbox->first == mbox->last) {
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
|
||||
/* We block while waiting for a mail to arrive in the mailbox. We
|
||||
must be prepared to timeout. */
|
||||
if (timeout != 0) {
|
||||
time_needed = sys_arch_sem_wait(&mbox->not_empty, timeout);
|
||||
|
||||
if (time_needed == SYS_ARCH_TIMEOUT) {
|
||||
return SYS_ARCH_TIMEOUT;
|
||||
}
|
||||
} else {
|
||||
sys_arch_sem_wait(&mbox->not_empty, 0);
|
||||
}
|
||||
|
||||
sys_arch_sem_wait(&mbox->mutex, 0);
|
||||
}
|
||||
|
||||
if (msg != NULL) {
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg));
|
||||
*msg = mbox->msgs[mbox->first % SYS_MBOX_SIZE];
|
||||
}
|
||||
else{
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox));
|
||||
}
|
||||
|
||||
mbox->first++;
|
||||
|
||||
if (mbox->wait_send) {
|
||||
sys_sem_signal(&mbox->not_full);
|
||||
}
|
||||
|
||||
sys_sem_signal(&mbox->mutex);
|
||||
|
||||
return time_needed;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Semaphore */
|
||||
static struct sys_sem *
|
||||
sys_sem_new_internal(u8_t count)
|
||||
{
|
||||
struct sys_sem *sem;
|
||||
|
||||
sem = (struct sys_sem *)malloc(sizeof(struct sys_sem));
|
||||
if (sem != NULL) {
|
||||
sem->c = count;
|
||||
pthread_condattr_init(&(sem->condattr));
|
||||
#if !(defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21))
|
||||
pthread_condattr_setclock(&(sem->condattr), CLOCK_MONOTONIC);
|
||||
#endif
|
||||
pthread_cond_init(&(sem->cond), &(sem->condattr));
|
||||
pthread_mutex_init(&(sem->mutex), NULL);
|
||||
}
|
||||
return sem;
|
||||
}
|
||||
|
||||
err_t
|
||||
sys_sem_new(struct sys_sem **sem, u8_t count)
|
||||
{
|
||||
SYS_STATS_INC_USED(sem);
|
||||
*sem = sys_sem_new_internal(count);
|
||||
if (*sem == NULL) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
static u32_t
|
||||
cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, u32_t timeout)
|
||||
{
|
||||
struct timespec rtime1, rtime2, ts;
|
||||
int ret;
|
||||
|
||||
#ifdef LWIP_UNIX_HURD
|
||||
#define pthread_cond_wait pthread_hurd_cond_wait_np
|
||||
#define pthread_cond_timedwait pthread_hurd_cond_timedwait_np
|
||||
#endif
|
||||
|
||||
if (timeout == 0) {
|
||||
ret = pthread_cond_wait(cond, mutex);
|
||||
return
|
||||
#ifdef LWIP_UNIX_HURD
|
||||
/* On the Hurd, ret == 1 means the RPC has been cancelled.
|
||||
* The thread is awakened (not terminated) and execution must continue */
|
||||
ret == 1 ? SYS_ARCH_INTR :
|
||||
#endif
|
||||
(u32_t)ret;
|
||||
}
|
||||
|
||||
/* Get a timestamp and add the timeout value. */
|
||||
get_monotonic_time(&rtime1);
|
||||
#if defined(LWIP_UNIX_MACH) || (defined(LWIP_UNIX_ANDROID) && __ANDROID_API__ < 21)
|
||||
ts.tv_sec = timeout / 1000L;
|
||||
ts.tv_nsec = (timeout % 1000L) * 1000000L;
|
||||
ret = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
|
||||
#else
|
||||
ts.tv_sec = rtime1.tv_sec + timeout / 1000L;
|
||||
ts.tv_nsec = rtime1.tv_nsec + (timeout % 1000L) * 1000000L;
|
||||
if (ts.tv_nsec >= 1000000000L) {
|
||||
ts.tv_sec++;
|
||||
ts.tv_nsec -= 1000000000L;
|
||||
}
|
||||
|
||||
ret = pthread_cond_timedwait(cond, mutex, &ts);
|
||||
#endif
|
||||
if (ret == ETIMEDOUT) {
|
||||
return SYS_ARCH_TIMEOUT;
|
||||
#ifdef LWIP_UNIX_HURD
|
||||
/* On the Hurd, ret == 1 means the RPC has been cancelled.
|
||||
* The thread is awakened (not terminated) and execution must continue */
|
||||
} else if (ret == EINTR) {
|
||||
return SYS_ARCH_INTR;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Calculate for how long we waited for the cond. */
|
||||
get_monotonic_time(&rtime2);
|
||||
ts.tv_sec = rtime2.tv_sec - rtime1.tv_sec;
|
||||
ts.tv_nsec = rtime2.tv_nsec - rtime1.tv_nsec;
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_sec--;
|
||||
ts.tv_nsec += 1000000000L;
|
||||
}
|
||||
return (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
|
||||
}
|
||||
|
||||
u32_t
|
||||
sys_arch_sem_wait(struct sys_sem **s, u32_t timeout)
|
||||
{
|
||||
u32_t time_needed = 0;
|
||||
struct sys_sem *sem;
|
||||
LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
|
||||
sem = *s;
|
||||
|
||||
pthread_mutex_lock(&(sem->mutex));
|
||||
while (sem->c <= 0) {
|
||||
if (timeout > 0) {
|
||||
time_needed = cond_wait(&(sem->cond), &(sem->mutex), timeout);
|
||||
|
||||
if (time_needed == SYS_ARCH_TIMEOUT) {
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return SYS_ARCH_TIMEOUT;
|
||||
#ifdef LWIP_UNIX_HURD
|
||||
} else if(time_needed == SYS_ARCH_INTR) {
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
/* pthread_mutex_unlock(&(sem->mutex));
|
||||
return time_needed; */
|
||||
} else if(cond_wait(&(sem->cond), &(sem->mutex), 0)) {
|
||||
/* Some error happened or the thread has been awakened but not by lwip */
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sem->c--;
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
return (u32_t)time_needed;
|
||||
}
|
||||
|
||||
void
|
||||
sys_sem_signal(struct sys_sem **s)
|
||||
{
|
||||
struct sys_sem *sem;
|
||||
LWIP_ASSERT("invalid sem", (s != NULL) && (*s != NULL));
|
||||
sem = *s;
|
||||
|
||||
pthread_mutex_lock(&(sem->mutex));
|
||||
sem->c++;
|
||||
|
||||
if (sem->c > 1) {
|
||||
sem->c = 1;
|
||||
}
|
||||
|
||||
pthread_cond_broadcast(&(sem->cond));
|
||||
pthread_mutex_unlock(&(sem->mutex));
|
||||
}
|
||||
|
||||
static void
|
||||
sys_sem_free_internal(struct sys_sem *sem)
|
||||
{
|
||||
pthread_cond_destroy(&(sem->cond));
|
||||
pthread_condattr_destroy(&(sem->condattr));
|
||||
pthread_mutex_destroy(&(sem->mutex));
|
||||
free(sem);
|
||||
}
|
||||
|
||||
void
|
||||
sys_sem_free(struct sys_sem **sem)
|
||||
{
|
||||
if ((sem != NULL) && (*sem != SYS_SEM_NULL)) {
|
||||
SYS_STATS_DEC(sem.used);
|
||||
sys_sem_free_internal(*sem);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Mutex */
|
||||
/** Create a new mutex
|
||||
* @param mutex pointer to the mutex to create
|
||||
* @return a new mutex */
|
||||
err_t
|
||||
sys_mutex_new(struct sys_mutex **mutex)
|
||||
{
|
||||
struct sys_mutex *mtx;
|
||||
|
||||
mtx = (struct sys_mutex *)malloc(sizeof(struct sys_mutex));
|
||||
if (mtx != NULL) {
|
||||
pthread_mutex_init(&(mtx->mutex), NULL);
|
||||
*mutex = mtx;
|
||||
return ERR_OK;
|
||||
}
|
||||
else {
|
||||
return ERR_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/** Lock a mutex
|
||||
* @param mutex the mutex to lock */
|
||||
void
|
||||
sys_mutex_lock(struct sys_mutex **mutex)
|
||||
{
|
||||
pthread_mutex_lock(&((*mutex)->mutex));
|
||||
}
|
||||
|
||||
/** Unlock a mutex
|
||||
* @param mutex the mutex to unlock */
|
||||
void
|
||||
sys_mutex_unlock(struct sys_mutex **mutex)
|
||||
{
|
||||
pthread_mutex_unlock(&((*mutex)->mutex));
|
||||
}
|
||||
|
||||
/** Delete a mutex
|
||||
* @param mutex the mutex to delete */
|
||||
void
|
||||
sys_mutex_free(struct sys_mutex **mutex)
|
||||
{
|
||||
pthread_mutex_destroy(&((*mutex)->mutex));
|
||||
free(*mutex);
|
||||
}
|
||||
|
||||
#endif /* !NO_SYS */
|
||||
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Semaphore per thread located TLS */
|
||||
|
||||
static void
|
||||
sys_thread_sem_free(void* data)
|
||||
{
|
||||
sys_sem_t *sem = (sys_sem_t*)(data);
|
||||
|
||||
if (sem) {
|
||||
sys_sem_free(sem);
|
||||
free(sem);
|
||||
}
|
||||
}
|
||||
|
||||
static sys_sem_t*
|
||||
sys_thread_sem_alloc(void)
|
||||
{
|
||||
sys_sem_t *sem;
|
||||
err_t err;
|
||||
int ret;
|
||||
|
||||
sem = (sys_sem_t*)malloc(sizeof(sys_sem_t*));
|
||||
LWIP_ASSERT("failed to allocate memory for TLS semaphore", sem != NULL);
|
||||
err = sys_sem_new(sem, 0);
|
||||
LWIP_ASSERT("failed to initialise TLS semaphore", err == ERR_OK);
|
||||
ret = pthread_setspecific(sys_thread_sem_key, sem);
|
||||
LWIP_ASSERT("failed to initialise TLS semaphore storage", ret == 0);
|
||||
return sem;
|
||||
}
|
||||
|
||||
sys_sem_t*
|
||||
sys_arch_netconn_sem_get(void)
|
||||
{
|
||||
sys_sem_t* sem = (sys_sem_t*)pthread_getspecific(sys_thread_sem_key);
|
||||
if (!sem) {
|
||||
sem = sys_thread_sem_alloc();
|
||||
}
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_sem_get s=%p\n", (void*)sem));
|
||||
return sem;
|
||||
}
|
||||
|
||||
void
|
||||
sys_arch_netconn_sem_alloc(void)
|
||||
{
|
||||
sys_sem_t* sem = sys_thread_sem_alloc();
|
||||
LWIP_DEBUGF(SYS_DEBUG, ("sys_thread_sem created s=%p\n", (void*)sem));
|
||||
}
|
||||
|
||||
void
|
||||
sys_arch_netconn_sem_free(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
sys_sem_t *sem = (sys_sem_t *)pthread_getspecific(sys_thread_sem_key);
|
||||
sys_thread_sem_free(sem);
|
||||
ret = pthread_setspecific(sys_thread_sem_key, NULL);
|
||||
LWIP_ASSERT("failed to de-init TLS semaphore storage", ret == 0);
|
||||
}
|
||||
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Time */
|
||||
u32_t
|
||||
sys_now(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
u32_t now;
|
||||
|
||||
get_monotonic_time(&ts);
|
||||
now = (u32_t)(ts.tv_sec * 1000L + ts.tv_nsec / 1000000L);
|
||||
#ifdef LWIP_FUZZ_SYS_NOW
|
||||
now += sys_now_offset;
|
||||
#endif
|
||||
return now;
|
||||
}
|
||||
|
||||
u32_t
|
||||
sys_jiffies(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
get_monotonic_time(&ts);
|
||||
return (u32_t)(ts.tv_sec * 1000000000L + ts.tv_nsec);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Init */
|
||||
|
||||
void
|
||||
sys_init(void)
|
||||
{
|
||||
#if LWIP_NETCONN_SEM_PER_THREAD
|
||||
pthread_key_create(&sys_thread_sem_key, sys_thread_sem_free);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Critical section */
|
||||
#if SYS_LIGHTWEIGHT_PROT
|
||||
/** sys_prot_t sys_arch_protect(void)
|
||||
|
||||
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.
|
||||
*/
|
||||
sys_prot_t
|
||||
sys_arch_protect(void)
|
||||
{
|
||||
/* Note that for the UNIX port, we are using a lightweight mutex, and our
|
||||
* own counter (which is locked by the mutex). The return code is not actually
|
||||
* used. */
|
||||
if (lwprot_thread != pthread_self())
|
||||
{
|
||||
/* We are locking the mutex where it has not been locked before *
|
||||
* or is being locked by another thread */
|
||||
pthread_mutex_lock(&lwprot_mutex);
|
||||
lwprot_thread = pthread_self();
|
||||
lwprot_count = 1;
|
||||
}
|
||||
else
|
||||
/* It is already locked by THIS thread */
|
||||
lwprot_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** void sys_arch_unprotect(sys_prot_t pval)
|
||||
|
||||
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.
|
||||
*/
|
||||
void
|
||||
sys_arch_unprotect(sys_prot_t pval)
|
||||
{
|
||||
LWIP_UNUSED_ARG(pval);
|
||||
if (lwprot_thread == pthread_self())
|
||||
{
|
||||
lwprot_count--;
|
||||
if (lwprot_count == 0)
|
||||
{
|
||||
lwprot_thread = (pthread_t) 0xDEAD;
|
||||
pthread_mutex_unlock(&lwprot_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SYS_LIGHTWEIGHT_PROT */
|
||||
|
||||
#if !NO_SYS
|
||||
/* get keyboard state to terminate the debug app by using select */
|
||||
int
|
||||
lwip_unix_keypressed(void)
|
||||
{
|
||||
struct timeval tv = { 0L, 0L };
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
return select(1, &fds, NULL, NULL, &tv);
|
||||
}
|
||||
#endif /* !NO_SYS */
|
||||
Reference in New Issue
Block a user