ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcpip.c
Go to the documentation of this file.
00001 
00007 /*
00008  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
00009  * All rights reserved.
00010  *
00011  * Redistribution and use in source and binary forms, with or without modification,
00012  * are permitted provided that the following conditions are met:
00013  *
00014  * 1. Redistributions of source code must retain the above copyright notice,
00015  *    this list of conditions and the following disclaimer.
00016  * 2. Redistributions in binary form must reproduce the above copyright notice,
00017  *    this list of conditions and the following disclaimer in the documentation
00018  *    and/or other materials provided with the distribution.
00019  * 3. The name of the author may not be used to endorse or promote products
00020  *    derived from this software without specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00023  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00024  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00025  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00026  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00027  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00030  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00031  * OF SUCH DAMAGE.
00032  *
00033  * This file is part of the lwIP TCP/IP stack.
00034  *
00035  * Author: Adam Dunkels <adam@sics.se>
00036  *
00037  */
00038 
00039 #include "lwip/opt.h"
00040 
00041 #if !NO_SYS /* don't build if not configured for use in lwipopts.h */
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 /* global variables */
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 /* LWIP_TCPIP_CORE_LOCKING */
00061 
00062 
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) {                          /* MAIN Loop */
00085     UNLOCK_TCPIP_CORE();
00086     LWIP_TCPIP_THREAD_ALIVE();
00087     /* wait for a message, timeouts are processed while waiting */
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 /* LWIP_NETCONN */
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 /* LWIP_ETHERNET */
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 /* LWIP_TCPIP_CORE_LOCKING_INPUT */
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 /* LWIP_NETIF_API */
00119 
00120     case TCPIP_MSG_CALLBACK:
00121       LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
00122       msg->msg.cb.function(msg->msg.cb.ctx);
00123       memp_free(MEMP_TCPIP_MSG_API, msg);
00124       break;
00125 
00126 #if LWIP_TCPIP_TIMEOUT
00127     case TCPIP_MSG_TIMEOUT:
00128       LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
00129       sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
00130       memp_free(MEMP_TCPIP_MSG_API, msg);
00131       break;
00132     case TCPIP_MSG_UNTIMEOUT:
00133       LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
00134       sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
00135       memp_free(MEMP_TCPIP_MSG_API, msg);
00136       break;
00137 #endif /* LWIP_TCPIP_TIMEOUT */
00138 
00139     default:
00140       LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
00141       LWIP_ASSERT("tcpip_thread: invalid message", 0);
00142       break;
00143     }
00144   }
00145 }
00146 
00155 err_t
00156 tcpip_input(struct pbuf *p, struct netif *inp)
00157 {
00158 #if LWIP_TCPIP_CORE_LOCKING_INPUT
00159   err_t ret;
00160   LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
00161   LOCK_TCPIP_CORE();
00162 #if LWIP_ETHERNET
00163   if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
00164     ret = ethernet_input(p, inp);
00165   } else
00166 #endif /* LWIP_ETHERNET */
00167   {
00168     ret = ip_input(p, inp);
00169   }
00170   UNLOCK_TCPIP_CORE();
00171   return ret;
00172 #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
00173   struct tcpip_msg *msg;
00174 
00175   if (sys_mbox_valid(&mbox)) {
00176     msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
00177     if (msg == NULL) {
00178       return ERR_MEM;
00179     }
00180 
00181     msg->type = TCPIP_MSG_INPKT;
00182     msg->msg.inp.p = p;
00183     msg->msg.inp.netif = inp;
00184     if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
00185       memp_free(MEMP_TCPIP_MSG_INPKT, msg);
00186       return ERR_MEM;
00187     }
00188     return ERR_OK;
00189   }
00190   return ERR_VAL;
00191 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
00192 }
00193 
00205 err_t
00206 tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
00207 {
00208   struct tcpip_msg *msg;
00209 
00210   if (sys_mbox_valid(&mbox)) {
00211     msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00212     if (msg == NULL) {
00213       return ERR_MEM;
00214     }
00215 
00216     msg->type = TCPIP_MSG_CALLBACK;
00217     msg->msg.cb.function = function;
00218     msg->msg.cb.ctx = ctx;
00219     if (block) {
00220       sys_mbox_post(&mbox, msg);
00221     } else {
00222       if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
00223         memp_free(MEMP_TCPIP_MSG_API, msg);
00224         return ERR_MEM;
00225       }
00226     }
00227     return ERR_OK;
00228   }
00229   return ERR_VAL;
00230 }
00231 
00232 #if LWIP_TCPIP_TIMEOUT
00233 
00241 err_t
00242 tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
00243 {
00244   struct tcpip_msg *msg;
00245 
00246   if (sys_mbox_valid(&mbox)) {
00247     msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00248     if (msg == NULL) {
00249       return ERR_MEM;
00250     }
00251 
00252     msg->type = TCPIP_MSG_TIMEOUT;
00253     msg->msg.tmo.msecs = msecs;
00254     msg->msg.tmo.h = h;
00255     msg->msg.tmo.arg = arg;
00256     sys_mbox_post(&mbox, msg);
00257     return ERR_OK;
00258   }
00259   return ERR_VAL;
00260 }
00261 
00270 err_t
00271 tcpip_untimeout(sys_timeout_handler h, void *arg)
00272 {
00273   struct tcpip_msg *msg;
00274 
00275   if (sys_mbox_valid(&mbox)) {
00276     msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
00277     if (msg == NULL) {
00278       return ERR_MEM;
00279     }
00280 
00281     msg->type = TCPIP_MSG_UNTIMEOUT;
00282     msg->msg.tmo.h = h;
00283     msg->msg.tmo.arg = arg;
00284     sys_mbox_post(&mbox, msg);
00285     return ERR_OK;
00286   }
00287   return ERR_VAL;
00288 }
00289 #endif /* LWIP_TCPIP_TIMEOUT */
00290 
00291 #if LWIP_NETCONN
00292 
00300 err_t
00301 tcpip_apimsg(struct api_msg *apimsg)
00302 {
00303   struct tcpip_msg msg;
00304 #ifdef LWIP_DEBUG
00305   /* catch functions that don't set err */
00306   apimsg->msg.err = ERR_VAL;
00307 #endif
00308   
00309   if (sys_mbox_valid(&mbox)) {
00310     msg.type = TCPIP_MSG_API;
00311     msg.msg.apimsg = apimsg;
00312     sys_mbox_post(&mbox, &msg);
00313     sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
00314     return apimsg->msg.err;
00315   }
00316   return ERR_VAL;
00317 }
00318 
00319 #if LWIP_TCPIP_CORE_LOCKING
00320 
00328 err_t
00329 tcpip_apimsg_lock(struct api_msg *apimsg)
00330 {
00331 #ifdef LWIP_DEBUG
00332   /* catch functions that don't set err */
00333   apimsg->msg.err = ERR_VAL;
00334 #endif
00335 
00336   LOCK_TCPIP_CORE();
00337   apimsg->function(&(apimsg->msg));
00338   UNLOCK_TCPIP_CORE();
00339   return apimsg->msg.err;
00340 
00341 }
00342 #endif /* LWIP_TCPIP_CORE_LOCKING */
00343 #endif /* LWIP_NETCONN */
00344 
00345 #if LWIP_NETIF_API
00346 #if !LWIP_TCPIP_CORE_LOCKING
00347 
00354 err_t
00355 tcpip_netifapi(struct netifapi_msg* netifapimsg)
00356 {
00357   struct tcpip_msg msg;
00358   
00359   if (sys_mbox_valid(&mbox)) {
00360     err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
00361     if (err != ERR_OK) {
00362       netifapimsg->msg.err = err;
00363       return err;
00364     }
00365     
00366     msg.type = TCPIP_MSG_NETIFAPI;
00367     msg.msg.netifapimsg = netifapimsg;
00368     sys_mbox_post(&mbox, &msg);
00369     sys_sem_wait(&netifapimsg->msg.sem);
00370     sys_sem_free(&netifapimsg->msg.sem);
00371     return netifapimsg->msg.err;
00372   }
00373   return ERR_VAL;
00374 }
00375 #else /* !LWIP_TCPIP_CORE_LOCKING */
00376 
00384 err_t
00385 tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
00386 {
00387   LOCK_TCPIP_CORE();  
00388   netifapimsg->function(&(netifapimsg->msg));
00389   UNLOCK_TCPIP_CORE();
00390   return netifapimsg->msg.err;
00391 }
00392 #endif /* !LWIP_TCPIP_CORE_LOCKING */
00393 #endif /* LWIP_NETIF_API */
00394 
00403 void
00404 tcpip_init(tcpip_init_done_fn initfunc, void *arg)
00405 {
00406   lwip_init();
00407 
00408   tcpip_init_done = initfunc;
00409   tcpip_init_done_arg = arg;
00410   if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
00411     LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
00412   }
00413 #if LWIP_TCPIP_CORE_LOCKING
00414   if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
00415     LWIP_ASSERT("failed to create lock_tcpip_core", 0);
00416   }
00417 #endif /* LWIP_TCPIP_CORE_LOCKING */
00418 
00419   sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
00420 }
00421 
00428 static void
00429 pbuf_free_int(void *p)
00430 {
00431   struct pbuf *q = (struct pbuf *)p;
00432   pbuf_free(q);
00433 }
00434 
00441 err_t
00442 pbuf_free_callback(struct pbuf *p)
00443 {
00444   return tcpip_callback_with_block(pbuf_free_int, p, 0);
00445 }
00446 
00454 err_t
00455 mem_free_callback(void *m)
00456 {
00457   return tcpip_callback_with_block(mem_free, m, 0);
00458 }
00459 
00460 #endif /* !NO_SYS */

Generated on Fri May 25 2012 04:34:32 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.