Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of lwip by
tcpip.c
00001 /** 00002 * @file 00003 * Sequential API Main thread module 00004 * 00005 */ 00006 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 #include <stdio.h> 00053 00054 /* global variables */ 00055 static tcpip_init_done_fn tcpip_init_done; 00056 static void *tcpip_init_done_arg; 00057 static sys_mbox_t mbox; 00058 00059 #if LWIP_TCPIP_CORE_LOCKING 00060 /** The global semaphore to lock the stack. */ 00061 sys_mutex_t lock_tcpip_core; 00062 #endif /* LWIP_TCPIP_CORE_LOCKING */ 00063 00064 00065 /** 00066 * The main lwIP thread. This thread has exclusive access to lwIP core functions 00067 * (unless access to them is not locked). Other threads communicate with this 00068 * thread using message boxes. 00069 * 00070 * It also starts all the timers to make sure they are running in the right 00071 * thread context. 00072 * 00073 * @param arg unused argument 00074 */ 00075 static void 00076 tcpip_thread(void *arg) 00077 { 00078 struct tcpip_msg *msg; 00079 LWIP_UNUSED_ARG(arg); 00080 00081 if (tcpip_init_done != NULL) { 00082 tcpip_init_done(tcpip_init_done_arg); 00083 } 00084 00085 LOCK_TCPIP_CORE(); 00086 while (1) { /* MAIN Loop */ 00087 UNLOCK_TCPIP_CORE(); 00088 //printf("Unlock realizado\n"); 00089 LWIP_TCPIP_THREAD_ALIVE(); 00090 /* wait for a message, timeouts are processed while waiting */ 00091 sys_timeouts_mbox_fetch(&mbox, (void **)&msg); 00092 /* 00093 if (msg->type == 0) 00094 printf("Tirou do Mbox %d Tipo %d\n\n", msg->msg.apimsg, msg->type); 00095 else 00096 printf("Tirou InPackt %d Tipo %d\n\n", (int) msg, msg->type); 00097 //printf("Pegou fetch\n"); 00098 */ 00099 LOCK_TCPIP_CORE(); 00100 //printf("Executou lock\n"); 00101 switch (msg->type) { 00102 #if LWIP_NETCONN 00103 case TCPIP_MSG_API: 00104 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); 00105 00106 msg->msg.apimsg->function(&(msg->msg.apimsg->msg)); 00107 //printf("Executou funcao\n"); 00108 break; 00109 #endif /* LWIP_NETCONN */ 00110 00111 #if !LWIP_TCPIP_CORE_LOCKING_INPUT 00112 case TCPIP_MSG_INPKT: 00113 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); 00114 #if LWIP_ETHERNET 00115 if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { 00116 ethernet_input(msg->msg.inp.p, msg->msg.inp.netif); 00117 } else 00118 #endif /* LWIP_ETHERNET */ 00119 { 00120 printf("AAAAAA\n"); 00121 ip_input(msg->msg.inp.p, msg->msg.inp.netif); 00122 } 00123 memp_free(MEMP_TCPIP_MSG_INPKT, msg); 00124 break; 00125 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ 00126 00127 #if LWIP_NETIF_API 00128 case TCPIP_MSG_NETIFAPI: 00129 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg)); 00130 msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg)); 00131 break; 00132 #endif /* LWIP_NETIF_API */ 00133 00134 case TCPIP_MSG_CALLBACK: 00135 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); 00136 msg->msg.cb.function(msg->msg.cb.ctx); 00137 memp_free(MEMP_TCPIP_MSG_API, msg); 00138 break; 00139 00140 #if LWIP_TCPIP_TIMEOUT 00141 case TCPIP_MSG_TIMEOUT: 00142 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); 00143 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); 00144 memp_free(MEMP_TCPIP_MSG_API, msg); 00145 break; 00146 case TCPIP_MSG_UNTIMEOUT: 00147 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); 00148 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); 00149 memp_free(MEMP_TCPIP_MSG_API, msg); 00150 break; 00151 #endif /* LWIP_TCPIP_TIMEOUT */ 00152 00153 default: 00154 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); 00155 LWIP_ASSERT("tcpip_thread: invalid message", 0); 00156 break; 00157 } 00158 } 00159 } 00160 00161 /** 00162 * Pass a received packet to tcpip_thread for input processing 00163 * 00164 * @param p the received packet, p->payload pointing to the Ethernet header or 00165 * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or 00166 * NETIF_FLAG_ETHERNET flags) 00167 * @param inp the network interface on which the packet was received 00168 */ 00169 err_t 00170 tcpip_input(struct pbuf *p, struct netif *inp) 00171 { 00172 #if LWIP_TCPIP_CORE_LOCKING_INPUT 00173 err_t ret; 00174 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp)); 00175 LOCK_TCPIP_CORE(); 00176 #if LWIP_ETHERNET 00177 if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { 00178 ret = ethernet_input(p, inp); 00179 } else 00180 #endif /* LWIP_ETHERNET */ 00181 { 00182 ret = ip_input(p, inp); 00183 } 00184 UNLOCK_TCPIP_CORE(); 00185 return ret; 00186 #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ 00187 struct tcpip_msg *msg; 00188 00189 if (sys_mbox_valid(&mbox)) { 00190 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); 00191 if (msg == NULL) { 00192 return ERR_MEM; 00193 } 00194 00195 msg->type = TCPIP_MSG_INPKT; 00196 msg->msg.inp.p = p; 00197 msg->msg.inp.netif = inp; 00198 //printf("Colocou InPact %d\n", (int) msg); 00199 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { 00200 memp_free(MEMP_TCPIP_MSG_INPKT, msg); 00201 return ERR_MEM; 00202 } 00203 return ERR_OK; 00204 } 00205 return ERR_VAL; 00206 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ 00207 } 00208 00209 /** 00210 * Call a specific function in the thread context of 00211 * tcpip_thread for easy access synchronization. 00212 * A function called in that way may access lwIP core code 00213 * without fearing concurrent access. 00214 * 00215 * @param f the function to call 00216 * @param ctx parameter passed to f 00217 * @param block 1 to block until the request is posted, 0 to non-blocking mode 00218 * @return ERR_OK if the function was called, another err_t if not 00219 */ 00220 err_t 00221 tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) 00222 { 00223 struct tcpip_msg *msg; 00224 00225 if (sys_mbox_valid(&mbox)) { 00226 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); 00227 if (msg == NULL) { 00228 return ERR_MEM; 00229 } 00230 00231 msg->type = TCPIP_MSG_CALLBACK; 00232 msg->msg.cb.function = function; 00233 msg->msg.cb.ctx = ctx; 00234 if (block) { 00235 sys_mbox_post(&mbox, msg); 00236 } else { 00237 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { 00238 memp_free(MEMP_TCPIP_MSG_API, msg); 00239 return ERR_MEM; 00240 } 00241 } 00242 return ERR_OK; 00243 } 00244 return ERR_VAL; 00245 } 00246 00247 #if LWIP_TCPIP_TIMEOUT 00248 /** 00249 * call sys_timeout in tcpip_thread 00250 * 00251 * @param msec time in milliseconds for timeout 00252 * @param h function to be called on timeout 00253 * @param arg argument to pass to timeout function h 00254 * @return ERR_MEM on memory error, ERR_OK otherwise 00255 */ 00256 err_t 00257 tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) 00258 { 00259 struct tcpip_msg *msg; 00260 00261 if (sys_mbox_valid(&mbox)) { 00262 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); 00263 if (msg == NULL) { 00264 return ERR_MEM; 00265 } 00266 00267 msg->type = TCPIP_MSG_TIMEOUT; 00268 msg->msg.tmo.msecs = msecs; 00269 msg->msg.tmo.h = h; 00270 msg->msg.tmo.arg = arg; 00271 sys_mbox_post(&mbox, msg); 00272 return ERR_OK; 00273 } 00274 return ERR_VAL; 00275 } 00276 00277 /** 00278 * call sys_untimeout in tcpip_thread 00279 * 00280 * @param msec time in milliseconds for timeout 00281 * @param h function to be called on timeout 00282 * @param arg argument to pass to timeout function h 00283 * @return ERR_MEM on memory error, ERR_OK otherwise 00284 */ 00285 err_t 00286 tcpip_untimeout(sys_timeout_handler h, void *arg) 00287 { 00288 struct tcpip_msg *msg; 00289 00290 if (sys_mbox_valid(&mbox)) { 00291 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); 00292 if (msg == NULL) { 00293 return ERR_MEM; 00294 } 00295 00296 msg->type = TCPIP_MSG_UNTIMEOUT; 00297 msg->msg.tmo.h = h; 00298 msg->msg.tmo.arg = arg; 00299 sys_mbox_post(&mbox, msg); 00300 return ERR_OK; 00301 } 00302 return ERR_VAL; 00303 } 00304 #endif /* LWIP_TCPIP_TIMEOUT */ 00305 00306 #if LWIP_NETCONN 00307 /** 00308 * Call the lower part of a netconn_* function 00309 * This function is then running in the thread context 00310 * of tcpip_thread and has exclusive access to lwIP core code. 00311 * 00312 * @param apimsg a struct containing the function to call and its parameters 00313 * @return ERR_OK if the function was called, another err_t if not 00314 */ 00315 err_t 00316 tcpip_apimsg(struct api_msg *apimsg) 00317 { 00318 struct tcpip_msg msg; 00319 int x=-1; 00320 #ifdef LWIP_DEBUG 00321 /* catch functions that don't set err */ 00322 apimsg->msg.err = ERR_VAL; 00323 #endif 00324 00325 if (sys_mbox_valid(&mbox)) { 00326 msg.type = TCPIP_MSG_API; 00327 msg.msg.apimsg = apimsg; 00328 //printf("Vai dar Post\n"); 00329 00330 sys_mbox_post(&mbox, &msg); 00331 //printf("Passou Post\n"); 00332 //printf("Colocou no Mbox %d\n\n", apimsg); 00333 x = sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0); 00334 //printf("Passou Wait %d\n", x); 00335 return apimsg->msg.err; 00336 } 00337 return ERR_VAL; 00338 } 00339 00340 #if LWIP_TCPIP_CORE_LOCKING 00341 /** 00342 * Call the lower part of a netconn_* function 00343 * This function has exclusive access to lwIP core code by locking it 00344 * before the function is called. 00345 * 00346 * @param apimsg a struct containing the function to call and its parameters 00347 * @return ERR_OK (only for compatibility fo tcpip_apimsg()) 00348 */ 00349 err_t 00350 tcpip_apimsg_lock(struct api_msg *apimsg) 00351 { 00352 #ifdef LWIP_DEBUG 00353 /* catch functions that don't set err */ 00354 apimsg->msg.err = ERR_VAL; 00355 #endif 00356 00357 LOCK_TCPIP_CORE(); 00358 apimsg->function(&(apimsg->msg)); 00359 UNLOCK_TCPIP_CORE(); 00360 return apimsg->msg.err; 00361 00362 } 00363 #endif /* LWIP_TCPIP_CORE_LOCKING */ 00364 #endif /* LWIP_NETCONN */ 00365 00366 #if LWIP_NETIF_API 00367 #if !LWIP_TCPIP_CORE_LOCKING 00368 /** 00369 * Much like tcpip_apimsg, but calls the lower part of a netifapi_* 00370 * function. 00371 * 00372 * @param netifapimsg a struct containing the function to call and its parameters 00373 * @return error code given back by the function that was called 00374 */ 00375 err_t 00376 tcpip_netifapi(struct netifapi_msg* netifapimsg) 00377 { 00378 struct tcpip_msg msg; 00379 00380 if (sys_mbox_valid(&mbox)) { 00381 err_t err = sys_sem_new(&netifapimsg->msg.sem, 0); 00382 if (err != ERR_OK) { 00383 netifapimsg->msg.err = err; 00384 return err; 00385 } 00386 00387 msg.type = TCPIP_MSG_NETIFAPI; 00388 msg.msg.netifapimsg = netifapimsg; 00389 sys_mbox_post(&mbox, &msg); 00390 sys_sem_wait(&netifapimsg->msg.sem); 00391 sys_sem_free(&netifapimsg->msg.sem); 00392 return netifapimsg->msg.err; 00393 } 00394 return ERR_VAL; 00395 } 00396 #else /* !LWIP_TCPIP_CORE_LOCKING */ 00397 /** 00398 * Call the lower part of a netifapi_* function 00399 * This function has exclusive access to lwIP core code by locking it 00400 * before the function is called. 00401 * 00402 * @param netifapimsg a struct containing the function to call and its parameters 00403 * @return ERR_OK (only for compatibility fo tcpip_netifapi()) 00404 */ 00405 err_t 00406 tcpip_netifapi_lock(struct netifapi_msg* netifapimsg) 00407 { 00408 LOCK_TCPIP_CORE(); 00409 netifapimsg->function(&(netifapimsg->msg)); 00410 UNLOCK_TCPIP_CORE(); 00411 return netifapimsg->msg.err; 00412 } 00413 #endif /* !LWIP_TCPIP_CORE_LOCKING */ 00414 #endif /* LWIP_NETIF_API */ 00415 00416 /** 00417 * Initialize this module: 00418 * - initialize all sub modules 00419 * - start the tcpip_thread 00420 * 00421 * @param initfunc a function to call when tcpip_thread is running and finished initializing 00422 * @param arg argument to pass to initfunc 00423 */ 00424 void 00425 tcpip_init(tcpip_init_done_fn initfunc, void *arg) 00426 { 00427 lwip_init(); 00428 00429 tcpip_init_done = initfunc; 00430 tcpip_init_done_arg = arg; 00431 if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { 00432 LWIP_ASSERT("failed to create tcpip_thread mbox", 0); 00433 } 00434 #if LWIP_TCPIP_CORE_LOCKING 00435 if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) { 00436 LWIP_ASSERT("failed to create lock_tcpip_core", 0); 00437 } 00438 #endif /* LWIP_TCPIP_CORE_LOCKING */ 00439 00440 sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); 00441 } 00442 00443 /** 00444 * Simple callback function used with tcpip_callback to free a pbuf 00445 * (pbuf_free has a wrong signature for tcpip_callback) 00446 * 00447 * @param p The pbuf (chain) to be dereferenced. 00448 */ 00449 static void 00450 pbuf_free_int(void *p) 00451 { 00452 struct pbuf *q = (struct pbuf *)p; 00453 pbuf_free(q); 00454 } 00455 00456 /** 00457 * A simple wrapper function that allows you to free a pbuf from interrupt context. 00458 * 00459 * @param p The pbuf (chain) to be dereferenced. 00460 * @return ERR_OK if callback could be enqueued, an err_t if not 00461 */ 00462 err_t 00463 pbuf_free_callback(struct pbuf *p) 00464 { 00465 return tcpip_callback_with_block(pbuf_free_int, p, 0); 00466 } 00467 00468 /** 00469 * A simple wrapper function that allows you to free heap memory from 00470 * interrupt context. 00471 * 00472 * @param m the heap memory to free 00473 * @return ERR_OK if callback could be enqueued, an err_t if not 00474 */ 00475 err_t 00476 mem_free_callback(void *m) 00477 { 00478 return tcpip_callback_with_block(mem_free, m, 0); 00479 } 00480 00481 #endif /* !NO_SYS */
Generated on Tue Jul 12 2022 21:59:36 by
1.7.2
