/** * Send some data on a TCP pcb contained in a netconn * Called from netconn_write * * @param msg the api_msg_msg pointing to the connection */ void do_write(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { #if LWIP_TCP msg->conn->state = NETCONN_WRITE; /* set all the variables used by do_writemore */ LWIP_ASSERT("already writing", msg->conn->write_msg == NULL && msg->conn->write_offset == 0); msg->conn->write_msg = msg; msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING msg->conn->write_delayed = 0; if (do_writemore(msg->conn) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); UNLOCK_TCPIP_CORE(); sys_arch_sem_wait(msg->conn->op_completed, 0); LOCK_TCPIP_CORE(); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); } #else do_writemore(msg->conn); #endif /* for both cases: if do_writemore was called, don't ACK the APIMSG! */ return; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { msg->conn->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } } TCPIP_APIMSG_ACK(msg); }
/** * Bind a pcb contained in a netconn * Called from netconn_bind. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to bind to */ void do_bind(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_VAL; if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_listen(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { if (msg->conn->state == NETCONN_NONE) { struct tcp_pcb* lpcb; #if LWIP_IPV6 if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen_dual(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } else #endif /* LWIP_IPV6 */ { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } if (lpcb == NULL) { /* in this case, the old pcb is still allocated */ msg->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (sys_mbox_valid(&msg->conn->recvmbox)) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(&msg->conn->recvmbox); sys_mbox_set_invalid(&msg->conn->recvmbox); } msg->err = ERR_OK; if (!sys_mbox_valid(&msg->conn->acceptmbox)) { msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); } if (msg->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } else { /* since the old pcb is already deallocated, free lpcb now */ tcp_close(lpcb); msg->conn->pcb.tcp = NULL; } } } } else { msg->err = ERR_ARG; } } } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a RAW or UDP pcb contained in a netconn * Called from netconn_send * * @param msg the api_msg_msg pointing to the connection */ void do_send(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (msg->msg.b->addr == NULL) { msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); } else { msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr); } break; #endif #if LWIP_UDP case NETCONN_UDP: if (msg->msg.b->addr == NULL) { msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port); } break; #endif /* LWIP_UDP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */ void do_join_leave_group(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); } else { msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ } } else { msg->err = ERR_CONN; } } TCPIP_APIMSG_ACK(msg); }
/** * Connect a pcb contained inside a netconn * Called from netconn_connect. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to connect to */ void lwip_netconn_do_connect(struct api_msg_msg *msg) { if (msg->conn->pcb.tcp == NULL) { /* This may happen when calling netconn_connect() a second time */ msg->err = ERR_CLSD; if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ sys_sem_signal(&msg->conn->op_completed); return; } } else { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: /* Prevent connect while doing any other action. */ if (msg->conn->state != NETCONN_NONE) { msg->err = ERR_ISCONN; } else { setup_tcp(msg->conn); msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port, lwip_netconn_do_connected); if (msg->err == ERR_OK) { u8_t non_blocking = netconn_is_nonblocking(msg->conn); msg->conn->state = NETCONN_CONNECT; SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); if (non_blocking) { msg->err = ERR_INPROGRESS; } else { msg->conn->current_msg = msg; /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), * when the connection is established! */ return; } } } /* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ sys_sem_signal(&msg->conn->op_completed); return; #endif /* LWIP_TCP */ default: LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); break; } } /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), so use TCPIP_APIMSG_ACK() here. */ TCPIP_APIMSG_ACK(msg); }
/** * Return a connection's local or remote address * Called from netconn_getaddr * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_getaddr(struct api_msg_msg *msg) { if (msg->conn->pcb.ip != NULL) { if (msg->msg.ad.local) { ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->local_ip); } else { ipX_addr_copy(PCB_ISIPV6(msg->conn->pcb.ip), API_EXPR_DEREF(msg->msg.ad.ipaddr), msg->conn->pcb.ip->remote_ip); } msg->err = ERR_OK; switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (msg->msg.ad.local) { API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; } else { /* return an error as connecting is only a helper for upper layers */ msg->err = ERR_CONN; } break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: if (msg->msg.ad.local) { API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; } else { if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { msg->err = ERR_CONN; } else { API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; } } break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: if ((msg->msg.ad.local == 0) && ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) { /* pcb is not connected and remote name is requested */ msg->err = ERR_CONN; } else { API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); } break; #endif /* LWIP_TCP */ default: LWIP_ASSERT("invalid netconn_type", 0); break; } } else { msg->err = ERR_CONN; } TCPIP_APIMSG_ACK(msg); }
/** * Connect a pcb contained inside a netconn * Only used for UDP netconns. * Called from netconn_disconnect. * * @param msg the api_msg_msg pointing to the connection to disconnect */ void do_disconnect(struct api_msg_msg *msg) { #if LWIP_UDP if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { udp_disconnect(msg->conn->pcb.udp); } #endif /* LWIP_UDP */ TCPIP_APIMSG_ACK(msg); }
/** * Bind a pcb contained in a netconn * Called from netconn_bind. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to bind to */ void do_bind(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { //[MS_CHANGE] - make sure we are binding to a valid address u8_t validAddr = ip_addr_isany(msg->msg.bc.ipaddr); if(!validAddr) { struct netif *netif; for(netif = netif_list; netif != NULL; netif = netif->next) { /* network mask matches? */ if (netif_is_up(netif)) { if(ip_addr_cmp(msg->msg.bc.ipaddr, &netif->ip_addr)) { validAddr = 1; break; } } } } //[MS_CHANGE] - make sure we are binding to a valid address if(validAddr) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: break; } } else { msg->conn->err = ERR_VAL; } } else { /* msg->conn->pcb is NULL */ msg->conn->err = ERR_VAL; } } TCPIP_APIMSG_ACK(msg); }
/** * Create a new pcb of a specific type inside a netconn. * Called from netconn_new_with_proto_and_callback. * * @param msg the api_msg_msg describing the connection type */ void do_newconn(struct api_msg_msg *msg) { if(msg->conn->pcb.tcp == NULL) { pcb_new(msg); } /* Else? This "new" connection already has a PCB allocated. */ /* Is this an error condition? Should it be deleted? */ /* We currently just are happy and return. */ TCPIP_APIMSG_ACK(msg); }
/** * Connect a pcb contained inside a netconn * Only used for UDP netconns. * Called from netconn_disconnect. * * @param msg the api_msg_msg pointing to the connection to disconnect */ void do_disconnect(struct api_msg_msg *msg) { #if LWIP_UDP if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { udp_disconnect(msg->conn->pcb.udp); msg->err = ERR_OK; } else #endif /* LWIP_UDP */ { msg->err = ERR_VAL; } TCPIP_APIMSG_ACK(msg); }
/** * Close a TCP pcb contained in a netconn * Called from netconn_close * * @param msg the api_msg_msg pointing to the connection */ void do_close(struct api_msg_msg *msg) { #if LWIP_TCP if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { msg->conn->state = NETCONN_CLOSE; do_close_internal(msg->conn); /* for tcp netconns, do_close_internal ACKs the message */ } else #endif /* LWIP_TCP */ { msg->conn->err = ERR_VAL; TCPIP_APIMSG_ACK(msg); } }
/** * Send some data on a TCP pcb contained in a netconn * Called from netconn_write * * @param msg the api_msg_msg pointing to the connection */ void do_write(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->type == NETCONN_TCP) { #if LWIP_TCP if (msg->conn->state != NETCONN_NONE) { /* netconn is connecting, closing or in blocking write */ msg->err = ERR_INPROGRESS; } else if (msg->conn->pcb.tcp != NULL) { msg->conn->state = NETCONN_WRITE; /* set all the variables used by do_writemore */ LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && msg->conn->write_offset == 0); LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); msg->conn->current_msg = msg; msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; if (do_writemore(msg->conn) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); UNLOCK_TCPIP_CORE(); sys_arch_sem_wait(&msg->conn->op_completed, 0); LOCK_TCPIP_CORE(); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); } #else /* LWIP_TCPIP_CORE_LOCKING */ do_writemore(msg->conn); #endif /* LWIP_TCPIP_CORE_LOCKING */ /* for both cases: if do_writemore was called, don't ACK the APIMSG since do_writemore ACKs it! */ return; } else { msg->err = ERR_CONN; } #else /* LWIP_TCP */ msg->err = ERR_VAL; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } } TCPIP_APIMSG_ACK(msg); }
/** * Return a connection's local or remote address * Called from netconn_getaddr * * @param msg the api_msg_msg pointing to the connection */ void do_getaddr(struct api_msg_msg *msg) { if (msg->conn->pcb.ip != NULL) { *(msg->msg.ad.ipaddr) = (msg->msg.ad.local ? msg->conn->pcb.ip->local_ip : msg->conn->pcb.ip->remote_ip); msg->err = ERR_OK; switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (msg->msg.ad.local) { *(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; } else { /* return an error as connecting is only a helper for upper layers */ msg->err = ERR_CONN; } break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: if (msg->msg.ad.local) { *(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; } else { if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { msg->err = ERR_CONN; } else { *(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; } } break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: *(msg->msg.ad.port) = (msg->msg.ad.local?msg->conn->pcb.tcp->local_port:msg->conn->pcb.tcp->remote_port); break; #endif /* LWIP_TCP */ default: LWIP_ASSERT("invalid netconn_type", 0); break; } } else { msg->err = ERR_CONN; } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a RAW or UDP pcb contained in a netconn * Called from netconn_send * * @param msg the api_msg_msg pointing to the connection */ void do_send(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); } else { msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); } break; #endif #if LWIP_UDP case NETCONN_UDP: #if LWIP_CHECKSUM_ON_COPY if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } else { msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } #else /* LWIP_CHECKSUM_ON_COPY */ if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); } #endif /* LWIP_CHECKSUM_ON_COPY */ break; #endif /* LWIP_UDP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP #if LWIP_IPV6 && LWIP_IPV6_MLD if (PCB_ISIPV6(msg->conn->pcb.udp)) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } } else #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ { #if LWIP_IGMP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } #endif /* LWIP_IGMP */ } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ } } else { msg->err = ERR_CONN; } } TCPIP_APIMSG_ACK(msg); }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void do_listen(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { if (msg->conn->pcb.tcp->state == CLOSED) { #if TCP_LISTEN_BACKLOG struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ if (lpcb == NULL) { msg->conn->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (msg->conn->recvmbox != SYS_MBOX_NULL) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(msg->conn->recvmbox); msg->conn->recvmbox = SYS_MBOX_NULL; } if (msg->conn->acceptmbox == SYS_MBOX_NULL) { if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) { msg->conn->err = ERR_MEM; } } if (msg->conn->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } } } else { msg->conn->err = ERR_CONN; } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */ void do_recv(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { #if TCP_LISTEN_BACKLOG if (msg->conn->pcb.tcp->state == LISTEN) { tcp_accepted(msg->conn->pcb.tcp); } else #endif /* TCP_LISTEN_BACKLOG */ { tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len); } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */ void do_recv(struct api_msg_msg *msg) { msg->err = ERR_OK; if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { #if TCP_LISTEN_BACKLOG if (msg->conn->pcb.tcp->state == LISTEN) { tcp_accepted(msg->conn->pcb.tcp); } else #endif /* TCP_LISTEN_BACKLOG */ { u32_t remaining = msg->msg.r.len; do { u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; tcp_recved(msg->conn->pcb.tcp, recved); remaining -= recved; } while(remaining != 0); } } } TCPIP_APIMSG_ACK(msg); }