Official mbed lwIP library (version 1.4.0)

Dependents:   LwIPNetworking NetServicesMin EthernetInterface EthernetInterface_RSF ... more

Legacy Networking Libraries

This is an mbed 2 networking library. For mbed OS 5, lwip has been integrated with built-in networking interfaces. The networking libraries have been revised to better support additional network stacks and thread safety here.

This library is based on the code of lwIP v1.4.0

Copyright (c) 2001, 2002 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:
mbed_official
Date:
Mon Mar 14 16:15:36 2016 +0000
Revision:
20:08f08bfc3f3d
Parent:
0:51ac1d130fd4
Synchronized with git revision fec574a5ed6db26aca1b13992ff271bf527d4a0d

Full URL: https://github.com/mbedmicro/mbed/commit/fec574a5ed6db26aca1b13992ff271bf527d4a0d/

Increased allocated netbufs to handle DTLS handshakes

Who changed what in which revision?

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