ReactOS 0.4.15-dev-7660-g0086d05
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#ifdef __REACTOS__
50#include "lwip/ip.h"
51#endif
52#include "netif/etharp.h"
53#include "netif/ppp_oe.h"
54
55/* global variables */
59
60#if LWIP_TCPIP_CORE_LOCKING
62sys_mutex_t lock_tcpip_core;
63#endif /* LWIP_TCPIP_CORE_LOCKING */
64
65
76static void
78{
79 struct tcpip_msg *msg;
81
82 if (tcpip_init_done != NULL) {
84 }
85
87 while (1) { /* MAIN Loop */
90 /* wait for a message, timeouts are processed while waiting */
91 sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
93 switch (msg->type) {
94#if LWIP_NETCONN
95 case TCPIP_MSG_API:
96 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
97 msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
98 break;
99#endif /* LWIP_NETCONN */
100
101#if !LWIP_TCPIP_CORE_LOCKING_INPUT
102 case TCPIP_MSG_INPKT:
103 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
104#if LWIP_ETHERNET
105 if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
106 ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
107 } else
108#endif /* LWIP_ETHERNET */
109 {
110 ip_input(msg->msg.inp.p, msg->msg.inp.netif);
111 }
112 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
113 break;
114#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
115
116#if LWIP_NETIF_API
117 case TCPIP_MSG_NETIFAPI:
118 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
119 msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
120 break;
121#endif /* LWIP_NETIF_API */
122
123#if LWIP_TCPIP_TIMEOUT
124 case TCPIP_MSG_TIMEOUT:
125 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
126 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
127 memp_free(MEMP_TCPIP_MSG_API, msg);
128 break;
129 case TCPIP_MSG_UNTIMEOUT:
130 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
131 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
132 memp_free(MEMP_TCPIP_MSG_API, msg);
133 break;
134#endif /* LWIP_TCPIP_TIMEOUT */
135
137 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
138 msg->msg.cb.function(msg->msg.cb.ctx);
139 memp_free(MEMP_TCPIP_MSG_API, msg);
140 break;
141
143 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
144 msg->msg.cb.function(msg->msg.cb.ctx);
145 break;
146
147 default:
148 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
149 LWIP_ASSERT("tcpip_thread: invalid message", 0);
150 break;
151 }
152 }
153}
154
163err_t
164tcpip_input(struct pbuf *p, struct netif *inp)
165{
166#if LWIP_TCPIP_CORE_LOCKING_INPUT
167 err_t ret;
168 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
170#if LWIP_ETHERNET
171 if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
172 ret = ethernet_input(p, inp);
173 } else
174#endif /* LWIP_ETHERNET */
175 {
176 ret = ip_input(p, inp);
177 }
179 return ret;
180#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
181 struct tcpip_msg *msg;
182
183 if (!sys_mbox_valid(&mbox)) {
184 return ERR_VAL;
185 }
186 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
187 if (msg == NULL) {
188 return ERR_MEM;
189 }
190
191 msg->type = TCPIP_MSG_INPKT;
192 msg->msg.inp.p = p;
193 msg->msg.inp.netif = inp;
194 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
195 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
196 return ERR_MEM;
197 }
198 return ERR_OK;
199#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
200}
201
213err_t
215{
216 struct tcpip_msg *msg;
217
218 if (sys_mbox_valid(&mbox)) {
219 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
220 if (msg == NULL) {
221 return ERR_MEM;
222 }
223
224 msg->type = TCPIP_MSG_CALLBACK;
225 msg->msg.cb.function = function;
226 msg->msg.cb.ctx = ctx;
227 if (block) {
229 } else {
230 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
231 memp_free(MEMP_TCPIP_MSG_API, msg);
232 return ERR_MEM;
233 }
234 }
235 return ERR_OK;
236 }
237 return ERR_VAL;
238}
239
240#if LWIP_TCPIP_TIMEOUT
249err_t
250tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
251{
252 struct tcpip_msg *msg;
253
254 if (sys_mbox_valid(&mbox)) {
255 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
256 if (msg == NULL) {
257 return ERR_MEM;
258 }
259
260 msg->type = TCPIP_MSG_TIMEOUT;
261 msg->msg.tmo.msecs = msecs;
262 msg->msg.tmo.h = h;
263 msg->msg.tmo.arg = arg;
265 return ERR_OK;
266 }
267 return ERR_VAL;
268}
269
278err_t
279tcpip_untimeout(sys_timeout_handler h, void *arg)
280{
281 struct tcpip_msg *msg;
282
283 if (sys_mbox_valid(&mbox)) {
284 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
285 if (msg == NULL) {
286 return ERR_MEM;
287 }
288
289 msg->type = TCPIP_MSG_UNTIMEOUT;
290 msg->msg.tmo.h = h;
291 msg->msg.tmo.arg = arg;
293 return ERR_OK;
294 }
295 return ERR_VAL;
296}
297#endif /* LWIP_TCPIP_TIMEOUT */
298
299#if LWIP_NETCONN
308err_t
309tcpip_apimsg(struct api_msg *apimsg)
310{
311 struct tcpip_msg msg;
312#ifdef LWIP_DEBUG
313 /* catch functions that don't set err */
314 apimsg->msg.err = ERR_VAL;
315#endif
316
317 if (sys_mbox_valid(&mbox)) {
318 msg.type = TCPIP_MSG_API;
319 msg.msg.apimsg = apimsg;
321 sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
322 return apimsg->msg.err;
323 }
324 return ERR_VAL;
325}
326
327#if LWIP_TCPIP_CORE_LOCKING
336err_t
337tcpip_apimsg_lock(struct api_msg *apimsg)
338{
339#ifdef LWIP_DEBUG
340 /* catch functions that don't set err */
341 apimsg->msg.err = ERR_VAL;
342#endif
343
345 apimsg->function(&(apimsg->msg));
347 return apimsg->msg.err;
348
349}
350#endif /* LWIP_TCPIP_CORE_LOCKING */
351#endif /* LWIP_NETCONN */
352
353#if LWIP_NETIF_API
354#if !LWIP_TCPIP_CORE_LOCKING
362err_t
363tcpip_netifapi(struct netifapi_msg* netifapimsg)
364{
365 struct tcpip_msg msg;
366
367 if (sys_mbox_valid(&mbox)) {
368 err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
369 if (err != ERR_OK) {
370 netifapimsg->msg.err = err;
371 return err;
372 }
373
374 msg.type = TCPIP_MSG_NETIFAPI;
375 msg.msg.netifapimsg = netifapimsg;
377 sys_sem_wait(&netifapimsg->msg.sem);
378 sys_sem_free(&netifapimsg->msg.sem);
379 return netifapimsg->msg.err;
380 }
381 return ERR_VAL;
382}
383#else /* !LWIP_TCPIP_CORE_LOCKING */
392err_t
393tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
394{
396 netifapimsg->function(&(netifapimsg->msg));
398 return netifapimsg->msg.err;
399}
400#endif /* !LWIP_TCPIP_CORE_LOCKING */
401#endif /* LWIP_NETIF_API */
402
411struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
412{
413 struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
414 if (msg == NULL) {
415 return NULL;
416 }
418 msg->msg.cb.function = function;
419 msg->msg.cb.ctx = ctx;
420 return (struct tcpip_callback_msg*)msg;
421}
422
428void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
429{
430 memp_free(MEMP_TCPIP_MSG_API, msg);
431}
432
440err_t
441tcpip_trycallback(struct tcpip_callback_msg* msg)
442{
443 if (!sys_mbox_valid(&mbox)) {
444 return ERR_VAL;
445 }
446 return sys_mbox_trypost(&mbox, msg);
447}
448
457void
459{
460 lwip_init();
461
462 tcpip_init_done = initfunc;
465 LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
466 }
467#if LWIP_TCPIP_CORE_LOCKING
468 if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
469 LWIP_ASSERT("failed to create lock_tcpip_core", 0);
470 }
471#endif /* LWIP_TCPIP_CORE_LOCKING */
472
474}
475
482static void
484{
485 struct pbuf *q = (struct pbuf *)p;
486 pbuf_free(q);
487}
488
495err_t
497{
499}
500
508err_t
510{
512}
513
514#endif /* !NO_SYS */
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:73
#define msg(x)
Definition: auth_time.c:54
#define mem_free(ptr, bsize)
Definition: types.h:124
#define NULL
Definition: types.h:112
unsigned long u32_t
Definition: cc.h:25
unsigned char u8_t
Definition: cc.h:23
void lwip_init(void)
Definition: init.c:286
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:95
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:66
#define ERR_MEM
Definition: err.h:53
#define ERR_OK
Definition: err.h:52
#define ERR_VAL
Definition: err.h:58
s8_t err_t
Definition: err.h:47
@ TCPIP_MSG_CALLBACK_STATIC
Definition: tcpip.h:130
@ TCPIP_MSG_CALLBACK
Definition: tcpip.h:129
@ TCPIP_MSG_INPKT
Definition: tcpip.h:121
void(* tcpip_callback_fn)(void *ctx)
Definition: tcpip.h:78
#define LOCK_TCPIP_CORE()
Definition: tcpip.h:67
void(* tcpip_init_done_fn)(void *arg)
Definition: tcpip.h:76
#define LWIP_TCPIP_THREAD_ALIVE()
Definition: tcpip.h:54
#define UNLOCK_TCPIP_CORE()
Definition: tcpip.h:68
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLfloat GLfloat p
Definition: glext.h:8902
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
#define TCPIP_DEBUG
Definition: lwipopts.h:206
err_t ip_input(struct pbuf *p, struct netif *inp)
Definition: ip.c:305
void * memp_malloc(memp_t type)
Definition: memp.c:390
void memp_free(memp_t type, void *mem)
Definition: memp.c:435
#define NETIF_FLAG_ETHERNET
Definition: netif.h:92
#define NETIF_FLAG_ETHARP
Definition: netif.h:88
#define TCPIP_THREAD_NAME
Definition: opt.h:1241
#define TCPIP_THREAD_PRIO
Definition: opt.h:1259
#define TCPIP_MBOX_SIZE
Definition: opt.h:1268
#define TCPIP_THREAD_STACKSIZE
Definition: opt.h:1250
u8_t pbuf_free(struct pbuf *p)
Definition: pbuf.c:618
#define err(...)
Definition: netif.h:136
Definition: pbuf.h:79
struct tcpip_msg::@1041::@1042 inp
void * ctx
Definition: tcpip.h:149
tcpip_callback_fn function
Definition: tcpip.h:148
err_t sys_mutex_new(sys_mutex_t *mutex)
#define sys_sem_wait(sem)
Definition: sys.h:153
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
Definition: sys_arch.c:275
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:72
int sys_mbox_valid(sys_mbox_t *mbox)
Definition: sys_arch.c:141
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
Definition: sys_arch.c:86
void sys_mbox_post(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:160
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
Definition: sys_arch.c:247
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
Definition: sys_arch.c:128
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:46
struct tcpip_callback_msg * tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
Definition: tcpip.c:411
static sys_mbox_t mbox
Definition: tcpip.c:58
void tcpip_init(tcpip_init_done_fn initfunc, void *arg)
Definition: tcpip.c:458
err_t mem_free_callback(void *m)
Definition: tcpip.c:509
err_t pbuf_free_callback(struct pbuf *p)
Definition: tcpip.c:496
static void tcpip_thread(void *arg)
Definition: tcpip.c:77
err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
Definition: tcpip.c:214
static tcpip_init_done_fn tcpip_init_done
Definition: tcpip.c:56
void tcpip_callbackmsg_delete(struct tcpip_callback_msg *msg)
Definition: tcpip.c:428
err_t tcpip_trycallback(struct tcpip_callback_msg *msg)
Definition: tcpip.c:441
static void pbuf_free_int(void *p)
Definition: tcpip.c:483
err_t tcpip_input(struct pbuf *p, struct netif *inp)
Definition: tcpip.c:164
static void * tcpip_init_done_arg
Definition: tcpip.c:57
void(* sys_timeout_handler)(void *arg)
Definition: timers.h:65
void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg)
void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg)
void sys_untimeout(sys_timeout_handler handler, void *arg)
int ret
void * arg
Definition: msvc.h:10
static unsigned int block
Definition: xmlmemory.c:101