espressif / esp-idf

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

ESP-IDF BLE throughput demos loosing too many packets (IDFGH-2391) #4508

Closed bonifacebassey closed 4 years ago

bonifacebassey commented 4 years ago

Environment

Problem Description

I am using ESP-IDF throughput GATT SERVER and GATT CLIENT demos between two ESP32-DevKitC v2, with CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT selected, i could realize the throughput of around 91kByte/s which is fine.

My concern is that, i wanted to know how many messages could be sent/received per second, and so, i added a counter that increments. The throughput GATT SERVER counted up to 25,321 packets/second sent while the throughput GATT CLIENT only received 187 packets/second

Expected Behavior

I wanted to see that all packets sent by the throughput GATT SERVER are received by the throughput GATT CLIENT

Actual Behavior

Extremely too many packets are being lost.

Question

As i can't afford to loose any packet sent, how can i send packets as fast as possible without loosing any of them?

Code to reproduce this issue

// the throughput GATT SERVER demo
static void throughput_server_task(void *param)
{
    ...
    static uint64_t timeNow = 0;
    static uint64_t sent_counter = 0;

    while(1) {
#if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT) 
        if (!can_send_notify) {
            int res = xSemaphoreTake(gatts_semaphore, portMAX_DELAY);
            assert(res == pdTRUE);
        } else {
            if (is_connecet) {
                esp_ble_gatts_send_indicate(gl_profile_tab[PROFILE_A_APP_ID].gatts_if, gl_profile_tab[PROFILE_A_APP_ID].conn_id,
                                            gl_profile_tab[PROFILE_A_APP_ID].char_handle,
                                            sizeof(indicate_data), indicate_data, false);
                sent_counter += 1;
                if ((esp_timer_get_time() - timeNow) / SECOND_TO_USECOND >= 2)
                {
                    printf("[Server-Write] %lld msg/s\n", sent_counter/2);
                    timeNow = esp_timer_get_time();
                    sent_counter = 0;
                }
            }
        }
#endif /* #if (CONFIG_EXAMPLE_GATTS_NOTIFY_THROUGHPUT) */

// Similarly at the throughput GATT CLIENT.

    case ESP_GATTC_NOTIFY_EVT: {
#if (CONFIG_GATTS_NOTIFY_THROUGHPUT)
        if (p_data->notify.is_notify && 
            (p_data->notify.value[p_data->notify.value_len - 1] ==
             check_sum(p_data->notify.value, p_data->notify.value_len - 1))){
            notify_len += p_data->notify.value_len;
            receive_counter += 1;
        } else {
            ESP_LOGE(GATTC_TAG, "ESP_GATTC_NOTIFY_EVT, receive indicate value:");
        }

static void throughput_client_task(void *param)
{
    ...
    static uint64_t receive_counter = 0;

     while(1) {
#if (CONFIG_GATTS_NOTIFY_THROUGHPUT)
        vTaskDelay(2000 / portTICK_PERIOD_MS);
        uint32_t bit_rate = 0;
        if(is_connecet){
            if (start_time) {
                current_time = esp_timer_get_time();
                bit_rate = notify_len * SECOND_TO_USECOND / (current_time - start_time);
                printf("[Client-Receive] %lld msg/s, BitRate = %d Bytes/s, = %d bit/s\n", receive_counter/2, bit_rate, bit_rate<<3);

                receive_counter = 0;
            } else {
        ESP_LOGI(GATTC_TAG, "Notify Bit rate = 0 Byte/s, = 0 bit/s");
        }
        }
    }
#endif /* #if (CONFIG_GATTS_NOTIFY_THROUGHPUT) */

Log Output

Capture

GYC-Espressif commented 4 years ago

Hello, Thank you for your report. We have noticed this issue, and we have a solution for that. We are testing it, and it will release in several days. BTW, Notify is unacknowledged, it is unreliable since you will not know whether your remote client has received the data. If you want to ensure that no data is lost, you can consider using indicate.

Alvin1Zhang commented 4 years ago

@BonifaceBassey Thanks for reporting, sorry for the slow turnaround and appreciate your patience in waiting for the fix. The fix has been available at https://github.com/espressif/esp-idf/commit/3634192deda85981466897869ac550665a8cb3df, feel free to reopen if the issue still happens. Thanks.