79 #define NETCONN_TCP_POLL_INTERVAL 2 81 #define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \ 82 (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ 84 (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) 85 #define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) 89 #if LWIP_TCPIP_CORE_LOCKING 90 #define WRITE_DELAYED , 1 91 #define WRITE_DELAYED_PARAM , u8_t delayed 94 #define WRITE_DELAYED_PARAM 96 static err_t lwip_netconn_do_writemore(
struct netconn *conn WRITE_DELAYED_PARAM);
97 static err_t lwip_netconn_do_close_internal(
struct netconn *conn WRITE_DELAYED_PARAM);
100 #if LWIP_TCPIP_CORE_LOCKING 101 #define TCPIP_APIMSG_ACK(m) NETCONN_SET_SAFE_ERR((m)->conn, (m)->err) 103 #define TCPIP_APIMSG_ACK(m) do { NETCONN_SET_SAFE_ERR((m)->conn, (m)->err); sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) 107 u8_t netconn_aborted;
119 recv_raw(
void *arg,
struct raw_pcb *pcb,
struct pbuf *p,
120 const ip_addr_t *addr)
124 struct netconn *conn;
127 conn = (
struct netconn *)arg;
132 SYS_ARCH_GET(conn->recv_avail, recv_avail);
133 if ((recv_avail + (
int)(p->
tot_len)) > conn->recv_bufsize) {
157 buf->port = pcb->protocol;
165 SYS_ARCH_INC(conn->recv_avail, len);
168 API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
185 recv_udp(
void *arg,
struct udp_pcb *pcb,
struct pbuf *p,
186 const ip_addr_t *addr, u16_t port)
189 struct netconn *conn;
196 LWIP_ASSERT(
"recv_udp must have a pcb argument", pcb != NULL);
197 LWIP_ASSERT(
"recv_udp must have an argument", arg != NULL);
198 conn = (
struct netconn *)arg;
199 LWIP_ASSERT(
"recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb);
202 SYS_ARCH_GET(conn->recv_avail, recv_avail);
204 ((recv_avail + (
int)(p->
tot_len)) > conn->recv_bufsize)) {
219 ip_addr_set(&buf->addr, addr);
221 #if LWIP_NETBUF_RECVINFO 224 const struct udp_hdr* udphdr = (
const struct udp_hdr*)ip_next_header_ptr();
225 #if LWIP_CHECKSUM_ON_COPY 226 buf->flags = NETBUF_FLAG_DESTADDR;
229 buf->toport_chksum = udphdr->dest;
240 SYS_ARCH_INC(conn->recv_avail, len);
243 API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
256 recv_tcp(
void *arg,
struct tcp_pcb *pcb,
struct pbuf *p,
err_t err)
258 struct netconn *conn;
262 LWIP_ASSERT(
"recv_tcp must have a pcb argument", pcb != NULL);
263 LWIP_ASSERT(
"recv_tcp must have an argument", arg != NULL);
264 conn = (
struct netconn *)arg;
269 LWIP_ASSERT(
"recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb);
285 NETCONN_SET_SAFE_ERR(conn, err);
299 SYS_ARCH_INC(conn->recv_avail, len);
302 API_EVENT(conn, NETCONN_EVT_RCVPLUS, len);
320 poll_tcp(
void *arg,
struct tcp_pcb *pcb)
322 struct netconn *conn = (
struct netconn *)arg;
325 LWIP_ASSERT(
"conn != NULL", (conn != NULL));
327 if (conn->state == NETCONN_WRITE) {
328 lwip_netconn_do_writemore(conn WRITE_DELAYED);
329 }
else if (conn->state == NETCONN_CLOSE) {
330 #if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER 331 if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
332 conn->current_msg->msg.sd.polls_left--;
335 lwip_netconn_do_close_internal(conn WRITE_DELAYED);
340 if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) {
343 if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) >
TCP_SNDLOWAT) &&
345 conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
346 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
361 sent_tcp(
void *arg,
struct tcp_pcb *pcb, u16_t len)
363 struct netconn *conn = (
struct netconn *)arg;
366 LWIP_ASSERT(
"conn != NULL", (conn != NULL));
369 if (conn->state == NETCONN_WRITE) {
370 lwip_netconn_do_writemore(conn WRITE_DELAYED);
371 }
else if (conn->state == NETCONN_CLOSE) {
372 lwip_netconn_do_close_internal(conn WRITE_DELAYED);
377 if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) >
TCP_SNDLOWAT) &&
379 conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE;
380 API_EVENT(conn, NETCONN_EVT_SENDPLUS, len);
395 err_tcp(
void *arg,
err_t err)
397 struct netconn *conn;
398 enum netconn_state old_state;
400 conn = (
struct netconn *)arg;
401 LWIP_ASSERT(
"conn != NULL", (conn != NULL));
403 conn->pcb.tcp = NULL;
406 old_state = conn->state;
407 conn->state = NETCONN_NONE;
409 if (old_state == NETCONN_CLOSE) {
412 NETCONN_SET_SAFE_ERR(conn,
ERR_OK);
415 SYS_ARCH_SET(conn->last_err, err);
421 API_EVENT(conn, NETCONN_EVT_ERROR, 0);
424 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
425 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
438 if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
439 (old_state == NETCONN_CONNECT)) {
442 int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn);
443 SET_NONBLOCKING_CONNECT(conn, 0);
445 if (!was_nonblocking_connect) {
446 sys_sem_t* op_completed_sem;
448 LWIP_ASSERT(
"conn->current_msg != NULL", conn->current_msg != NULL);
449 conn->current_msg->err = err;
450 op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
451 LWIP_ASSERT(
"inavlid op_completed_sem",
sys_sem_valid(op_completed_sem));
452 conn->current_msg = NULL;
454 NETCONN_SET_SAFE_ERR(conn, err);
458 LWIP_ASSERT(
"conn->current_msg == NULL", conn->current_msg == NULL);
469 setup_tcp(
struct netconn *conn)
475 tcp_recv(pcb, recv_tcp);
476 tcp_sent(pcb, sent_tcp);
477 tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL);
478 tcp_err(pcb, err_tcp);
488 accept_function(
void *arg,
struct tcp_pcb *newpcb,
err_t err)
490 struct netconn *newconn;
491 struct netconn *conn = (
struct netconn *)arg;
503 if (newpcb == NULL) {
507 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
514 newconn = netconn_alloc(conn->type, conn->callback);
515 if (newconn == NULL) {
519 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
523 newconn->pcb.tcp = newpcb;
527 newconn->last_err = err;
530 tcp_backlog_delayed(newpcb);
536 struct tcp_pcb* pcb = newconn->pcb.tcp;
540 tcp_poll(pcb, NULL, 0);
543 newconn->pcb.tcp = NULL;
547 netconn_free(newconn);
551 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
565 pcb_new(
struct api_msg *msg)
569 LWIP_ASSERT(
"pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL);
571 #if LWIP_IPV6 && LWIP_IPV4 573 if(NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) {
579 switch(NETCONNTYPE_GROUP(msg->conn->type)) {
582 msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto);
583 if (msg->conn->pcb.raw != NULL) {
586 if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) {
587 msg->conn->pcb.raw->chksum_reqd = 1;
588 msg->conn->pcb.raw->chksum_offset = 2;
591 raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn);
597 msg->conn->pcb.udp = udp_new_ip_type(iptype);
598 if (msg->conn->pcb.udp != NULL) {
600 if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) {
601 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE);
604 if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) {
605 udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM);
607 udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn);
613 msg->conn->pcb.tcp = tcp_new_ip_type(iptype);
614 if (msg->conn->pcb.tcp != NULL) {
615 setup_tcp(msg->conn);
624 if (msg->conn->pcb.ip == NULL) {
636 lwip_netconn_do_newconn(
void *m)
638 struct api_msg *msg = (
struct api_msg*)m;
641 if (msg->conn->pcb.tcp == NULL) {
648 TCPIP_APIMSG_ACK(msg);
661 netconn_alloc(
enum netconn_type t, netconn_callback callback)
663 struct netconn *conn;
666 conn = (
struct netconn *)
memp_malloc(MEMP_NETCONN);
673 conn->pcb.tcp = NULL;
676 switch(NETCONNTYPE_GROUP(t)) {
693 LWIP_ASSERT(
"netconn_alloc: undefined netconn_type", 0);
694 goto free_and_return;
698 goto free_and_return;
700 #if !LWIP_NETCONN_SEM_PER_THREAD 703 goto free_and_return;
710 conn->state = NETCONN_NONE;
715 conn->callback = callback;
717 conn->current_msg = NULL;
718 conn->write_offset = 0;
721 conn->send_timeout = 0;
724 conn->recv_timeout = 0;
728 conn->recv_avail = 0;
747 netconn_free(
struct netconn *conn)
749 LWIP_ASSERT(
"PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
750 LWIP_ASSERT(
"recvmbox must be deallocated before calling this function",
753 LWIP_ASSERT(
"acceptmbox must be deallocated before calling this function",
757 #if !LWIP_NETCONN_SEM_PER_THREAD 774 netconn_drain(
struct netconn *conn)
787 if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) {
789 p = (
struct pbuf*)mem;
791 if (conn->pcb.tcp != NULL) {
792 tcp_recved(conn->pcb.tcp, p->
tot_len);
799 netbuf_delete((
struct netbuf *)mem);
810 if (mem != &netconn_aborted) {
811 struct netconn *newconn = (
struct netconn *)mem;
815 netconn_drain(newconn);
816 if (newconn->pcb.tcp != NULL) {
817 tcp_abort(newconn->pcb.tcp);
818 newconn->pcb.tcp = NULL;
820 netconn_free(newconn);
838 lwip_netconn_do_close_internal(
struct netconn *conn WRITE_DELAYED_PARAM)
841 u8_t shut, shut_rx, shut_tx, close;
842 u8_t close_finished = 0;
843 struct tcp_pcb* tpcb;
845 u8_t linger_wait_required = 0;
848 LWIP_ASSERT(
"invalid conn", (conn != NULL));
849 LWIP_ASSERT(
"this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP));
850 LWIP_ASSERT(
"conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
851 LWIP_ASSERT(
"pcb already closed", (conn->pcb.tcp != NULL));
852 LWIP_ASSERT(
"conn->current_msg != NULL", conn->current_msg != NULL);
854 tpcb = conn->pcb.tcp;
855 shut = conn->current_msg->msg.sd.shut;
856 shut_rx = shut & NETCONN_SHUT_RD;
857 shut_tx = shut & NETCONN_SHUT_WR;
860 if (shut == NETCONN_SHUT_RDWR) {
862 }
else if (shut_rx &&
863 ((tpcb->state == FIN_WAIT_1) ||
864 (tpcb->state == FIN_WAIT_2) ||
865 (tpcb->state == CLOSING))) {
867 }
else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) {
877 if (tpcb->state == LISTEN) {
878 tcp_accept(tpcb, NULL);
882 tcp_recv(tpcb, NULL);
883 tcp_accept(tpcb, NULL);
886 tcp_sent(tpcb, NULL);
889 tcp_poll(tpcb, NULL, 0);
899 if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) {
900 if ((conn->linger == 0)) {
904 }
else if (conn->linger > 0) {
906 if (netconn_is_nonblocking(conn)) {
909 }
else if ((s32_t)(
sys_now() - conn->current_msg->msg.sd.time_started) >=
910 (conn->linger * 1000)) {
917 linger_wait_required = 1;
921 if ((err ==
ERR_OK) && (tpcb != NULL))
924 err = tcp_close(tpcb);
927 err = tcp_shutdown(tpcb, shut_rx, shut_tx);
932 if (linger_wait_required) {
945 #if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER 948 if (conn->send_timeout > 0) {
949 close_timeout = conn->send_timeout;
953 if (conn->linger >= 0) {
955 close_timeout = conn->linger * 1000U;
958 if ((s32_t)(
sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) {
960 if (conn->current_msg->msg.sd.polls_left == 0) {
974 if (close_finished) {
976 sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
977 conn->current_msg->err = err;
978 conn->current_msg = NULL;
979 conn->state = NETCONN_NONE;
983 conn->pcb.tcp = NULL;
986 API_EVENT(conn, NETCONN_EVT_ERROR, 0);
989 API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
992 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
995 NETCONN_SET_SAFE_ERR(conn, err);
996 #if LWIP_TCPIP_CORE_LOCKING 1005 if (!close_finished) {
1008 LWIP_ASSERT(
"Closing a listen pcb may not fail!", (tpcb->state != LISTEN));
1010 tcp_sent(tpcb, sent_tcp);
1013 tcp_poll(tpcb, poll_tcp, 1);
1014 tcp_err(tpcb, err_tcp);
1015 tcp_arg(tpcb, conn);
1020 LWIP_ASSERT(
"err != ERR_OK", err !=
ERR_OK);
1032 lwip_netconn_do_delconn(
void *m)
1034 struct api_msg *msg = (
struct api_msg*)m;
1036 enum netconn_state state = msg->conn->state;
1037 LWIP_ASSERT(
"netconn state error",
1038 (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP));
1039 #if LWIP_NETCONN_FULLDUPLEX 1041 if (state != NETCONN_NONE) {
1042 if ((state == NETCONN_WRITE) ||
1043 ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
1045 sys_sem_t* op_completed_sem;
1046 LWIP_ASSERT(
"msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
1047 op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
1048 msg->conn->current_msg->err =
ERR_CLSD;
1049 msg->conn->current_msg = NULL;
1050 msg->conn->write_offset = 0;
1051 msg->conn->state = NETCONN_NONE;
1052 NETCONN_SET_SAFE_ERR(msg->conn,
ERR_CLSD);
1057 if (((state != NETCONN_NONE) &&
1058 (state != NETCONN_LISTEN) &&
1059 (state != NETCONN_CONNECT)) ||
1060 ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
1067 LWIP_ASSERT(
"blocking connect in progress",
1068 (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
1071 netconn_drain(msg->conn);
1073 if (msg->conn->pcb.tcp != NULL) {
1075 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
1078 raw_remove(msg->conn->pcb.raw);
1083 msg->conn->pcb.udp->recv_arg = NULL;
1084 udp_remove(msg->conn->pcb.udp);
1089 LWIP_ASSERT(
"already writing or closing", msg->conn->current_msg == NULL &&
1090 msg->conn->write_offset == 0);
1091 msg->conn->state = NETCONN_CLOSE;
1092 msg->msg.sd.shut = NETCONN_SHUT_RDWR;
1093 msg->conn->current_msg = msg;
1094 #if LWIP_TCPIP_CORE_LOCKING 1095 if (lwip_netconn_do_close_internal(msg->conn, 0) !=
ERR_OK) {
1096 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_CLOSE);
1097 UNLOCK_TCPIP_CORE();
1100 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_NONE);
1103 lwip_netconn_do_close_internal(msg->conn);
1112 msg->conn->pcb.tcp = NULL;
1118 API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
1119 API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
1122 TCPIP_APIMSG_ACK(msg);
1134 lwip_netconn_do_bind(
void *m)
1136 struct api_msg *msg = (
struct api_msg*)m;
1138 if (ERR_IS_FATAL(msg->conn->last_err)) {
1139 msg->err = msg->conn->last_err;
1142 if (msg->conn->pcb.tcp != NULL) {
1143 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
1146 msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
1151 msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
1156 msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
1164 TCPIP_APIMSG_ACK(msg);
1175 lwip_netconn_do_connected(
void *arg,
struct tcp_pcb *pcb,
err_t err)
1177 struct netconn *conn;
1179 sys_sem_t* op_completed_sem = NULL;
1183 conn = (
struct netconn *)arg;
1189 LWIP_ASSERT(
"conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT);
1190 LWIP_ASSERT(
"(conn->current_msg != NULL) || conn->in_non_blocking_connect",
1191 (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn));
1193 if (conn->current_msg != NULL) {
1194 conn->current_msg->err = err;
1195 op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
1197 if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err ==
ERR_OK)) {
1200 was_blocking = !IN_NONBLOCKING_CONNECT(conn);
1201 SET_NONBLOCKING_CONNECT(conn, 0);
1202 LWIP_ASSERT(
"blocking connect state error",
1203 (was_blocking && op_completed_sem != NULL) ||
1204 (!was_blocking && op_completed_sem == NULL));
1205 conn->current_msg = NULL;
1206 conn->state = NETCONN_NONE;
1207 NETCONN_SET_SAFE_ERR(conn,
ERR_OK);
1208 API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
1225 lwip_netconn_do_connect(
void *m)
1227 struct api_msg *msg = (
struct api_msg*)m;
1229 if (msg->conn->pcb.tcp == NULL) {
1233 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
1236 msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr));
1241 msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port);
1247 if (msg->conn->state == NETCONN_CONNECT) {
1249 }
else if (msg->conn->state != NETCONN_NONE) {
1252 setup_tcp(msg->conn);
1253 msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr),
1254 msg->msg.bc.port, lwip_netconn_do_connected);
1255 if (msg->err ==
ERR_OK) {
1256 u8_t non_blocking = netconn_is_nonblocking(msg->conn);
1257 msg->conn->state = NETCONN_CONNECT;
1258 SET_NONBLOCKING_CONNECT(msg->conn, non_blocking);
1262 msg->conn->current_msg = msg;
1265 #if LWIP_TCPIP_CORE_LOCKING 1266 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_CONNECT);
1267 UNLOCK_TCPIP_CORE();
1270 LWIP_ASSERT(
"state!", msg->conn->state != NETCONN_CONNECT);
1279 LWIP_ERROR(
"Invalid netconn type", 0,
do{ msg->err =
ERR_VAL; }
while(0));
1285 TCPIP_APIMSG_ACK(msg);
1296 lwip_netconn_do_disconnect(
void *m)
1298 struct api_msg *msg = (
struct api_msg*)m;
1301 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
1302 udp_disconnect(msg->conn->pcb.udp);
1309 TCPIP_APIMSG_ACK(msg);
1320 lwip_netconn_do_listen(
void *m)
1322 struct api_msg *msg = (
struct api_msg*)m;
1324 if (ERR_IS_FATAL(msg->conn->last_err)) {
1325 msg->err = msg->conn->last_err;
1328 if (msg->conn->pcb.tcp != NULL) {
1329 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
1330 if (msg->conn->state == NETCONN_NONE) {
1331 struct tcp_pcb* lpcb;
1332 if (msg->conn->pcb.tcp->state != CLOSED) {
1338 #if TCP_LISTEN_BACKLOG 1339 backlog = msg->msg.lb.backlog;
1343 #if LWIP_IPV4 && LWIP_IPV6 1347 if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) &&
1348 (netconn_get_ipv6only(msg->conn) == 0)) {
1355 lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err);
1371 if (msg->err ==
ERR_OK) {
1372 msg->conn->state = NETCONN_LISTEN;
1373 msg->conn->pcb.tcp = lpcb;
1374 tcp_arg(msg->conn->pcb.tcp, msg->conn);
1375 tcp_accept(msg->conn->pcb.tcp, accept_function);
1379 msg->conn->pcb.tcp = NULL;
1383 }
else if (msg->conn->state == NETCONN_LISTEN) {
1386 tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog);
1393 TCPIP_APIMSG_ACK(msg);
1404 lwip_netconn_do_send(
void *m)
1406 struct api_msg *msg = (
struct api_msg*)m;
1408 if (ERR_IS_FATAL(msg->conn->last_err)) {
1409 msg->err = msg->conn->last_err;
1412 if (msg->conn->pcb.tcp != NULL) {
1413 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
1416 if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
1417 msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p);
1419 msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr);
1425 #if LWIP_CHECKSUM_ON_COPY 1426 if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
1427 msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p,
1428 msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
1430 msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p,
1431 &msg->msg.b->addr, msg->msg.b->port,
1432 msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum);
1435 if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) {
1436 msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p);
1438 msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port);
1448 TCPIP_APIMSG_ACK(msg);
1459 lwip_netconn_do_recv(
void *m)
1461 struct api_msg *msg = (
struct api_msg*)m;
1464 if (msg->conn->pcb.tcp != NULL) {
1465 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
1466 u32_t remaining = msg->msg.r.len;
1468 u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining;
1469 tcp_recved(msg->conn->pcb.tcp, recved);
1470 remaining -= recved;
1471 }
while (remaining != 0);
1474 TCPIP_APIMSG_ACK(msg);
1477 #if TCP_LISTEN_BACKLOG 1484 lwip_netconn_do_accepted(
void *m)
1486 struct api_msg *msg = (
struct api_msg*)m;
1489 if (msg->conn->pcb.tcp != NULL) {
1490 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
1491 tcp_backlog_accepted(msg->conn->pcb.tcp);
1494 TCPIP_APIMSG_ACK(msg);
1510 lwip_netconn_do_writemore(
struct netconn *conn WRITE_DELAYED_PARAM)
1513 const void *dataptr;
1514 u16_t len, available;
1515 u8_t write_finished = 0;
1520 LWIP_ASSERT(
"conn != NULL", conn != NULL);
1521 LWIP_ASSERT(
"conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE));
1522 LWIP_ASSERT(
"conn->current_msg != NULL", conn->current_msg != NULL);
1523 LWIP_ASSERT(
"conn->pcb.tcp != NULL", conn->pcb.tcp != NULL);
1524 LWIP_ASSERT(
"conn->write_offset < conn->current_msg->msg.w.len",
1525 conn->write_offset < conn->current_msg->msg.w.len);
1527 apiflags = conn->current_msg->msg.w.apiflags;
1528 dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK);
1530 #if LWIP_SO_SNDTIMEO 1531 if ((conn->send_timeout != 0) &&
1532 ((s32_t)(
sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) {
1534 if (conn->write_offset == 0) {
1537 conn->current_msg->msg.w.len = 0;
1541 conn->current_msg->msg.w.len = conn->write_offset;
1542 conn->write_offset = 0;
1547 dataptr = (
const u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset;
1548 diff = conn->current_msg->msg.w.len - conn->write_offset;
1549 if (diff > 0xffffUL) {
1551 apiflags |= TCP_WRITE_FLAG_MORE;
1555 available = tcp_sndbuf(conn->pcb.tcp);
1556 if (available < len) {
1565 apiflags |= TCP_WRITE_FLAG_MORE;
1568 LWIP_ASSERT(
"lwip_netconn_do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len));
1569 err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags);
1573 if (dontblock && (len < conn->current_msg->msg.w.len)) {
1576 API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
1577 conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE;
1578 }
else if ((tcp_sndbuf(conn->pcb.tcp) <=
TCP_SNDLOWAT) ||
1582 API_EVENT(conn, NETCONN_EVT_SENDMINUS, len);
1588 conn->write_offset += len;
1589 if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) {
1591 conn->current_msg->msg.w.len = conn->write_offset;
1595 out_err = tcp_output(conn->pcb.tcp);
1596 if (ERR_IS_FATAL(out_err) || (out_err ==
ERR_RTE)) {
1602 conn->current_msg->msg.w.len = 0;
1611 err_t out_err = tcp_output(conn->pcb.tcp);
1612 if (ERR_IS_FATAL(out_err) || (out_err ==
ERR_RTE)) {
1618 conn->current_msg->msg.w.len = 0;
1619 }
else if (dontblock) {
1623 conn->current_msg->msg.w.len = 0;
1629 conn->current_msg->msg.w.len = 0;
1632 if (write_finished) {
1635 sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg);
1636 conn->current_msg->err = err;
1637 conn->current_msg = NULL;
1638 conn->write_offset = 0;
1639 conn->state = NETCONN_NONE;
1640 NETCONN_SET_SAFE_ERR(conn, err);
1641 #if LWIP_TCPIP_CORE_LOCKING 1648 #if LWIP_TCPIP_CORE_LOCKING 1664 lwip_netconn_do_write(
void *m)
1666 struct api_msg *msg = (
struct api_msg*)m;
1668 if (ERR_IS_FATAL(msg->conn->last_err)) {
1669 msg->err = msg->conn->last_err;
1671 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
1673 if (msg->conn->state != NETCONN_NONE) {
1676 }
else if (msg->conn->pcb.tcp != NULL) {
1677 msg->conn->state = NETCONN_WRITE;
1679 LWIP_ASSERT(
"already writing or closing", msg->conn->current_msg == NULL &&
1680 msg->conn->write_offset == 0);
1681 LWIP_ASSERT(
"msg->msg.w.len != 0", msg->msg.w.len != 0);
1682 msg->conn->current_msg = msg;
1683 msg->conn->write_offset = 0;
1684 #if LWIP_TCPIP_CORE_LOCKING 1685 if (lwip_netconn_do_writemore(msg->conn, 0) !=
ERR_OK) {
1686 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_WRITE);
1687 UNLOCK_TCPIP_CORE();
1690 LWIP_ASSERT(
"state!", msg->conn->state != NETCONN_WRITE);
1693 lwip_netconn_do_writemore(msg->conn);
1704 #if (LWIP_UDP || LWIP_RAW) 1710 TCPIP_APIMSG_ACK(msg);
1720 lwip_netconn_do_getaddr(
void *m)
1722 struct api_msg *msg = (
struct api_msg*)m;
1724 if (msg->conn->pcb.ip != NULL) {
1725 if (msg->msg.ad.local) {
1726 ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
1727 msg->conn->pcb.ip->local_ip);
1729 ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr),
1730 msg->conn->pcb.ip->remote_ip);
1734 switch (NETCONNTYPE_GROUP(msg->conn->type)) {
1737 if (msg->msg.ad.local) {
1738 API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol;
1747 if (msg->msg.ad.local) {
1748 API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port;
1750 if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) {
1753 API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port;
1760 if ((msg->msg.ad.local == 0) &&
1761 ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) {
1765 API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port);
1770 LWIP_ASSERT(
"invalid netconn_type", 0);
1776 TCPIP_APIMSG_ACK(msg);
1787 lwip_netconn_do_close(
void *m)
1789 struct api_msg *msg = (
struct api_msg*)m;
1792 enum netconn_state state = msg->conn->state;
1795 if ((msg->conn->pcb.tcp != NULL) &&
1796 (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
1797 ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) {
1799 if (state == NETCONN_CONNECT) {
1802 }
else if (state == NETCONN_WRITE) {
1803 #if LWIP_NETCONN_FULLDUPLEX 1804 if (msg->msg.sd.shut & NETCONN_SHUT_WR) {
1806 sys_sem_t* write_completed_sem;
1807 LWIP_ASSERT(
"msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
1808 write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
1809 msg->conn->current_msg->err =
ERR_CLSD;
1810 msg->conn->current_msg = NULL;
1811 msg->conn->write_offset = 0;
1812 msg->conn->state = NETCONN_NONE;
1813 state = NETCONN_NONE;
1814 NETCONN_SET_SAFE_ERR(msg->conn,
ERR_CLSD);
1817 LWIP_ASSERT(
"msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD);
1820 msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0);
1823 if (state == NETCONN_NONE) {
1828 if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
1830 netconn_drain(msg->conn);
1832 LWIP_ASSERT(
"already writing or closing", msg->conn->current_msg == NULL &&
1833 msg->conn->write_offset == 0);
1834 msg->conn->state = NETCONN_CLOSE;
1835 msg->conn->current_msg = msg;
1836 #if LWIP_TCPIP_CORE_LOCKING 1837 if (lwip_netconn_do_close_internal(msg->conn, 0) !=
ERR_OK) {
1838 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_CLOSE);
1839 UNLOCK_TCPIP_CORE();
1842 LWIP_ASSERT(
"state!", msg->conn->state == NETCONN_NONE);
1845 lwip_netconn_do_close_internal(msg->conn);
1855 TCPIP_APIMSG_ACK(msg);
1858 #if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) 1866 lwip_netconn_do_join_leave_group(
void *m)
1868 struct api_msg *msg = (
struct api_msg*)m;
1870 if (ERR_IS_FATAL(msg->conn->last_err)) {
1871 msg->err = msg->conn->last_err;
1873 if (msg->conn->pcb.tcp != NULL) {
1874 if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) {
1876 #if LWIP_IPV6 && LWIP_IPV6_MLD 1877 if (NETCONNTYPE_ISIPV6(msg->conn->type)) {
1878 if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
1879 msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
1880 ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
1882 msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)),
1883 ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr)));
1890 if (msg->msg.jl.join_or_leave == NETCONN_JOIN) {
1891 msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)),
1892 ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
1894 msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)),
1895 ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr)));
1900 #if (LWIP_TCP || LWIP_RAW) 1909 TCPIP_APIMSG_ACK(msg);
1920 lwip_netconn_do_dns_found(
const char *name,
const ip_addr_t *ipaddr,
void *arg)
1922 struct dns_api_msg *msg = (
struct dns_api_msg*)arg;
1927 if (ipaddr == NULL) {
1929 API_EXPR_DEREF(msg->err) =
ERR_VAL;
1932 API_EXPR_DEREF(msg->err) =
ERR_OK;
1933 API_EXPR_DEREF(msg->addr) = *ipaddr;
1946 lwip_netconn_do_gethostbyname(
void *arg)
1948 struct dns_api_msg *msg = (
struct dns_api_msg*)arg;
1950 #if LWIP_IPV4 && LWIP_IPV6 1953 LWIP_DNS_ADDRTYPE_DEFAULT;
1956 API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name,
1957 API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype);
void sys_sem_free(sys_sem_t *sem)
#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT
#define DEFAULT_TCP_RECVMBOX_SIZE
#define ip_current_src_addr()
#define sys_mbox_tryfetch(mbox, msg)
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
void memp_free(memp_t type, void *mem)
err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from)
#define ip_current_dest_addr()
void sys_mbox_free(sys_mbox_t *mbox)
void sys_mbox_set_invalid(sys_mbox_t *mbox)
int sys_mbox_valid(sys_mbox_t *mbox)
#define RECV_BUFSIZE_DEFAULT
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
#define DEFAULT_ACCEPTMBOX_SIZE
void sys_sem_signal(sys_sem_t *sem)
err_t sys_sem_new(sys_sem_t *sem, u8_t count)
void sys_sem_set_invalid(sys_sem_t *sem)
#define LWIP_DEBUGF(debug, message)
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
#define DEFAULT_UDP_RECVMBOX_SIZE
err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
#define LWIP_UNUSED_ARG(x)
u8_t pbuf_free(struct pbuf *p)
#define DEFAULT_RAW_RECVMBOX_SIZE
#define TCP_SNDQUEUELOWAT
void * memp_malloc(memp_t type)
int sys_sem_valid(sys_sem_t *sem)
#define TCP_DEFAULT_LISTEN_BACKLOG