LwIP with PPP & Ethernet integration

Dependents:   NetworkingCoreLib

This is the mbed port of the LwIP stack: http://savannah.nongnu.org/projects/lwip/

It includes contributed content from NXP's port for LPCxxxx devices: http://www.lpcware.com/content/project/lightweight-ip-lwip-networking-stack

Licence

LwIP is licenced under the BSD licence:

Copyright (c) 2001-2004 Swedish Institute of Computer Science. 
All rights reserved. 
Redistribution and use in source and binary forms, with or without modification, 
are permitted provided that the following conditions are met: 
1. Redistributions of source code must retain the above copyright notice, 
this list of conditions and the following disclaimer. 
2. Redistributions in binary form must reproduce the above copyright notice, 
this list of conditions and the following disclaimer in the documentation 
and/or other materials provided with the distribution. 
3. The name of the author may not be used to endorse or promote products 
derived from this software without specific prior written permission. 
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 
OF SUCH DAMAGE.
Committer:
donatien
Date:
Thu May 24 15:53:48 2012 +0000
Revision:
0:8e01dca41002
Merge with Emilio's LwIp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 0:8e01dca41002 1 /**
donatien 0:8e01dca41002 2 * @file
donatien 0:8e01dca41002 3 * Sequential API Main thread module
donatien 0:8e01dca41002 4 *
donatien 0:8e01dca41002 5 */
donatien 0:8e01dca41002 6
donatien 0:8e01dca41002 7 /*
donatien 0:8e01dca41002 8 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
donatien 0:8e01dca41002 9 * All rights reserved.
donatien 0:8e01dca41002 10 *
donatien 0:8e01dca41002 11 * Redistribution and use in source and binary forms, with or without modification,
donatien 0:8e01dca41002 12 * are permitted provided that the following conditions are met:
donatien 0:8e01dca41002 13 *
donatien 0:8e01dca41002 14 * 1. Redistributions of source code must retain the above copyright notice,
donatien 0:8e01dca41002 15 * this list of conditions and the following disclaimer.
donatien 0:8e01dca41002 16 * 2. Redistributions in binary form must reproduce the above copyright notice,
donatien 0:8e01dca41002 17 * this list of conditions and the following disclaimer in the documentation
donatien 0:8e01dca41002 18 * and/or other materials provided with the distribution.
donatien 0:8e01dca41002 19 * 3. The name of the author may not be used to endorse or promote products
donatien 0:8e01dca41002 20 * derived from this software without specific prior written permission.
donatien 0:8e01dca41002 21 *
donatien 0:8e01dca41002 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
donatien 0:8e01dca41002 23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
donatien 0:8e01dca41002 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
donatien 0:8e01dca41002 25 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
donatien 0:8e01dca41002 26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
donatien 0:8e01dca41002 27 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
donatien 0:8e01dca41002 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
donatien 0:8e01dca41002 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
donatien 0:8e01dca41002 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
donatien 0:8e01dca41002 31 * OF SUCH DAMAGE.
donatien 0:8e01dca41002 32 *
donatien 0:8e01dca41002 33 * This file is part of the lwIP TCP/IP stack.
donatien 0:8e01dca41002 34 *
donatien 0:8e01dca41002 35 * Author: Adam Dunkels <adam@sics.se>
donatien 0:8e01dca41002 36 *
donatien 0:8e01dca41002 37 */
donatien 0:8e01dca41002 38
donatien 0:8e01dca41002 39 #include "lwip/opt.h"
donatien 0:8e01dca41002 40
donatien 0:8e01dca41002 41 #if !NO_SYS /* don't build if not configured for use in lwipopts.h */
donatien 0:8e01dca41002 42
donatien 0:8e01dca41002 43 #include "lwip/sys.h"
donatien 0:8e01dca41002 44 #include "lwip/memp.h"
donatien 0:8e01dca41002 45 #include "lwip/mem.h"
donatien 0:8e01dca41002 46 #include "lwip/pbuf.h"
donatien 0:8e01dca41002 47 #include "lwip/tcpip.h"
donatien 0:8e01dca41002 48 #include "lwip/init.h"
donatien 0:8e01dca41002 49 #include "netif/etharp.h"
donatien 0:8e01dca41002 50 #include "netif/ppp_oe.h"
donatien 0:8e01dca41002 51
donatien 0:8e01dca41002 52 /* global variables */
donatien 0:8e01dca41002 53 static tcpip_init_done_fn tcpip_init_done;
donatien 0:8e01dca41002 54 static void *tcpip_init_done_arg;
donatien 0:8e01dca41002 55 static sys_mbox_t mbox;
donatien 0:8e01dca41002 56
donatien 0:8e01dca41002 57 #if LWIP_TCPIP_CORE_LOCKING
donatien 0:8e01dca41002 58 /** The global semaphore to lock the stack. */
donatien 0:8e01dca41002 59 sys_mutex_t lock_tcpip_core;
donatien 0:8e01dca41002 60 #endif /* LWIP_TCPIP_CORE_LOCKING */
donatien 0:8e01dca41002 61
donatien 0:8e01dca41002 62
donatien 0:8e01dca41002 63 /**
donatien 0:8e01dca41002 64 * The main lwIP thread. This thread has exclusive access to lwIP core functions
donatien 0:8e01dca41002 65 * (unless access to them is not locked). Other threads communicate with this
donatien 0:8e01dca41002 66 * thread using message boxes.
donatien 0:8e01dca41002 67 *
donatien 0:8e01dca41002 68 * It also starts all the timers to make sure they are running in the right
donatien 0:8e01dca41002 69 * thread context.
donatien 0:8e01dca41002 70 *
donatien 0:8e01dca41002 71 * @param arg unused argument
donatien 0:8e01dca41002 72 */
donatien 0:8e01dca41002 73 static void
donatien 0:8e01dca41002 74 tcpip_thread(void *arg)
donatien 0:8e01dca41002 75 {
donatien 0:8e01dca41002 76 struct tcpip_msg *msg;
donatien 0:8e01dca41002 77 LWIP_UNUSED_ARG(arg);
donatien 0:8e01dca41002 78
donatien 0:8e01dca41002 79 if (tcpip_init_done != NULL) {
donatien 0:8e01dca41002 80 tcpip_init_done(tcpip_init_done_arg);
donatien 0:8e01dca41002 81 }
donatien 0:8e01dca41002 82
donatien 0:8e01dca41002 83 LOCK_TCPIP_CORE();
donatien 0:8e01dca41002 84 while (1) { /* MAIN Loop */
donatien 0:8e01dca41002 85 UNLOCK_TCPIP_CORE();
donatien 0:8e01dca41002 86 LWIP_TCPIP_THREAD_ALIVE();
donatien 0:8e01dca41002 87 /* wait for a message, timeouts are processed while waiting */
donatien 0:8e01dca41002 88 sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
donatien 0:8e01dca41002 89 LOCK_TCPIP_CORE();
donatien 0:8e01dca41002 90 switch (msg->type) {
donatien 0:8e01dca41002 91 #if LWIP_NETCONN
donatien 0:8e01dca41002 92 case TCPIP_MSG_API:
donatien 0:8e01dca41002 93 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg));
donatien 0:8e01dca41002 94 msg->msg.apimsg->function(&(msg->msg.apimsg->msg));
donatien 0:8e01dca41002 95 break;
donatien 0:8e01dca41002 96 #endif /* LWIP_NETCONN */
donatien 0:8e01dca41002 97
donatien 0:8e01dca41002 98 #if !LWIP_TCPIP_CORE_LOCKING_INPUT
donatien 0:8e01dca41002 99 case TCPIP_MSG_INPKT:
donatien 0:8e01dca41002 100 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg));
donatien 0:8e01dca41002 101 #if LWIP_ETHERNET
donatien 0:8e01dca41002 102 if (msg->msg.inp.netif->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
donatien 0:8e01dca41002 103 ethernet_input(msg->msg.inp.p, msg->msg.inp.netif);
donatien 0:8e01dca41002 104 } else
donatien 0:8e01dca41002 105 #endif /* LWIP_ETHERNET */
donatien 0:8e01dca41002 106 {
donatien 0:8e01dca41002 107 ip_input(msg->msg.inp.p, msg->msg.inp.netif);
donatien 0:8e01dca41002 108 }
donatien 0:8e01dca41002 109 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
donatien 0:8e01dca41002 110 break;
donatien 0:8e01dca41002 111 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
donatien 0:8e01dca41002 112
donatien 0:8e01dca41002 113 #if LWIP_NETIF_API
donatien 0:8e01dca41002 114 case TCPIP_MSG_NETIFAPI:
donatien 0:8e01dca41002 115 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: Netif API message %p\n", (void *)msg));
donatien 0:8e01dca41002 116 msg->msg.netifapimsg->function(&(msg->msg.netifapimsg->msg));
donatien 0:8e01dca41002 117 break;
donatien 0:8e01dca41002 118 #endif /* LWIP_NETIF_API */
donatien 0:8e01dca41002 119
donatien 0:8e01dca41002 120 case TCPIP_MSG_CALLBACK:
donatien 0:8e01dca41002 121 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg));
donatien 0:8e01dca41002 122 msg->msg.cb.function(msg->msg.cb.ctx);
donatien 0:8e01dca41002 123 memp_free(MEMP_TCPIP_MSG_API, msg);
donatien 0:8e01dca41002 124 break;
donatien 0:8e01dca41002 125
donatien 0:8e01dca41002 126 #if LWIP_TCPIP_TIMEOUT
donatien 0:8e01dca41002 127 case TCPIP_MSG_TIMEOUT:
donatien 0:8e01dca41002 128 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg));
donatien 0:8e01dca41002 129 sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg);
donatien 0:8e01dca41002 130 memp_free(MEMP_TCPIP_MSG_API, msg);
donatien 0:8e01dca41002 131 break;
donatien 0:8e01dca41002 132 case TCPIP_MSG_UNTIMEOUT:
donatien 0:8e01dca41002 133 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg));
donatien 0:8e01dca41002 134 sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg);
donatien 0:8e01dca41002 135 memp_free(MEMP_TCPIP_MSG_API, msg);
donatien 0:8e01dca41002 136 break;
donatien 0:8e01dca41002 137 #endif /* LWIP_TCPIP_TIMEOUT */
donatien 0:8e01dca41002 138
donatien 0:8e01dca41002 139 default:
donatien 0:8e01dca41002 140 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type));
donatien 0:8e01dca41002 141 LWIP_ASSERT("tcpip_thread: invalid message", 0);
donatien 0:8e01dca41002 142 break;
donatien 0:8e01dca41002 143 }
donatien 0:8e01dca41002 144 }
donatien 0:8e01dca41002 145 }
donatien 0:8e01dca41002 146
donatien 0:8e01dca41002 147 /**
donatien 0:8e01dca41002 148 * Pass a received packet to tcpip_thread for input processing
donatien 0:8e01dca41002 149 *
donatien 0:8e01dca41002 150 * @param p the received packet, p->payload pointing to the Ethernet header or
donatien 0:8e01dca41002 151 * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or
donatien 0:8e01dca41002 152 * NETIF_FLAG_ETHERNET flags)
donatien 0:8e01dca41002 153 * @param inp the network interface on which the packet was received
donatien 0:8e01dca41002 154 */
donatien 0:8e01dca41002 155 err_t
donatien 0:8e01dca41002 156 tcpip_input(struct pbuf *p, struct netif *inp)
donatien 0:8e01dca41002 157 {
donatien 0:8e01dca41002 158 #if LWIP_TCPIP_CORE_LOCKING_INPUT
donatien 0:8e01dca41002 159 err_t ret;
donatien 0:8e01dca41002 160 LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_input: PACKET %p/%p\n", (void *)p, (void *)inp));
donatien 0:8e01dca41002 161 LOCK_TCPIP_CORE();
donatien 0:8e01dca41002 162 #if LWIP_ETHERNET
donatien 0:8e01dca41002 163 if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) {
donatien 0:8e01dca41002 164 ret = ethernet_input(p, inp);
donatien 0:8e01dca41002 165 } else
donatien 0:8e01dca41002 166 #endif /* LWIP_ETHERNET */
donatien 0:8e01dca41002 167 {
donatien 0:8e01dca41002 168 ret = ip_input(p, inp);
donatien 0:8e01dca41002 169 }
donatien 0:8e01dca41002 170 UNLOCK_TCPIP_CORE();
donatien 0:8e01dca41002 171 return ret;
donatien 0:8e01dca41002 172 #else /* LWIP_TCPIP_CORE_LOCKING_INPUT */
donatien 0:8e01dca41002 173 struct tcpip_msg *msg;
donatien 0:8e01dca41002 174
donatien 0:8e01dca41002 175 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 176 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
donatien 0:8e01dca41002 177 if (msg == NULL) {
donatien 0:8e01dca41002 178 return ERR_MEM;
donatien 0:8e01dca41002 179 }
donatien 0:8e01dca41002 180
donatien 0:8e01dca41002 181 msg->type = TCPIP_MSG_INPKT;
donatien 0:8e01dca41002 182 msg->msg.inp.p = p;
donatien 0:8e01dca41002 183 msg->msg.inp.netif = inp;
donatien 0:8e01dca41002 184 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
donatien 0:8e01dca41002 185 memp_free(MEMP_TCPIP_MSG_INPKT, msg);
donatien 0:8e01dca41002 186 return ERR_MEM;
donatien 0:8e01dca41002 187 }
donatien 0:8e01dca41002 188 return ERR_OK;
donatien 0:8e01dca41002 189 }
donatien 0:8e01dca41002 190 return ERR_VAL;
donatien 0:8e01dca41002 191 #endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */
donatien 0:8e01dca41002 192 }
donatien 0:8e01dca41002 193
donatien 0:8e01dca41002 194 /**
donatien 0:8e01dca41002 195 * Call a specific function in the thread context of
donatien 0:8e01dca41002 196 * tcpip_thread for easy access synchronization.
donatien 0:8e01dca41002 197 * A function called in that way may access lwIP core code
donatien 0:8e01dca41002 198 * without fearing concurrent access.
donatien 0:8e01dca41002 199 *
donatien 0:8e01dca41002 200 * @param f the function to call
donatien 0:8e01dca41002 201 * @param ctx parameter passed to f
donatien 0:8e01dca41002 202 * @param block 1 to block until the request is posted, 0 to non-blocking mode
donatien 0:8e01dca41002 203 * @return ERR_OK if the function was called, another err_t if not
donatien 0:8e01dca41002 204 */
donatien 0:8e01dca41002 205 err_t
donatien 0:8e01dca41002 206 tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
donatien 0:8e01dca41002 207 {
donatien 0:8e01dca41002 208 struct tcpip_msg *msg;
donatien 0:8e01dca41002 209
donatien 0:8e01dca41002 210 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 211 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
donatien 0:8e01dca41002 212 if (msg == NULL) {
donatien 0:8e01dca41002 213 return ERR_MEM;
donatien 0:8e01dca41002 214 }
donatien 0:8e01dca41002 215
donatien 0:8e01dca41002 216 msg->type = TCPIP_MSG_CALLBACK;
donatien 0:8e01dca41002 217 msg->msg.cb.function = function;
donatien 0:8e01dca41002 218 msg->msg.cb.ctx = ctx;
donatien 0:8e01dca41002 219 if (block) {
donatien 0:8e01dca41002 220 sys_mbox_post(&mbox, msg);
donatien 0:8e01dca41002 221 } else {
donatien 0:8e01dca41002 222 if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
donatien 0:8e01dca41002 223 memp_free(MEMP_TCPIP_MSG_API, msg);
donatien 0:8e01dca41002 224 return ERR_MEM;
donatien 0:8e01dca41002 225 }
donatien 0:8e01dca41002 226 }
donatien 0:8e01dca41002 227 return ERR_OK;
donatien 0:8e01dca41002 228 }
donatien 0:8e01dca41002 229 return ERR_VAL;
donatien 0:8e01dca41002 230 }
donatien 0:8e01dca41002 231
donatien 0:8e01dca41002 232 #if LWIP_TCPIP_TIMEOUT
donatien 0:8e01dca41002 233 /**
donatien 0:8e01dca41002 234 * call sys_timeout in tcpip_thread
donatien 0:8e01dca41002 235 *
donatien 0:8e01dca41002 236 * @param msec time in milliseconds for timeout
donatien 0:8e01dca41002 237 * @param h function to be called on timeout
donatien 0:8e01dca41002 238 * @param arg argument to pass to timeout function h
donatien 0:8e01dca41002 239 * @return ERR_MEM on memory error, ERR_OK otherwise
donatien 0:8e01dca41002 240 */
donatien 0:8e01dca41002 241 err_t
donatien 0:8e01dca41002 242 tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
donatien 0:8e01dca41002 243 {
donatien 0:8e01dca41002 244 struct tcpip_msg *msg;
donatien 0:8e01dca41002 245
donatien 0:8e01dca41002 246 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 247 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
donatien 0:8e01dca41002 248 if (msg == NULL) {
donatien 0:8e01dca41002 249 return ERR_MEM;
donatien 0:8e01dca41002 250 }
donatien 0:8e01dca41002 251
donatien 0:8e01dca41002 252 msg->type = TCPIP_MSG_TIMEOUT;
donatien 0:8e01dca41002 253 msg->msg.tmo.msecs = msecs;
donatien 0:8e01dca41002 254 msg->msg.tmo.h = h;
donatien 0:8e01dca41002 255 msg->msg.tmo.arg = arg;
donatien 0:8e01dca41002 256 sys_mbox_post(&mbox, msg);
donatien 0:8e01dca41002 257 return ERR_OK;
donatien 0:8e01dca41002 258 }
donatien 0:8e01dca41002 259 return ERR_VAL;
donatien 0:8e01dca41002 260 }
donatien 0:8e01dca41002 261
donatien 0:8e01dca41002 262 /**
donatien 0:8e01dca41002 263 * call sys_untimeout in tcpip_thread
donatien 0:8e01dca41002 264 *
donatien 0:8e01dca41002 265 * @param msec time in milliseconds for timeout
donatien 0:8e01dca41002 266 * @param h function to be called on timeout
donatien 0:8e01dca41002 267 * @param arg argument to pass to timeout function h
donatien 0:8e01dca41002 268 * @return ERR_MEM on memory error, ERR_OK otherwise
donatien 0:8e01dca41002 269 */
donatien 0:8e01dca41002 270 err_t
donatien 0:8e01dca41002 271 tcpip_untimeout(sys_timeout_handler h, void *arg)
donatien 0:8e01dca41002 272 {
donatien 0:8e01dca41002 273 struct tcpip_msg *msg;
donatien 0:8e01dca41002 274
donatien 0:8e01dca41002 275 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 276 msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
donatien 0:8e01dca41002 277 if (msg == NULL) {
donatien 0:8e01dca41002 278 return ERR_MEM;
donatien 0:8e01dca41002 279 }
donatien 0:8e01dca41002 280
donatien 0:8e01dca41002 281 msg->type = TCPIP_MSG_UNTIMEOUT;
donatien 0:8e01dca41002 282 msg->msg.tmo.h = h;
donatien 0:8e01dca41002 283 msg->msg.tmo.arg = arg;
donatien 0:8e01dca41002 284 sys_mbox_post(&mbox, msg);
donatien 0:8e01dca41002 285 return ERR_OK;
donatien 0:8e01dca41002 286 }
donatien 0:8e01dca41002 287 return ERR_VAL;
donatien 0:8e01dca41002 288 }
donatien 0:8e01dca41002 289 #endif /* LWIP_TCPIP_TIMEOUT */
donatien 0:8e01dca41002 290
donatien 0:8e01dca41002 291 #if LWIP_NETCONN
donatien 0:8e01dca41002 292 /**
donatien 0:8e01dca41002 293 * Call the lower part of a netconn_* function
donatien 0:8e01dca41002 294 * This function is then running in the thread context
donatien 0:8e01dca41002 295 * of tcpip_thread and has exclusive access to lwIP core code.
donatien 0:8e01dca41002 296 *
donatien 0:8e01dca41002 297 * @param apimsg a struct containing the function to call and its parameters
donatien 0:8e01dca41002 298 * @return ERR_OK if the function was called, another err_t if not
donatien 0:8e01dca41002 299 */
donatien 0:8e01dca41002 300 err_t
donatien 0:8e01dca41002 301 tcpip_apimsg(struct api_msg *apimsg)
donatien 0:8e01dca41002 302 {
donatien 0:8e01dca41002 303 struct tcpip_msg msg;
donatien 0:8e01dca41002 304 #ifdef LWIP_DEBUG
donatien 0:8e01dca41002 305 /* catch functions that don't set err */
donatien 0:8e01dca41002 306 apimsg->msg.err = ERR_VAL;
donatien 0:8e01dca41002 307 #endif
donatien 0:8e01dca41002 308
donatien 0:8e01dca41002 309 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 310 msg.type = TCPIP_MSG_API;
donatien 0:8e01dca41002 311 msg.msg.apimsg = apimsg;
donatien 0:8e01dca41002 312 sys_mbox_post(&mbox, &msg);
donatien 0:8e01dca41002 313 sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
donatien 0:8e01dca41002 314 return apimsg->msg.err;
donatien 0:8e01dca41002 315 }
donatien 0:8e01dca41002 316 return ERR_VAL;
donatien 0:8e01dca41002 317 }
donatien 0:8e01dca41002 318
donatien 0:8e01dca41002 319 #if LWIP_TCPIP_CORE_LOCKING
donatien 0:8e01dca41002 320 /**
donatien 0:8e01dca41002 321 * Call the lower part of a netconn_* function
donatien 0:8e01dca41002 322 * This function has exclusive access to lwIP core code by locking it
donatien 0:8e01dca41002 323 * before the function is called.
donatien 0:8e01dca41002 324 *
donatien 0:8e01dca41002 325 * @param apimsg a struct containing the function to call and its parameters
donatien 0:8e01dca41002 326 * @return ERR_OK (only for compatibility fo tcpip_apimsg())
donatien 0:8e01dca41002 327 */
donatien 0:8e01dca41002 328 err_t
donatien 0:8e01dca41002 329 tcpip_apimsg_lock(struct api_msg *apimsg)
donatien 0:8e01dca41002 330 {
donatien 0:8e01dca41002 331 #ifdef LWIP_DEBUG
donatien 0:8e01dca41002 332 /* catch functions that don't set err */
donatien 0:8e01dca41002 333 apimsg->msg.err = ERR_VAL;
donatien 0:8e01dca41002 334 #endif
donatien 0:8e01dca41002 335
donatien 0:8e01dca41002 336 LOCK_TCPIP_CORE();
donatien 0:8e01dca41002 337 apimsg->function(&(apimsg->msg));
donatien 0:8e01dca41002 338 UNLOCK_TCPIP_CORE();
donatien 0:8e01dca41002 339 return apimsg->msg.err;
donatien 0:8e01dca41002 340
donatien 0:8e01dca41002 341 }
donatien 0:8e01dca41002 342 #endif /* LWIP_TCPIP_CORE_LOCKING */
donatien 0:8e01dca41002 343 #endif /* LWIP_NETCONN */
donatien 0:8e01dca41002 344
donatien 0:8e01dca41002 345 #if LWIP_NETIF_API
donatien 0:8e01dca41002 346 #if !LWIP_TCPIP_CORE_LOCKING
donatien 0:8e01dca41002 347 /**
donatien 0:8e01dca41002 348 * Much like tcpip_apimsg, but calls the lower part of a netifapi_*
donatien 0:8e01dca41002 349 * function.
donatien 0:8e01dca41002 350 *
donatien 0:8e01dca41002 351 * @param netifapimsg a struct containing the function to call and its parameters
donatien 0:8e01dca41002 352 * @return error code given back by the function that was called
donatien 0:8e01dca41002 353 */
donatien 0:8e01dca41002 354 err_t
donatien 0:8e01dca41002 355 tcpip_netifapi(struct netifapi_msg* netifapimsg)
donatien 0:8e01dca41002 356 {
donatien 0:8e01dca41002 357 struct tcpip_msg msg;
donatien 0:8e01dca41002 358
donatien 0:8e01dca41002 359 if (sys_mbox_valid(&mbox)) {
donatien 0:8e01dca41002 360 err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
donatien 0:8e01dca41002 361 if (err != ERR_OK) {
donatien 0:8e01dca41002 362 netifapimsg->msg.err = err;
donatien 0:8e01dca41002 363 return err;
donatien 0:8e01dca41002 364 }
donatien 0:8e01dca41002 365
donatien 0:8e01dca41002 366 msg.type = TCPIP_MSG_NETIFAPI;
donatien 0:8e01dca41002 367 msg.msg.netifapimsg = netifapimsg;
donatien 0:8e01dca41002 368 sys_mbox_post(&mbox, &msg);
donatien 0:8e01dca41002 369 sys_sem_wait(&netifapimsg->msg.sem);
donatien 0:8e01dca41002 370 sys_sem_free(&netifapimsg->msg.sem);
donatien 0:8e01dca41002 371 return netifapimsg->msg.err;
donatien 0:8e01dca41002 372 }
donatien 0:8e01dca41002 373 return ERR_VAL;
donatien 0:8e01dca41002 374 }
donatien 0:8e01dca41002 375 #else /* !LWIP_TCPIP_CORE_LOCKING */
donatien 0:8e01dca41002 376 /**
donatien 0:8e01dca41002 377 * Call the lower part of a netifapi_* function
donatien 0:8e01dca41002 378 * This function has exclusive access to lwIP core code by locking it
donatien 0:8e01dca41002 379 * before the function is called.
donatien 0:8e01dca41002 380 *
donatien 0:8e01dca41002 381 * @param netifapimsg a struct containing the function to call and its parameters
donatien 0:8e01dca41002 382 * @return ERR_OK (only for compatibility fo tcpip_netifapi())
donatien 0:8e01dca41002 383 */
donatien 0:8e01dca41002 384 err_t
donatien 0:8e01dca41002 385 tcpip_netifapi_lock(struct netifapi_msg* netifapimsg)
donatien 0:8e01dca41002 386 {
donatien 0:8e01dca41002 387 LOCK_TCPIP_CORE();
donatien 0:8e01dca41002 388 netifapimsg->function(&(netifapimsg->msg));
donatien 0:8e01dca41002 389 UNLOCK_TCPIP_CORE();
donatien 0:8e01dca41002 390 return netifapimsg->msg.err;
donatien 0:8e01dca41002 391 }
donatien 0:8e01dca41002 392 #endif /* !LWIP_TCPIP_CORE_LOCKING */
donatien 0:8e01dca41002 393 #endif /* LWIP_NETIF_API */
donatien 0:8e01dca41002 394
donatien 0:8e01dca41002 395 /**
donatien 0:8e01dca41002 396 * Initialize this module:
donatien 0:8e01dca41002 397 * - initialize all sub modules
donatien 0:8e01dca41002 398 * - start the tcpip_thread
donatien 0:8e01dca41002 399 *
donatien 0:8e01dca41002 400 * @param initfunc a function to call when tcpip_thread is running and finished initializing
donatien 0:8e01dca41002 401 * @param arg argument to pass to initfunc
donatien 0:8e01dca41002 402 */
donatien 0:8e01dca41002 403 void
donatien 0:8e01dca41002 404 tcpip_init(tcpip_init_done_fn initfunc, void *arg)
donatien 0:8e01dca41002 405 {
donatien 0:8e01dca41002 406 lwip_init();
donatien 0:8e01dca41002 407
donatien 0:8e01dca41002 408 tcpip_init_done = initfunc;
donatien 0:8e01dca41002 409 tcpip_init_done_arg = arg;
donatien 0:8e01dca41002 410 if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
donatien 0:8e01dca41002 411 LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
donatien 0:8e01dca41002 412 }
donatien 0:8e01dca41002 413 #if LWIP_TCPIP_CORE_LOCKING
donatien 0:8e01dca41002 414 if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
donatien 0:8e01dca41002 415 LWIP_ASSERT("failed to create lock_tcpip_core", 0);
donatien 0:8e01dca41002 416 }
donatien 0:8e01dca41002 417 #endif /* LWIP_TCPIP_CORE_LOCKING */
donatien 0:8e01dca41002 418
donatien 0:8e01dca41002 419 sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
donatien 0:8e01dca41002 420 }
donatien 0:8e01dca41002 421
donatien 0:8e01dca41002 422 /**
donatien 0:8e01dca41002 423 * Simple callback function used with tcpip_callback to free a pbuf
donatien 0:8e01dca41002 424 * (pbuf_free has a wrong signature for tcpip_callback)
donatien 0:8e01dca41002 425 *
donatien 0:8e01dca41002 426 * @param p The pbuf (chain) to be dereferenced.
donatien 0:8e01dca41002 427 */
donatien 0:8e01dca41002 428 static void
donatien 0:8e01dca41002 429 pbuf_free_int(void *p)
donatien 0:8e01dca41002 430 {
donatien 0:8e01dca41002 431 struct pbuf *q = (struct pbuf *)p;
donatien 0:8e01dca41002 432 pbuf_free(q);
donatien 0:8e01dca41002 433 }
donatien 0:8e01dca41002 434
donatien 0:8e01dca41002 435 /**
donatien 0:8e01dca41002 436 * A simple wrapper function that allows you to free a pbuf from interrupt context.
donatien 0:8e01dca41002 437 *
donatien 0:8e01dca41002 438 * @param p The pbuf (chain) to be dereferenced.
donatien 0:8e01dca41002 439 * @return ERR_OK if callback could be enqueued, an err_t if not
donatien 0:8e01dca41002 440 */
donatien 0:8e01dca41002 441 err_t
donatien 0:8e01dca41002 442 pbuf_free_callback(struct pbuf *p)
donatien 0:8e01dca41002 443 {
donatien 0:8e01dca41002 444 return tcpip_callback_with_block(pbuf_free_int, p, 0);
donatien 0:8e01dca41002 445 }
donatien 0:8e01dca41002 446
donatien 0:8e01dca41002 447 /**
donatien 0:8e01dca41002 448 * A simple wrapper function that allows you to free heap memory from
donatien 0:8e01dca41002 449 * interrupt context.
donatien 0:8e01dca41002 450 *
donatien 0:8e01dca41002 451 * @param m the heap memory to free
donatien 0:8e01dca41002 452 * @return ERR_OK if callback could be enqueued, an err_t if not
donatien 0:8e01dca41002 453 */
donatien 0:8e01dca41002 454 err_t
donatien 0:8e01dca41002 455 mem_free_callback(void *m)
donatien 0:8e01dca41002 456 {
donatien 0:8e01dca41002 457 return tcpip_callback_with_block(mem_free, m, 0);
donatien 0:8e01dca41002 458 }
donatien 0:8e01dca41002 459
donatien 0:8e01dca41002 460 #endif /* !NO_SYS */