60#define NETCONN_TCP_POLL_INTERVAL 2
62#define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \
63 netconn_set_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); \
65 netconn_clear_flags(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT); }} while(0)
66#define IN_NONBLOCKING_CONNECT(conn) netconn_is_flag_set(conn, NETCONN_FLAG_IN_NONBLOCKING_CONNECT)
68#if LWIP_NETCONN_FULLDUPLEX
69#define NETCONN_MBOX_VALID(conn, mbox) (sys_mbox_valid(mbox) && ((conn->flags & NETCONN_FLAG_MBOXINVALID) == 0))
71#define NETCONN_MBOX_VALID(conn, mbox) sys_mbox_valid(mbox)
76#if LWIP_TCPIP_CORE_LOCKING
77#define WRITE_DELAYED , 1
78#define WRITE_DELAYED_PARAM , u8_t delayed
81#define WRITE_DELAYED_PARAM
83static err_t lwip_netconn_do_writemore(
struct netconn *conn WRITE_DELAYED_PARAM);
84static err_t lwip_netconn_do_close_internal(
struct netconn *conn WRITE_DELAYED_PARAM);
87static void netconn_drain(
struct netconn *conn);
89#if LWIP_TCPIP_CORE_LOCKING
90#define TCPIP_APIMSG_ACK(m)
92#define TCPIP_APIMSG_ACK(m) do { sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0)
95#if LWIP_NETCONN_FULLDUPLEX
96static const u8_t netconn_deleted = 0;
99lwip_netconn_is_deallocated_msg(
void *
msg)
101 if (
msg == &netconn_deleted) {
109static const u8_t netconn_aborted = 0;
110static const u8_t netconn_reset = 0;
111static const u8_t netconn_closed = 0;
135 if (
msg == &netconn_aborted) {
138 }
else if (
msg == &netconn_reset) {
141 }
else if (
msg == &netconn_closed) {
159recv_raw(
void *
arg,
struct raw_pcb *pcb,
struct pbuf *
p,
169 if ((conn !=
NULL) && NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
173 if ((recv_avail + (
int)(
p->tot_len)) > conn->recv_bufsize) {
190 buf->port = pcb->protocol;
201 API_EVENT(conn, NETCONN_EVT_RCVPLUS,
len);
218recv_udp(
void *
arg,
struct udp_pcb *pcb,
struct pbuf *
p,
239 LWIP_ASSERT(
"recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
243 if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox) ||
244 ((recv_avail + (
int)(
p->tot_len)) > conn->recv_bufsize)) {
246 if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
261#if LWIP_NETBUF_RECVINFO
262 if (conn->flags & NETCONN_FLAG_PKTINFO) {
265 buf->flags = NETBUF_FLAG_DESTADDR;
283 API_EVENT(conn, NETCONN_EVT_RCVPLUS,
len);
312 LWIP_ASSERT(
"recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
314 if (!NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
317 tcp_recved(pcb,
p->tot_len);
342 API_EVENT(conn, NETCONN_EVT_RCVPLUS,
len);
360poll_tcp(
void *
arg,
struct tcp_pcb *pcb)
367 if (conn->state == NETCONN_WRITE) {
368 lwip_netconn_do_writemore(conn WRITE_DELAYED);
369 }
else if (conn->state == NETCONN_CLOSE) {
370#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER
371 if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
372 conn->current_msg->msg.sd.polls_left--;
375 lwip_netconn_do_close_internal(conn WRITE_DELAYED);
380 if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
383 if ((conn->pcb.tcp !=
NULL) && (tcp_sndbuf(conn->pcb.tcp) >
TCP_SNDLOWAT) &&
385 netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE);
386 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
409 if (conn->state == NETCONN_WRITE) {
410 lwip_netconn_do_writemore(conn WRITE_DELAYED);
411 }
else if (conn->state == NETCONN_CLOSE) {
412 lwip_netconn_do_close_internal(conn WRITE_DELAYED);
417 if ((conn->pcb.tcp !=
NULL) && (tcp_sndbuf(conn->pcb.tcp) >
TCP_SNDLOWAT) &&
419 netconn_clear_flags(conn, NETCONN_FLAG_CHECK_WRITESPACE);
420 API_EVENT(conn, NETCONN_EVT_SENDPLUS,
len);
438 enum netconn_state old_state;
448 conn->pcb.tcp =
NULL;
450 conn->pending_err =
err;
452 conn->flags |= NETCONN_FLAG_MBOXCLOSED;
455 old_state = conn->state;
456 conn->state = NETCONN_NONE;
461 API_EVENT(conn, NETCONN_EVT_ERROR, 0);
464 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
465 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
467 mbox_msg = lwip_netconn_err_to_msg(
err);
469 if (NETCONN_MBOX_VALID(conn, &conn->recvmbox)) {
474 if (NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) {
479 if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
480 (old_state == NETCONN_CONNECT)) {
483 int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
484 SET_NONBLOCKING_CONNECT(conn, 0);
486 if (!was_nonblocking_connect) {
490 if (old_state == NETCONN_CLOSE) {
492 conn->current_msg->err =
ERR_OK;
495 conn->current_msg->err =
err;
497 op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
499 conn->current_msg =
NULL;
524 tcp_sent(pcb, sent_tcp);
525 tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL);
526 tcp_err(pcb, err_tcp);
536accept_function(
void *
arg,
struct tcp_pcb *newpcb,
err_t err)
544 if (!NETCONN_MBOX_VALID(conn, &conn->acceptmbox)) {
549 if (newpcb ==
NULL) {
553 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
564 newconn = netconn_alloc(conn->type, conn->callback);
565 if (newconn ==
NULL) {
569 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
573 newconn->pcb.tcp = newpcb;
577 tcp_backlog_delayed(newpcb);
583 struct tcp_pcb *pcb = newconn->pcb.tcp;
590 newconn->pcb.tcp =
NULL;
594 netconn_free(newconn);
598 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
612pcb_new(
struct api_msg *
msg)
618#if LWIP_IPV6 && LWIP_IPV4
620 if (NETCONNTYPE_ISIPV6(netconn_type(
msg->conn))) {
626 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
629 msg->conn->pcb.raw = raw_new_ip_type(iptype,
msg->msg.n.proto);
630 if (
msg->conn->pcb.raw !=
NULL) {
634 msg->conn->pcb.raw->chksum_reqd = 1;
635 msg->conn->pcb.raw->chksum_offset = 2;
638 raw_recv(
msg->conn->pcb.raw, recv_raw,
msg->conn);
644 msg->conn->pcb.udp = udp_new_ip_type(iptype);
645 if (
msg->conn->pcb.udp !=
NULL) {
647 if (NETCONNTYPE_ISUDPLITE(
msg->conn->type)) {
648 udp_setflags(
msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
651 if (NETCONNTYPE_ISUDPNOCHKSUM(
msg->conn->type)) {
652 udp_setflags(
msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
654 udp_recv(
msg->conn->pcb.udp, recv_udp,
msg->conn);
660 msg->conn->pcb.tcp = tcp_new_ip_type(iptype);
661 if (
msg->conn->pcb.tcp !=
NULL) {
662 setup_tcp(
msg->conn);
671 if (
msg->conn->pcb.ip ==
NULL) {
683lwip_netconn_do_newconn(
void *
m)
685 struct api_msg *
msg = (
struct api_msg *)
m;
688 if (
msg->conn->pcb.tcp ==
NULL) {
695 TCPIP_APIMSG_ACK(
msg);
708netconn_alloc(
enum netconn_type
t, netconn_callback
callback)
719 conn->pending_err =
ERR_OK;
721 conn->pcb.tcp =
NULL;
722#if LWIP_NETCONN_FULLDUPLEX
723 conn->mbox_threads_waiting = 0;
727 switch (NETCONNTYPE_GROUP(
t)) {
736#if LWIP_NETBUF_RECVINFO
737 init_flags |= NETCONN_FLAG_PKTINFO;
747 LWIP_ASSERT(
"netconn_alloc: undefined netconn_type", 0);
748 goto free_and_return;
752 goto free_and_return;
754#if !LWIP_NETCONN_SEM_PER_THREAD
757 goto free_and_return;
764 conn->state = NETCONN_NONE;
766 conn->callback_arg.
socket = -1;
769 conn->current_msg =
NULL;
772 conn->send_timeout = 0;
775 conn->recv_timeout = 0;
779 conn->recv_avail = 0;
784 conn->flags = init_flags;
798netconn_free(
struct netconn *conn)
800 LWIP_ASSERT(
"PCB must be deallocated outside this function", conn->pcb.tcp ==
NULL);
802#if LWIP_NETCONN_FULLDUPLEX
807 LWIP_ASSERT(
"recvmbox must be deallocated before calling this function",
810 LWIP_ASSERT(
"acceptmbox must be deallocated before calling this function",
814#if !LWIP_NETCONN_SEM_PER_THREAD
831netconn_drain(
struct netconn *conn)
837#if LWIP_NETCONN_FULLDUPLEX
838 LWIP_ASSERT(
"netconn marked closed", conn->flags & NETCONN_FLAG_MBOXINVALID);
844#if LWIP_NETCONN_FULLDUPLEX
845 if (!lwip_netconn_is_deallocated_msg(
mem))
849 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) {
851 if (!lwip_netconn_is_err_msg(
mem, &
err)) {
869#if LWIP_NETCONN_FULLDUPLEX
870 if (!lwip_netconn_is_deallocated_msg(
mem))
874 if (!lwip_netconn_is_err_msg(
mem, &
err)) {
879 netconn_drain(newconn);
880 if (newconn->pcb.tcp !=
NULL) {
881 tcp_abort(newconn->pcb.tcp);
882 newconn->pcb.tcp =
NULL;
884 netconn_free(newconn);
894#if LWIP_NETCONN_FULLDUPLEX
896netconn_mark_mbox_invalid(
struct netconn *conn)
902 conn->flags |= NETCONN_FLAG_MBOXINVALID;
905 for (
i = 0;
i < num_waiting;
i++) {
924lwip_netconn_do_close_internal(
struct netconn *conn WRITE_DELAYED_PARAM)
927 u8_t shut, shut_rx, shut_tx, shut_close;
928 u8_t close_finished = 0;
929 struct tcp_pcb *tpcb;
931 u8_t linger_wait_required = 0;
935 LWIP_ASSERT(
"this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP));
936 LWIP_ASSERT(
"conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
940 tpcb = conn->pcb.tcp;
941 shut = conn->current_msg->msg.sd.shut;
942 shut_rx = shut & NETCONN_SHUT_RD;
943 shut_tx = shut & NETCONN_SHUT_WR;
946 if (shut == NETCONN_SHUT_RDWR) {
948 }
else if (shut_rx &&
949 ((tpcb->state == FIN_WAIT_1) ||
950 (tpcb->state == FIN_WAIT_2) ||
951 (tpcb->state == CLOSING))) {
953 }
else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) {
963 if (tpcb->state == LISTEN) {
972 tcp_sent(tpcb,
NULL);
985 if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
986 if ((conn->linger == 0)) {
990 }
else if (conn->linger > 0) {
992 if (netconn_is_nonblocking(conn)) {
995 }
else if ((
s32_t)(
sys_now() - conn->current_msg->msg.sd.time_started) >=
996 (conn->linger * 1000)) {
1003 linger_wait_required = 1;
1018 if (linger_wait_required) {
1031#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER
1034 if (conn->send_timeout > 0) {
1035 close_timeout = conn->send_timeout;
1039 if (conn->linger >= 0) {
1041 close_timeout = conn->linger * 1000U;
1044 if ((
s32_t)(
sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) {
1046 if (conn->current_msg->msg.sd.polls_left == 0) {
1060 if (close_finished) {
1062 sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
1063 conn->current_msg->err =
err;
1064 conn->current_msg =
NULL;
1065 conn->state = NETCONN_NONE;
1069 conn->pcb.tcp =
NULL;
1072 API_EVENT(conn, NETCONN_EVT_ERROR, 0);
1075 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
1078 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
1081#if LWIP_TCPIP_CORE_LOCKING
1090 if (!close_finished) {
1093 LWIP_ASSERT(
"Closing a listen pcb may not fail!", (tpcb->state != LISTEN));
1095 tcp_sent(tpcb, sent_tcp);
1099 tcp_err(tpcb, err_tcp);
1100 tcp_arg(tpcb, conn);
1117lwip_netconn_do_delconn(
void *
m)
1119 struct api_msg *
msg = (
struct api_msg *)
m;
1121 enum netconn_state
state =
msg->conn->state;
1123 (
state == NETCONN_NONE) || (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP));
1124#if LWIP_NETCONN_FULLDUPLEX
1126 if (
state != NETCONN_NONE) {
1127 if ((
state == NETCONN_WRITE) ||
1128 ((
state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(
msg->conn))) {
1132 op_completed_sem = LWIP_API_MSG_SEM(
msg->conn->current_msg);
1134 msg->conn->current_msg =
NULL;
1135 msg->conn->state = NETCONN_NONE;
1140 if (((
state != NETCONN_NONE) &&
1141 (
state != NETCONN_LISTEN) &&
1142 (
state != NETCONN_CONNECT)) ||
1143 ((
state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(
msg->conn))) {
1151 (
state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(
msg->conn));
1153#if LWIP_NETCONN_FULLDUPLEX
1155 netconn_mark_mbox_invalid(
msg->conn);
1157 netconn_drain(
msg->conn);
1160 if (
msg->conn->pcb.tcp !=
NULL) {
1162 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1165 raw_remove(
msg->conn->pcb.raw);
1170 msg->conn->pcb.udp->recv_arg =
NULL;
1171 udp_remove(
msg->conn->pcb.udp);
1177 msg->conn->state = NETCONN_CLOSE;
1178 msg->msg.sd.shut = NETCONN_SHUT_RDWR;
1179 msg->conn->current_msg =
msg;
1180#if LWIP_TCPIP_CORE_LOCKING
1181 if (lwip_netconn_do_close_internal(
msg->conn, 0) !=
ERR_OK) {
1189 lwip_netconn_do_close_internal(
msg->conn);
1204 API_EVENT(
msg->conn, NETCONN_EVT_RCVPLUS, 0);
1205 API_EVENT(
msg->conn, NETCONN_EVT_SENDPLUS, 0);
1208 TCPIP_APIMSG_ACK(
msg);
1220lwip_netconn_do_bind(
void *
m)
1222 struct api_msg *
msg = (
struct api_msg *)
m;
1225 if (
msg->conn->pcb.tcp !=
NULL) {
1226 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1250 TCPIP_APIMSG_ACK(
msg);
1260lwip_netconn_do_bind_if(
void *
m)
1263 struct api_msg *
msg = (
struct api_msg *)
m;
1270 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1273 raw_bind_netif(
msg->conn->pcb.raw,
netif);
1278 udp_bind_netif(
msg->conn->pcb.udp,
netif);
1283 tcp_bind_netif(
msg->conn->pcb.tcp,
netif);
1294 TCPIP_APIMSG_ACK(
msg);
1305lwip_netconn_do_connected(
void *
arg,
struct tcp_pcb *pcb,
err_t err)
1319 LWIP_ASSERT(
"conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
1320 LWIP_ASSERT(
"(conn->current_msg != NULL) || conn->in_non_blocking_connect",
1321 (conn->current_msg !=
NULL) || IN_NONBLOCKING_CONNECT(conn));
1323 if (conn->current_msg !=
NULL) {
1324 conn->current_msg->err =
err;
1325 op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
1327 if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (
err ==
ERR_OK)) {
1330 was_blocking = !IN_NONBLOCKING_CONNECT(conn);
1331 SET_NONBLOCKING_CONNECT(conn, 0);
1333 (was_blocking && op_completed_sem !=
NULL) ||
1334 (!was_blocking && op_completed_sem ==
NULL));
1335 conn->current_msg =
NULL;
1336 conn->state = NETCONN_NONE;
1337 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
1354lwip_netconn_do_connect(
void *
m)
1356 struct api_msg *
msg = (
struct api_msg *)
m;
1359 if (
msg->conn->pcb.tcp ==
NULL) {
1363 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1377 if (
msg->conn->state == NETCONN_CONNECT) {
1379 }
else if (
msg->conn->state != NETCONN_NONE) {
1382 setup_tcp(
msg->conn);
1384 msg->msg.bc.port, lwip_netconn_do_connected);
1386 u8_t non_blocking = netconn_is_nonblocking(
msg->conn);
1387 msg->conn->state = NETCONN_CONNECT;
1388 SET_NONBLOCKING_CONNECT(
msg->conn, non_blocking);
1392 msg->conn->current_msg =
msg;
1395#if LWIP_TCPIP_CORE_LOCKING
1418 TCPIP_APIMSG_ACK(
msg);
1429lwip_netconn_do_disconnect(
void *
m)
1431 struct api_msg *
msg = (
struct api_msg *)
m;
1434 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_UDP) {
1435 udp_disconnect(
msg->conn->pcb.udp);
1442 TCPIP_APIMSG_ACK(
msg);
1453lwip_netconn_do_listen(
void *
m)
1455 struct api_msg *
msg = (
struct api_msg *)
m;
1458 if (
msg->conn->pcb.tcp !=
NULL) {
1459 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP) {
1460 if (
msg->conn->state == NETCONN_NONE) {
1461 struct tcp_pcb *lpcb;
1462 if (
msg->conn->pcb.tcp->state != CLOSED) {
1467#if TCP_LISTEN_BACKLOG
1468 backlog =
msg->msg.lb.backlog;
1472#if LWIP_IPV4 && LWIP_IPV6
1476 if (
ip_addr_eq(&
msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) &&
1477 (netconn_get_ipv6only(
msg->conn) == 0)) {
1484 lpcb = tcp_listen_with_backlog_and_err(
msg->conn->pcb.tcp, backlog, &
err);
1500 msg->conn->state = NETCONN_LISTEN;
1501 msg->conn->pcb.tcp = lpcb;
1502 tcp_arg(
msg->conn->pcb.tcp,
msg->conn);
1511 }
else if (
msg->conn->state == NETCONN_LISTEN) {
1514 tcp_backlog_set(
msg->conn->pcb.tcp,
msg->msg.lb.backlog);
1525 TCPIP_APIMSG_ACK(
msg);
1536lwip_netconn_do_send(
void *
m)
1538 struct api_msg *
msg = (
struct api_msg *)
m;
1542 if (
msg->conn->pcb.tcp !=
NULL) {
1543 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1547 err = raw_send(
msg->conn->pcb.raw,
msg->msg.b->p);
1549 err = raw_sendto(
msg->conn->pcb.raw,
msg->msg.b->p, &
msg->msg.b->addr);
1555#if LWIP_CHECKSUM_ON_COPY
1557 err = udp_send_chksum(
msg->conn->pcb.udp,
msg->msg.b->p,
1558 msg->msg.b->flags & NETBUF_FLAG_CHKSUM,
msg->msg.b->toport_chksum);
1560 err = udp_sendto_chksum(
msg->conn->pcb.udp,
msg->msg.b->p,
1561 &
msg->msg.b->addr,
msg->msg.b->port,
1562 msg->msg.b->flags & NETBUF_FLAG_CHKSUM,
msg->msg.b->toport_chksum);
1566 err = udp_send(
msg->conn->pcb.udp,
msg->msg.b->p);
1568 err = udp_sendto(
msg->conn->pcb.udp,
msg->msg.b->p, &
msg->msg.b->addr,
msg->msg.b->port);
1582 TCPIP_APIMSG_ACK(
msg);
1593lwip_netconn_do_recv(
void *
m)
1595 struct api_msg *
msg = (
struct api_msg *)
m;
1598 if (
msg->conn->pcb.tcp !=
NULL) {
1599 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP) {
1600 size_t remaining =
msg->msg.r.len;
1602 u16_t recved = (
u16_t)((remaining > 0xffff) ? 0xffff : remaining);
1603 tcp_recved(
msg->conn->pcb.tcp, recved);
1604 remaining -= recved;
1605 }
while (remaining != 0);
1608 TCPIP_APIMSG_ACK(
msg);
1611#if TCP_LISTEN_BACKLOG
1618lwip_netconn_do_accepted(
void *
m)
1620 struct api_msg *
msg = (
struct api_msg *)
m;
1623 if (
msg->conn->pcb.tcp !=
NULL) {
1624 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP) {
1625 tcp_backlog_accepted(
msg->conn->pcb.tcp);
1628 TCPIP_APIMSG_ACK(
msg);
1644lwip_netconn_do_writemore(
struct netconn *conn WRITE_DELAYED_PARAM)
1649 u8_t write_finished = 0;
1656 LWIP_ASSERT(
"conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
1659 LWIP_ASSERT(
"conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len",
1660 conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len);
1661 LWIP_ASSERT(
"conn->current_msg->msg.w.vector_cnt > 0", conn->current_msg->msg.w.vector_cnt > 0);
1663 apiflags = conn->current_msg->msg.w.apiflags;
1664 dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
1667 if ((conn->send_timeout != 0) &&
1668 ((
s32_t)(
sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
1670 if (conn->current_msg->msg.w.offset == 0) {
1681 dataptr = (
const u8_t *)conn->current_msg->msg.w.vector->ptr + conn->current_msg->msg.w.vector_off;
1682 diff = conn->current_msg->msg.w.vector->len - conn->current_msg->msg.w.vector_off;
1683 if (diff > 0xffffUL) {
1685 apiflags |= TCP_WRITE_FLAG_MORE;
1700 apiflags |= TCP_WRITE_FLAG_MORE;
1703 LWIP_ASSERT(
"lwip_netconn_do_writemore: invalid length!",
1704 ((conn->current_msg->msg.w.vector_off +
len) <= conn->current_msg->msg.w.vector->len));
1709 if ((
len == 0xffff && diff > 0xffffUL) ||
1710 (
len == (
u16_t)diff && conn->current_msg->msg.w.vector_cnt > 1)) {
1712 apiflags |= TCP_WRITE_FLAG_MORE;
1718 conn->current_msg->msg.w.offset +=
len;
1719 conn->current_msg->msg.w.vector_off +=
len;
1721 if (conn->current_msg->msg.w.vector_off == conn->current_msg->msg.w.vector->len) {
1722 conn->current_msg->msg.w.vector_cnt--;
1724 if (conn->current_msg->msg.w.vector_cnt > 0) {
1725 conn->current_msg->msg.w.vector++;
1726 conn->current_msg->msg.w.vector_off = 0;
1734 if (dontblock && (conn->current_msg->msg.w.offset < conn->current_msg->msg.w.len)) {
1737 API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
1738 conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
1739 }
else if ((tcp_sndbuf(conn->pcb.tcp) <=
TCP_SNDLOWAT) ||
1743 API_EVENT(conn, NETCONN_EVT_SENDMINUS, 0);
1749 if ((conn->current_msg->msg.w.offset == conn->current_msg->msg.w.len) || dontblock) {
1753 out_err = tcp_output(conn->pcb.tcp);
1768 err_t out_err = tcp_output(conn->pcb.tcp);
1775 }
else if (dontblock) {
1787 if (write_finished) {
1790 sys_sem_t *op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
1791 conn->current_msg->err =
err;
1792 conn->current_msg =
NULL;
1793 conn->state = NETCONN_NONE;
1794#if LWIP_TCPIP_CORE_LOCKING
1801#if LWIP_TCPIP_CORE_LOCKING
1817lwip_netconn_do_write(
void *
m)
1819 struct api_msg *
msg = (
struct api_msg *)
m;
1823 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP) {
1825 if (
msg->conn->state != NETCONN_NONE) {
1828 }
else if (
msg->conn->pcb.tcp !=
NULL) {
1829 msg->conn->state = NETCONN_WRITE;
1833 msg->conn->current_msg =
msg;
1834#if LWIP_TCPIP_CORE_LOCKING
1835 if (lwip_netconn_do_writemore(
msg->conn, 0) !=
ERR_OK) {
1843 lwip_netconn_do_writemore(
msg->conn);
1854#if (LWIP_UDP || LWIP_RAW)
1861 TCPIP_APIMSG_ACK(
msg);
1871lwip_netconn_do_getaddr(
void *
m)
1873 struct api_msg *
msg = (
struct api_msg *)
m;
1875 if (
msg->conn->pcb.ip !=
NULL) {
1876 if (
msg->msg.ad.local) {
1878 msg->conn->pcb.ip->local_ip);
1881 msg->conn->pcb.ip->remote_ip);
1885 switch (NETCONNTYPE_GROUP(
msg->conn->type)) {
1888 if (
msg->msg.ad.local) {
1898 if (
msg->msg.ad.local) {
1901 if ((
msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
1911 if ((
msg->msg.ad.local == 0) &&
1912 ((
msg->conn->pcb.tcp->state == CLOSED) || (
msg->conn->pcb.tcp->state == LISTEN))) {
1927 TCPIP_APIMSG_ACK(
msg);
1938lwip_netconn_do_close(
void *
m)
1940 struct api_msg *
msg = (
struct api_msg *)
m;
1943 enum netconn_state
state =
msg->conn->state;
1946 if ((
msg->conn->pcb.tcp !=
NULL) &&
1947 (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_TCP) &&
1948 ((
msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (
state != NETCONN_LISTEN))) {
1950 if (
state == NETCONN_CONNECT) {
1953 }
else if (
state == NETCONN_WRITE) {
1954#if LWIP_NETCONN_FULLDUPLEX
1955 if (
msg->msg.sd.shut & NETCONN_SHUT_WR) {
1959 write_completed_sem = LWIP_API_MSG_SEM(
msg->conn->current_msg);
1961 msg->conn->current_msg =
NULL;
1962 msg->conn->state = NETCONN_NONE;
1963 state = NETCONN_NONE;
1966 LWIP_ASSERT(
"msg->msg.sd.shut == NETCONN_SHUT_RD",
msg->msg.sd.shut == NETCONN_SHUT_RD);
1972 if (
state == NETCONN_NONE) {
1977 if (
msg->msg.sd.shut & NETCONN_SHUT_RD) {
1978#if LWIP_NETCONN_FULLDUPLEX
1980 netconn_mark_mbox_invalid(
msg->conn);
1982 netconn_drain(
msg->conn);
1986 msg->conn->state = NETCONN_CLOSE;
1987 msg->conn->current_msg =
msg;
1988#if LWIP_TCPIP_CORE_LOCKING
1989 if (lwip_netconn_do_close_internal(
msg->conn, 0) !=
ERR_OK) {
1997 lwip_netconn_do_close_internal(
msg->conn);
2007 TCPIP_APIMSG_ACK(
msg);
2010#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD)
2018lwip_netconn_do_join_leave_group(
void *
m)
2020 struct api_msg *
msg = (
struct api_msg *)
m;
2023 if (
msg->conn->pcb.tcp !=
NULL) {
2024 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_UDP) {
2026#if LWIP_IPV6 && LWIP_IPV6_MLD
2027 if (NETCONNTYPE_ISIPV6(
msg->conn->type)) {
2028 if (
msg->msg.jl.join_or_leave == NETCONN_JOIN) {
2039 if (
msg->msg.jl.join_or_leave == NETCONN_JOIN) {
2049#if (LWIP_TCP || LWIP_RAW)
2055 TCPIP_APIMSG_ACK(
msg);
2064lwip_netconn_do_join_leave_group_netif(
void *
m)
2066 struct api_msg *
msg = (
struct api_msg *)
m;
2076 if (
msg->conn->pcb.tcp !=
NULL) {
2077 if (NETCONNTYPE_GROUP(
msg->conn->type) == NETCONN_UDP) {
2079#if LWIP_IPV6 && LWIP_IPV6_MLD
2080 if (NETCONNTYPE_ISIPV6(
msg->conn->type)) {
2081 if (
msg->msg.jl.join_or_leave == NETCONN_JOIN) {
2082 msg->err = mld6_joingroup_netif(
netif,
2085 msg->err = mld6_leavegroup_netif(
netif,
2092 if (
msg->msg.jl.join_or_leave == NETCONN_JOIN) {
2093 msg->err = igmp_joingroup_netif(
netif,
2096 msg->err = igmp_leavegroup_netif(
netif,
2102#if (LWIP_TCP || LWIP_RAW)
2110 TCPIP_APIMSG_ACK(
msg);
2121lwip_netconn_do_dns_found(
const char *
name,
const ip_addr_t *ipaddr,
void *
arg)
2123 struct dns_api_msg *
msg = (
struct dns_api_msg *)
arg;
2128 if (ipaddr ==
NULL) {
2147lwip_netconn_do_gethostbyname(
void *
arg)
2149 struct dns_api_msg *
msg = (
struct dns_api_msg *)
arg;
2151#if LWIP_IPV4 && LWIP_IPV6
2154 LWIP_DNS_ADDRTYPE_DEFAULT;
2159#if LWIP_TCPIP_CORE_LOCKING
STREAM tcp_recv(STREAM s, uint32 length)
RD_BOOL tcp_connect(char *server)
static WCHAR available[MAX_STRING_RESOURCE_LEN]
#define SYS_ARCH_UNPROTECT(lev)
#define SYS_ARCH_PROTECT(lev)
#define SYS_ARCH_DECL_PROTECT(lev)
#define LWIP_DEBUGF(debug, message)
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define ip_current_src_addr()
#define ip_current_dest_addr()
#define LOCK_TCPIP_CORE()
#define UNLOCK_TCPIP_CORE()
GLdouble GLdouble GLdouble GLdouble q
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum const GLvoid * addr
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
#define LWIP_UNUSED_ARG(x)
#define LWIP_CONST_CAST(target_type, val)
#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT
#define RECV_BUFSIZE_DEFAULT
#define TCP_SNDQUEUELOWAT
#define TCP_DEFAULT_LISTEN_BACKLOG
#define DEFAULT_UDP_RECVMBOX_SIZE
#define DEFAULT_TCP_RECVMBOX_SIZE
#define DEFAULT_RAW_RECVMBOX_SIZE
#define DEFAULT_ACCEPTMBOX_SIZE
struct netif * netif_get_by_index(u8_t idx)
u8_t pbuf_free(struct pbuf *p)
struct pbuf * pbuf_clone(pbuf_layer layer, pbuf_type type, struct pbuf *p)
void sys_mbox_set_invalid(sys_mbox_t *mbox)
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
void sys_mbox_free(sys_mbox_t *mbox)
void sys_sem_set_invalid(sys_sem_t *sem)
void sys_sem_free(sys_sem_t *sem)
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
void sys_sem_signal(sys_sem_t *sem)
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
#define ip_addr_isany(ipaddr)
#define ip_addr_set(dest, src)
#define ip_addr_eq(addr1, addr2)
#define ip_addr_copy(dest, src)
#define IP_IS_ANY_TYPE_VAL(ipaddr)
#define IP_SET_TYPE_VAL(ipaddr, iptype)
#define ip_addr_isany_val(ipaddr)
int const JOCTET * dataptr
#define sys_mbox_valid(mbox)
#define sys_sem_valid(sema)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
static IPrintDialogCallback callback
#define SYS_ARCH_GET(var, ret)
#define sys_sem_wait(sem)
#define SYS_ARCH_LOCKED(code)
#define sys_mbox_valid_val(mbox)
#define sys_mbox_tryfetch(mbox, msg)
#define SYS_ARCH_INC(var, val)
void tcp_close(struct sock *sk, long timeout)
struct sock * tcp_accept(struct sock *sk, int flags, int *err)
void tcp_shutdown(struct sock *sk, int how)
unsigned int tcp_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait)
#define API_EXPR_REF(expr)
#define API_EXPR_DEREF(expr)
#define API_EXPR_REF_SEM(expr)