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