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 External 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 /* This is the part of the API that is linked with
donatien 0:8e01dca41002 40 the application */
donatien 0:8e01dca41002 41
donatien 0:8e01dca41002 42 #include "lwip/opt.h"
donatien 0:8e01dca41002 43
donatien 0:8e01dca41002 44 #if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
donatien 0:8e01dca41002 45
donatien 0:8e01dca41002 46 #include "lwip/api.h"
donatien 0:8e01dca41002 47 #include "lwip/tcpip.h"
donatien 0:8e01dca41002 48 #include "lwip/memp.h"
donatien 0:8e01dca41002 49
donatien 0:8e01dca41002 50 #include "lwip/ip.h"
donatien 0:8e01dca41002 51 #include "lwip/raw.h"
donatien 0:8e01dca41002 52 #include "lwip/udp.h"
donatien 0:8e01dca41002 53 #include "lwip/tcp.h"
donatien 0:8e01dca41002 54
donatien 0:8e01dca41002 55 #include <string.h>
donatien 0:8e01dca41002 56
donatien 0:8e01dca41002 57 /**
donatien 0:8e01dca41002 58 * Create a new netconn (of a specific type) that has a callback function.
donatien 0:8e01dca41002 59 * The corresponding pcb is also created.
donatien 0:8e01dca41002 60 *
donatien 0:8e01dca41002 61 * @param t the type of 'connection' to create (@see enum netconn_type)
donatien 0:8e01dca41002 62 * @param proto the IP protocol for RAW IP pcbs
donatien 0:8e01dca41002 63 * @param callback a function to call on status changes (RX available, TX'ed)
donatien 0:8e01dca41002 64 * @return a newly allocated struct netconn or
donatien 0:8e01dca41002 65 * NULL on memory error
donatien 0:8e01dca41002 66 */
donatien 0:8e01dca41002 67 struct netconn*
donatien 0:8e01dca41002 68 netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
donatien 0:8e01dca41002 69 {
donatien 0:8e01dca41002 70 struct netconn *conn;
donatien 0:8e01dca41002 71 struct api_msg msg;
donatien 0:8e01dca41002 72
donatien 0:8e01dca41002 73 conn = netconn_alloc(t, callback);
donatien 0:8e01dca41002 74 if (conn != NULL) {
donatien 0:8e01dca41002 75 LWIP_DEBUGF(API_LIB_DEBUG, ("Alloc OK"));
donatien 0:8e01dca41002 76 msg.function = do_newconn;
donatien 0:8e01dca41002 77 msg.msg.msg.n.proto = proto;
donatien 0:8e01dca41002 78 msg.msg.conn = conn;
donatien 0:8e01dca41002 79 if (TCPIP_APIMSG(&msg) != ERR_OK) {
donatien 0:8e01dca41002 80 LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
donatien 0:8e01dca41002 81 LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
donatien 0:8e01dca41002 82 LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
donatien 0:8e01dca41002 83 #if LWIP_TCP
donatien 0:8e01dca41002 84 LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
donatien 0:8e01dca41002 85 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 86 sys_sem_free(&conn->op_completed);
donatien 0:8e01dca41002 87 sys_mbox_free(&conn->recvmbox);
donatien 0:8e01dca41002 88 memp_free(MEMP_NETCONN, conn);
donatien 0:8e01dca41002 89 return NULL;
donatien 0:8e01dca41002 90 }
donatien 0:8e01dca41002 91 }
donatien 0:8e01dca41002 92 return conn;
donatien 0:8e01dca41002 93 }
donatien 0:8e01dca41002 94
donatien 0:8e01dca41002 95 /**
donatien 0:8e01dca41002 96 * Close a netconn 'connection' and free its resources.
donatien 0:8e01dca41002 97 * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate
donatien 0:8e01dca41002 98 * after this returns.
donatien 0:8e01dca41002 99 *
donatien 0:8e01dca41002 100 * @param conn the netconn to delete
donatien 0:8e01dca41002 101 * @return ERR_OK if the connection was deleted
donatien 0:8e01dca41002 102 */
donatien 0:8e01dca41002 103 err_t
donatien 0:8e01dca41002 104 netconn_delete(struct netconn *conn)
donatien 0:8e01dca41002 105 {
donatien 0:8e01dca41002 106 struct api_msg msg;
donatien 0:8e01dca41002 107
donatien 0:8e01dca41002 108 /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
donatien 0:8e01dca41002 109 if (conn == NULL) {
donatien 0:8e01dca41002 110 return ERR_OK;
donatien 0:8e01dca41002 111 }
donatien 0:8e01dca41002 112
donatien 0:8e01dca41002 113 msg.function = do_delconn;
donatien 0:8e01dca41002 114 msg.msg.conn = conn;
donatien 0:8e01dca41002 115 tcpip_apimsg(&msg);
donatien 0:8e01dca41002 116
donatien 0:8e01dca41002 117 netconn_free(conn);
donatien 0:8e01dca41002 118
donatien 0:8e01dca41002 119 /* don't care for return value of do_delconn since it only calls void functions */
donatien 0:8e01dca41002 120
donatien 0:8e01dca41002 121 return ERR_OK;
donatien 0:8e01dca41002 122 }
donatien 0:8e01dca41002 123
donatien 0:8e01dca41002 124 /**
donatien 0:8e01dca41002 125 * Get the local or remote IP address and port of a netconn.
donatien 0:8e01dca41002 126 * For RAW netconns, this returns the protocol instead of a port!
donatien 0:8e01dca41002 127 *
donatien 0:8e01dca41002 128 * @param conn the netconn to query
donatien 0:8e01dca41002 129 * @param addr a pointer to which to save the IP address
donatien 0:8e01dca41002 130 * @param port a pointer to which to save the port (or protocol for RAW)
donatien 0:8e01dca41002 131 * @param local 1 to get the local IP address, 0 to get the remote one
donatien 0:8e01dca41002 132 * @return ERR_CONN for invalid connections
donatien 0:8e01dca41002 133 * ERR_OK if the information was retrieved
donatien 0:8e01dca41002 134 */
donatien 0:8e01dca41002 135 err_t
donatien 0:8e01dca41002 136 netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
donatien 0:8e01dca41002 137 {
donatien 0:8e01dca41002 138 struct api_msg msg;
donatien 0:8e01dca41002 139 err_t err;
donatien 0:8e01dca41002 140
donatien 0:8e01dca41002 141 LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 142 LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 143 LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 144
donatien 0:8e01dca41002 145 msg.function = do_getaddr;
donatien 0:8e01dca41002 146 msg.msg.conn = conn;
donatien 0:8e01dca41002 147 msg.msg.msg.ad.ipaddr = addr;
donatien 0:8e01dca41002 148 msg.msg.msg.ad.port = port;
donatien 0:8e01dca41002 149 msg.msg.msg.ad.local = local;
donatien 0:8e01dca41002 150 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 151
donatien 0:8e01dca41002 152 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 153 return err;
donatien 0:8e01dca41002 154 }
donatien 0:8e01dca41002 155
donatien 0:8e01dca41002 156 /**
donatien 0:8e01dca41002 157 * Bind a netconn to a specific local IP address and port.
donatien 0:8e01dca41002 158 * Binding one netconn twice might not always be checked correctly!
donatien 0:8e01dca41002 159 *
donatien 0:8e01dca41002 160 * @param conn the netconn to bind
donatien 0:8e01dca41002 161 * @param addr the local IP address to bind the netconn to (use IP_ADDR_ANY
donatien 0:8e01dca41002 162 * to bind to all addresses)
donatien 0:8e01dca41002 163 * @param port the local port to bind the netconn to (not used for RAW)
donatien 0:8e01dca41002 164 * @return ERR_OK if bound, any other err_t on failure
donatien 0:8e01dca41002 165 */
donatien 0:8e01dca41002 166 err_t
donatien 0:8e01dca41002 167 netconn_bind(struct netconn *conn, ip_addr_t *addr, u16_t port)
donatien 0:8e01dca41002 168 {
donatien 0:8e01dca41002 169 struct api_msg msg;
donatien 0:8e01dca41002 170 err_t err;
donatien 0:8e01dca41002 171
donatien 0:8e01dca41002 172 LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 173
donatien 0:8e01dca41002 174 msg.function = do_bind;
donatien 0:8e01dca41002 175 msg.msg.conn = conn;
donatien 0:8e01dca41002 176 msg.msg.msg.bc.ipaddr = addr;
donatien 0:8e01dca41002 177 msg.msg.msg.bc.port = port;
donatien 0:8e01dca41002 178 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 179
donatien 0:8e01dca41002 180 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 181 return err;
donatien 0:8e01dca41002 182 }
donatien 0:8e01dca41002 183
donatien 0:8e01dca41002 184 /**
donatien 0:8e01dca41002 185 * Connect a netconn to a specific remote IP address and port.
donatien 0:8e01dca41002 186 *
donatien 0:8e01dca41002 187 * @param conn the netconn to connect
donatien 0:8e01dca41002 188 * @param addr the remote IP address to connect to
donatien 0:8e01dca41002 189 * @param port the remote port to connect to (no used for RAW)
donatien 0:8e01dca41002 190 * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise
donatien 0:8e01dca41002 191 */
donatien 0:8e01dca41002 192 err_t
donatien 0:8e01dca41002 193 netconn_connect(struct netconn *conn, ip_addr_t *addr, u16_t port)
donatien 0:8e01dca41002 194 {
donatien 0:8e01dca41002 195 struct api_msg msg;
donatien 0:8e01dca41002 196 err_t err;
donatien 0:8e01dca41002 197
donatien 0:8e01dca41002 198 LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 199
donatien 0:8e01dca41002 200 msg.function = do_connect;
donatien 0:8e01dca41002 201 msg.msg.conn = conn;
donatien 0:8e01dca41002 202 msg.msg.msg.bc.ipaddr = addr;
donatien 0:8e01dca41002 203 msg.msg.msg.bc.port = port;
donatien 0:8e01dca41002 204 /* This is the only function which need to not block tcpip_thread */
donatien 0:8e01dca41002 205 err = tcpip_apimsg(&msg);
donatien 0:8e01dca41002 206
donatien 0:8e01dca41002 207 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 208 return err;
donatien 0:8e01dca41002 209 }
donatien 0:8e01dca41002 210
donatien 0:8e01dca41002 211 /**
donatien 0:8e01dca41002 212 * Disconnect a netconn from its current peer (only valid for UDP netconns).
donatien 0:8e01dca41002 213 *
donatien 0:8e01dca41002 214 * @param conn the netconn to disconnect
donatien 0:8e01dca41002 215 * @return TODO: return value is not set here...
donatien 0:8e01dca41002 216 */
donatien 0:8e01dca41002 217 err_t
donatien 0:8e01dca41002 218 netconn_disconnect(struct netconn *conn)
donatien 0:8e01dca41002 219 {
donatien 0:8e01dca41002 220 struct api_msg msg;
donatien 0:8e01dca41002 221 err_t err;
donatien 0:8e01dca41002 222
donatien 0:8e01dca41002 223 LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 224
donatien 0:8e01dca41002 225 msg.function = do_disconnect;
donatien 0:8e01dca41002 226 msg.msg.conn = conn;
donatien 0:8e01dca41002 227 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 228
donatien 0:8e01dca41002 229 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 230 return err;
donatien 0:8e01dca41002 231 }
donatien 0:8e01dca41002 232
donatien 0:8e01dca41002 233 /**
donatien 0:8e01dca41002 234 * Set a TCP netconn into listen mode
donatien 0:8e01dca41002 235 *
donatien 0:8e01dca41002 236 * @param conn the tcp netconn to set to listen mode
donatien 0:8e01dca41002 237 * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1
donatien 0:8e01dca41002 238 * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns
donatien 0:8e01dca41002 239 * don't return any error (yet?))
donatien 0:8e01dca41002 240 */
donatien 0:8e01dca41002 241 err_t
donatien 0:8e01dca41002 242 netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
donatien 0:8e01dca41002 243 {
donatien 0:8e01dca41002 244 #if LWIP_TCP
donatien 0:8e01dca41002 245 struct api_msg msg;
donatien 0:8e01dca41002 246 err_t err;
donatien 0:8e01dca41002 247
donatien 0:8e01dca41002 248 /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
donatien 0:8e01dca41002 249 LWIP_UNUSED_ARG(backlog);
donatien 0:8e01dca41002 250
donatien 0:8e01dca41002 251 LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 252
donatien 0:8e01dca41002 253 msg.function = do_listen;
donatien 0:8e01dca41002 254 msg.msg.conn = conn;
donatien 0:8e01dca41002 255 #if TCP_LISTEN_BACKLOG
donatien 0:8e01dca41002 256 msg.msg.msg.lb.backlog = backlog;
donatien 0:8e01dca41002 257 #endif /* TCP_LISTEN_BACKLOG */
donatien 0:8e01dca41002 258 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 259
donatien 0:8e01dca41002 260 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 261 return err;
donatien 0:8e01dca41002 262 #else /* LWIP_TCP */
donatien 0:8e01dca41002 263 LWIP_UNUSED_ARG(conn);
donatien 0:8e01dca41002 264 LWIP_UNUSED_ARG(backlog);
donatien 0:8e01dca41002 265 return ERR_ARG;
donatien 0:8e01dca41002 266 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 267 }
donatien 0:8e01dca41002 268
donatien 0:8e01dca41002 269 /**
donatien 0:8e01dca41002 270 * Accept a new connection on a TCP listening netconn.
donatien 0:8e01dca41002 271 *
donatien 0:8e01dca41002 272 * @param conn the TCP listen netconn
donatien 0:8e01dca41002 273 * @param new_conn pointer where the new connection is stored
donatien 0:8e01dca41002 274 * @return ERR_OK if a new connection has been received or an error
donatien 0:8e01dca41002 275 * code otherwise
donatien 0:8e01dca41002 276 */
donatien 0:8e01dca41002 277 err_t
donatien 0:8e01dca41002 278 netconn_accept(struct netconn *conn, struct netconn **new_conn)
donatien 0:8e01dca41002 279 {
donatien 0:8e01dca41002 280 #if LWIP_TCP
donatien 0:8e01dca41002 281 struct netconn *newconn;
donatien 0:8e01dca41002 282 err_t err;
donatien 0:8e01dca41002 283 #if TCP_LISTEN_BACKLOG
donatien 0:8e01dca41002 284 struct api_msg msg;
donatien 0:8e01dca41002 285 #endif /* TCP_LISTEN_BACKLOG */
donatien 0:8e01dca41002 286
donatien 0:8e01dca41002 287 LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 288 *new_conn = NULL;
donatien 0:8e01dca41002 289 LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 290 LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;);
donatien 0:8e01dca41002 291
donatien 0:8e01dca41002 292 err = conn->last_err;
donatien 0:8e01dca41002 293 if (ERR_IS_FATAL(err)) {
donatien 0:8e01dca41002 294 /* don't recv on fatal errors: this might block the application task
donatien 0:8e01dca41002 295 waiting on acceptmbox forever! */
donatien 0:8e01dca41002 296 return err;
donatien 0:8e01dca41002 297 }
donatien 0:8e01dca41002 298
donatien 0:8e01dca41002 299 #if LWIP_SO_RCVTIMEO
donatien 0:8e01dca41002 300 if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
donatien 0:8e01dca41002 301 NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
donatien 0:8e01dca41002 302 return ERR_TIMEOUT;
donatien 0:8e01dca41002 303 }
donatien 0:8e01dca41002 304 #else
donatien 0:8e01dca41002 305 sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
donatien 0:8e01dca41002 306 #endif /* LWIP_SO_RCVTIMEO*/
donatien 0:8e01dca41002 307 /* Register event with callback */
donatien 0:8e01dca41002 308 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
donatien 0:8e01dca41002 309
donatien 0:8e01dca41002 310 if (newconn == NULL) {
donatien 0:8e01dca41002 311 /* connection has been aborted */
donatien 0:8e01dca41002 312 NETCONN_SET_SAFE_ERR(conn, ERR_ABRT);
donatien 0:8e01dca41002 313 return ERR_ABRT;
donatien 0:8e01dca41002 314 }
donatien 0:8e01dca41002 315 #if TCP_LISTEN_BACKLOG
donatien 0:8e01dca41002 316 /* Let the stack know that we have accepted the connection. */
donatien 0:8e01dca41002 317 msg.function = do_recv;
donatien 0:8e01dca41002 318 msg.msg.conn = conn;
donatien 0:8e01dca41002 319 /* don't care for the return value of do_recv */
donatien 0:8e01dca41002 320 TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 321 #endif /* TCP_LISTEN_BACKLOG */
donatien 0:8e01dca41002 322
donatien 0:8e01dca41002 323 *new_conn = newconn;
donatien 0:8e01dca41002 324 /* don't set conn->last_err: it's only ERR_OK, anyway */
donatien 0:8e01dca41002 325 return ERR_OK;
donatien 0:8e01dca41002 326 #else /* LWIP_TCP */
donatien 0:8e01dca41002 327 LWIP_UNUSED_ARG(conn);
donatien 0:8e01dca41002 328 LWIP_UNUSED_ARG(new_conn);
donatien 0:8e01dca41002 329 return ERR_ARG;
donatien 0:8e01dca41002 330 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 331 }
donatien 0:8e01dca41002 332
donatien 0:8e01dca41002 333 /**
donatien 0:8e01dca41002 334 * Receive data: actual implementation that doesn't care whether pbuf or netbuf
donatien 0:8e01dca41002 335 * is received
donatien 0:8e01dca41002 336 *
donatien 0:8e01dca41002 337 * @param conn the netconn from which to receive data
donatien 0:8e01dca41002 338 * @param new_buf pointer where a new pbuf/netbuf is stored when received data
donatien 0:8e01dca41002 339 * @return ERR_OK if data has been received, an error code otherwise (timeout,
donatien 0:8e01dca41002 340 * memory error or another error)
donatien 0:8e01dca41002 341 */
donatien 0:8e01dca41002 342 static err_t
donatien 0:8e01dca41002 343 netconn_recv_data(struct netconn *conn, void **new_buf)
donatien 0:8e01dca41002 344 {
donatien 0:8e01dca41002 345 void *buf = NULL;
donatien 0:8e01dca41002 346 u16_t len;
donatien 0:8e01dca41002 347 err_t err;
donatien 0:8e01dca41002 348 #if LWIP_TCP
donatien 0:8e01dca41002 349 struct api_msg msg;
donatien 0:8e01dca41002 350 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 351
donatien 0:8e01dca41002 352 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 353 *new_buf = NULL;
donatien 0:8e01dca41002 354 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 355 LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
donatien 0:8e01dca41002 356
donatien 0:8e01dca41002 357 err = conn->last_err;
donatien 0:8e01dca41002 358 if (ERR_IS_FATAL(err)) {
donatien 0:8e01dca41002 359 /* don't recv on fatal errors: this might block the application task
donatien 0:8e01dca41002 360 waiting on recvmbox forever! */
donatien 0:8e01dca41002 361 /* @todo: this does not allow us to fetch data that has been put into recvmbox
donatien 0:8e01dca41002 362 before the fatal error occurred - is that a problem? */
donatien 0:8e01dca41002 363 return err;
donatien 0:8e01dca41002 364 }
donatien 0:8e01dca41002 365
donatien 0:8e01dca41002 366 #if LWIP_SO_RCVTIMEO
donatien 0:8e01dca41002 367 if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
donatien 0:8e01dca41002 368 NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
donatien 0:8e01dca41002 369 return ERR_TIMEOUT;
donatien 0:8e01dca41002 370 }
donatien 0:8e01dca41002 371 #else
donatien 0:8e01dca41002 372 sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
donatien 0:8e01dca41002 373 #endif /* LWIP_SO_RCVTIMEO*/
donatien 0:8e01dca41002 374
donatien 0:8e01dca41002 375 #if LWIP_TCP
donatien 0:8e01dca41002 376 if (conn->type == NETCONN_TCP) {
donatien 0:8e01dca41002 377 if (!netconn_get_noautorecved(conn) || (buf == NULL)) {
donatien 0:8e01dca41002 378 /* Let the stack know that we have taken the data. */
donatien 0:8e01dca41002 379 /* TODO: Speedup: Don't block and wait for the answer here
donatien 0:8e01dca41002 380 (to prevent multiple thread-switches). */
donatien 0:8e01dca41002 381 msg.function = do_recv;
donatien 0:8e01dca41002 382 msg.msg.conn = conn;
donatien 0:8e01dca41002 383 if (buf != NULL) {
donatien 0:8e01dca41002 384 msg.msg.msg.r.len = ((struct pbuf *)buf)->tot_len;
donatien 0:8e01dca41002 385 } else {
donatien 0:8e01dca41002 386 msg.msg.msg.r.len = 1;
donatien 0:8e01dca41002 387 }
donatien 0:8e01dca41002 388 /* don't care for the return value of do_recv */
donatien 0:8e01dca41002 389 TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 390 }
donatien 0:8e01dca41002 391
donatien 0:8e01dca41002 392 /* If we are closed, we indicate that we no longer wish to use the socket */
donatien 0:8e01dca41002 393 if (buf == NULL) {
donatien 0:8e01dca41002 394 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
donatien 0:8e01dca41002 395 /* Avoid to lose any previous error code */
donatien 0:8e01dca41002 396 NETCONN_SET_SAFE_ERR(conn, ERR_CLSD);
donatien 0:8e01dca41002 397 return ERR_CLSD;
donatien 0:8e01dca41002 398 }
donatien 0:8e01dca41002 399 len = ((struct pbuf *)buf)->tot_len;
donatien 0:8e01dca41002 400 }
donatien 0:8e01dca41002 401 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 402 #if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
donatien 0:8e01dca41002 403 else
donatien 0:8e01dca41002 404 #endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
donatien 0:8e01dca41002 405 #if (LWIP_UDP || LWIP_RAW)
donatien 0:8e01dca41002 406 {
donatien 0:8e01dca41002 407 LWIP_ASSERT("buf != NULL", buf != NULL);
donatien 0:8e01dca41002 408 len = netbuf_len((struct netbuf *)buf);
donatien 0:8e01dca41002 409 }
donatien 0:8e01dca41002 410 #endif /* (LWIP_UDP || LWIP_RAW) */
donatien 0:8e01dca41002 411
donatien 0:8e01dca41002 412 #if LWIP_SO_RCVBUF
donatien 0:8e01dca41002 413 SYS_ARCH_DEC(conn->recv_avail, len);
donatien 0:8e01dca41002 414 #endif /* LWIP_SO_RCVBUF */
donatien 0:8e01dca41002 415 /* Register event with callback */
donatien 0:8e01dca41002 416 API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
donatien 0:8e01dca41002 417
donatien 0:8e01dca41002 418 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
donatien 0:8e01dca41002 419
donatien 0:8e01dca41002 420 *new_buf = buf;
donatien 0:8e01dca41002 421 /* don't set conn->last_err: it's only ERR_OK, anyway */
donatien 0:8e01dca41002 422 return ERR_OK;
donatien 0:8e01dca41002 423 }
donatien 0:8e01dca41002 424
donatien 0:8e01dca41002 425 /**
donatien 0:8e01dca41002 426 * Receive data (in form of a pbuf) from a TCP netconn
donatien 0:8e01dca41002 427 *
donatien 0:8e01dca41002 428 * @param conn the netconn from which to receive data
donatien 0:8e01dca41002 429 * @param new_buf pointer where a new pbuf is stored when received data
donatien 0:8e01dca41002 430 * @return ERR_OK if data has been received, an error code otherwise (timeout,
donatien 0:8e01dca41002 431 * memory error or another error)
donatien 0:8e01dca41002 432 * ERR_ARG if conn is not a TCP netconn
donatien 0:8e01dca41002 433 */
donatien 0:8e01dca41002 434 err_t
donatien 0:8e01dca41002 435 netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
donatien 0:8e01dca41002 436 {
donatien 0:8e01dca41002 437 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) &&
donatien 0:8e01dca41002 438 netconn_type(conn) == NETCONN_TCP, return ERR_ARG;);
donatien 0:8e01dca41002 439
donatien 0:8e01dca41002 440 return netconn_recv_data(conn, (void **)new_buf);
donatien 0:8e01dca41002 441 }
donatien 0:8e01dca41002 442
donatien 0:8e01dca41002 443 /**
donatien 0:8e01dca41002 444 * Receive data (in form of a netbuf containing a packet buffer) from a netconn
donatien 0:8e01dca41002 445 *
donatien 0:8e01dca41002 446 * @param conn the netconn from which to receive data
donatien 0:8e01dca41002 447 * @param new_buf pointer where a new netbuf is stored when received data
donatien 0:8e01dca41002 448 * @return ERR_OK if data has been received, an error code otherwise (timeout,
donatien 0:8e01dca41002 449 * memory error or another error)
donatien 0:8e01dca41002 450 */
donatien 0:8e01dca41002 451 err_t
donatien 0:8e01dca41002 452 netconn_recv(struct netconn *conn, struct netbuf **new_buf)
donatien 0:8e01dca41002 453 {
donatien 0:8e01dca41002 454 #if LWIP_TCP
donatien 0:8e01dca41002 455 struct netbuf *buf = NULL;
donatien 0:8e01dca41002 456 err_t err;
donatien 0:8e01dca41002 457 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 458
donatien 0:8e01dca41002 459 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 460 *new_buf = NULL;
donatien 0:8e01dca41002 461 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 462 LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
donatien 0:8e01dca41002 463
donatien 0:8e01dca41002 464 #if LWIP_TCP
donatien 0:8e01dca41002 465 if (conn->type == NETCONN_TCP) {
donatien 0:8e01dca41002 466 struct pbuf *p = NULL;
donatien 0:8e01dca41002 467 /* This is not a listening netconn, since recvmbox is set */
donatien 0:8e01dca41002 468
donatien 0:8e01dca41002 469 buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
donatien 0:8e01dca41002 470 if (buf == NULL) {
donatien 0:8e01dca41002 471 NETCONN_SET_SAFE_ERR(conn, ERR_MEM);
donatien 0:8e01dca41002 472 return ERR_MEM;
donatien 0:8e01dca41002 473 }
donatien 0:8e01dca41002 474
donatien 0:8e01dca41002 475 err = netconn_recv_data(conn, (void **)&p);
donatien 0:8e01dca41002 476 if (err != ERR_OK) {
donatien 0:8e01dca41002 477 memp_free(MEMP_NETBUF, buf);
donatien 0:8e01dca41002 478 return err;
donatien 0:8e01dca41002 479 }
donatien 0:8e01dca41002 480 LWIP_ASSERT("p != NULL", p != NULL);
donatien 0:8e01dca41002 481
donatien 0:8e01dca41002 482 buf->p = p;
donatien 0:8e01dca41002 483 buf->ptr = p;
donatien 0:8e01dca41002 484 buf->port = 0;
donatien 0:8e01dca41002 485 ip_addr_set_any(&buf->addr);
donatien 0:8e01dca41002 486 *new_buf = buf;
donatien 0:8e01dca41002 487 /* don't set conn->last_err: it's only ERR_OK, anyway */
donatien 0:8e01dca41002 488 return ERR_OK;
donatien 0:8e01dca41002 489 } else
donatien 0:8e01dca41002 490 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 491 {
donatien 0:8e01dca41002 492 #if (LWIP_UDP || LWIP_RAW)
donatien 0:8e01dca41002 493 return netconn_recv_data(conn, (void **)new_buf);
donatien 0:8e01dca41002 494 #endif /* (LWIP_UDP || LWIP_RAW) */
donatien 0:8e01dca41002 495 }
donatien 0:8e01dca41002 496 }
donatien 0:8e01dca41002 497
donatien 0:8e01dca41002 498 /**
donatien 0:8e01dca41002 499 * TCP: update the receive window: by calling this, the application
donatien 0:8e01dca41002 500 * tells the stack that it has processed data and is able to accept
donatien 0:8e01dca41002 501 * new data.
donatien 0:8e01dca41002 502 * ATTENTION: use with care, this is mainly used for sockets!
donatien 0:8e01dca41002 503 * Can only be used when calling netconn_set_noautorecved(conn, 1) before.
donatien 0:8e01dca41002 504 *
donatien 0:8e01dca41002 505 * @param conn the netconn for which to update the receive window
donatien 0:8e01dca41002 506 * @param length amount of data processed (ATTENTION: this must be accurate!)
donatien 0:8e01dca41002 507 */
donatien 0:8e01dca41002 508 void
donatien 0:8e01dca41002 509 netconn_recved(struct netconn *conn, u32_t length)
donatien 0:8e01dca41002 510 {
donatien 0:8e01dca41002 511 #if LWIP_TCP
donatien 0:8e01dca41002 512 if ((conn != NULL) && (conn->type == NETCONN_TCP) &&
donatien 0:8e01dca41002 513 (netconn_get_noautorecved(conn))) {
donatien 0:8e01dca41002 514 struct api_msg msg;
donatien 0:8e01dca41002 515 /* Let the stack know that we have taken the data. */
donatien 0:8e01dca41002 516 /* TODO: Speedup: Don't block and wait for the answer here
donatien 0:8e01dca41002 517 (to prevent multiple thread-switches). */
donatien 0:8e01dca41002 518 msg.function = do_recv;
donatien 0:8e01dca41002 519 msg.msg.conn = conn;
donatien 0:8e01dca41002 520 msg.msg.msg.r.len = length;
donatien 0:8e01dca41002 521 /* don't care for the return value of do_recv */
donatien 0:8e01dca41002 522 TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 523 }
donatien 0:8e01dca41002 524 #else /* LWIP_TCP */
donatien 0:8e01dca41002 525 LWIP_UNUSED_ARG(conn);
donatien 0:8e01dca41002 526 LWIP_UNUSED_ARG(length);
donatien 0:8e01dca41002 527 #endif /* LWIP_TCP */
donatien 0:8e01dca41002 528 }
donatien 0:8e01dca41002 529
donatien 0:8e01dca41002 530 /**
donatien 0:8e01dca41002 531 * Send data (in form of a netbuf) to a specific remote IP address and port.
donatien 0:8e01dca41002 532 * Only to be used for UDP and RAW netconns (not TCP).
donatien 0:8e01dca41002 533 *
donatien 0:8e01dca41002 534 * @param conn the netconn over which to send data
donatien 0:8e01dca41002 535 * @param buf a netbuf containing the data to send
donatien 0:8e01dca41002 536 * @param addr the remote IP address to which to send the data
donatien 0:8e01dca41002 537 * @param port the remote port to which to send the data
donatien 0:8e01dca41002 538 * @return ERR_OK if data was sent, any other err_t on error
donatien 0:8e01dca41002 539 */
donatien 0:8e01dca41002 540 err_t
donatien 0:8e01dca41002 541 netconn_sendto(struct netconn *conn, struct netbuf *buf, ip_addr_t *addr, u16_t port)
donatien 0:8e01dca41002 542 {
donatien 0:8e01dca41002 543 if (buf != NULL) {
donatien 0:8e01dca41002 544 ip_addr_set(&buf->addr, addr);
donatien 0:8e01dca41002 545 buf->port = port;
donatien 0:8e01dca41002 546 return netconn_send(conn, buf);
donatien 0:8e01dca41002 547 }
donatien 0:8e01dca41002 548 return ERR_VAL;
donatien 0:8e01dca41002 549 }
donatien 0:8e01dca41002 550
donatien 0:8e01dca41002 551 /**
donatien 0:8e01dca41002 552 * Send data over a UDP or RAW netconn (that is already connected).
donatien 0:8e01dca41002 553 *
donatien 0:8e01dca41002 554 * @param conn the UDP or RAW netconn over which to send data
donatien 0:8e01dca41002 555 * @param buf a netbuf containing the data to send
donatien 0:8e01dca41002 556 * @return ERR_OK if data was sent, any other err_t on error
donatien 0:8e01dca41002 557 */
donatien 0:8e01dca41002 558 err_t
donatien 0:8e01dca41002 559 netconn_send(struct netconn *conn, struct netbuf *buf)
donatien 0:8e01dca41002 560 {
donatien 0:8e01dca41002 561 struct api_msg msg;
donatien 0:8e01dca41002 562 err_t err;
donatien 0:8e01dca41002 563
donatien 0:8e01dca41002 564 LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 565
donatien 0:8e01dca41002 566 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
donatien 0:8e01dca41002 567 msg.function = do_send;
donatien 0:8e01dca41002 568 msg.msg.conn = conn;
donatien 0:8e01dca41002 569 msg.msg.msg.b = buf;
donatien 0:8e01dca41002 570 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 571
donatien 0:8e01dca41002 572 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 573 return err;
donatien 0:8e01dca41002 574 }
donatien 0:8e01dca41002 575
donatien 0:8e01dca41002 576 /**
donatien 0:8e01dca41002 577 * Send data over a TCP netconn.
donatien 0:8e01dca41002 578 *
donatien 0:8e01dca41002 579 * @param conn the TCP netconn over which to send data
donatien 0:8e01dca41002 580 * @param dataptr pointer to the application buffer that contains the data to send
donatien 0:8e01dca41002 581 * @param size size of the application data to send
donatien 0:8e01dca41002 582 * @param apiflags combination of following flags :
donatien 0:8e01dca41002 583 * - NETCONN_COPY: data will be copied into memory belonging to the stack
donatien 0:8e01dca41002 584 * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent
donatien 0:8e01dca41002 585 * - NETCONN_DONTBLOCK: only write the data if all dat can be written at once
donatien 0:8e01dca41002 586 * @return ERR_OK if data was sent, any other err_t on error
donatien 0:8e01dca41002 587 */
donatien 0:8e01dca41002 588 err_t
donatien 0:8e01dca41002 589 netconn_write(struct netconn *conn, const void *dataptr, size_t size, u8_t apiflags)
donatien 0:8e01dca41002 590 {
donatien 0:8e01dca41002 591 struct api_msg msg;
donatien 0:8e01dca41002 592 err_t err;
donatien 0:8e01dca41002 593
donatien 0:8e01dca41002 594 LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 595 LWIP_ERROR("netconn_write: invalid conn->type", (conn->type == NETCONN_TCP), return ERR_VAL;);
donatien 0:8e01dca41002 596 if (size == 0) {
donatien 0:8e01dca41002 597 return ERR_OK;
donatien 0:8e01dca41002 598 }
donatien 0:8e01dca41002 599
donatien 0:8e01dca41002 600 /* @todo: for non-blocking write, check if 'size' would ever fit into
donatien 0:8e01dca41002 601 snd_queue or snd_buf */
donatien 0:8e01dca41002 602 msg.function = do_write;
donatien 0:8e01dca41002 603 msg.msg.conn = conn;
donatien 0:8e01dca41002 604 msg.msg.msg.w.dataptr = dataptr;
donatien 0:8e01dca41002 605 msg.msg.msg.w.apiflags = apiflags;
donatien 0:8e01dca41002 606 msg.msg.msg.w.len = size;
donatien 0:8e01dca41002 607 /* For locking the core: this _can_ be delayed on low memory/low send buffer,
donatien 0:8e01dca41002 608 but if it is, this is done inside api_msg.c:do_write(), so we can use the
donatien 0:8e01dca41002 609 non-blocking version here. */
donatien 0:8e01dca41002 610 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 611
donatien 0:8e01dca41002 612 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 613 return err;
donatien 0:8e01dca41002 614 }
donatien 0:8e01dca41002 615
donatien 0:8e01dca41002 616 /**
donatien 0:8e01dca41002 617 * Close ot shutdown a TCP netconn (doesn't delete it).
donatien 0:8e01dca41002 618 *
donatien 0:8e01dca41002 619 * @param conn the TCP netconn to close or shutdown
donatien 0:8e01dca41002 620 * @param how fully close or only shutdown one side?
donatien 0:8e01dca41002 621 * @return ERR_OK if the netconn was closed, any other err_t on error
donatien 0:8e01dca41002 622 */
donatien 0:8e01dca41002 623 static err_t
donatien 0:8e01dca41002 624 netconn_close_shutdown(struct netconn *conn, u8_t how)
donatien 0:8e01dca41002 625 {
donatien 0:8e01dca41002 626 struct api_msg msg;
donatien 0:8e01dca41002 627 err_t err;
donatien 0:8e01dca41002 628
donatien 0:8e01dca41002 629 LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 630
donatien 0:8e01dca41002 631 msg.function = do_close;
donatien 0:8e01dca41002 632 msg.msg.conn = conn;
donatien 0:8e01dca41002 633 /* shutting down both ends is the same as closing */
donatien 0:8e01dca41002 634 msg.msg.msg.sd.shut = how;
donatien 0:8e01dca41002 635 /* because of the LWIP_TCPIP_CORE_LOCKING implementation of do_close,
donatien 0:8e01dca41002 636 don't use TCPIP_APIMSG here */
donatien 0:8e01dca41002 637 err = tcpip_apimsg(&msg);
donatien 0:8e01dca41002 638
donatien 0:8e01dca41002 639 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 640 return err;
donatien 0:8e01dca41002 641 }
donatien 0:8e01dca41002 642
donatien 0:8e01dca41002 643 /**
donatien 0:8e01dca41002 644 * Close a TCP netconn (doesn't delete it).
donatien 0:8e01dca41002 645 *
donatien 0:8e01dca41002 646 * @param conn the TCP netconn to close
donatien 0:8e01dca41002 647 * @return ERR_OK if the netconn was closed, any other err_t on error
donatien 0:8e01dca41002 648 */
donatien 0:8e01dca41002 649 err_t
donatien 0:8e01dca41002 650 netconn_close(struct netconn *conn)
donatien 0:8e01dca41002 651 {
donatien 0:8e01dca41002 652 /* shutting down both ends is the same as closing */
donatien 0:8e01dca41002 653 return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
donatien 0:8e01dca41002 654 }
donatien 0:8e01dca41002 655
donatien 0:8e01dca41002 656 /**
donatien 0:8e01dca41002 657 * Shut down one or both sides of a TCP netconn (doesn't delete it).
donatien 0:8e01dca41002 658 *
donatien 0:8e01dca41002 659 * @param conn the TCP netconn to shut down
donatien 0:8e01dca41002 660 * @return ERR_OK if the netconn was closed, any other err_t on error
donatien 0:8e01dca41002 661 */
donatien 0:8e01dca41002 662 err_t
donatien 0:8e01dca41002 663 netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
donatien 0:8e01dca41002 664 {
donatien 0:8e01dca41002 665 return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0));
donatien 0:8e01dca41002 666 }
donatien 0:8e01dca41002 667
donatien 0:8e01dca41002 668 #if LWIP_IGMP
donatien 0:8e01dca41002 669 /**
donatien 0:8e01dca41002 670 * Join multicast groups for UDP netconns.
donatien 0:8e01dca41002 671 *
donatien 0:8e01dca41002 672 * @param conn the UDP netconn for which to change multicast addresses
donatien 0:8e01dca41002 673 * @param multiaddr IP address of the multicast group to join or leave
donatien 0:8e01dca41002 674 * @param netif_addr the IP address of the network interface on which to send
donatien 0:8e01dca41002 675 * the igmp message
donatien 0:8e01dca41002 676 * @param join_or_leave flag whether to send a join- or leave-message
donatien 0:8e01dca41002 677 * @return ERR_OK if the action was taken, any err_t on error
donatien 0:8e01dca41002 678 */
donatien 0:8e01dca41002 679 err_t
donatien 0:8e01dca41002 680 netconn_join_leave_group(struct netconn *conn,
donatien 0:8e01dca41002 681 ip_addr_t *multiaddr,
donatien 0:8e01dca41002 682 ip_addr_t *netif_addr,
donatien 0:8e01dca41002 683 enum netconn_igmp join_or_leave)
donatien 0:8e01dca41002 684 {
donatien 0:8e01dca41002 685 struct api_msg msg;
donatien 0:8e01dca41002 686 err_t err;
donatien 0:8e01dca41002 687
donatien 0:8e01dca41002 688 LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 689
donatien 0:8e01dca41002 690 msg.function = do_join_leave_group;
donatien 0:8e01dca41002 691 msg.msg.conn = conn;
donatien 0:8e01dca41002 692 msg.msg.msg.jl.multiaddr = multiaddr;
donatien 0:8e01dca41002 693 msg.msg.msg.jl.netif_addr = netif_addr;
donatien 0:8e01dca41002 694 msg.msg.msg.jl.join_or_leave = join_or_leave;
donatien 0:8e01dca41002 695 err = TCPIP_APIMSG(&msg);
donatien 0:8e01dca41002 696
donatien 0:8e01dca41002 697 NETCONN_SET_SAFE_ERR(conn, err);
donatien 0:8e01dca41002 698 return err;
donatien 0:8e01dca41002 699 }
donatien 0:8e01dca41002 700 #endif /* LWIP_IGMP */
donatien 0:8e01dca41002 701
donatien 0:8e01dca41002 702 #if LWIP_DNS
donatien 0:8e01dca41002 703 /**
donatien 0:8e01dca41002 704 * Execute a DNS query, only one IP address is returned
donatien 0:8e01dca41002 705 *
donatien 0:8e01dca41002 706 * @param name a string representation of the DNS host name to query
donatien 0:8e01dca41002 707 * @param addr a preallocated ip_addr_t where to store the resolved IP address
donatien 0:8e01dca41002 708 * @return ERR_OK: resolving succeeded
donatien 0:8e01dca41002 709 * ERR_MEM: memory error, try again later
donatien 0:8e01dca41002 710 * ERR_ARG: dns client not initialized or invalid hostname
donatien 0:8e01dca41002 711 * ERR_VAL: dns server response was invalid
donatien 0:8e01dca41002 712 */
donatien 0:8e01dca41002 713 err_t
donatien 0:8e01dca41002 714 netconn_gethostbyname(const char *name, ip_addr_t *addr)
donatien 0:8e01dca41002 715 {
donatien 0:8e01dca41002 716 struct dns_api_msg msg;
donatien 0:8e01dca41002 717 err_t err;
donatien 0:8e01dca41002 718 sys_sem_t sem;
donatien 0:8e01dca41002 719
donatien 0:8e01dca41002 720 LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 721 LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
donatien 0:8e01dca41002 722
donatien 0:8e01dca41002 723 err = sys_sem_new(&sem, 0);
donatien 0:8e01dca41002 724 if (err != ERR_OK) {
donatien 0:8e01dca41002 725 return err;
donatien 0:8e01dca41002 726 }
donatien 0:8e01dca41002 727
donatien 0:8e01dca41002 728 msg.name = name;
donatien 0:8e01dca41002 729 msg.addr = addr;
donatien 0:8e01dca41002 730 msg.err = &err;
donatien 0:8e01dca41002 731 msg.sem = &sem;
donatien 0:8e01dca41002 732
donatien 0:8e01dca41002 733 tcpip_callback(do_gethostbyname, &msg);
donatien 0:8e01dca41002 734 sys_sem_wait(&sem);
donatien 0:8e01dca41002 735 sys_sem_free(&sem);
donatien 0:8e01dca41002 736
donatien 0:8e01dca41002 737 return err;
donatien 0:8e01dca41002 738 }
donatien 0:8e01dca41002 739 #endif /* LWIP_DNS*/
donatien 0:8e01dca41002 740
donatien 0:8e01dca41002 741 #endif /* LWIP_NETCONN */