/****************************************************************************** * FunctionName : espconn_tcp_write * Description : write the packet which in the active connection's list. * Parameters : arg -- the node pointer which reverse the packet * Returns : ESPCONN_MEM: memory error * ESPCONN_OK:have enough space for write packet *******************************************************************************/ err_t ICACHE_FLASH_ATTR espconn_tcp_write(void *arg) { espconn_msg *pwrite = (espconn_msg *) arg; err_t err = ERR_OK; struct tcp_pcb *pcb = (struct tcp_pcb *)(pwrite->pcommon.pcb); /*for one active connection,limit the sender buffer space*/ if (tcp_nagle_disabled(pcb) && (pcb->snd_queuelen >= TCP_SND_QUEUELEN(0))) return ESPCONN_MEM; while (tcp_sndbuf(pcb) != 0){ if (pwrite->pcommon.ptail != NULL) { /*Find the node whether in the list's tail or not*/ if (pwrite->pcommon.ptail->unsent == 0) { pwrite->pcommon.ptail = pwrite->pcommon.ptail->pnext; continue; } /*Send the packet for the active connection*/ err = espconn_tcp_sent(pwrite, pwrite->pcommon.ptail->punsent,pwrite->pcommon.ptail->unsent); if (err != ERR_OK) break; } else break; } return err; }
static int altcp_tcp_nagle_disabled(struct altcp_pcb *conn) { if (conn && conn->state) { struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; ALTCP_TCP_ASSERT_CONN(conn); return tcp_nagle_disabled(pcb); } return 0; }
static int ol_tcp_get_opts(outlet_t *ol, uint8_t *data, int dlen, char *buf, int sz) { uint8_t *p = data; char *q = buf; int left = sz; while (p < data +dlen) { int opt = *p++; uint32_t val; switch (opt) { case INET_OPT_RCVBUF: val = ol->recv_bufsize; break; case INET_OPT_PRIORITY: // // See comment in ol_tcp_animate() // val = ol->tcp->prio; break; case INET_OPT_TOS: val = ol->tcp->tos; break; case TCP_OPT_NODELAY: val = tcp_nagle_disabled(ol->tcp); break; default: if (inet_get_opt(ol, opt, &val) < 0) return -BAD_ARG; } if (left < 1 +4) return -TOO_LONG; *q++ = opt; left--; PUT_UINT_32(q, val); q += 4; left -= 4; } return q -buf; }
socket_error_t lwipv4_socket_send(struct socket *socket, const void * buf, const size_t len) { err_t err = ERR_VAL; switch(socket->family) { case SOCKET_DGRAM: { struct pbuf *pb = pbuf_alloc(PBUF_TRANSPORT,len,PBUF_RAM); socket_event_t e; socket_api_handler_t handler = socket->handler; err = pbuf_take(pb, buf, len); if (err != ERR_OK) break; err = udp_send(socket->impl, pb); pbuf_free(pb); if (err != ERR_OK) break; //Notify the application that the transfer is queued at the MAC layer e.event = SOCKET_EVENT_TX_DONE; e.sock = socket; e.i.t.sentbytes = len; socket->event = &e; handler(); socket->event = NULL; break; } case SOCKET_STREAM:{ struct tcp_pcb* pcb = socket->impl; err = tcp_write(pcb,buf,len,TCP_WRITE_FLAG_COPY); if (tcp_nagle_disabled(pcb)) { // TODO: Remove when sal-driver-lwip-k64f-eth/#8 is fixed #ifdef YOTTA_SAL_DRIVER_LWIP_K64F_ETH_VERSION_STRING emac_tcp_push_pcb = (struct pbuf * volatile)pcb; vIRQ_SetPendingIRQ(ENET_Receive_IRQn); #else tcp_output(pcb); #endif } break; } } return lwipv4_socket_error_remap(err); }
bool AsyncServer::getNoDelay(){ if (!_pcb) return false; return tcp_nagle_disabled(_pcb); }