espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
12.56k stars 7.01k forks source link

esp_websocket_client CORRUPT HEAP with Node.js ws server (IDFGH-12709) #13695

Open DAV3Y06L3GO opened 2 weeks ago

DAV3Y06L3GO commented 2 weeks ago

Answers checklist.

General issue report

Board: ESP32C3

I'm trying to set up a websocket client on my esp that connects to a Node.js server and the ESP can communicate to the server just fine but I get a "CORRUPT HEAP" error whenever the server tries to send data to the client.

Here is my error:

CORRUPT HEAP: Bad head at 0x3fca769c. Expected 0xabba1234 got 0x3fc96634

assert failed: multi_heap_free multi_heap_poisoning.c:259 (head != NULL)

Here is my ESP code:

#include <Arduino.h>
#include <ESP32Servo.h>

#include <stdio.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "my_data.h"

#include "esp_log.h"
#include "esp_websocket_client.h"
#include "esp_event.h"

Servo jail_servo;

static const char *TAG = "WEBSOCKET";
static bool ws_disable = false;

static void wifi_event_handler(void *event_handler_arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    switch (event_id)
    {
    case WIFI_EVENT_STA_START:
        printf("WiFi connecting ... \n");
        break;
    case WIFI_EVENT_STA_CONNECTED:
        printf("WiFi connected ... \n");
        break;
    case WIFI_EVENT_STA_DISCONNECTED:
        printf("WiFi lost connection ... \n");
        break;
    case IP_EVENT_STA_GOT_IP:
        printf("WiFi got IP ... \n\n");
        break;
    default:
        break;
    }
}

void wifi_connection()
{
    nvs_flash_init();
    // 1 - Wi-Fi/LwIP Init Phase
    esp_netif_init();                    // TCP/IP initiation                   s1.1
    esp_event_loop_create_default();     // event loop                          s1.2
    esp_netif_create_default_wifi_sta(); // WiFi station                        s1.3
    wifi_init_config_t wifi_initiation = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&wifi_initiation); //                                         s1.4
    // 2 - Wi-Fi Configuration Phase
    esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, wifi_event_handler, NULL);
    esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, wifi_event_handler, NULL);

    wifi_config_t wifi_configuration = {
        .sta = {
            {.ssid = SSID},
            {.password = PASS}}};

    esp_wifi_set_config(WIFI_IF_STA, &wifi_configuration);
    // 3 - Wi-Fi Start Phase
    esp_wifi_start();
    // 4- Wi-Fi Connect Phase
    esp_wifi_connect();
}

static void websocket_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
    esp_websocket_event_data_t *data = (esp_websocket_event_data_t *)event_data;
    switch (event_id) {
    case WEBSOCKET_EVENT_CONNECTED:
        ESP_LOGI(TAG, "WEBSOCKET_EVENT_CONNECTED");
        break;
    case WEBSOCKET_EVENT_DATA:
        ESP_LOGW(TAG, "Received=%.*s\n", data->data_len, (char *)data->data_ptr);
        ws_disable = true;
        break;
    }
}

static void websocket_app_start(void)
{
    // Define the websocket connection
    esp_websocket_client_config_t websocket_cfg = {};
    websocket_cfg.uri = "ws://192.168.1.252:8080";
    ESP_LOGI(TAG, "Connecting to %s ...", websocket_cfg.uri);

    // Connect to Websocket Server
    esp_websocket_client_handle_t client = esp_websocket_client_init(&websocket_cfg);
    esp_websocket_register_events(client, WEBSOCKET_EVENT_ANY, websocket_event_handler, (void *)client);

    // Send "Hello ..." to Websocket Server
    esp_websocket_client_start(client);
    char data[32];
    int i = 0;
    while (i < 10) {
        if (esp_websocket_client_is_connected(client)) {
            int len = sprintf(data, "Hello %04d", i++);
            ESP_LOGI(TAG, "Sending %s", data);
            esp_websocket_client_send(client, data, len, portMAX_DELAY);
        }
        vTaskDelay(1000 / portTICK_RATE_MS);
    }

    // Stop websocket connection when ws_disable is set to true

    while (true) {
        if (ws_disable) {
            esp_websocket_client_stop(client);
            ESP_LOGI(TAG, "Websocket Stopped");
            esp_websocket_client_destroy(client);
        }
    }
}

void setup()
{
    jail_servo.attach(1);
    jail_servo.write(90);
    delay(1000);
    jail_servo.write(0); 

    wifi_connection();
    vTaskDelay(1000 / portTICK_RATE_MS);
    websocket_app_start();
}

void loop() {

}

Here is my Node server code:

wss.on('connection', (ws) => {
    console.log('client connected');
    clients.push(ws);

    ws.on('message', (message) => {
        console.log(message.toString());

        if(message.toString() == "Hello 0009") {
            ws.send(“Hi ESP32”);
        }
    });

    ws.on('close', () => {
        console.log("Disconnected");
    });
});