00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "lwip/opt.h"
00040
00041 #if !NO_SYS
00042
00043 #include "lwip/sys.h"
00044 #include "lwip/memp.h"
00045 #include "lwip/mem.h"
00046 #include "lwip/pbuf.h"
00047 #include "lwip/tcpip.h"
00048 #include "lwip/init.h"
00049 #include "netif/etharp.h"
00050 #include "netif/ppp_oe.h"
00051
00052
00053 static tcpip_init_done_fn tcpip_init_done;
00054 static void *tcpip_init_done_arg;
00055 static sys_mbox_t mbox;
00056
00057 #if LWIP_TCPIP_CORE_LOCKING
00058
00059 sys_mutex_t lock_tcpip_core;
00060 #endif
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static void
00074 tcpip_thread(void *arg)
00075 {
00076 struct tcpip_msg *msg;
00077 LWIP_UNUSED_ARG(arg);
00078
00079 if (tcpip_init_done != NULL) {
00080 tcpip_init_done(tcpip_init_done_arg);
00081 }
00082
00083 LOCK_TCPIP_CORE();
00084 while (1) {
00085 UNLOCK_TCPIP_CORE();
00086 LWIP_TCPIP_THREAD_ALIVE();
00087
00088 sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
00089 LOCK_TCPIP_CORE();
00090 switch (msg->type) {
00091 #if LWIP_NETCONN
00092 case TCPIP_MSG_API:
00093 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
00094 msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
00095 break;
00096 #endif
00097
00098 #if !LWIP_TCPIP_CORE_LOCKING_INPUT
00099 case TCPIP_MSG_INPKT:
00100 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
00101 #if LWIP_ETHERNET
00102 if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
00103 ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
00104 } else
00105 #endif
00106 {
00107 ip_input(msg->msg.inp.p, msg->msg.inp.netif);
00108 }
00109 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
00110 break;
00111 #endif
00112
00113 #if LWIP_NETIF_API
00114 case TCPIP_MSG_NETIFAPI:
00115 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
00116 msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
00117 break;
00118 #endif
00119
00120 #if LWIP_TCPIP_TIMEOUT
00121 case TCPIP_MSG_TIMEOUT:
00122 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
00123 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
00124 memp_free(MEMP_TCPIP_MSG_API, msg);
00125 break;
00126 case TCPIP_MSG_UNTIMEOUT:
00127 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
00128 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
00129 memp_free(MEMP_TCPIP_MSG_API, msg);
00130 break;
00131 #endif
00132
00133 case TCPIP_MSG_CALLBACK:
00134 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
00135 msg->msg.cb.function(msg->msg.cb.ctx);
00136 memp_free(MEMP_TCPIP_MSG_API, msg);
00137 break;
00138
00139 case TCPIP_MSG_CALLBACK_STATIC:
00140 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg));
00141 msg->msg.cb.function(msg->msg.cb.ctx);
00142 break;
00143
00144 default:
00145 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
00146 LWIP_ASSERT("tcpip_thread: invalid message", 0);
00147 break;
00148 }
00149 }
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 err_t
00161 tcpip_input(struct pbuf *p, struct netif *inp)
00162 {
00163 #if LWIP_TCPIP_CORE_LOCKING_INPUT
00164 err_t ret;
00165 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
00166 LOCK_TCPIP_CORE();
00167 #if LWIP_ETHERNET
00168 if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
00169 ret = ethernet_input(p, inp);
00170 } else
00171 #endif
00172 {
00173 ret = ip_input(p, inp);
00174 }
00175 UNLOCK_TCPIP_CORE();
00176 return ret;
00177 #else
00178 struct tcpip_msg *msg;
00179
00180 if (!sys_mbox_valid(&mbox)) {
00181 return ERR_VAL;
00182 }
00183 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
00184 if (msg == NULL) {
00185 return ERR_MEM;
00186 }
00187
00188 msg->type = TCPIP_MSG_INPKT;
00189 msg->msg.inp.p = p;
00190 msg->msg.inp.netif = inp;
00191 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
00192 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
00193 return ERR_MEM;
00194 }
00195 return ERR_OK;
00196 #endif
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 err_t
00211 tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
00212 {
00213 struct tcpip_msg *msg;
00214
00215 if (sys_mbox_valid(&mbox)) {
00216 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00217 if (msg == NULL) {
00218 return ERR_MEM;
00219 }
00220
00221 msg->type = TCPIP_MSG_CALLBACK;
00222 msg->msg.cb.function = function;
00223 msg->msg.cb.ctx = ctx;
00224 if (block) {
00225 sys_mbox_post(&mbox, msg);
00226 } else {
00227 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
00228 memp_free(MEMP_TCPIP_MSG_API, msg);
00229 return ERR_MEM;
00230 }
00231 }
00232 return ERR_OK;
00233 }
00234 return ERR_VAL;
00235 }
00236
00237 #if LWIP_TCPIP_TIMEOUT
00238
00239
00240
00241
00242
00243
00244
00245
00246 err_t
00247 tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
00248 {
00249 struct tcpip_msg *msg;
00250
00251 if (sys_mbox_valid(&mbox)) {
00252 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00253 if (msg == NULL) {
00254 return ERR_MEM;
00255 }
00256
00257 msg->type = TCPIP_MSG_TIMEOUT;
00258 msg->msg.tmo.msecs = msecs;
00259 msg->msg.tmo.h = h;
00260 msg->msg.tmo.arg = arg;
00261 sys_mbox_post(&mbox, msg);
00262 return ERR_OK;
00263 }
00264 return ERR_VAL;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 err_t
00276 tcpip_untimeout(sys_timeout_handler h, void *arg)
00277 {
00278 struct tcpip_msg *msg;
00279
00280 if (sys_mbox_valid(&mbox)) {
00281 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00282 if (msg == NULL) {
00283 return ERR_MEM;
00284 }
00285
00286 msg->type = TCPIP_MSG_UNTIMEOUT;
00287 msg->msg.tmo.h = h;
00288 msg->msg.tmo.arg = arg;
00289 sys_mbox_post(&mbox, msg);
00290 return ERR_OK;
00291 }
00292 return ERR_VAL;
00293 }
00294 #endif
00295
00296 #if LWIP_NETCONN
00297
00298
00299
00300
00301
00302
00303
00304
00305 err_t
00306 tcpip_apimsg(struct api_msg *apimsg)
00307 {
00308 struct tcpip_msg msg;
00309 #ifdef LWIP_DEBUG
00310
00311 apimsg->msg.err = ERR_VAL;
00312 #endif
00313
00314 if (sys_mbox_valid(&mbox)) {
00315 msg.type = TCPIP_MSG_API;
00316 msg.msg.apimsg = apimsg;
00317 sys_mbox_post(&mbox, &msg);
00318 sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
00319 return apimsg->msg.err;
00320 }
00321 return ERR_VAL;
00322 }
00323
00324 #if LWIP_TCPIP_CORE_LOCKING
00325
00326
00327
00328
00329
00330
00331
00332
00333 err_t
00334 tcpip_apimsg_lock(struct api_msg *apimsg)
00335 {
00336 #ifdef LWIP_DEBUG
00337
00338 apimsg->msg.err = ERR_VAL;
00339 #endif
00340
00341 LOCK_TCPIP_CORE();
00342 apimsg->function(&(apimsg->msg));
00343 UNLOCK_TCPIP_CORE();
00344 return apimsg->msg.err;
00345
00346 }
00347 #endif
00348 #endif
00349
00350 #if LWIP_NETIF_API
00351 #if !LWIP_TCPIP_CORE_LOCKING
00352
00353
00354
00355
00356
00357
00358
00359 err_t
00360 tcpip_netifapi(struct netifapi_msg* netifapimsg)
00361 {
00362 struct tcpip_msg msg;
00363
00364 if (sys_mbox_valid(&mbox)) {
00365 err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
00366 if (err != ERR_OK) {
00367 netifapimsg->msg.err = err;
00368 return err;
00369 }
00370
00371 msg.type = TCPIP_MSG_NETIFAPI;
00372 msg.msg.netifapimsg = netifapimsg;
00373 sys_mbox_post(&mbox, &msg);
00374 sys_sem_wait(&netifapimsg->msg.sem);
00375 sys_sem_free(&netifapimsg->msg.sem);
00376 return netifapimsg->msg.err;
00377 }
00378 return ERR_VAL;
00379 }
00380 #else
00381
00382
00383
00384
00385
00386
00387
00388
00389 err_t
00390 tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
00391 {
00392 LOCK_TCPIP_CORE();
00393 netifapimsg->function(&(netifapimsg->msg));
00394 UNLOCK_TCPIP_CORE();
00395 return netifapimsg->msg.err;
00396 }
00397 #endif
00398 #endif
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx)
00409 {
00410 struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00411 if (msg == NULL) {
00412 return NULL;
00413 }
00414 msg->type = TCPIP_MSG_CALLBACK_STATIC;
00415 msg->msg.cb.function = function;
00416 msg->msg.cb.ctx = ctx;
00417 return (struct tcpip_callback_msg*)msg;
00418 }
00419
00420
00421
00422
00423
00424
00425 void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg)
00426 {
00427 memp_free(MEMP_TCPIP_MSG_API, msg);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437 err_t
00438 tcpip_trycallback(struct tcpip_callback_msg* msg)
00439 {
00440 if (!sys_mbox_valid(&mbox)) {
00441 return ERR_VAL;
00442 }
00443 return sys_mbox_trypost(&mbox, msg);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 void
00455 tcpip_init(tcpip_init_done_fn initfunc, void *arg)
00456 {
00457 lwip_init();
00458
00459 tcpip_init_done = initfunc;
00460 tcpip_init_done_arg = arg;
00461 if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
00462 LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
00463 }
00464 #if LWIP_TCPIP_CORE_LOCKING
00465 if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
00466 LWIP_ASSERT("failed to create lock_tcpip_core", 0);
00467 }
00468 #endif
00469
00470 sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 static void
00480 pbuf_free_int(void *p)
00481 {
00482 struct pbuf *q = (struct pbuf *)p;
00483 pbuf_free(q);
00484 }
00485
00486
00487
00488
00489
00490
00491
00492 err_t
00493 pbuf_free_callback(struct pbuf *p)
00494 {
00495 return tcpip_callback_with_block(pbuf_free_int, p, 0);
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505 err_t
00506 mem_free_callback(void *m)
00507 {
00508 return tcpip_callback_with_block(mem_free, m, 0);
00509 }
00510
00511 #endif