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