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

BSD socket: Certain send data size (256) may lead to loss of first or last byte (IDFGH-14771) #15509

Open
wuwbobo2021 opened this issue Mar 3, 2025 · 0 comments
Assignees
Labels
Status: Opened Issue is new

Comments

@wuwbobo2021
Copy link

Tested on ESP32-S2FH4, ESP-IDF 5.3.0 and 5.4.0.

This is a working test case. Change TX_DATA_SIZE to 256, then it will produce strange data at the receiver side.

CMakeList.txt:

# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(esp32s2_wifi_test)

sdkconfig.defaults (from iperf example):

CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=8
CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=24
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=24
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
CONFIG_ESP_WIFI_TX_BA_WIN=16
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
CONFIG_ESP_WIFI_RX_BA_WIN=16

CONFIG_LWIP_TCP_SND_BUF_DEFAULT=28000
CONFIG_LWIP_TCP_WND_DEFAULT=28000
CONFIG_LWIP_TCP_RECVMBOX_SIZE=32
CONFIG_LWIP_UDP_RECVMBOX_SIZE=32
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32

CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240

CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
CONFIG_ESPTOOLPY_FLASHFREQ_80M=y

CONFIG_ESP32S2_INSTRUCTION_CACHE_16KB=y
CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B=y
CONFIG_ESP32S2_INSTRUCTION_CACHE_WRAP=y

CONFIG_LWIP_TCPIP_CORE_LOCKING=y
CONFIG_LWIP_TCPIP_CORE_LOCKING_INPUT=y

CONFIG_I2S_ENABLE_DEBUG_LOG=y

main/CMakeList.txt:

idf_component_register(
    SRCS "main.c"
    INCLUDE_DIRS "."
    PRIV_REQUIRES esp_driver_gpio esp_wifi esp_phy esp_netif lwip
                  esp_event wpa_supplicant nvs_flash
)

main/main.c:

#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#include "soc/soc.h"

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include <sys/socket.h>
#include "lwip/err.h"
#include "lwip/sys.h"

#include "sdkconfig.h"

#define TAG "main"

#define TX_DATA_SIZE 240
static uint8_t tx_data[TX_DATA_SIZE] = {0};

static uint8_t frm_head[] = {0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0xef, 0x00};

// portTICK_PERIOD_MS can be 10ms, which is the minimum (unit) delay time
#define os_delay_ms(ms) vTaskDelay(ms / portTICK_PERIOD_MS)

#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static EventGroupHandle_t s_wifi_event_group;

static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        esp_wifi_connect();
        ESP_LOGI(TAG, "retry to connect to the AP");
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

void app_wifi_sta_init(void)
{
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_sta();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    esp_event_handler_instance_t instance_any_id, instance_got_ip;
    ESP_ERROR_CHECK(esp_event_handler_instance_register(
        WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(
        IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = "YOUR_AP",         // !!!! TO BE CHANGED
            .password = "-----------", // !!!! TO BE CHANGED
            .threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK,
            .sae_pwe_h2e = WPA3_SAE_PWE_HUNT_AND_PECK,
            .sae_h2e_identifier = "",
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_init_sta finished.");

    // waits until either the connection is established (WIFI_CONNECTED_BIT)
    // The bits are set by event_handler()
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);

    if (bits & WIFI_CONNECTED_BIT) {
        ESP_LOGI(TAG, "connected.");
    } else {
        ESP_LOGE(TAG, "UNEXPECTED EVENT");
        ESP_ERROR_CHECK(1); //TODO: retry
    }
}

static int server_socket = 0;
static int connect_socket = 0;

#define SERVER_PORT ((uint16_t) 21231)
static struct sockaddr_in server_addr;

static esp_err_t server_socket_init()
{
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0) {
        close(server_socket);
        return ESP_FAIL;
    }
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        close(server_socket);
        return ESP_FAIL;
    }

    return ESP_OK;
}

static esp_err_t server_socket_listen()
{
    if (listen(server_socket, 1) < 0) {
        return ESP_FAIL;
    }
    socklen_t addr_len = sizeof(server_addr);
    connect_socket = accept(server_socket, (struct sockaddr *)&server_addr, &addr_len);
    if (connect_socket < 0) {
        close(connect_socket);
        return ESP_FAIL;
    }
    return ESP_OK;
}

static esp_err_t send_all(int s, void *dataptr, size_t size) {
    while (size > 0) {
        ssize_t result = send(s, dataptr, size, 0);
        if (result < 0) {
            ESP_LOGE(TAG, "send() failed: %d", result);
            return ESP_FAIL;
        }
        dataptr += result;
        size -= result;
    }
    return ESP_OK;
}

static void server_loop()
{
    for (uint16_t i = 0; i < TX_DATA_SIZE; i++) {
        tx_data[i] = (uint8_t) i;
    }

    if (server_socket_init() == ESP_FAIL) {
        return;
    }

    while (true) {
        if (server_socket_listen() == ESP_FAIL) {
            os_delay_ms(1000);
            continue;
        }
        ESP_LOGI(TAG, "connected to client.");

        uint8_t cnt = 0;
        while (true) {
            if (cnt == 0) {
                if (send_all(connect_socket, frm_head, 8) == ESP_FAIL) {
                    break;
                }
                frm_head[7] += 1;
            }
            cnt += 1; cnt %= 8;
            
            if (send_all(connect_socket, tx_data, TX_DATA_SIZE) == ESP_FAIL) {
                break;
            }
            tx_data[0] += 1;
        }

        ESP_LOGI(TAG, "disconnecting with client.");
        close(connect_socket);
    }
}

static void app_nvs_init(void)
{
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);
}

void app_main(void)
{
    app_nvs_init();
    app_wifi_sta_init();
    server_loop();
}

Correct data received:

12 34 56 78 AB CD EF 00 
00 01 02 03 04            ... EE EF
01 01 02 03 04            ... EE EF
02 01 02 03 04            ... EE EF
03 01 02 03 04            ... EE EF
04 01 02 03 04            ... EE EF
05 01 02 03 04            ... EE EF
06 01 02 03 04            ... EE EF
07 01 02 03 04            ... EE EF
12 34 56 78 AB CD EF 01
08 01 02 03 04            ... EE EF
09 01 02 03 04            ... EE EF
...

Wrong data received after changing TX_DATA_SIZE to 256:

12 34 56 78 AB CD EF 00 
00 01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   01 02 03 04            ... FE
   34 56 78 AB CD EF 01
08 01 02 03 04            ... FE
   01 02 03 04            ... FE
...

Expected:

12 34 56 78 AB CD EF 00 
00 01 02 03 04            ... FE FF
01 01 02 03 04            ... FE FF
02 01 02 03 04            ... FE FF
03 01 02 03 04            ... FE FF
04 01 02 03 04            ... FE FF
05 01 02 03 04            ... FE FF
06 01 02 03 04            ... FE FF
07 01 02 03 04            ... FE FF
12 34 56 78 AB CD EF 01
08 01 02 03 04            ... FE FF
09 01 02 03 04            ... FE FF
...
@espressif-bot espressif-bot added the Status: Opened Issue is new label Mar 3, 2025
@github-actions github-actions bot changed the title BSD socket: Certain send data size (256) may lead to loss of first or last byte BSD socket: Certain send data size (256) may lead to loss of first or last byte (IDFGH-14771) Mar 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Opened Issue is new
Projects
None yet
Development

No branches or pull requests

4 participants