📄 api_msg.c
字号:
*/voiddo_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);}/** * 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 */voiddo_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);}/** * 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 */voiddo_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);}/** * 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 */voiddo_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);}#if LWIP_TCP/** * See if more data needs to be written from a previous call to netconn_write. * Called initially from do_write. If the first call can't send all data * (because of low memory or empty send-buffer), this function is called again * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the * blocking application thread (waiting in netconn_write) is released. * * @param conn netconn (that is currently in state NETCONN_WRITE) to process * @return ERR_OK * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished */static err_tdo_writemore(struct netconn *conn){ err_t err; void *dataptr; u16_t len, available; u8_t write_finished = 0; size_t diff; LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); dataptr = (u8_t*)conn->write_msg->msg.w.dataptr + conn->write_offset; diff = conn->write_msg->msg.w.len - conn->write_offset; if (diff > 0xffffUL) { /* max_u16_t */ len = 0xffff;#if LWIP_TCPIP_CORE_LOCKING conn->write_delayed = 1;#endif } else { len = (u16_t)diff; } available = tcp_sndbuf(conn->pcb.tcp); if (available < len) { /* don't try to write more than sendbuf */ len = available;#if LWIP_TCPIP_CORE_LOCKING conn->write_delayed = 1;#endif } err = tcp_write(conn->pcb.tcp, dataptr, len, conn->write_msg->msg.w.apiflags); LWIP_ASSERT("do_writemore: invalid length!", ((conn->write_offset + len) <= conn->write_msg->msg.w.len)); if (err == ERR_OK) { conn->write_offset += len; if (conn->write_offset == conn->write_msg->msg.w.len) { /* everything was written */ write_finished = 1; conn->write_msg = NULL; conn->write_offset = 0; /* API_EVENT might call tcp_tmr, so reset conn->state now */ conn->state = NETCONN_NONE; } err = tcp_output_nagle(conn->pcb.tcp); conn->err = err; if ((err == ERR_OK) && (tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT)) { API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); } } else if (err == ERR_MEM) { /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called we do NOT return to the application thread, since ERR_MEM is only a temporary error! */ /* tcp_enqueue returned ERR_MEM, try tcp_output anyway */ err = tcp_output(conn->pcb.tcp);#if LWIP_TCPIP_CORE_LOCKING conn->write_delayed = 1;#endif } else { /* On errors != ERR_MEM, we don't try writing any more but return the error to the application thread. */ conn->err = err; write_finished = 1; } if (write_finished) { /* everything was written: set back connection state and back to application task */ conn->state = NETCONN_NONE;#if LWIP_TCPIP_CORE_LOCKING if (conn->write_delayed != 0)#endif { sys_sem_signal(conn->op_completed); } }#if LWIP_TCPIP_CORE_LOCKING else return ERR_MEM;#endif return ERR_OK;}#endif /* LWIP_TCP *//** * 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 */voiddo_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);}/** * Return a connection's local or remote address * Called from netconn_getaddr * * @param msg the api_msg_msg pointing to the connection */voiddo_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); 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->conn->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->conn->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 */ } } else { msg->conn->err = ERR_CONN; } 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 */voiddo_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; sys_sem_signal(msg->conn->op_completed); }}#if LWIP_IGMP/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */voiddo_join_leave_group(struct api_msg_msg *msg){ if (!ERR_IS_FATAL(msg->conn->err)) { 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->conn->err = igmp_joingroup(msg->msg.jl.interface, msg->msg.jl.multiaddr); } else { msg->conn->err = igmp_leavegroup(msg->msg.jl.interface, msg->msg.jl.multiaddr); }#endif /* LWIP_UDP */#if (LWIP_TCP || LWIP_RAW) } else { msg->conn->err = ERR_VAL;#endif /* (LWIP_TCP || LWIP_RAW) */ } } } TCPIP_APIMSG_ACK(msg);}#endif /* LWIP_IGMP */#if LWIP_DNS/** * Callback function that is called when DNS name is resolved * (or on timeout). A waiting application thread is waked up by * signaling the semaphore. */static voiddo_dns_found(const char *name, struct ip_addr *ipaddr, void *arg){ struct dns_api_msg *msg = (struct dns_api_msg*)arg; LWIP_ASSERT("DNS response for wrong host name", strcmp(msg->name, name) == 0); if (ipaddr == NULL) { /* timeout or memory error */ *msg->err = ERR_VAL; } else { /* address was resolved */ *msg->err = ERR_OK; *msg->addr = *ipaddr; } /* wake up the application task waiting in netconn_gethostbyname */ sys_sem_signal(msg->sem);}/** * Execute a DNS query * Called from netconn_gethostbyname * * @param arg the dns_api_msg pointing to the query */voiddo_gethostbyname(void *arg){ struct dns_api_msg *msg = (struct dns_api_msg*)arg; *msg->err = dns_gethostbyname(msg->name, msg->addr, do_dns_found, msg); if (*msg->err != ERR_INPROGRESS) { /* on error or immediate success, wake up the application * task waiting in netconn_gethostbyname */ sys_sem_signal(msg->sem); }}#endif /* LWIP_DNS */#endif /* LWIP_NETCONN */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -