• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /**
3  * @file
4  * netconn API (to be used from non-TCPIP threads)
5  */
6 
7 /*
8  * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification,
12  * are permitted provided that the following conditions are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright notice,
15  *    this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright notice,
17  *    this list of conditions and the following disclaimer in the documentation
18  *    and/or other materials provided with the distribution.
19  * 3. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
23  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
27  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  *
33  * This file is part of the lwIP TCP/IP stack.
34  *
35  * Author: Adam Dunkels <adam@sics.se>
36  *
37  */
38 #ifndef LWIP_HDR_API_H
39 #define LWIP_HDR_API_H
40 
41 #include "lwip/opt.h"
42 
43 #if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */
44 /* Note: Netconn API is always available when sockets are enabled -
45  * sockets are implemented on top of them */
46 
47 #include "lwip/arch.h"
48 #include "lwip/netbuf.h"
49 #include "lwip/sys.h"
50 #include "lwip/ip_addr.h"
51 #include "lwip/netif.h"
52 #include "lwip/err.h"
53 #if LWIP_SOCK_FILTER
54 #include "lwip/filter.h"
55 #endif
56 
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60 
61 /* Throughout this file, IP addresses and port numbers are expected to be in
62  * the same byte order as in the corresponding pcb.
63  */
64 
65 /* Flags for netconn_write (u8_t) */
66 #define NETCONN_NOFLAG      0x00
67 #define NETCONN_NOCOPY      0x00 /* Only for source code compatibility */
68 #define NETCONN_COPY        0x01
69 #define NETCONN_MORE        0x02
70 #define NETCONN_DONTBLOCK   0x04
71 #define NETCONN_NOAUTORCVD  0x08 /* prevent netconn_recv_data_tcp() from updating the tcp window - must be done manually via netconn_tcp_recvd() */
72 #define NETCONN_NOFIN       0x10 /* upper layer already received data, leave FIN in queue until called again */
73 
74 /* Flags for struct netconn.flags (u8_t) */
75 /** This netconn had an error, don't block on recvmbox/acceptmbox any more */
76 #define NETCONN_FLAG_MBOXCLOSED               0x01
77 /** Should this netconn avoid blocking? */
78 #define NETCONN_FLAG_NON_BLOCKING             0x02
79 /** Was the last connect action a non-blocking one? */
80 #define NETCONN_FLAG_IN_NONBLOCKING_CONNECT   0x04
81 #if LWIP_NETCONN_FULLDUPLEX
82   /** The mbox of this netconn is being deallocated, don't use it anymore */
83 #define NETCONN_FLAG_MBOXINVALID              0x08
84 #endif /* LWIP_NETCONN_FULLDUPLEX */
85 /** If a nonblocking write has been rejected before, poll_tcp needs to
86     check if the netconn is writable again */
87 #define NETCONN_FLAG_CHECK_WRITESPACE         0x10
88 #if LWIP_IPV6
89 /** If this flag is set then only IPv6 communication is allowed on the
90     netconn. As per RFC#3493 this features defaults to OFF allowing
91     dual-stack usage by default. */
92 #define NETCONN_FLAG_IPV6_V6ONLY              0x20
93 #endif /* LWIP_IPV6 */
94 #if LWIP_NETBUF_RECVINFO
95 /** Received packet info will be recorded for this netconn */
96 #define NETCONN_FLAG_PKTINFO                  0x40
97 #endif /* LWIP_NETBUF_RECVINFO */
98 /** A FIN has been received but not passed to the application yet */
99 #define NETCONN_FIN_RX_PENDING                0x80
100 
101 /* Helpers to process several netconn_types by the same code */
102 #define NETCONNTYPE_GROUP(t)         ((t)&0xF0)
103 #define NETCONNTYPE_DATAGRAM(t)      ((t)&0xE0)
104 #if LWIP_IPV6
105 #define NETCONN_TYPE_IPV6            0x08
106 #define NETCONNTYPE_ISIPV6(t)        (((t)&NETCONN_TYPE_IPV6) != 0)
107 #define NETCONNTYPE_ISUDPLITE(t)     (((t)&0xF3) == NETCONN_UDPLITE)
108 #define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM)
109 #else /* LWIP_IPV6 */
110 #define NETCONNTYPE_ISIPV6(t)        (0)
111 #define NETCONNTYPE_ISUDPLITE(t)     ((t) == NETCONN_UDPLITE)
112 #define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM)
113 #endif /* LWIP_IPV6 */
114 
115 /** @ingroup netconn_common
116  * Protocol family and type of the netconn
117  */
118 enum netconn_type {
119   NETCONN_INVALID     = 0,
120   /** TCP IPv4 */
121   NETCONN_TCP         = 0x10,
122 #if LWIP_IPV6
123   /** TCP IPv6 */
124   NETCONN_TCP_IPV6    = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */,
125 #endif /* LWIP_IPV6 */
126   /** UDP IPv4 */
127   NETCONN_UDP         = 0x20,
128   /** UDP IPv4 lite */
129   NETCONN_UDPLITE     = 0x21,
130   /** UDP IPv4 no checksum */
131   NETCONN_UDPNOCHKSUM = 0x22,
132 
133 #if LWIP_IPV6
134   /** UDP IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
135   NETCONN_UDP_IPV6         = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */,
136   /** UDP IPv6 lite (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
137   NETCONN_UDPLITE_IPV6     = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */,
138   /** UDP IPv6 no checksum (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
139   NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */,
140 #endif /* LWIP_IPV6 */
141 
142   /** Raw connection IPv4 */
143   NETCONN_RAW         = 0x40
144 #if LWIP_IPV6
145   /** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */
146   , NETCONN_RAW_IPV6    = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */
147 #endif /* LWIP_IPV6 */
148 #if PF_PKT_SUPPORT
149   , NETCONN_PKT_RAW    = 0x80
150 #endif
151   , NETCONN_TYPE_LAST = 0xFFFFFFFF
152 };
153 
154 /** Current state of the netconn. Non-TCP netconns are always
155  * in state NETCONN_NONE! */
156 enum netconn_state {
157   NETCONN_NONE,
158   NETCONN_WRITE,
159   NETCONN_LISTEN,
160   NETCONN_CONNECT,
161   NETCONN_CLOSE,
162   NETCONN_CLOSED,
163   NETCONN_STATE_LAST = 0xFFFFFFFF
164 };
165 
166 /** Used to inform the callback function about changes
167  *
168  * Event explanation:
169  *
170  * In the netconn implementation, there are three ways to block a client:
171  *
172  * - accept mbox (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); in netconn_accept())
173  * - receive mbox (sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); in netconn_recv_data())
174  * - send queue is full (sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); in lwip_netconn_do_write())
175  *
176  * The events have to be seen as events signaling the state of these mboxes/semaphores. For non-blocking
177  * connections, you need to know in advance whether a call to a netconn function call would block or not,
178  * and these events tell you about that.
179  *
180  * RCVPLUS events say: Safe to perform a potentially blocking call call once more.
181  * They are counted in sockets - three RCVPLUS events for accept mbox means you are safe
182  * to call netconn_accept 3 times without being blocked.
183  * Same thing for receive mbox.
184  *
185  * RCVMINUS events say: Your call to to a possibly blocking function is "acknowledged".
186  * Socket implementation decrements the counter.
187  *
188  * For TX, there is no need to count, its merely a flag. SENDPLUS means you may send something.
189  * SENDPLUS occurs when enough data was delivered to peer so netconn_send() can be called again.
190  * A SENDMINUS event occurs when the next call to a netconn_send() would be blocking.
191  */
192 enum netconn_evt {
193   NETCONN_EVT_RCVPLUS,
194   NETCONN_EVT_RCVMINUS,
195   NETCONN_EVT_SENDPLUS,
196   NETCONN_EVT_SENDMINUS,
197   NETCONN_EVT_ERROR
198 };
199 
200 #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
201 /* Used for netconn_leave_group() and  netconn_leave_group_netif */
202 enum netconn_igmp {
203   NETCONN_JOIN,
204   NETCONN_LEAVE
205 };
206 #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
207 
208 enum netconn_shutdown {
209   NON_SHUTDOWN = 0,
210   RCV_SHUTDOWN,
211   SND_SHUTDOWN,
212   SHUTDOWN_MASK,
213   NCS_LAST_FLAG = 0xFFFFFFFF
214 };
215 
216 #if LWIP_DNS
217 /* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */
218 #if LWIP_IPV4 && LWIP_IPV6
219 #ifndef NETCONN_DNS_DEFAULT
220 #define NETCONN_DNS_DEFAULT   NETCONN_DNS_IPV4_IPV6
221 #endif /* NETCONN_DNS_DEFAULT */
222 #elif LWIP_IPV4
223 #define NETCONN_DNS_DEFAULT   NETCONN_DNS_IPV4
224 #else
225 #define NETCONN_DNS_DEFAULT   NETCONN_DNS_IPV6
226 #endif /* LWIP_IPV4 && LWIP_IPV6 */
227 
228 #define NETCONN_DNS_IPV4      0
229 #define NETCONN_DNS_IPV6      1
230 #define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */
231 #define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */
232 #endif /* LWIP_DNS */
233 
234 /* forward-declare some structs to avoid to include their headers */
235 struct ip_pcb;
236 struct tcp_pcb;
237 struct udp_pcb;
238 struct raw_pcb;
239 struct netconn;
240 struct api_msg;
241 
242 /** A callback prototype to inform about events for a netconn */
243 typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len);
244 
245 /** A netconn descriptor */
246 struct netconn {
247   /** type of the netconn (TCP, UDP or RAW) */
248   enum netconn_type type;
249   /** current state of the netconn */
250   enum netconn_state state;
251   /** the lwIP internal protocol control block */
252   union {
253     struct ip_pcb  *ip;
254     struct tcp_pcb *tcp;
255     struct udp_pcb *udp;
256     struct raw_pcb *raw;
257 #if PF_PKT_SUPPORT
258     struct raw_pcb *pkt_raw;
259 #endif
260   } pcb;
261 
262 #define net_tcp_pcb pcb.tcp
263 #define net_tcp_state pcb.tcp->state
264 #define net_udp_pcb pcb.udp
265 #define net_raw_pcb pcb.raw
266 #define net_ip_pcb pcb.ip
267 
268   /** the last asynchronous unreported error this netconn had */
269   err_t last_err;
270 #if !LWIP_NETCONN_SEM_PER_THREAD
271   /** sem that is used to synchronously execute functions in the core context */
272   sys_sem_t op_completed;
273 #endif
274   /** mbox where received packets are stored until they are fetched
275       by the netconn application thread (can grow quite big) */
276   sys_mbox_t recvmbox;
277 #if LWIP_TCP
278   /** mbox where new connections are stored until processed
279       by the application thread */
280   sys_mbox_t acceptmbox;
281 #endif /* LWIP_TCP */
282 #if LWIP_NETCONN_FULLDUPLEX
283   /** number of threads waiting on an mbox. This is required to unblock
284       all threads when closing while threads are waiting. */
285   int mbox_threads_waiting;
286 #endif
287   /** only used for socket layer */
288 #if LWIP_SOCKET
289   int socket;
290 #endif /* LWIP_SOCKET */
291 #if LWIP_SO_SNDTIMEO
292   /** timeout to wait for sending data (which means enqueueing data for sending
293       in internal buffers) in milliseconds */
294   s32_t send_timeout;
295 #endif /* LWIP_SO_RCVTIMEO */
296 #if LWIP_SO_RCVTIMEO
297   /** timeout in milliseconds to wait for new data to be received
298       (or connections to arrive for listening netconns) */
299   u32_t recv_timeout;
300 #endif /* LWIP_SO_RCVTIMEO */
301 #if LWIP_SO_RCVBUF
302   /** maximum amount of bytes queued in recvmbox
303       not used for TCP: adjust TCP_WND instead! */
304   int recv_bufsize;
305   /** number of bytes currently in recvmbox to be received,
306       tested against recv_bufsize to limit bytes on recvmbox
307       for UDP and RAW, used for FIONREAD */
308   int recv_avail;
309 #endif /* LWIP_SO_RCVBUF */
310   /** number of bytes left on last recv, for non-stream connections, this value was the buffer_len
311       on last peek operation; for stream connection, this value was either the bytes count
312       not copied to application on last recv or the buffer_len on last peek operation */
313   u32_t lrcv_left;
314 #if LWIP_SO_LINGER
315    /** values <0 mean linger is disabled, values > 0 are seconds to linger */
316   s16_t linger;
317 #endif /* LWIP_SO_LINGER */
318   /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */
319   u8_t flags;
320 #if LWIP_TCP
321   /* TCP: when data passed to netconn_write doesn't fit into the send buffer,
322       this temporarily stores how much is already sent. */
323   size_t write_offset;
324   /** TCP: when data passed to netconn_write doesn't fit into the send buffer,
325       this temporarily stores the message.
326       Also used during connect and close. */
327   struct api_msg *current_msg;
328 
329 #if LWIP_SO_PRIORITY
330   prio_t priority;
331 #endif /* LWIP_SO_PRIORITY */
332 
333   atomic_t tcp_connected;
334 #endif /* LWIP_TCP */
335   /** A callback function that is informed about events for this netconn */
336   netconn_callback callback;
337   enum netconn_shutdown shutdown;
338 #if LWIP_SOCK_FILTER
339   struct sock_fprog sk_filter;
340 #endif
341 
342 #if LWIP_TCP
343   struct pbuf *refused_data;
344   ip_addr_t remote_ip;
345   u16_t remote_port;
346   /** record pending error state after recving RST */
347   u16_t pending_err;
348 #endif
349 };
350 
351 /** This vector type is passed to @ref netconn_write_vectors_partly to send
352  * multiple buffers at once.
353  * ATTENTION: This type has to directly map struct iovec since one is casted
354  *            into the other!
355  */
356 struct netvector {
357   /** pointer to the application buffer that contains the data to send */
358   const void *ptr;
359   /** size of the application data to send */
360   size_t len;
361 };
362 
363 /** Register an Network connection event */
364 #define API_EVENT(c,e,l) if (c->callback) {         \
365                            (*c->callback)(c, e, l); \
366                          }
367 
368 #define NETCONN_SET_SAFE_ERR_VAL(conn, err) do { \
369   SYS_ARCH_DECL_PROTECT(netconn_set_safe_err_lev); \
370   SYS_ARCH_PROTECT(netconn_set_safe_err_lev); \
371   if (!ERR_IS_FATAL((conn)->last_err)) { \
372     (conn)->last_err = err; \
373   } \
374   SYS_ARCH_UNPROTECT(netconn_set_safe_err_lev); \
375 } while (0)
376 
377 /* Set conn->last_err to err but don't overwrite fatal errors */
378 #define NETCONN_SET_SAFE_ERR(conn, err) do { if ((conn) != NULL) { \
379     NETCONN_SET_SAFE_ERR_VAL(conn, err); \
380 }} while (0)
381 
382 /* Network connection functions: */
383 
384 /** @ingroup netconn_common
385  * Create new netconn connection
386  * @param t @ref netconn_type */
387 #define netconn_new(t)                  netconn_new_with_proto_and_callback(t, 0, NULL)
388 #define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c)
389 struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u16_t proto,
390                                              netconn_callback callback);
391 
392 void
393 netconn_finish_delete(struct netconn *conn);
394 
395 err_t netconn_getconninfo(struct netconn *conn, void *conn_info);
396 err_t   netconn_prepare_delete(struct netconn *conn);
397 err_t   netconn_delete(struct netconn *conn);
398 /** Get the type of a netconn (as enum netconn_type). */
399 #define NETCONN_TYPE(conn) ((u32_t)(conn->type))
400 
401 err_t   netconn_getaddr(struct netconn *conn, ip_addr_t *addr,
402                         u16_t *port, u8_t local);
403 #if PF_PKT_SUPPORT
404 struct pf_pkt_ll {
405   u16_t sll_protocol;
406   u16_t sll_hatype;
407   u8_t if_idx;
408   u8_t sll_halen;
409   u8_t sll_addr[NETIF_MAX_HWADDR_LEN];
410 };
411 
412 err_t netconn_getaddr_pfpkt(struct netconn *conn, struct pf_pkt_ll *ll, u8_t local);
413 #endif
414 /** @ingroup netconn_common */
415 #define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0)
416 /** @ingroup netconn_common */
417 #define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1)
418 
419 #if PF_PKT_SUPPORT
420 err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port, u8_t ifindex);
421 #else
422 err_t   netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port);
423 #endif
424 
425 err_t   netconn_bind_if(struct netconn *conn, u8_t if_idx);
426 err_t   netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port);
427 err_t   netconn_disconnect (struct netconn *conn);
428 err_t   netconn_listen_with_backlog(struct netconn *conn, u8_t backlog);
429 /** @ingroup netconn_tcp */
430 #define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG)
431 err_t   netconn_accept(struct netconn *conn, struct netconn **new_conn);
432 err_t   netconn_recv(struct netconn *conn, struct netbuf **new_buf);
433 err_t   netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf);
434 err_t   netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags);
435 err_t   netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf);
436 err_t   netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags);
437 err_t   netconn_tcp_recvd(struct netconn *conn, size_t len);
438 err_t   netconn_sendto(struct netconn *conn, struct netbuf *buf,
439                              const ip_addr_t *addr, u16_t port);
440 err_t   netconn_send(struct netconn *conn, struct netbuf *buf);
441 err_t   netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
442                              u8_t apiflags, size_t *bytes_written);
443 err_t   netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
444                                      u8_t apiflags, size_t *bytes_written);
445 /** @ingroup netconn_tcp */
446 #define netconn_write(conn, dataptr, size, apiflags) \
447           netconn_write_partly(conn, dataptr, size, apiflags, NULL)
448 err_t   netconn_close(struct netconn *conn);
449 err_t   netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx);
450 
451 #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
452 /* Internal function */
453 err_t   netconn_leave_group(struct netconn *conn, const ip_addr_t *multiaddr,
454                              const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave);
455 /* Stack needs to support to leave group for ipv6 multicast */
456 err_t   netconn_leave_group_netif(struct netconn *conn, const ip_addr_t *multiaddr,
457                              u8_t if_idx, enum netconn_igmp join_or_leave);
458 #endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
459 #if LWIP_DNS
460 #if LWIP_IPV4 && LWIP_IPV6
461 err_t   netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u32_t *count, u8_t dns_addrtype);
462 #define netconn_gethostbyname(name, addr, count) netconn_gethostbyname_addrtype(name, addr, count, NETCONN_DNS_DEFAULT)
463 #else /* LWIP_IPV4 && LWIP_IPV6 */
464 err_t   netconn_gethostbyname(const char *name, ip_addr_t *addr, u32_t *count);
465 #define netconn_gethostbyname_addrtype(name, addr, count, dns_addrtype) netconn_gethostbyname(name, addr, count)
466 #endif /* LWIP_IPV4 && LWIP_IPV6 */
467 #if LWIP_DNS_REVERSE
468 err_t netconn_getnameinfo(ip_addr_t *addr, char *hostname);
469 #endif /* LWIP_DNS_REVERSE */
470 #endif /* LWIP_DNS */
471 
472 err_t   netconn_err(struct netconn *conn);
473 #define netconn_recv_bufsize(conn)      ((conn)->recv_bufsize)
474 
475 #define netconn_set_flags(conn, set_flags)     do { (conn)->flags = (u8_t)((conn)->flags |  (set_flags)); } while(0)
476 #define netconn_clear_flags(conn, clr_flags)   do { (conn)->flags = (u8_t)((conn)->flags & (u8_t)(~(clr_flags) & 0xff)); } while(0)
477 #define netconn_is_flag_set(conn, flag)        (((conn)->flags & (flag)) != 0)
478 
479 /** Set the blocking status of netconn calls (@todo: write/send is missing) */
480 #define netconn_set_nonblocking(conn, val)  do { if(val) { \
481   netconn_set_flags(conn, NETCONN_FLAG_NON_BLOCKING); \
482 } else { \
483   netconn_clear_flags(conn, NETCONN_FLAG_NON_BLOCKING); }} while(0)
484 /** Get the blocking status of netconn calls (@todo: write/send is missing) */
485 #define netconn_is_nonblocking(conn)        (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0)
486 
487 #if LWIP_IPV6
488 /** @ingroup netconn_common
489  * TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
490  */
491 #define netconn_set_ipv6only(conn, val)  do { if(val) { \
492   netconn_set_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); \
493 } else { \
494   netconn_clear_flags(conn, NETCONN_FLAG_IPV6_V6ONLY); }} while(0)
495 /** @ingroup netconn_common
496  * TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY)
497  */
498 #define netconn_get_ipv6only(conn)        (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0)
499 #endif /* LWIP_IPV6 */
500 
501 #if LWIP_SO_SNDTIMEO
502 /** Set the send timeout in milliseconds */
503 #define netconn_set_sendtimeout(conn, timeout)      ((conn)->send_timeout = (timeout))
504 /** Get the send timeout in milliseconds */
505 #define netconn_get_sendtimeout(conn)               ((conn)->send_timeout)
506 #endif /* LWIP_SO_SNDTIMEO */
507 #if LWIP_SO_RCVTIMEO
508 /** Set the receive timeout in milliseconds */
509 #define netconn_set_recvtimeout(conn, timeout)      ((conn)->recv_timeout = (timeout))
510 /** Get the receive timeout in milliseconds */
511 #define netconn_get_recvtimeout(conn)               ((conn)->recv_timeout)
512 #endif /* LWIP_SO_RCVTIMEO */
513 #if LWIP_SO_RCVBUF
514 /** Set the receive buffer in bytes */
515 #define netconn_set_recvbufsize(conn, recvbufsize)  ((conn)->recv_bufsize = (recvbufsize))
516 /** Get the receive buffer in bytes */
517 #define netconn_get_recvbufsize(conn)               ((conn)->recv_bufsize)
518 #endif /* LWIP_SO_RCVBUF*/
519 
520 #if LWIP_NETCONN_SEM_PER_THREAD
521 void netconn_thread_init(void);
522 void netconn_thread_cleanup(void);
523 #else /* LWIP_NETCONN_SEM_PER_THREAD */
524 #define netconn_thread_init()
525 #define netconn_thread_cleanup()
526 #endif /* LWIP_NETCONN_SEM_PER_THREAD */
527 
528 #ifdef __cplusplus
529 }
530 #endif
531 
532 #endif /* LWIP_NETCONN || LWIP_SOCKET */
533 
534 #endif /* LWIP_HDR_API_H */
535