ReactOS  0.4.13-dev-249-gcba1a2f
tcpip.c
Go to the documentation of this file.
1 
7 /*
8  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  * this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  * this list of conditions and the following disclaimer in the documentation
18  * and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  * derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  *
33  * This file is part of the lwIP TCP/IP stack.
34  *
35  * Author: Adam Dunkels <adam@sics.se>
36  *
37  */
38 
39 #include "lwip/opt.h"
40 
41 #if !NO_SYS /* don't build if not configured for use in lwipopts.h */
42 
43 #include "lwip/sys.h"
44 #include "lwip/memp.h"
45 #include "lwip/mem.h"
46 #include "lwip/pbuf.h"
47 #include "lwip/tcpip.h"
48 #include "lwip/init.h"
49 #include "lwip/ip.h"
50 #include "netif/etharp.h"
51 #include "netif/ppp_oe.h"
52 
53 /* global variables */
55 static void *tcpip_init_done_arg;
57 
58 #if LWIP_TCPIP_CORE_LOCKING
59 
60 sys_mutex_t lock_tcpip_core;
61 #endif /* LWIP_TCPIP_CORE_LOCKING */
62 
63 
74 static void
76 {
77  struct tcpip_msg *msg;
79 
80  if (tcpip_init_done != NULL) {
82  }
83 
85  while (1) { /* MAIN Loop */
88  /* wait for a message, timeouts are processed while waiting */
89  sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
91  switch (msg->type) {
92 #if LWIP_NETCONN
93  case TCPIP_MSG_API:
94  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
95  msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
96  break;
97 #endif /* LWIP_NETCONN */
98 
99 #if !LWIP_TCPIP_CORE_LOCKING_INPUT
100  case TCPIP_MSG_INPKT:
101  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
102 #if LWIP_ETHERNET
103  if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
104  ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
105  } else
106 #endif /* LWIP_ETHERNET */
107  {
108  ip_input(msg->msg.inp.p, msg->msg.inp.netif);
109  }
110  memp_free(MEMP_TCPIP_MSG_INPKT, msg);
111  break;
112 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
113 
114 #if LWIP_NETIF_API
115  case TCPIP_MSG_NETIFAPI:
116  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
117  msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
118  break;
119 #endif /* LWIP_NETIF_API */
120 
121 #if LWIP_TCPIP_TIMEOUT
122  case TCPIP_MSG_TIMEOUT:
123  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
124  sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
125  memp_free(MEMP_TCPIP_MSG_API, msg);
126  break;
127  case TCPIP_MSG_UNTIMEOUT:
128  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
129  sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
130  memp_free(MEMP_TCPIP_MSG_API, msg);
131  break;
132 #endif /* LWIP_TCPIP_TIMEOUT */
133 
134  case TCPIP_MSG_CALLBACK:
135  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
136  msg->msg.cb.function(msg->msg.cb.ctx);
137  memp_free(MEMP_TCPIP_MSG_API, msg);
138  break;
139 
141  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
142  msg->msg.cb.function(msg->msg.cb.ctx);
143  break;
144 
145  default:
146  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
147  LWIP_ASSERT("tcpip_thread: invalid message", 0);
148  break;
149  }
150  }
151 }
152 
161 err_t
162 tcpip_input(struct pbuf *p, struct netif *inp)
163 {
164 #if LWIP_TCPIP_CORE_LOCKING_INPUT
165  err_t ret;
166  LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
167  LOCK_TCPIP_CORE();
168 #if LWIP_ETHERNET
169  if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
170  ret = ethernet_input(p, inp);
171  } else
172 #endif /* LWIP_ETHERNET */
173  {
174  ret = ip_input(p, inp);
175  }
177  return ret;
178 #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
179  struct tcpip_msg *msg;
180 
181  if (!sys_mbox_valid(&mbox)) {
182  return ERR_VAL;
183  }
184  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
185  if (msg == NULL) {
186  return ERR_MEM;
187  }
188 
189  msg->type = TCPIP_MSG_INPKT;
190  msg->msg.inp.p = p;
191  msg->msg.inp.netif = inp;
192  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
193  memp_free(MEMP_TCPIP_MSG_INPKT, msg);
194  return ERR_MEM;
195  }
196  return ERR_OK;
197 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
198 }
199 
211 err_t
213 {
214  struct tcpip_msg *msg;
215 
216  if (sys_mbox_valid(&mbox)) {
217  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
218  if (msg == NULL) {
219  return ERR_MEM;
220  }
221 
222  msg->type = TCPIP_MSG_CALLBACK;
223  msg->msg.cb.function = function;
224  msg->msg.cb.ctx = ctx;
225  if (block) {
227  } else {
228  if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
229  memp_free(MEMP_TCPIP_MSG_API, msg);
230  return ERR_MEM;
231  }
232  }
233  return ERR_OK;
234  }
235  return ERR_VAL;
236 }
237 
238 #if LWIP_TCPIP_TIMEOUT
239 
247 err_t
248 tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
249 {
250  struct tcpip_msg *msg;
251 
252  if (sys_mbox_valid(&mbox)) {
253  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
254  if (msg == NULL) {
255  return ERR_MEM;
256  }
257 
258  msg->type = TCPIP_MSG_TIMEOUT;
259  msg->msg.tmo.msecs = msecs;
260  msg->msg.tmo.h = h;
261  msg->msg.tmo.arg = arg;
263  return ERR_OK;
264  }
265  return ERR_VAL;
266 }
267 
276 err_t
277 tcpip_untimeout(sys_timeout_handler h, void *arg)
278 {
279  struct tcpip_msg *msg;
280 
281  if (sys_mbox_valid(&mbox)) {
282  msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
283  if (msg == NULL) {
284  return ERR_MEM;
285  }
286 
287  msg->type = TCPIP_MSG_UNTIMEOUT;
288  msg->msg.tmo.h = h;
289  msg->msg.tmo.arg = arg;
291  return ERR_OK;
292  }
293  return ERR_VAL;
294 }
295 #endif /* LWIP_TCPIP_TIMEOUT */
296 
297 #if LWIP_NETCONN
298 
306 err_t
307 tcpip_apimsg(struct api_msg *apimsg)
308 {
309  struct tcpip_msg msg;
310 #ifdef LWIP_DEBUG
311  /* catch functions that don't set err */
312  apimsg->msg.err = ERR_VAL;
313 #endif
314 
315  if (sys_mbox_valid(&mbox)) {
316  msg.type = TCPIP_MSG_API;
317  msg.msg.apimsg = apimsg;
318  sys_mbox_post(&mbox, &msg);
319  sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
320  return apimsg->msg.err;
321  }
322  return ERR_VAL;
323 }
324 
325 #if LWIP_TCPIP_CORE_LOCKING
326 
334 err_t
335 tcpip_apimsg_lock(struct api_msg *apimsg)
336 {
337 #ifdef LWIP_DEBUG
338  /* catch functions that don't set err */
339  apimsg->msg.err = ERR_VAL;
340 #endif
341 
342  LOCK_TCPIP_CORE();
343  apimsg->function(&(apimsg->msg));
345  return apimsg->msg.err;
346 
347 }
348 #endif /* LWIP_TCPIP_CORE_LOCKING */
349 #endif /* LWIP_NETCONN */
350 
351 #if LWIP_NETIF_API
352 #if !LWIP_TCPIP_CORE_LOCKING
353 
360 err_t
361 tcpip_netifapi(struct netifapi_msg* netifapimsg)
362 {
363  struct tcpip_msg msg;
364 
365  if (sys_mbox_valid(&mbox)) {
366  err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
367  if (err != ERR_OK) {
368  netifapimsg->msg.err = err;
369  return err;
370  }
371 
372  msg.type = TCPIP_MSG_NETIFAPI;
373  msg.msg.netifapimsg = netifapimsg;
374  sys_mbox_post(&mbox, &msg);
375  sys_sem_wait(&netifapimsg->msg.sem);
376  sys_sem_free(&netifapimsg->msg.sem);
377  return netifapimsg->msg.err;
378  }
379  return ERR_VAL;
380 }
381 #else /* !LWIP_TCPIP_CORE_LOCKING */
382 
390 err_t
391 tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
392 {
393  LOCK_TCPIP_CORE();
394  netifapimsg->function(&(netifapimsg->msg));
396  return netifapimsg->msg.err;
397 }
398 #endif /* !LWIP_TCPIP_CORE_LOCKING */
399 #endif /* LWIP_NETIF_API */
400 
409 struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
410 {
411  struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
412  if (msg == NULL) {
413  return NULL;
414  }
416  msg->msg.cb.function = function;
417  msg->msg.cb.ctx = ctx;
418  return (struct tcpip_callback_msg*)msg;
419 }
420 
426 void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
427 {
428  memp_free(MEMP_TCPIP_MSG_API, msg);
429 }
430 
438 err_t
439 tcpip_trycallback(struct tcpip_callback_msg* msg)
440 {
441  if (!sys_mbox_valid(&mbox)) {
442  return ERR_VAL;
443  }
444  return sys_mbox_trypost(&mbox, msg);
445 }
446 
455 void
457 {
458  lwip_init();
459 
460  tcpip_init_done = initfunc;
463  LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
464  }
465 #if LWIP_TCPIP_CORE_LOCKING
466  if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
467  LWIP_ASSERT("failed to create lock_tcpip_core", 0);
468  }
469 #endif /* LWIP_TCPIP_CORE_LOCKING */
470 
472 }
473 
480 static void
482 {
483  struct pbuf *q = (struct pbuf *)p;
484  pbuf_free(q);
485 }
486 
493 err_t
495 {
497 }
498 
506 err_t
508 {
510 }
511 
512 #endif /* !NO_SYS */
static unsigned int block
Definition: xmlmemory.c:118
#define TCPIP_THREAD_NAME
Definition: opt.h:1241
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:280
static void pbuf_free_int(void *p)
Definition: tcpip.c:481
err_t sys_mutex_new(sys_mutex_t *mutex)
void(* sys_timeout_handler)(void *arg)
Definition: timers.h:65
#define UNLOCK_TCPIP_CORE()
Definition: tcpip.h:68
err_t mem_free_callback(void *m)
Definition: tcpip.c:507
int sys_mbox_valid(sys_mbox_t *mbox)
Definition: sys_arch.c:146
#define TCPIP_THREAD_PRIO
Definition: opt.h:1259
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
Definition: tcpip.c:212
err_t ip_input(struct pbuf *p, struct netif *inp)
Definition: ip.c:305
#define LWIP_TCPIP_THREAD_ALIVE()
Definition: tcpip.h:54
err_t tcpip_trycallback(struct tcpip_callback_msg *msg)
Definition: tcpip.c:439
void * arg
Definition: msvc.h:12
static void tcpip_thread(void *arg)
Definition: tcpip.c:75
err_t pbuf_free_callback(struct pbuf *p)
Definition: tcpip.c:494
#define TCPIP_MBOX_SIZE
Definition: opt.h:1268
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
const GLfloat * m
Definition: glext.h:10848
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define sys_sem_wait(sem)
Definition: sys.h:153
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:77
#define ERR_VAL
Definition: err.h:58
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:51
void(* tcpip_init_done_fn)(void *arg)
Definition: tcpip.h:76
struct tcpip_msg::@3915::@3916 inp
smooth NULL
Definition: ftsmooth.c:416
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
s8_t err_t
Definition: err.h:47
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
void lwip_init(void)
Definition: init.c:289
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:133
#define NETIF_FLAG_ETHARP
Definition: netif.h:88
#define ERR_OK
Definition: err.h:52
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition: tcpip.c:162
Definition: pbuf.h:79
unsigned long u32_t
Definition: cc.h:25
void(* tcpip_callback_fn)(void *ctx)
Definition: tcpip.h:78
void sys_untimeout(sys_timeout_handler handler, void *arg)
Definition: netif.h:136
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
#define NETIF_FLAG_ETHERNET
Definition: netif.h:92
#define LOCK_TCPIP_CORE()
Definition: tcpip.h:67
int ret
void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
Definition: tcpip.c:456
#define err(...)
static tcpip_init_done_fn tcpip_init_done
Definition: tcpip.c:54
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:91
static void * tcpip_init_done_arg
Definition: tcpip.c:55
#define ERR_MEM
Definition: fontsub.h:52
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:252
unsigned char u8_t
Definition: cc.h:23
void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
void * ctx
Definition: tcpip.h:149
#define msg(x)
Definition: auth_time.c:54
#define TCPIP_THREAD_STACKSIZE
Definition: opt.h:1250
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:165
#define mem_free(ptr, bsize)
Definition: types.h:124
void tcpip_callbackmsg_delete(struct tcpip_callback_msg *msg)
Definition: tcpip.c:426
void * memp_malloc(memp_t type)
Definition: memp.c:390
GLfloat GLfloat p
Definition: glext.h:8902
static sys_mbox_t mbox
Definition: tcpip.c:56
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
struct tcpip_callback_msg * tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
Definition: tcpip.c:409
#define TCPIP_DEBUG
Definition: lwipopts.h:206