SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.53k stars 491 forks source link

Unable to use netconn_recv or netconn_recv_tcp_pbuf #357

Open thumsl opened 7 years ago

thumsl commented 7 years ago

Every way I tried to use both netconn_recv() and netconn_recv_tcp_pbuf() failed catastrophically so far. I tried following examples/access_point and tests/cases/04_wifi_basic.c to craft the code below, which is supposed to listen to port 99 and then print whatever was received (if anything). But, as soon as either of the mentioned functions are called, I get a Fatal exception.

Hopefully someone can help me understand what I am doing wrong, here are my code and serial output:

#include <string.h>
#include <espressif/esp_common.h>
#include <esp/uart.h>
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>

#include <lwip/api.h>
#include <lwip/err.h>
#include <lwip/sockets.h>
#include <lwip/sys.h>
#include <lwip/netdb.h>
#include <lwip/dns.h>

#include <dhcpserver.h>

#define SSID "SSID"
#define PASSWORD "testing1"
#define PORT 99

void wifi_task(void *pvParamaters)
{
    char msg_buf[16];
    struct netconn *con = netconn_new(NETCONN_TCP);

    if (!con) {
        printf("Error: failed to allocate socket.\n");
        return;
    }

    netconn_bind(con, IP_ADDR_ANY, PORT);
    netconn_listen(con);

    while (1) {
        struct netconn *client = NULL;
        if (netconn_accept(con, &client) != ERR_OK) {
            printf("No clients to accept\n");
            if (client)
                netconn_delete(client);
            continue;
        }

        struct pbuf *buf;
        printf("Right before netconn_recv()\n");
        if (netconn_recv_tcp_pbuf(con, &buf) != ERR_OK) {
            netconn_delete(client);
            printf("No messages received\n");
            continue;
        }

        if (buf->len > 0) {
            memcpy(msg_buf, buf->payload, 15);
            msg_buf[15] = 0;
            printf("Received:\t%s\n", msg_buf);
        }

        netconn_delete(client);
    }
}

void user_init(void)
{
    printf("SDK version:%s\n", sdk_system_get_sdk_version());

    // UART INIT
    uart_set_baud(0, 115200);

    // WIFI INIT
    sdk_wifi_set_opmode(SOFTAP_MODE);

    struct ip_info ap_ip;
    IP4_ADDR(&ap_ip.ip, 192, 168, 0, 1);
    IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0);
    IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0);

    sdk_wifi_set_ip_info(1, &ap_ip);

    struct sdk_softap_config ap_config = {
        .ssid = SSID,
        .ssid_hidden = 0,
        .channel = 3,
        .ssid_len = strlen(SSID),
        .authmode = AUTH_WPA_WPA2_PSK,
        .password = PASSWORD,
        .max_connection = 1,
        .beacon_interval = 100,
    };

    sdk_wifi_softap_set_config(&ap_config);

    ip_addr_t first_ip;
    IP4_ADDR(&first_ip, 192, 168, 0, 100);
    dhcpserver_start(&first_ip, 4);

    xTaskCreate(wifi_task, "WiFi Task", 1024, NULL, 2, NULL);
}
SDK version:0.9.9
mode : softAP(62:01:94:10:0e:8e)
add if1
bcn 100
add 1
aid 1
station: ::removed:: join, AID = 1
State dump. Message type 1
lease slot 0 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 1 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 2 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 3 expiry 0 hwaddr 00:00:00:00:00:00
State dump. Message type 3
lease slot 0 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 1 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 2 expiry 0 hwaddr 00:00:00:00:00:00
lease slot 3 expiry 0 hwaddr 00:00:00:00:00:00
DHCP lease addr 192.168.0.100 assigned to MAC ::removed::
Right before netconn_recv()
Fatal exception (28): 
epc1=0x40203eb8
epc2=0x00000000
epc3=0x40203181
excvaddr=0x00000038
depc=0x00000000
excsave1=0x40203eb5
Registers:
a0 40203eb5 a1 3fff7d80 a2  3fff0e18 a3  00000001
a4  00000020 a5  00000000 a6  0000007f a7  60000000
a8  3ffe8c86 a9  0000000d a10 3ffe8c86 a11 0000000a
a12 00000000 a13 00000000 SAR 00000000

Stack: SP=0x3fff7d80
0x3fff7d80: 00000000 00000000 3fff8638 402125b4
0x3fff7d90: ffffffff 00000000 00000001 00000001
0x3fff7da0: 3fff7e00 3ffe800c 3fff150c 00000831
0x3fff7db0: 3fff8514 3fff7e0c 00000000 40209ea0
0x3fff7dc0: 3fff8518 3fff7e00 00000001 40209ea8
0x3fff7dd0: 00000000 00000000 3fff7e00 40214a30
0x3fff7de0: fffffff7 3fff7e40 3fff8500 4020b51e
0x3fff7df0: 40214a48 0000001b 3ffe8c85 00000001

Free Heap: 32552
_heap_start 0x3fff1418 brk 0x3fff86c0 supervisor sp 0x3ffffbs
arena (total_size) 29352 fordblks (free_size) 2792 uordblock0

 ets Jan  8 2013,rst cause:2, boot mode:(3,7)
thumsl commented 7 years ago

The crash happens during the execution of netconn_recv_tcp_pbuf(), neither of the printfs on the following snippet are executed:

                struct pbuf *buf;
                if (netconn_recv_tcp_pbuf(con, &buf) != ERR_OK) {
                        printf("buf=%p\n", buf);
                        netconn_delete(client);
                        continue;
                }
                printf("buf=%p\n", buf);

The line that's causing the crash:

╰─➤  xtensa-lx106-elf-addr2line -pfia -e program.out 0x40203eb5
0x40203eb5: xQueueGenericReceive at /media/Development/esp-openrtos/FreeRTOS/Source/queue.c:1610
phlemoine commented 7 years ago

msg_buf is 16 bytes. When connecting with telnet, there is a 24 bytes header sent. Over http, header is few hundreds. I would probably increase msg_buf and in any case limit the memcpy operation to the smallest of buf->len and msg_buf size.

On Mar 22, 2017 7:29 AM, "lcthums" notifications@github.com wrote:

Every way I tried to use both netconn_recv() and netconn_recv_tcp_pbuf() failed catastrophically so far. I tried following examples/access_point https://github.com/SuperHouse/esp-open-rtos/blob/master/examples/access_point/access_point.c and tests/cases/04_wifi_basic.c https://github.com/SuperHouse/esp-open-rtos/blob/master/tests/cases/04_wifi_basic.c to craft the code below, which is supposed to listen to port 99 and then print whatever was received (if anything). But, as soon as either of the mentioned functions are called, I get a Fatal exception.

Hopefully someone can help me understand what I am doing wrong, here are my code and serial output:

include

include <espressif/esp_common.h>

include <esp/uart.h>

include

include

include

include <lwip/api.h>

include <lwip/err.h>

include <lwip/sockets.h>

include <lwip/sys.h>

include <lwip/netdb.h>

include <lwip/dns.h>

include

define SSID "SSID"

define PASSWORD "testing1"

define PORT 99

void wifi_task(void pvParamaters) { char msg_buf[16]; struct netconn con = netconn_new(NETCONN_TCP);

if (!con) { printf("Error: failed to allocate socket.\n"); return; }

netconn_bind(con, IP_ADDR_ANY, PORT); netconn_listen(con);

while (1) { struct netconn *client = NULL; if (netconn_accept(con, &client) != ERR_OK) { printf("No clients to accept\n"); if (client) netconn_delete(client); continue; }

  struct pbuf *buf;
  printf("Right before netconn_recv()\n");
  if (netconn_recv_tcp_pbuf(con, &buf) != ERR_OK) {
      netconn_delete(client);
      printf("No messages received\n");
      continue;
  }

  if (buf->len > 0) {
      memcpy(msg_buf, buf->payload, buf->len);
      msg_buf[buf->len] = 0;
      printf("Received:\t%s\n", msg_buf);
  }

  netconn_delete(client);

} }

void user_init(void) { printf("SDK version:%s\n", sdk_system_get_sdk_version());

// UART INIT uart_set_baud(0, 115200);

// WIFI INIT sdk_wifi_set_opmode(SOFTAP_MODE);

struct ip_info ap_ip; IP4_ADDR(&ap_ip.ip, 192, 168, 0, 1); IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0); IP4_ADDR(&ap_ip.netmask, 255, 255, 0, 0);

sdk_wifi_set_ip_info(1, &ap_ip);

struct sdk_softap_config ap_config = { .ssid = SSID, .ssid_hidden = 0, .channel = 3, .ssid_len = strlen(SSID), .authmode = AUTH_WPA_WPA2_PSK, .password = PASSWORD, .max_connection = 1, .beacon_interval = 100, };

sdk_wifi_softap_set_config(&ap_config);

ip_addr_t first_ip; IP4_ADDR(&first_ip, 192, 168, 0, 100); dhcpserver_start(&first_ip, 4);

xTaskCreate(wifi_task, "WiFi Task", 1024, NULL, 2, NULL); }

SDK version:0.9.9 mode : softAP(62:01:94:10:0e:8e) add if1 bcn 100 add 1 aid 1 station: c0:ee:fb:ee:8a:6c join, AID = 1 State dump. Message type 1 lease slot 0 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 1 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 2 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 3 expiry 0 hwaddr 00:00:00:00:00:00 State dump. Message type 3 lease slot 0 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 1 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 2 expiry 0 hwaddr 00:00:00:00:00:00 lease slot 3 expiry 0 hwaddr 00:00:00:00:00:00 DHCP lease addr 192.168.0.100 assigned to MAC ::removed:: Right before netconn_recv() Fatal exception (28): epc1=0x40203eb8 epc2=0x00000000 epc3=0x40203181 excvaddr=0x00000038 depc=0x00000000 excsave1=0x40203eb5 Registers: a0 40203eb5 a1 3fff7d80 a2 3fff0e18 a3 00000001 a4 00000020 a5 00000000 a6 0000007f a7 60000000 a8 3ffe8c86 a9 0000000d a10 3ffe8c86 a11 0000000a a12 00000000 a13 00000000 SAR 00000000

Stack: SP=0x3fff7d80 0x3fff7d80: 00000000 00000000 3fff8638 402125b4 0x3fff7d90: ffffffff 00000000 00000001 00000001 0x3fff7da0: 3fff7e00 3ffe800c 3fff150c 00000831 0x3fff7db0: 3fff8514 3fff7e0c 00000000 40209ea0 0x3fff7dc0: 3fff8518 3fff7e00 00000001 40209ea8 0x3fff7dd0: 00000000 00000000 3fff7e00 40214a30 0x3fff7de0: fffffff7 3fff7e40 3fff8500 4020b51e 0x3fff7df0: 40214a48 0000001b 3ffe8c85 00000001

Free Heap: 32552 _heap_start 0x3fff1418 brk 0x3fff86c0 supervisor sp 0x3ffffbs arena (total_size) 29352 fordblks (free_size) 2792 uordblock0

ets Jan 8 2013,rst cause:2, boot mode:(3,7)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/SuperHouse/esp-open-rtos/issues/357, or mute the thread https://github.com/notifications/unsubscribe-auth/ATZ3zE7hOsaQei64yAY01IK3drtT3OtMks5roTA9gaJpZM4MlSLZ .

thumsl commented 7 years ago

msg_buf is 16 bytes.

Yes, I am sorry, that's my bad as I seem to have shared an older version of the code with you. I was already copying only 15 bytes with memcpy() and zeroing the 16th byte (msg_buf[15]).

I'm gona edit the original post to reflect this.

malachib commented 7 years ago

I'm curious what the resolution for this issue is. Smells similar to #322

anyn99 commented 7 years ago

Since the crash was inside the FreeRtos code, try defining a function for configASSERT (just try searching for it in the FreeRtos source, if you don't know what i mean, just ask again) I was planning anyway to submit a pull request on this, since it's a very useful debugging tool.

I bet if the Freertos queue is failing, there is something going wrong before that, a there should be an assert detecting this.

Zaltora commented 7 years ago

I got an example of wifi echo with netconn. It is work well : (i do it from a pdf that talk about Lwip api. i change the original example. Remove char buf[50];, i put it for some test)

static void echoTask(void *pvParameters)
{
    struct netconn *conn, *client;
    err_t err;
    struct netbuf *netbuf;
    void *data;
    uint16_t len;
    err_t recv_err;
    char buf[50];

    /* Create a new connection identifier. */
    conn = netconn_new(NETCONN_TCP);
    if (conn==NULL)
        goto error_loop;
    /* Bind connection to well known port number 7. */
    err = netconn_bind(conn, NULL, ECHO_PORT);
    if (err != ERR_OK)
        goto error_loop;
    /* Tell connection to go into listening mode. */
    netconn_listen(conn);

    while(1)
    {
        /* Grab new connection. */
        err = netconn_accept(conn, &client);
        if ( err != ERR_OK ) {
            if(client)
                netconn_delete(client);
            continue;
        }

        while (( recv_err = netconn_recv(client, &netbuf)) == ERR_OK)
        {
            do
            {
                netbuf_data(netbuf, &data, &len);
                netconn_write(client, data, len, NETCONN_COPY);
            }
            while (netbuf_next(netbuf) >= 0);
            netbuf_delete(netbuf);
        }
        /* Close connection and discard connection identifier. */
        netconn_close(client);
        netconn_delete(client);

    }

    error_loop:
    printf("%s: error detected\n", __func__);
    for(;;){
        vTaskDelay(2000/portTICK_PERIOD_MS);
        printf("%s: error loop\n", __FUNCTION__);
    }

}
argandas commented 5 years ago

I got an example of wifi echo with netconn. It is work well : (i do it from a pdf that talk about Lwip api. i change the original example. Remove char buf[50];, i put it for some test)

static void echoTask(void *pvParameters)
{
    struct netconn *conn, *client;
    err_t err;
    struct netbuf *netbuf;
    void *data;
    uint16_t len;
    err_t recv_err;
    char buf[50];

    /* Create a new connection identifier. */
    conn = netconn_new(NETCONN_TCP);
    if (conn==NULL)
        goto error_loop;
    /* Bind connection to well known port number 7. */
    err = netconn_bind(conn, NULL, ECHO_PORT);
    if (err != ERR_OK)
        goto error_loop;
    /* Tell connection to go into listening mode. */
    netconn_listen(conn);

    while(1)
    {
        /* Grab new connection. */
        err = netconn_accept(conn, &client);
        if ( err != ERR_OK ) {
            if(client)
                netconn_delete(client);
            continue;
        }

        while (( recv_err = netconn_recv(client, &netbuf)) == ERR_OK)
        {
            do
            {
                netbuf_data(netbuf, &data, &len);
                netconn_write(client, data, len, NETCONN_COPY);
            }
            while (netbuf_next(netbuf) >= 0);
            netbuf_delete(netbuf);
        }
        /* Close connection and discard connection identifier. */
        netconn_close(client);
        netconn_delete(client);

    }

    error_loop:
    printf("%s: error detected\n", __func__);
    for(;;){
        vTaskDelay(2000/portTICK_PERIOD_MS);
        printf("%s: error loop\n", __FUNCTION__);
    }

}

Could you please share the PDF where you get the example from? :)

ajfs2093 commented 2 years ago

Hola

Encontré una solución que me funcionó. También se me estaba bloqueando mi código.

Dentro de la función netconn_accept(conn, &newconn) está la función sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);

Cambien el 0, por un valor de 1000 o 2000 o 3000, o el valor que ustedes quieran. Yo en mi aplicación lo tengo de 1000. Si después de 1000 milisegundos, no se conecta, me salgo de la función. sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 1000);

Dentro de la función netconn_recv(newconn, &buf) está la función netconn_recv_data(struct netconn *conn, void **new_buf) y esta a su vez llama a sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0);

Para mi aplicación, yo le puse un valor de 4000 milisegundos, que es el timeout que le doy para tener comunicación con mi servidor. Si no tengo comunicación con mi servidor, me salgo a los 4 segundos.

sys_arch_mbox_fetch(&conn->recvmbox, &buf, 4000);

A mi me funcionó esto. Saludos