Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use netconn_recv or netconn_recv_tcp_pbuf #357

Open
thumsl opened this issue Mar 22, 2017 · 8 comments
Open

Unable to use netconn_recv or netconn_recv_tcp_pbuf #357

thumsl opened this issue Mar 22, 2017 · 8 comments
Labels

Comments

@thumsl
Copy link

thumsl commented Mar 22, 2017

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
Copy link
Author

thumsl commented Mar 22, 2017

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
Copy link

phlemoine commented Mar 22, 2017 via email

@thumsl
Copy link
Author

thumsl commented Mar 22, 2017

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
Copy link

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

@anyn99
Copy link

anyn99 commented Mar 26, 2017

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
Copy link
Contributor

Zaltora commented Apr 12, 2017

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
Copy link

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants