ReactOS 0.4.16-dev-959-g2ec3a19
api_lib.c
Go to the documentation of this file.
1
24/*
25 * Copyright (c) 2001-2004 Swedish Institute of Computer Science.
26 * All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without modification,
29 * are permitted provided that the following conditions are met:
30 *
31 * 1. Redistributions of source code must retain the above copyright notice,
32 * this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright notice,
34 * this list of conditions and the following disclaimer in the documentation
35 * and/or other materials provided with the distribution.
36 * 3. The name of the author may not be used to endorse or promote products
37 * derived from this software without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
40 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
41 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
42 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
43 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
44 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
45 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
46 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
47 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
48 * OF SUCH DAMAGE.
49 *
50 * This file is part of the lwIP TCP/IP stack.
51 *
52 * Author: Adam Dunkels <adam@sics.se>
53 */
54
55/* This is the part of the API that is linked with
56 the application */
57
58#include "lwip/opt.h"
59
60#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */
61
62#include "lwip/api.h"
63#include "lwip/memp.h"
64
65#include "lwip/ip.h"
66#include "lwip/raw.h"
67#include "lwip/udp.h"
68#include "lwip/priv/api_msg.h"
69#include "lwip/priv/tcp_priv.h"
71
72#ifdef LWIP_HOOK_FILENAME
73#include LWIP_HOOK_FILENAME
74#endif
75
76#include <string.h>
77
78#define API_MSG_VAR_REF(name) API_VAR_REF(name)
79#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name)
80#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM)
81#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL)
82#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name)
83
84#if TCP_LISTEN_BACKLOG
85/* need to allocate API message for accept so empty message pool does not result in event loss
86 * see bug #47512: MPU_COMPATIBLE may fail on empty pool */
87#define API_MSG_VAR_ALLOC_ACCEPT(msg) API_MSG_VAR_ALLOC(msg)
88#define API_MSG_VAR_FREE_ACCEPT(msg) API_MSG_VAR_FREE(msg)
89#else /* TCP_LISTEN_BACKLOG */
90#define API_MSG_VAR_ALLOC_ACCEPT(msg)
91#define API_MSG_VAR_FREE_ACCEPT(msg)
92#endif /* TCP_LISTEN_BACKLOG */
93
94#if LWIP_NETCONN_FULLDUPLEX
95#define NETCONN_RECVMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->recvmbox) && (((conn)->flags & NETCONN_FLAG_MBOXINVALID) == 0))
96#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & (NETCONN_FLAG_MBOXCLOSED|NETCONN_FLAG_MBOXINVALID)) == 0))
97#define NETCONN_MBOX_WAITING_INC(conn) SYS_ARCH_INC(conn->mbox_threads_waiting, 1)
98#define NETCONN_MBOX_WAITING_DEC(conn) SYS_ARCH_DEC(conn->mbox_threads_waiting, 1)
99#else /* LWIP_NETCONN_FULLDUPLEX */
100#define NETCONN_RECVMBOX_WAITABLE(conn) sys_mbox_valid(&(conn)->recvmbox)
101#define NETCONN_ACCEPTMBOX_WAITABLE(conn) (sys_mbox_valid(&(conn)->acceptmbox) && (((conn)->flags & NETCONN_FLAG_MBOXCLOSED) == 0))
102#define NETCONN_MBOX_WAITING_INC(conn)
103#define NETCONN_MBOX_WAITING_DEC(conn)
104#endif /* LWIP_NETCONN_FULLDUPLEX */
105
106static err_t netconn_close_shutdown(struct netconn *conn, u8_t how);
107
117static err_t
118netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg)
119{
120 err_t err;
121
122#ifdef LWIP_DEBUG
123 /* catch functions that don't set err */
124 apimsg->err = ERR_VAL;
125#endif /* LWIP_DEBUG */
126
127#if LWIP_NETCONN_SEM_PER_THREAD
128 apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET();
129#endif /* LWIP_NETCONN_SEM_PER_THREAD */
130
131 err = tcpip_send_msg_wait_sem(fn, apimsg, LWIP_API_MSG_SEM(apimsg));
132 if (err == ERR_OK) {
133 return apimsg->err;
134 }
135 return err;
136}
137
148struct netconn *
149netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback)
150{
151 struct netconn *conn;
152 API_MSG_VAR_DECLARE(msg);
153 API_MSG_VAR_ALLOC_RETURN_NULL(msg);
154
155 conn = netconn_alloc(t, callback);
156 if (conn != NULL) {
157 err_t err;
158
159 API_MSG_VAR_REF(msg).msg.n.proto = proto;
160 API_MSG_VAR_REF(msg).conn = conn;
161 err = netconn_apimsg(lwip_netconn_do_newconn, &API_MSG_VAR_REF(msg));
162 if (err != ERR_OK) {
163 LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
164 LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
165#if LWIP_TCP
166 LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
167#endif /* LWIP_TCP */
168#if !LWIP_NETCONN_SEM_PER_THREAD
169 LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
170 sys_sem_free(&conn->op_completed);
171#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
172 sys_mbox_free(&conn->recvmbox);
173 memp_free(MEMP_NETCONN, conn);
174 API_MSG_VAR_FREE(msg);
175 return NULL;
176 }
177 }
178 API_MSG_VAR_FREE(msg);
179 return conn;
180}
181
191err_t
192netconn_prepare_delete(struct netconn *conn)
193{
194 err_t err;
195 API_MSG_VAR_DECLARE(msg);
196
197 /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
198 if (conn == NULL) {
199 return ERR_OK;
200 }
201
202 API_MSG_VAR_ALLOC(msg);
203 API_MSG_VAR_REF(msg).conn = conn;
204#if LWIP_TCP
205#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
206 /* get the time we started, which is later compared to
207 sys_now() + conn->send_timeout */
208 API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
209#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
210 API_MSG_VAR_REF(msg).msg.sd.polls_left =
211 ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
212#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
213#endif /* LWIP_TCP */
214 err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg));
215 API_MSG_VAR_FREE(msg);
216
217 if (err != ERR_OK) {
218 return err;
219 }
220 return ERR_OK;
221}
222
232err_t
233netconn_delete(struct netconn *conn)
234{
235 err_t err;
236
237 /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */
238 if (conn == NULL) {
239 return ERR_OK;
240 }
241
242#if LWIP_NETCONN_FULLDUPLEX
243 if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
244 /* Already called netconn_prepare_delete() before */
245 err = ERR_OK;
246 } else
247#endif /* LWIP_NETCONN_FULLDUPLEX */
248 {
249 err = netconn_prepare_delete(conn);
250 }
251 if (err == ERR_OK) {
252 netconn_free(conn);
253 }
254 return err;
255}
256
268err_t
269netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local)
270{
271 API_MSG_VAR_DECLARE(msg);
272 err_t err;
273
274 LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;);
275 LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;);
276 LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;);
277
278 API_MSG_VAR_ALLOC(msg);
279 API_MSG_VAR_REF(msg).conn = conn;
280 API_MSG_VAR_REF(msg).msg.ad.local = local;
281#if LWIP_MPU_COMPATIBLE
282 err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg));
283 *addr = msg->msg.ad.ipaddr;
284 *port = msg->msg.ad.port;
285#else /* LWIP_MPU_COMPATIBLE */
286 msg.msg.ad.ipaddr = addr;
287 msg.msg.ad.port = port;
288 err = netconn_apimsg(lwip_netconn_do_getaddr, &msg);
289#endif /* LWIP_MPU_COMPATIBLE */
290 API_MSG_VAR_FREE(msg);
291
292 return err;
293}
294
306err_t
307netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port)
308{
309 API_MSG_VAR_DECLARE(msg);
310 err_t err;
311
312 LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;);
313
314#if LWIP_IPV4
315 /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
316 if (addr == NULL) {
317 addr = IP4_ADDR_ANY;
318 }
319#endif /* LWIP_IPV4 */
320
321#if LWIP_IPV4 && LWIP_IPV6
322 /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY,
323 * and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind
324 */
325 if ((netconn_get_ipv6only(conn) == 0) &&
326 ip_addr_eq(addr, IP6_ADDR_ANY)) {
328 }
329#endif /* LWIP_IPV4 && LWIP_IPV6 */
330
331 API_MSG_VAR_ALLOC(msg);
332 API_MSG_VAR_REF(msg).conn = conn;
333 API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
334 API_MSG_VAR_REF(msg).msg.bc.port = port;
335 err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg));
336 API_MSG_VAR_FREE(msg);
337
338 return err;
339}
340
350err_t
351netconn_bind_if(struct netconn *conn, u8_t if_idx)
352{
353 API_MSG_VAR_DECLARE(msg);
354 err_t err;
355
356 LWIP_ERROR("netconn_bind_if: invalid conn", (conn != NULL), return ERR_ARG;);
357
358 API_MSG_VAR_ALLOC(msg);
359 API_MSG_VAR_REF(msg).conn = conn;
360 API_MSG_VAR_REF(msg).msg.bc.if_idx = if_idx;
361 err = netconn_apimsg(lwip_netconn_do_bind_if, &API_MSG_VAR_REF(msg));
362 API_MSG_VAR_FREE(msg);
363
364 return err;
365}
366
376err_t
377netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
378{
379 API_MSG_VAR_DECLARE(msg);
380 err_t err;
381
382 LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;);
383
384#if LWIP_IPV4
385 /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
386 if (addr == NULL) {
387 addr = IP4_ADDR_ANY;
388 }
389#endif /* LWIP_IPV4 */
390
391 API_MSG_VAR_ALLOC(msg);
392 API_MSG_VAR_REF(msg).conn = conn;
393 API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr);
394 API_MSG_VAR_REF(msg).msg.bc.port = port;
395 err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg));
396 API_MSG_VAR_FREE(msg);
397
398 return err;
399}
400
408err_t
409netconn_disconnect(struct netconn *conn)
410{
411 API_MSG_VAR_DECLARE(msg);
412 err_t err;
413
414 LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;);
415
416 API_MSG_VAR_ALLOC(msg);
417 API_MSG_VAR_REF(msg).conn = conn;
418 err = netconn_apimsg(lwip_netconn_do_disconnect, &API_MSG_VAR_REF(msg));
419 API_MSG_VAR_FREE(msg);
420
421 return err;
422}
423
433err_t
434netconn_listen_with_backlog(struct netconn *conn, u8_t backlog)
435{
436#if LWIP_TCP
437 API_MSG_VAR_DECLARE(msg);
438 err_t err;
439
440 /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */
441 LWIP_UNUSED_ARG(backlog);
442
443 LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;);
444
445 API_MSG_VAR_ALLOC(msg);
446 API_MSG_VAR_REF(msg).conn = conn;
447#if TCP_LISTEN_BACKLOG
448 API_MSG_VAR_REF(msg).msg.lb.backlog = backlog;
449#endif /* TCP_LISTEN_BACKLOG */
450 err = netconn_apimsg(lwip_netconn_do_listen, &API_MSG_VAR_REF(msg));
451 API_MSG_VAR_FREE(msg);
452
453 return err;
454#else /* LWIP_TCP */
455 LWIP_UNUSED_ARG(conn);
456 LWIP_UNUSED_ARG(backlog);
457 return ERR_ARG;
458#endif /* LWIP_TCP */
459}
460
470err_t
471netconn_accept(struct netconn *conn, struct netconn **new_conn)
472{
473#if LWIP_TCP
474 err_t err;
475 void *accept_ptr;
476 struct netconn *newconn;
477#if TCP_LISTEN_BACKLOG
478 API_MSG_VAR_DECLARE(msg);
479#endif /* TCP_LISTEN_BACKLOG */
480
481 LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
482 *new_conn = NULL;
483 LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
484
485 /* NOTE: Although the opengroup spec says a pending error shall be returned to
486 send/recv/getsockopt(SO_ERROR) only, we return it for listening
487 connections also, to handle embedded-system errors */
488 err = netconn_err(conn);
489 if (err != ERR_OK) {
490 /* return pending error */
491 return err;
492 }
493 if (!NETCONN_ACCEPTMBOX_WAITABLE(conn)) {
494 /* don't accept if closed: this might block the application task
495 waiting on acceptmbox forever! */
496 return ERR_CLSD;
497 }
498
499 API_MSG_VAR_ALLOC_ACCEPT(msg);
500
501 NETCONN_MBOX_WAITING_INC(conn);
502 if (netconn_is_nonblocking(conn)) {
503 if (sys_arch_mbox_tryfetch(&conn->acceptmbox, &accept_ptr) == SYS_MBOX_EMPTY) {
504 API_MSG_VAR_FREE_ACCEPT(msg);
505 NETCONN_MBOX_WAITING_DEC(conn);
506 return ERR_WOULDBLOCK;
507 }
508 } else {
509#if LWIP_SO_RCVTIMEO
510 if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
511 API_MSG_VAR_FREE_ACCEPT(msg);
512 NETCONN_MBOX_WAITING_DEC(conn);
513 return ERR_TIMEOUT;
514 }
515#else
516 sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);
517#endif /* LWIP_SO_RCVTIMEO*/
518 }
519 NETCONN_MBOX_WAITING_DEC(conn);
520#if LWIP_NETCONN_FULLDUPLEX
521 if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
522 if (lwip_netconn_is_deallocated_msg(accept_ptr)) {
523 /* the netconn has been closed from another thread */
524 API_MSG_VAR_FREE_ACCEPT(msg);
525 return ERR_CONN;
526 }
527 }
528#endif
529
530 /* Register event with callback */
531 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
532
533 if (lwip_netconn_is_err_msg(accept_ptr, &err)) {
534 /* a connection has been aborted: e.g. out of pcbs or out of netconns during accept */
535 API_MSG_VAR_FREE_ACCEPT(msg);
536 return err;
537 }
538 if (accept_ptr == NULL) {
539 /* connection has been aborted */
540 API_MSG_VAR_FREE_ACCEPT(msg);
541 return ERR_CLSD;
542 }
543 newconn = (struct netconn *)accept_ptr;
544#if TCP_LISTEN_BACKLOG
545 /* Let the stack know that we have accepted the connection. */
546 API_MSG_VAR_REF(msg).conn = newconn;
547 /* don't care for the return value of lwip_netconn_do_recv */
548 netconn_apimsg(lwip_netconn_do_accepted, &API_MSG_VAR_REF(msg));
549 API_MSG_VAR_FREE(msg);
550#endif /* TCP_LISTEN_BACKLOG */
551
552 *new_conn = newconn;
553 /* don't set conn->last_err: it's only ERR_OK, anyway */
554 return ERR_OK;
555#else /* LWIP_TCP */
556 LWIP_UNUSED_ARG(conn);
557 LWIP_UNUSED_ARG(new_conn);
558 return ERR_ARG;
559#endif /* LWIP_TCP */
560}
561
578static err_t
579netconn_recv_data(struct netconn *conn, void **new_buf, u8_t apiflags)
580{
581 void *buf = NULL;
582 u16_t len;
583
584 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
585 *new_buf = NULL;
586 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
587
588 if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
589 err_t err = netconn_err(conn);
590 if (err != ERR_OK) {
591 /* return pending error */
592 return err;
593 }
594 return ERR_CONN;
595 }
596
597 NETCONN_MBOX_WAITING_INC(conn);
598 if (netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK) ||
599 (conn->flags & NETCONN_FLAG_MBOXCLOSED) || (conn->pending_err != ERR_OK)) {
600 if (sys_arch_mbox_tryfetch(&conn->recvmbox, &buf) == SYS_MBOX_EMPTY) {
601 err_t err;
602 NETCONN_MBOX_WAITING_DEC(conn);
603 err = netconn_err(conn);
604 if (err != ERR_OK) {
605 /* return pending error */
606 return err;
607 }
608 if (conn->flags & NETCONN_FLAG_MBOXCLOSED) {
609 return ERR_CONN;
610 }
611 return ERR_WOULDBLOCK;
612 }
613 } else {
614#if LWIP_SO_RCVTIMEO
615 if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
616 NETCONN_MBOX_WAITING_DEC(conn);
617 return ERR_TIMEOUT;
618 }
619#else
620 sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0);
621#endif /* LWIP_SO_RCVTIMEO*/
622 }
623 NETCONN_MBOX_WAITING_DEC(conn);
624#if LWIP_NETCONN_FULLDUPLEX
625 if (conn->flags & NETCONN_FLAG_MBOXINVALID) {
626 if (lwip_netconn_is_deallocated_msg(buf)) {
627 /* the netconn has been closed from another thread */
628 API_MSG_VAR_FREE_ACCEPT(msg);
629 return ERR_CONN;
630 }
631 }
632#endif
633
634#if LWIP_TCP
635#if (LWIP_UDP || LWIP_RAW)
636 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
637#endif /* (LWIP_UDP || LWIP_RAW) */
638 {
639 err_t err;
640 /* Check if this is an error message or a pbuf */
641 if (lwip_netconn_is_err_msg(buf, &err)) {
642 /* new_buf has been zeroed above already */
643 if (err == ERR_CLSD) {
644 /* connection closed translates to ERR_OK with *new_buf == NULL */
645 return ERR_OK;
646 }
647 return err;
648 }
649 len = ((struct pbuf *)buf)->tot_len;
650 }
651#endif /* LWIP_TCP */
652#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
653 else
654#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
655#if (LWIP_UDP || LWIP_RAW)
656 {
657 LWIP_ASSERT("buf != NULL", buf != NULL);
658 len = netbuf_len((struct netbuf *)buf);
659 }
660#endif /* (LWIP_UDP || LWIP_RAW) */
661
662#if LWIP_SO_RCVBUF
663 SYS_ARCH_DEC(conn->recv_avail, len);
664#endif /* LWIP_SO_RCVBUF */
665 /* Register event with callback */
666 API_EVENT(conn, NETCONN_EVT_RCVMINUS, len);
667
668 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len));
669
670 *new_buf = buf;
671 /* don't set conn->last_err: it's only ERR_OK, anyway */
672 return ERR_OK;
673}
674
675#if LWIP_TCP
676static err_t
677netconn_tcp_recvd_msg(struct netconn *conn, size_t len, struct api_msg *msg)
678{
679 LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
680 NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
681
682 msg->conn = conn;
683 msg->msg.r.len = len;
684
685 return netconn_apimsg(lwip_netconn_do_recv, msg);
686}
687
688err_t
689netconn_tcp_recvd(struct netconn *conn, size_t len)
690{
691 err_t err;
692 API_MSG_VAR_DECLARE(msg);
693 LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
694 NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
695
696 API_MSG_VAR_ALLOC(msg);
697 err = netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
698 API_MSG_VAR_FREE(msg);
699 return err;
700}
701
702static err_t
703netconn_recv_data_tcp(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
704{
705 err_t err;
706 struct pbuf *buf;
707 API_MSG_VAR_DECLARE(msg);
708#if LWIP_MPU_COMPATIBLE
709 msg = NULL;
710#endif
711
712 if (!NETCONN_RECVMBOX_WAITABLE(conn)) {
713 /* This only happens when calling this function more than once *after* receiving FIN */
714 return ERR_CONN;
715 }
716 if (netconn_is_flag_set(conn, NETCONN_FIN_RX_PENDING)) {
717 netconn_clear_flags(conn, NETCONN_FIN_RX_PENDING);
718 goto handle_fin;
719 }
720
721 if (!(apiflags & NETCONN_NOAUTORCVD)) {
722 /* need to allocate API message here so empty message pool does not result in event loss
723 * see bug #47512: MPU_COMPATIBLE may fail on empty pool */
724 API_MSG_VAR_ALLOC(msg);
725 }
726
727 err = netconn_recv_data(conn, (void **)new_buf, apiflags);
728 if (err != ERR_OK) {
729 if (!(apiflags & NETCONN_NOAUTORCVD)) {
730 API_MSG_VAR_FREE(msg);
731 }
732 return err;
733 }
734 buf = *new_buf;
735 if (!(apiflags & NETCONN_NOAUTORCVD)) {
736 /* Let the stack know that we have taken the data. */
737 u16_t len = buf ? buf->tot_len : 1;
738 /* don't care for the return value of lwip_netconn_do_recv */
739 /* @todo: this should really be fixed, e.g. by retrying in poll on error */
740 netconn_tcp_recvd_msg(conn, len, &API_VAR_REF(msg));
741 API_MSG_VAR_FREE(msg);
742 }
743
744 /* If we are closed, we indicate that we no longer wish to use the socket */
745 if (buf == NULL) {
746 if (apiflags & NETCONN_NOFIN) {
747 /* received a FIN but the caller cannot handle it right now:
748 re-enqueue it and return "no data" */
749 netconn_set_flags(conn, NETCONN_FIN_RX_PENDING);
750 return ERR_WOULDBLOCK;
751 } else {
752handle_fin:
753 API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
754 if (conn->pcb.ip == NULL) {
755 /* race condition: RST during recv */
756 err = netconn_err(conn);
757 if (err != ERR_OK) {
758 return err;
759 }
760 return ERR_RST;
761 }
762 /* RX side is closed, so deallocate the recvmbox */
763 netconn_close_shutdown(conn, NETCONN_SHUT_RD);
764 /* Don' store ERR_CLSD as conn->err since we are only half-closed */
765 return ERR_CLSD;
766 }
767 }
768 return err;
769}
770
781err_t
782netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf)
783{
784 LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
785 NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
786
787 return netconn_recv_data_tcp(conn, new_buf, 0);
788}
789
802err_t
803netconn_recv_tcp_pbuf_flags(struct netconn *conn, struct pbuf **new_buf, u8_t apiflags)
804{
805 LWIP_ERROR("netconn_recv_tcp_pbuf: invalid conn", (conn != NULL) &&
806 NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;);
807
808 return netconn_recv_data_tcp(conn, new_buf, apiflags);
809}
810#endif /* LWIP_TCP */
811
821err_t
822netconn_recv_udp_raw_netbuf(struct netconn *conn, struct netbuf **new_buf)
823{
824 LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
825 NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
826
827 return netconn_recv_data(conn, (void **)new_buf, 0);
828}
829
841err_t
842netconn_recv_udp_raw_netbuf_flags(struct netconn *conn, struct netbuf **new_buf, u8_t apiflags)
843{
844 LWIP_ERROR("netconn_recv_udp_raw_netbuf: invalid conn", (conn != NULL) &&
845 NETCONNTYPE_GROUP(netconn_type(conn)) != NETCONN_TCP, return ERR_ARG;);
846
847 return netconn_recv_data(conn, (void **)new_buf, apiflags);
848}
849
859err_t
860netconn_recv(struct netconn *conn, struct netbuf **new_buf)
861{
862#if LWIP_TCP
863 struct netbuf *buf = NULL;
864 err_t err;
865#endif /* LWIP_TCP */
866
867 LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
868 *new_buf = NULL;
869 LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
870
871#if LWIP_TCP
872#if (LWIP_UDP || LWIP_RAW)
873 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
874#endif /* (LWIP_UDP || LWIP_RAW) */
875 {
876 struct pbuf *p = NULL;
877 /* This is not a listening netconn, since recvmbox is set */
878
879 buf = (struct netbuf *)memp_malloc(MEMP_NETBUF);
880 if (buf == NULL) {
881 return ERR_MEM;
882 }
883
884 err = netconn_recv_data_tcp(conn, &p, 0);
885 if (err != ERR_OK) {
886 memp_free(MEMP_NETBUF, buf);
887 return err;
888 }
889 LWIP_ASSERT("p != NULL", p != NULL);
890
891 buf->p = p;
892 buf->ptr = p;
893 buf->port = 0;
894 ip_addr_set_zero(&buf->addr);
895 *new_buf = buf;
896 /* don't set conn->last_err: it's only ERR_OK, anyway */
897 return ERR_OK;
898 }
899#endif /* LWIP_TCP */
900#if LWIP_TCP && (LWIP_UDP || LWIP_RAW)
901 else
902#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */
903 {
904#if (LWIP_UDP || LWIP_RAW)
905 return netconn_recv_data(conn, (void **)new_buf, 0);
906#endif /* (LWIP_UDP || LWIP_RAW) */
907 }
908}
909
921err_t
922netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr, u16_t port)
923{
924 if (buf != NULL) {
925 ip_addr_set(&buf->addr, addr);
926 buf->port = port;
927 return netconn_send(conn, buf);
928 }
929 return ERR_VAL;
930}
931
940err_t
941netconn_send(struct netconn *conn, struct netbuf *buf)
942{
943 API_MSG_VAR_DECLARE(msg);
944 err_t err;
945
946 LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;);
947
948 LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len));
949
950 API_MSG_VAR_ALLOC(msg);
951 API_MSG_VAR_REF(msg).conn = conn;
952 API_MSG_VAR_REF(msg).msg.b = buf;
953 err = netconn_apimsg(lwip_netconn_do_send, &API_MSG_VAR_REF(msg));
954 API_MSG_VAR_FREE(msg);
955
956 return err;
957}
958
973err_t
974netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size,
975 u8_t apiflags, size_t *bytes_written)
976{
977 struct netvector vector;
978 vector.ptr = dataptr;
979 vector.len = size;
980 return netconn_write_vectors_partly(conn, &vector, 1, apiflags, bytes_written);
981}
982
996err_t
997netconn_write_vectors_partly(struct netconn *conn, struct netvector *vectors, u16_t vectorcnt,
998 u8_t apiflags, size_t *bytes_written)
999{
1000 API_MSG_VAR_DECLARE(msg);
1001 err_t err;
1002 u8_t dontblock;
1003 size_t size;
1004 int i;
1005
1006 LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;);
1007 LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP), return ERR_VAL;);
1008 dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
1009#if LWIP_SO_SNDTIMEO
1010 if (conn->send_timeout != 0) {
1011 dontblock = 1;
1012 }
1013#endif /* LWIP_SO_SNDTIMEO */
1014 if (dontblock && !bytes_written) {
1015 /* This implies netconn_write() cannot be used for non-blocking send, since
1016 it has no way to return the number of bytes written. */
1017 return ERR_VAL;
1018 }
1019
1020 /* sum up the total size */
1021 size = 0;
1022 for (i = 0; i < vectorcnt; i++) {
1023 size += vectors[i].len;
1024 if (size < vectors[i].len) {
1025 /* overflow */
1026 return ERR_VAL;
1027 }
1028 }
1029 if (size == 0) {
1030 return ERR_OK;
1031 } else if (size > SSIZE_MAX) {
1032 ssize_t limited;
1033 /* this is required by the socket layer (cannot send full size_t range) */
1034 if (!bytes_written) {
1035 return ERR_VAL;
1036 }
1037 /* limit the amount of data to send */
1038 limited = SSIZE_MAX;
1039 size = (size_t)limited;
1040 }
1041
1042 API_MSG_VAR_ALLOC(msg);
1043 /* non-blocking write sends as much */
1044 API_MSG_VAR_REF(msg).conn = conn;
1045 API_MSG_VAR_REF(msg).msg.w.vector = vectors;
1046 API_MSG_VAR_REF(msg).msg.w.vector_cnt = vectorcnt;
1047 API_MSG_VAR_REF(msg).msg.w.vector_off = 0;
1048 API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags;
1049 API_MSG_VAR_REF(msg).msg.w.len = size;
1050 API_MSG_VAR_REF(msg).msg.w.offset = 0;
1051#if LWIP_SO_SNDTIMEO
1052 if (conn->send_timeout != 0) {
1053 /* get the time we started, which is later compared to
1054 sys_now() + conn->send_timeout */
1055 API_MSG_VAR_REF(msg).msg.w.time_started = sys_now();
1056 } else {
1057 API_MSG_VAR_REF(msg).msg.w.time_started = 0;
1058 }
1059#endif /* LWIP_SO_SNDTIMEO */
1060
1061 /* For locking the core: this _can_ be delayed on low memory/low send buffer,
1062 but if it is, this is done inside api_msg.c:do_write(), so we can use the
1063 non-blocking version here. */
1064 err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg));
1065 if (err == ERR_OK) {
1066 if (bytes_written != NULL) {
1067 *bytes_written = API_MSG_VAR_REF(msg).msg.w.offset;
1068 }
1069 /* for blocking, check all requested bytes were written, NOTE: send_timeout is
1070 treated as dontblock (see dontblock assignment above) */
1071 if (!dontblock) {
1072 LWIP_ASSERT("do_write failed to write all bytes", API_MSG_VAR_REF(msg).msg.w.offset == size);
1073 }
1074 }
1075 API_MSG_VAR_FREE(msg);
1076
1077 return err;
1078}
1079
1088static err_t
1089netconn_close_shutdown(struct netconn *conn, u8_t how)
1090{
1091 API_MSG_VAR_DECLARE(msg);
1092 err_t err;
1093 LWIP_UNUSED_ARG(how);
1094
1095 LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;);
1096
1097 API_MSG_VAR_ALLOC(msg);
1098 API_MSG_VAR_REF(msg).conn = conn;
1099#if LWIP_TCP
1100 /* shutting down both ends is the same as closing */
1101 API_MSG_VAR_REF(msg).msg.sd.shut = how;
1102#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
1103 /* get the time we started, which is later compared to
1104 sys_now() + conn->send_timeout */
1105 API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now();
1106#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
1107 API_MSG_VAR_REF(msg).msg.sd.polls_left =
1108 ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1;
1109#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */
1110#endif /* LWIP_TCP */
1111 err = netconn_apimsg(lwip_netconn_do_close, &API_MSG_VAR_REF(msg));
1112 API_MSG_VAR_FREE(msg);
1113
1114 return err;
1115}
1116
1124err_t
1125netconn_close(struct netconn *conn)
1126{
1127 /* shutting down both ends is the same as closing */
1128 return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR);
1129}
1130
1138err_t
1139netconn_err(struct netconn *conn)
1140{
1141 err_t err;
1143 if (conn == NULL) {
1144 return ERR_OK;
1145 }
1146 SYS_ARCH_PROTECT(lev);
1147 err = conn->pending_err;
1148 conn->pending_err = ERR_OK;
1149 SYS_ARCH_UNPROTECT(lev);
1150 return err;
1151}
1152
1162err_t
1163netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx)
1164{
1165 return netconn_close_shutdown(conn, (u8_t)((shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)));
1166}
1167
1168#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
1180err_t
1181netconn_join_leave_group(struct netconn *conn,
1182 const ip_addr_t *multiaddr,
1183 const ip_addr_t *netif_addr,
1184 enum netconn_igmp join_or_leave)
1185{
1186 API_MSG_VAR_DECLARE(msg);
1187 err_t err;
1188
1189 LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
1190
1191 API_MSG_VAR_ALLOC(msg);
1192
1193#if LWIP_IPV4
1194 /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
1195 if (multiaddr == NULL) {
1196 multiaddr = IP4_ADDR_ANY;
1197 }
1198 if (netif_addr == NULL) {
1199 netif_addr = IP4_ADDR_ANY;
1200 }
1201#endif /* LWIP_IPV4 */
1202
1203 API_MSG_VAR_REF(msg).conn = conn;
1204 API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
1205 API_MSG_VAR_REF(msg).msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr);
1206 API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave;
1207 err = netconn_apimsg(lwip_netconn_do_join_leave_group, &API_MSG_VAR_REF(msg));
1208 API_MSG_VAR_FREE(msg);
1209
1210 return err;
1211}
1222err_t
1223netconn_join_leave_group_netif(struct netconn *conn,
1224 const ip_addr_t *multiaddr,
1225 u8_t if_idx,
1226 enum netconn_igmp join_or_leave)
1227{
1228 API_MSG_VAR_DECLARE(msg);
1229 err_t err;
1230
1231 LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;);
1232
1233 API_MSG_VAR_ALLOC(msg);
1234
1235#if LWIP_IPV4
1236 /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */
1237 if (multiaddr == NULL) {
1238 multiaddr = IP4_ADDR_ANY;
1239 }
1240 if (if_idx == NETIF_NO_INDEX) {
1241 return ERR_IF;
1242 }
1243#endif /* LWIP_IPV4 */
1244
1245 API_MSG_VAR_REF(msg).conn = conn;
1246 API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr);
1247 API_MSG_VAR_REF(msg).msg.jl.if_idx = if_idx;
1248 API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave;
1249 err = netconn_apimsg(lwip_netconn_do_join_leave_group_netif, &API_MSG_VAR_REF(msg));
1250 API_MSG_VAR_FREE(msg);
1251
1252 return err;
1253}
1254#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */
1255
1256#if LWIP_DNS
1268#if LWIP_IPV4 && LWIP_IPV6
1270err_t
1271netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype)
1272#else
1273err_t
1274netconn_gethostbyname(const char *name, ip_addr_t *addr)
1275#endif
1276{
1277 API_VAR_DECLARE(struct dns_api_msg, msg);
1278#if !LWIP_MPU_COMPATIBLE
1279 sys_sem_t sem;
1280#endif /* LWIP_MPU_COMPATIBLE */
1281 err_t err;
1282 err_t cberr;
1283
1284 LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;);
1285 LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;);
1286#if LWIP_MPU_COMPATIBLE
1288 return ERR_ARG;
1289 }
1290#endif
1291
1292#ifdef LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE
1293#if LWIP_IPV4 && LWIP_IPV6
1294 if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, dns_addrtype, &err)) {
1295#else
1296 if (LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE(name, addr, NETCONN_DNS_DEFAULT, &err)) {
1297#endif /* LWIP_IPV4 && LWIP_IPV6 */
1298 return err;
1299 }
1300#endif /* LWIP_HOOK_NETCONN_EXTERNAL_RESOLVE */
1301
1302 API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg, ERR_MEM);
1303#if LWIP_MPU_COMPATIBLE
1306#else /* LWIP_MPU_COMPATIBLE */
1307 msg.err = &err;
1308 msg.sem = &sem;
1311#endif /* LWIP_MPU_COMPATIBLE */
1312#if LWIP_IPV4 && LWIP_IPV6
1313 API_VAR_REF(msg).dns_addrtype = dns_addrtype;
1314#endif /* LWIP_IPV4 && LWIP_IPV6 */
1315#if LWIP_NETCONN_SEM_PER_THREAD
1317#else /* LWIP_NETCONN_SEM_PER_THREAD*/
1319 if (err != ERR_OK) {
1320 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
1321 return err;
1322 }
1323#endif /* LWIP_NETCONN_SEM_PER_THREAD */
1324
1325 cberr = tcpip_send_msg_wait_sem(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg), API_EXPR_REF(API_VAR_REF(msg).sem));
1326#if !LWIP_NETCONN_SEM_PER_THREAD
1328#endif /* !LWIP_NETCONN_SEM_PER_THREAD */
1329 if (cberr != ERR_OK) {
1330 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
1331 return cberr;
1332 }
1333
1334#if LWIP_MPU_COMPATIBLE
1335 *addr = msg->addr;
1336 err = msg->err;
1337#endif /* LWIP_MPU_COMPATIBLE */
1338
1339 API_VAR_FREE(MEMP_DNS_API_MSG, msg);
1340 return err;
1341}
1342#endif /* LWIP_DNS*/
1343
1344#if LWIP_NETCONN_SEM_PER_THREAD
1345void
1346netconn_thread_init(void)
1347{
1349 if (!sys_sem_valid(sem)) {
1350 /* call alloc only once */
1352 LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET()));
1353 }
1354}
1355
1356void
1357netconn_thread_cleanup(void)
1358{
1360 if (sys_sem_valid(sem)) {
1361 /* call free only once */
1363 }
1364}
1365#endif /* LWIP_NETCONN_SEM_PER_THREAD */
1366
1367#endif /* LWIP_NETCONN */
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define msg(x)
Definition: auth_time.c:54
#define NULL
Definition: types.h:112
USHORT port
Definition: uri.c:228
void netconn_close(struct netconn *conn)
Definition: net.c:250
BOOL netconn_recv(struct netconn *conn, void *buf, size_t len, int flags, int *recvd)
Definition: net.c:539
BOOL netconn_send(struct netconn *conn, const void *msg, size_t len, int *sent)
Definition: net.c:424
__kernel_size_t size_t
Definition: linux.h:237
#define SYS_ARCH_UNPROTECT(lev)
Definition: cc.h:39
#define SYS_ARCH_PROTECT(lev)
Definition: cc.h:38
#define SYS_ARCH_DECL_PROTECT(lev)
Definition: cc.h:37
#define U16_F
Definition: cc.h:19
#define LWIP_DEBUGF(debug, message)
Definition: debug.h:158
#define LWIP_ERROR(message, expression, handler)
Definition: debug.h:130
#define LWIP_ASSERT(message, assertion)
Definition: debug.h:116
void(* tcpip_callback_fn)(void *ctx)
Definition: tcpip.h:72
#define ERR_MEM
Definition: fontsub.h:52
#define local
Definition: zutil.h:30
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define SSIZE_MAX
Definition: arch.h:203
uint8_t u8_t
Definition: arch.h:125
#define LWIP_UNUSED_ARG(x)
Definition: arch.h:373
uint16_t u16_t
Definition: arch.h:127
s8_t err_t
Definition: err.h:96
@ ERR_RST
Definition: err.h:84
@ ERR_IF
Definition: err.h:79
@ ERR_OK
Definition: err.h:55
@ ERR_CLSD
Definition: err.h:86
@ ERR_VAL
Definition: err.h:67
@ ERR_CONN
Definition: err.h:77
@ ERR_ARG
Definition: err.h:88
@ ERR_WOULDBLOCK
Definition: err.h:69
@ ERR_TIMEOUT
Definition: err.h:61
#define IP_ANY_TYPE
Definition: ip_addr.h:461
#define API_LIB_DEBUG
Definition: opt.h:3350
#define DNS_MAX_NAME_LENGTH
Definition: opt.h:1145
#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT
Definition: opt.h:2100
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
Definition: sys_arch.c:177
void sys_mbox_free(sys_mbox_t *mbox)
Definition: sys_arch.c:152
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
Definition: sys_arch.c:238
void sys_sem_free(sys_sem_t *sem)
Definition: sys_arch.c:72
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
Definition: sys_arch.c:46
u32_t sys_now(void)
Definition: sys_arch.c:23
#define ip_addr_set(dest, src)
Definition: ip_addr.h:363
#define ip_addr_eq(addr1, addr2)
Definition: ip_addr.h:374
ip6_addr_t ip_addr_t
Definition: ip_addr.h:344
#define ip_addr_set_zero(ipaddr)
Definition: ip_addr.h:365
int const JOCTET * dataptr
Definition: jpeglib.h:1031
#define sys_mbox_valid(mbox)
Definition: sys_arch.h:50
#define LWIP_NETCONN_THREAD_SEM_GET()
Definition: sys_arch.h:74
#define LWIP_NETCONN_THREAD_SEM_ALLOC()
Definition: sys_arch.h:75
#define LWIP_NETCONN_THREAD_SEM_FREE()
Definition: sys_arch.h:76
#define sys_sem_valid(sema)
Definition: sys_arch.h:36
void * memp_malloc(memp_t type)
Definition: memp.c:337
void memp_free(memp_t type, void *mem)
Definition: memp.c:420
static IPrintDialogCallback callback
Definition: printdlg.c:326
static HANDLE sem
Definition: sync.c:674
#define NETIF_NO_INDEX
Definition: netif.h:579
#define err(...)
int ssize_t
Definition: rosdhcp.h:48
strncpy
Definition: string.h:335
char * name
Definition: compiler.c:66
Definition: name.c:39
Definition: types.h:144
Definition: pbuf.h:186
u16_t tot_len
Definition: pbuf.h:200
#define SYS_ARCH_DEC(var, val)
Definition: sys.h:535
#define SYS_MBOX_EMPTY
Definition: sys.h:92
#define SYS_ARCH_TIMEOUT
Definition: sys.h:87
err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t *sem)
Definition: tcpip.c:442
#define API_EXPR_REF(expr)
Definition: tcpip_priv.h:90
#define API_VAR_FREE(pool, name)
Definition: tcpip_priv.h:88
#define API_VAR_REF(name)
Definition: tcpip_priv.h:83
#define API_VAR_ALLOC(type, pool, name, errorval)
Definition: tcpip_priv.h:86
#define API_VAR_DECLARE(type, name)
Definition: tcpip_priv.h:84
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159