Left here for archival purposes.

User avatar
By zeroday
#4491 Hi,
socket:send() is a simple wrap for espconn_sent() in sdk.

socket:send()-->get string from para, check len<1460---> call espconn_sent() from sdk
-->call espconn_tcp_sent() if type=tcp--> call tcp_write() in lwip stack.
Code: Select all  const char *payload = luaL_checklstring( L, 2, &l );
  if (l>1460 || payload == NULL)
    return luaL_error( L, "need <1460 payload" );
  if(nud->secure)
    espconn_secure_sent(pesp_conn, (unsigned char *)payload, l);
  else
    espconn_sent(pesp_conn, (unsigned char *)payload, l);


Code: Select allsint8 ICACHE_FLASH_ATTR
espconn_sent(struct espconn *espconn, uint8 *psent, uint16 length)
{
   espconn_msg *pnode = NULL;
   bool value = false;
    if (espconn == NULL) {
        return ESPCONN_ARG;
    }
    espconn ->state = ESPCONN_WRITE;
    value = espconn_find_connection(espconn, &pnode);
    switch (espconn ->type) {
        case ESPCONN_TCP:
            if (value)
               espconn_tcp_sent(pnode, psent, length);
            else
               return ESPCONN_ARG;
            break;

        case ESPCONN_UDP: {
           if (value)
              espconn_udp_sent(pnode, psent, length);
           else
              return ESPCONN_ARG;
            break;
        }

        default :
            break;
    }
    return ESPCONN_OK;
}


Code: Select allvoid ICACHE_FLASH_ATTR
espconn_tcp_sent(void *arg, uint8 *psent, uint16 length)
{
   espconn_msg *ptcp_sent = arg;
    struct tcp_pcb *pcb = NULL;
    err_t err = 0;
    u16_t len = 0;
    u8_t data_to_send = false;

    espconn_printf("espconn_tcp_sent ptcp_sent %p psent %p length %d\n", ptcp_sent, psent, length);

    if (ptcp_sent == NULL || psent == NULL || length == 0) {
        return;
    }

    pcb = ptcp_sent->pcommon.pcb;
    if (tcp_sndbuf(pcb) < length) {
        len = tcp_sndbuf(pcb);
    } else {
        len = length;
        LWIP_ASSERT("length did not fit into uint16!", (len == length));
    }

    if (len > (2 * pcb->mss)) {
        len = 2 * pcb->mss;
    }

    do {
       espconn_printf("espconn_tcp_sent writing %d bytes %p\n", len, pcb);
        err = tcp_write(pcb, psent, len, 0);

        if (err == ERR_MEM) {
            len /= 2;
        }
    } while (err == ERR_MEM && len > 1);

    if (err == ERR_OK) {
        data_to_send = true;
        ptcp_sent->pcommon.ptrbuf = psent + len;
        ptcp_sent->pcommon.cntr = length - len;
        espconn_printf("espconn_tcp_sent sending %d bytes\n", length);
    }

    if (data_to_send == true) {
        err = tcp_output(pcb);
    } else {
       ptcp_sent->pespconn ->state = ESPCONN_CLOSE;
    }
}


and never have a look at the lwip tcp_XXX raw api.
don't know how to flush them :oops:
the code espconn_tcp_sent and espconn_sent is included in sdk 0.9.2
which can be downloaded from
http://bbs.espressif.com/viewtopic.php?f=5&t=3
User avatar
By ThomasW
#4562 Hi,
Digged around in sources/mailinglists and found something interesting:
tcp_nagle_disable(pcb);
This should set TCP_NODELAY on the connection and thus force the stack to send the data out immediately. What I dont know is *where* to place it correctly, I think possible candidates are:
Code: Select allvoid ICACHE_FLASH_ATTR
espconn_tcp_sent(void *arg, uint8 *psent, uint16 length)
{
   espconn_msg *ptcp_sent = arg;
    struct tcp_pcb *pcb = NULL;
    err_t err = 0;
    u16_t len = 0;
    u8_t data_to_send = false;

    espconn_printf("espconn_tcp_sent ptcp_sent %p psent %p length %d\n", ptcp_sent, psent, length);

    if (ptcp_sent == NULL || psent == NULL || length == 0) {
        return;
    }

    pcb = ptcp_sent->pcommon.pcb;
    tcp_nagle_disable(pcb);                   // <============================
    if (tcp_sndbuf(pcb) < length) {
        len = tcp_sndbuf(pcb);
    } else {
        len = length;
        LWIP_ASSERT("length did not fit into uint16!", (len == length));
    }

    if (len > (2 * pcb->mss)) {
        len = 2 * pcb->mss;
    }

    do {
       espconn_printf("espconn_tcp_sent writing %d bytes %p\n", len, pcb);
        tcp_nagle_disable(pcb);                   // <============================
        err = tcp_write(pcb, psent, len, 0);

        if (err == ERR_MEM) {
            len /= 2;
        }
    } while (err == ERR_MEM && len > 1);

    if (err == ERR_OK) {
        data_to_send = true;
        ptcp_sent->pcommon.ptrbuf = psent + len;
        ptcp_sent->pcommon.cntr = length - len;
        espconn_printf("espconn_tcp_sent sending %d bytes\n", length);
    }

    if (data_to_send == true) {
        tcp_nagle_disable(pcb);                   // <============================
        err = tcp_output(pcb);
    } else {
       ptcp_sent->pespconn ->state = ESPCONN_CLOSE;
    }
}

If this works at all - maybe it's sufficient to place it in the calls for opening a listener/sender (which perhaps could be used to implement this as an option to the lua-functions?)
Do you think it's worth a try? It would (if working) have several implications:
+ Hopefully lower the risk for overflowing the send-buffer
+ Let the application decide about packet size
- Probably slow down network speed
- Probably break all examples/apps that have an unconditional socket:close() in their 'sent' - event

Thomas
User avatar
By zeroday
#4576
ThomasW wrote:Hi,
Digged around in sources/mailinglists and found something interesting:
tcp_nagle_disable(pcb);
This should set TCP_NODELAY on the connection and thus force the stack to send the data out immediately. What I dont know is *where* to place it correctly, I think possible candidates are:
Code: Select allvoid ICACHE_FLASH_ATTR
espconn_tcp_sent(void *arg, uint8 *psent, uint16 length)
{
   espconn_msg *ptcp_sent = arg;
    struct tcp_pcb *pcb = NULL;
    err_t err = 0;
    u16_t len = 0;
    u8_t data_to_send = false;

    espconn_printf("espconn_tcp_sent ptcp_sent %p psent %p length %d\n", ptcp_sent, psent, length);

    if (ptcp_sent == NULL || psent == NULL || length == 0) {
        return;
    }

    pcb = ptcp_sent->pcommon.pcb;
    tcp_nagle_disable(pcb);                   // <============================
    if (tcp_sndbuf(pcb) < length) {
        len = tcp_sndbuf(pcb);
    } else {
        len = length;
        LWIP_ASSERT("length did not fit into uint16!", (len == length));
    }

    if (len > (2 * pcb->mss)) {
        len = 2 * pcb->mss;
    }

    do {
       espconn_printf("espconn_tcp_sent writing %d bytes %p\n", len, pcb);
        tcp_nagle_disable(pcb);                   // <============================
        err = tcp_write(pcb, psent, len, 0);

        if (err == ERR_MEM) {
            len /= 2;
        }
    } while (err == ERR_MEM && len > 1);

    if (err == ERR_OK) {
        data_to_send = true;
        ptcp_sent->pcommon.ptrbuf = psent + len;
        ptcp_sent->pcommon.cntr = length - len;
        espconn_printf("espconn_tcp_sent sending %d bytes\n", length);
    }

    if (data_to_send == true) {
        tcp_nagle_disable(pcb);                   // <============================
        err = tcp_output(pcb);
    } else {
       ptcp_sent->pespconn ->state = ESPCONN_CLOSE;
    }
}

If this works at all - maybe it's sufficient to place it in the calls for opening a listener/sender (which perhaps could be used to implement this as an option to the lua-functions?)
Do you think it's worth a try? It would (if working) have several implications:
+ Hopefully lower the risk for overflowing the send-buffer
+ Let the application decide about packet size
- Probably slow down network speed
- Probably break all examples/apps that have an unconditional socket:close() in their 'sent' - event

Thomas


I build a temp firmware, put the code here
Code: Select all    pcb = ptcp_sent->pcommon.pcb;
    tcp_nagle_disable(pcb);                   // <============================
    if (tcp_sndbuf(pcb) < length) {

try this out in attachment.
(219.57 KiB) Downloaded 292 times
User avatar
By ThomasW
#4588
zeroday wrote:
ThomasW wrote:Hi,
I build a temp firmware, put the code here
Code: Select all    pcb = ptcp_sent->pcommon.pcb;
    tcp_nagle_disable(pcb);                   // <============================
    if (tcp_sndbuf(pcb) < length) {

try this out in attachment.
nodemcu_512k-1212.7z


Hi,
That was fast! Alas, no effect on first tests :(
I did some simple consecutive socket:send()'s and hoped for distinct packets - but they still end up
combined into one packet...
Will do more test later...

Thanks for your efforts!
Thomas