ProjetoBB

Dependencies:   F7_Ethernet WebSocketClient mbed mcp3008

Fork of Nucleo_F746ZG_Ethernet by Dieter Graef

Committer:
DieterGraef
Date:
Sat Jun 18 10:49:12 2016 +0000
Revision:
0:f9b6112278fe
Ethernet for the NUCLEO STM32F746 Board Testprogram uses DHCP and NTP to set the clock

Who changed what in which revision?

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