ReactOS 0.4.16-dev-823-g9a093ec
tcpip.c File Reference
#include "lwip/opt.h"
#include "lwip/priv/tcpip_priv.h"
#include "lwip/sys.h"
#include "lwip/memp.h"
#include "lwip/mem.h"
#include "lwip/init.h"
#include "lwip/ip.h"
#include "lwip/pbuf.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h"
Include dependency graph for tcpip.c:

Go to the source code of this file.

Macros

#define TCPIP_MSG_VAR_REF(name)   API_VAR_REF(name)
 
#define TCPIP_MSG_VAR_DECLARE(name)   API_VAR_DECLARE(struct tcpip_msg, name)
 
#define TCPIP_MSG_VAR_ALLOC(name)   API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)
 
#define TCPIP_MSG_VAR_FREE(name)   API_VAR_FREE(MEMP_TCPIP_MSG_API, name)
 
#define TCPIP_MBOX_FETCH(mbox, msg)   sys_mbox_fetch(mbox, msg)
 

Functions

static void tcpip_thread_handle_msg (struct tcpip_msg *msg)
 
static void tcpip_thread (void *arg)
 
err_t tcpip_inpkt (struct pbuf *p, struct netif *inp, netif_input_fn input_fn)
 
err_t tcpip_input (struct pbuf *p, struct netif *inp)
 
err_t tcpip_callback (tcpip_callback_fn function, void *ctx)
 
err_t tcpip_try_callback (tcpip_callback_fn function, void *ctx)
 
err_t tcpip_send_msg_wait_sem (tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
 
err_t tcpip_api_call (tcpip_api_call_fn fn, struct tcpip_api_call_data *call)
 
struct tcpip_callback_msg * tcpip_callbackmsg_new (tcpip_callback_fn function, void *ctx)
 
void tcpip_callbackmsg_delete (struct tcpip_callback_msg *msg)
 
err_t tcpip_callbackmsg_trycallback (struct tcpip_callback_msg *msg)
 
err_t tcpip_callbackmsg_trycallback_fromisr (struct tcpip_callback_msg *msg)
 
err_t tcpip_callback_wait (tcpip_callback_fn function, void *ctx)
 
void tcpip_init (tcpip_init_done_fn initfunc, void *arg)
 
static void pbuf_free_int (void *p)
 
err_t pbuf_free_callback (struct pbuf *p)
 
err_t mem_free_callback (void *m)
 

Variables

static tcpip_init_done_fn tcpip_init_done
 
static voidtcpip_init_done_arg
 
static sys_mbox_t tcpip_mbox
 

Detailed Description

Sequential API Main thread module

Definition in file tcpip.c.

Macro Definition Documentation

◆ TCPIP_MBOX_FETCH

#define TCPIP_MBOX_FETCH (   mbox,
  msg 
)    sys_mbox_fetch(mbox, msg)

Definition at line 72 of file tcpip.c.

◆ TCPIP_MSG_VAR_ALLOC

#define TCPIP_MSG_VAR_ALLOC (   name)    API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM)

Definition at line 55 of file tcpip.c.

◆ TCPIP_MSG_VAR_DECLARE

#define TCPIP_MSG_VAR_DECLARE (   name)    API_VAR_DECLARE(struct tcpip_msg, name)

Definition at line 54 of file tcpip.c.

◆ TCPIP_MSG_VAR_FREE

#define TCPIP_MSG_VAR_FREE (   name)    API_VAR_FREE(MEMP_TCPIP_MSG_API, name)

Definition at line 56 of file tcpip.c.

◆ TCPIP_MSG_VAR_REF

#define TCPIP_MSG_VAR_REF (   name)    API_VAR_REF(name)

Definition at line 53 of file tcpip.c.

Function Documentation

◆ mem_free_callback()

err_t mem_free_callback ( void m)

A simple wrapper function that allows you to free heap memory from interrupt context.

Parameters
mthe heap memory to free
Returns
ERR_OK if callback could be enqueued, an err_t if not

Definition at line 701 of file tcpip.c.

702{
704}
#define mem_free(ptr, bsize)
Definition: types.h:124
const GLfloat * m
Definition: glext.h:10848
err_t tcpip_try_callback(tcpip_callback_fn function, void *ctx)
Definition: tcpip.c:350

◆ pbuf_free_callback()

err_t pbuf_free_callback ( struct pbuf p)

A simple wrapper function that allows you to free a pbuf from interrupt context.

Parameters
pThe pbuf (chain) to be dereferenced.
Returns
ERR_OK if callback could be enqueued, an err_t if not

Definition at line 688 of file tcpip.c.

689{
691}
GLfloat GLfloat p
Definition: glext.h:8902
static void pbuf_free_int(void *p)
Definition: tcpip.c:675

Referenced by LibTCPGetDataFromConnectionQueue().

◆ pbuf_free_int()

static void pbuf_free_int ( void p)
static

Simple callback function used with tcpip_callback to free a pbuf (pbuf_free has a wrong signature for tcpip_callback)

Parameters
pThe pbuf (chain) to be dereferenced.

Definition at line 675 of file tcpip.c.

676{
677 struct pbuf *q = (struct pbuf *)p;
678 pbuf_free(q);
679}
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:727
Definition: pbuf.h:186

Referenced by pbuf_free_callback().

◆ tcpip_api_call()

err_t tcpip_api_call ( tcpip_api_call_fn  fn,
struct tcpip_api_call_data call 
)

Synchronously calls function in TCPIP thread and waits for its completion. It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or LWIP_NETCONN_SEM_PER_THREAD. If not, a semaphore is created and destroyed on every call which is usually an expensive/slow operation.

Parameters
fnFunction to call
callCall parameters
Returns
Return value from tcpip_api_call_fn

Definition at line 478 of file tcpip.c.

479{
480#if LWIP_TCPIP_CORE_LOCKING
481 err_t err;
483 err = fn(call);
485 return err;
486#else /* LWIP_TCPIP_CORE_LOCKING */
488
489#if !LWIP_NETCONN_SEM_PER_THREAD
490 err_t err = sys_sem_new(&call->sem, 0);
491 if (err != ERR_OK) {
492 return err;
493 }
494#endif /* LWIP_NETCONN_SEM_PER_THREAD */
495
496 LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
497
500 TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call;
501 TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn;
502#if LWIP_NETCONN_SEM_PER_THREAD
504#else /* LWIP_NETCONN_SEM_PER_THREAD */
505 TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem;
506#endif /* LWIP_NETCONN_SEM_PER_THREAD */
508 sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0);
510
511#if !LWIP_NETCONN_SEM_PER_THREAD
512 sys_sem_free(&call->sem);
513#endif /* LWIP_NETCONN_SEM_PER_THREAD */
514
515 return call->err;
516#endif /* LWIP_TCPIP_CORE_LOCKING */
517}
#define msg(x)
Definition: auth_time.c:54
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
#define LOCK_TCPIP_CORE()
Definition: tcpip.h:62
#define UNLOCK_TCPIP_CORE()
Definition: tcpip.h:63
s8_t err_t
Definition: err.h:96
@ ERR_OK
Definition: err.h:55
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:160
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:72
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:86
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:46
#define LWIP_NETCONN_THREAD_SEM_GET()
Definition: sys_arch.h:74
#define err(...)
#define sys_mbox_valid_val(mbox)
Definition: sys.h:395
#define TCPIP_MSG_VAR_ALLOC(name)
Definition: tcpip.c:55
static sys_mbox_t tcpip_mbox
Definition: tcpip.c:61
#define TCPIP_MSG_VAR_FREE(name)
Definition: tcpip.c:56
#define TCPIP_MSG_VAR_REF(name)
Definition: tcpip.c:53
#define TCPIP_MSG_VAR_DECLARE(name)
Definition: tcpip.c:54
@ TCPIP_MSG_API_CALL
Definition: tcpip_priv.h:116
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159

◆ tcpip_callback_wait()

err_t tcpip_callback_wait ( tcpip_callback_fn  function,
void ctx 
)

Sends a message to TCPIP thread to call a function. Caller thread blocks until the function returns. It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or LWIP_NETCONN_SEM_PER_THREAD. If not, a semaphore is created and destroyed on every call which is usually an expensive/slow operation.

Parameters
functionthe function to call
ctxparameter passed to f
Returns
ERR_OK if the function was called, another err_t if not

Definition at line 610 of file tcpip.c.

611{
612#if LWIP_TCPIP_CORE_LOCKING
614 function(ctx);
616 return ERR_OK;
617#else /* LWIP_TCPIP_CORE_LOCKING */
618 err_t err;
620 struct tcpip_msg msg;
621
622 LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
623
624 err = sys_sem_new(&sem, 0);
625 if (err != ERR_OK) {
626 return err;
627 }
628
630 msg.msg.cb_wait.function = function;
631 msg.msg.cb_wait.ctx = ctx;
632 msg.msg.cb_wait.sem = &sem;
636 return ERR_OK;
637#endif /* LWIP_TCPIP_CORE_LOCKING */
638}
static HANDLE sem
Definition: sync.c:674
void * ctx
Definition: tcpip_priv.h:145
tcpip_callback_fn function
Definition: tcpip_priv.h:135
@ TCPIP_MSG_CALLBACK_STATIC_WAIT
Definition: tcpip_priv.h:127

◆ tcpip_inpkt()

err_t tcpip_inpkt ( struct pbuf p,
struct netif inp,
netif_input_fn  input_fn 
)

Pass a received packet to tcpip_thread for input processing

Parameters
pthe received packet
inpthe network interface on which the packet was received
input_fninput function to call

Definition at line 245 of file tcpip.c.

246{
247#if LWIP_TCPIP_CORE_LOCKING_INPUT
248 err_t ret;
249 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp));
251 ret = input_fn(p, inp);
253 return ret;
254#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
255 struct tcpip_msg *msg;
256
257 LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
258
259 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
260 if (msg == NULL) {
261 return ERR_MEM;
262 }
263
264 msg->type = TCPIP_MSG_INPKT;
265 msg->msg.inp.p = p;
266 msg->msg.inp.netif = inp;
267 msg->msg.inp.input_fn = input_fn;
269 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
270 return ERR_MEM;
271 }
272 return ERR_OK;
273#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
274}
#define NULL
Definition: types.h:112
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define ERR_MEM
Definition: fontsub.h:52
#define TCPIP_DEBUG
Definition: opt.h:3512
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:247
void * memp_malloc(memp_t type)
Definition: memp.c:337
void memp_free(memp_t type, void *mem)
Definition: memp.c:420
netif_input_fn input_fn
Definition: tcpip_priv.h:153
struct tcpip_msg::@1059::@1063 inp
@ TCPIP_MSG_INPKT
Definition: tcpip_priv.h:119
int ret

Referenced by tcpip_input().

◆ tcpip_send_msg_wait_sem()

err_t tcpip_send_msg_wait_sem ( tcpip_callback_fn  fn,
void apimsg,
sys_sem_t sem 
)

Sends a message to TCPIP thread to call a function. Caller thread blocks on on a provided semaphore, which ist NOT automatically signalled by TCPIP thread, this has to be done by the user. It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way with least runtime overhead.

Parameters
fnfunction to be called from TCPIP thread
apimsgargument to API function
semsemaphore to wait on
Returns
ERR_OK if the function was called, another err_t if not

Definition at line 442 of file tcpip.c.

443{
444#if LWIP_TCPIP_CORE_LOCKING
447 fn(apimsg);
449 return ERR_OK;
450#else /* LWIP_TCPIP_CORE_LOCKING */
452
453 LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem));
454 LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox));
455
458 TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn;
459 TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg;
463 return ERR_OK;
464#endif /* LWIP_TCPIP_CORE_LOCKING */
465}
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
#define sys_sem_valid(sema)
Definition: sys_arch.h:36
@ TCPIP_MSG_API
Definition: tcpip_priv.h:115

◆ tcpip_thread()

static void tcpip_thread ( void arg)
static

The main lwIP thread. This thread has exclusive access to lwIP core functions (unless access to them is not locked). Other threads communicate with this thread using message boxes.

It also starts all the timers to make sure they are running in the right thread context.

Parameters
argunused argument

Definition at line 127 of file tcpip.c.

128{
129 struct tcpip_msg *msg;
131
133
135 if (tcpip_init_done != NULL) {
137 }
138
139 while (1) { /* MAIN Loop */
141 /* wait for a message, timeouts are processed while waiting */
142 TCPIP_MBOX_FETCH(&tcpip_mbox, (void **)&msg);
143 if (msg == NULL) {
144 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n"));
145 LWIP_ASSERT("tcpip_thread: invalid message", 0);
146 continue;
147 }
149 }
150}
#define LWIP_MARK_TCPIP_THREAD()
Definition: sys.h:431
#define LWIP_TCPIP_THREAD_ALIVE()
Definition: opt.h:1842
static void tcpip_thread_handle_msg(struct tcpip_msg *msg)
Definition: tcpip.c:156
#define TCPIP_MBOX_FETCH(mbox, msg)
Definition: tcpip.c:72
static tcpip_init_done_fn tcpip_init_done
Definition: tcpip.c:59
static void * tcpip_init_done_arg
Definition: tcpip.c:60

Referenced by tcpip_init().

◆ tcpip_thread_handle_msg()

static void tcpip_thread_handle_msg ( struct tcpip_msg msg)
static

Definition at line 156 of file tcpip.c.

157{
158 switch (msg->type) {
159#if !LWIP_TCPIP_CORE_LOCKING
160 case TCPIP_MSG_API:
161 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
162 msg->msg.api_msg.function(msg->msg.api_msg.msg);
163 break;
165 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg));
166 msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg);
167 sys_sem_signal(msg->msg.api_call.sem);
168 break;
170 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK WAIT message %p\n", (void *)msg));
171 msg->msg.cb_wait.function(msg->msg.cb_wait.ctx);
172 sys_sem_signal(msg->msg.cb_wait.sem);
173 break;
174#endif /* !LWIP_TCPIP_CORE_LOCKING */
175
176#if !LWIP_TCPIP_CORE_LOCKING_INPUT
177 case TCPIP_MSG_INPKT:
178 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
179 if (msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif) != ERR_OK) {
180 pbuf_free(msg->msg.inp.p);
181 }
182 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
183 break;
184#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */
185
186#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS
187 case TCPIP_MSG_TIMEOUT:
188 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
189 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
190 memp_free(MEMP_TCPIP_MSG_API, msg);
191 break;
192 case TCPIP_MSG_UNTIMEOUT:
193 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
194 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
195 memp_free(MEMP_TCPIP_MSG_API, msg);
196 break;
197#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */
198
200 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
201 msg->msg.cb.function(msg->msg.cb.ctx);
202 memp_free(MEMP_TCPIP_MSG_API, msg);
203 break;
204
206 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
207 msg->msg.cb.function(msg->msg.cb.ctx);
208 break;
209
210 default:
211 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
212 LWIP_ASSERT("tcpip_thread: invalid message", 0);
213 break;
214 }
215}
void sys_sem_signal(sys_sem_t *sem)
Definition: sys_arch.c:80
@ TCPIP_MSG_CALLBACK_STATIC
Definition: tcpip_priv.h:126
@ TCPIP_MSG_CALLBACK
Definition: tcpip_priv.h:125

Referenced by tcpip_thread().

Variable Documentation

◆ tcpip_init_done

tcpip_init_done_fn tcpip_init_done
static

Definition at line 59 of file tcpip.c.

Referenced by tcpip_init(), and tcpip_thread().

◆ tcpip_init_done_arg

void* tcpip_init_done_arg
static

Definition at line 60 of file tcpip.c.

Referenced by tcpip_init(), and tcpip_thread().

◆ tcpip_mbox