mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
fix(bitscrambler): clean up loopback create failures
Clear the returned handle on loopback creation failure and route initialized objects through bitscrambler_free so channel ownership and extra cleanup state cannot leak after partial setup errors. Add a regression test for the failed create path.
This commit is contained in:
@@ -72,11 +72,13 @@ esp_err_t bitscrambler_loopback_create(bitscrambler_handle_t *handle, int attach
|
|||||||
if (!handle) {
|
if (!handle) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
*handle = NULL;
|
||||||
if (attach_to < 0 || attach_to > SOC_BITSCRAMBLER_ATTACH_MAX) {
|
if (attach_to < 0 || attach_to > SOC_BITSCRAMBLER_ATTACH_MAX) {
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t ret = ESP_OK;
|
esp_err_t ret = ESP_OK;
|
||||||
|
bool bs_initialized = false;
|
||||||
bitscrambler_loopback_t *bs = calloc(1, sizeof(bitscrambler_loopback_t));
|
bitscrambler_loopback_t *bs = calloc(1, sizeof(bitscrambler_loopback_t));
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
@@ -88,14 +90,13 @@ esp_err_t bitscrambler_loopback_create(bitscrambler_handle_t *handle, int attach
|
|||||||
.attach_to = attach_to
|
.attach_to = attach_to
|
||||||
};
|
};
|
||||||
ESP_GOTO_ON_ERROR(bitscrambler_init_loopback(&bs->bs, &cfg), err, TAG, "failed bitscrambler init for loopback");
|
ESP_GOTO_ON_ERROR(bitscrambler_init_loopback(&bs->bs, &cfg), err, TAG, "failed bitscrambler init for loopback");
|
||||||
|
bs_initialized = true;
|
||||||
|
|
||||||
// register extra cleanup function to free loopback resources
|
// register extra cleanup function to free loopback resources
|
||||||
bitscrambler_register_extra_clean_up(&bs->bs, bitscrambler_loopback_cleanup, bs);
|
bitscrambler_register_extra_clean_up(&bs->bs, bitscrambler_loopback_cleanup, bs);
|
||||||
|
|
||||||
bs->sema_done = xSemaphoreCreateBinary();
|
bs->sema_done = xSemaphoreCreateBinary();
|
||||||
if (!bs->sema_done) {
|
ESP_GOTO_ON_FALSE(bs->sema_done, ESP_ERR_NO_MEM, err, TAG, "failed to create semaphore");
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bs->max_transfer_sz_bytes = max_transfer_sz_bytes;
|
bs->max_transfer_sz_bytes = max_transfer_sz_bytes;
|
||||||
size_t desc_ct = esp_dma_calculate_node_count(max_transfer_sz_bytes, 4, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
size_t desc_ct = esp_dma_calculate_node_count(max_transfer_sz_bytes, 4, DMA_DESCRIPTOR_BUFFER_MAX_SIZE);
|
||||||
@@ -137,8 +138,11 @@ esp_err_t bitscrambler_loopback_create(bitscrambler_handle_t *handle, int attach
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
bitscrambler_loopback_free(bs);
|
if (bs_initialized) {
|
||||||
free(bs);
|
bitscrambler_free(&bs->bs);
|
||||||
|
} else {
|
||||||
|
free(bs);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "unity.h"
|
#include "unity.h"
|
||||||
#include "unity_test_utils.h"
|
#include "unity_test_utils.h"
|
||||||
@@ -59,6 +60,19 @@ TEST_CASE("Timeout on stuck program", "[bs]")
|
|||||||
free(data_out);
|
free(data_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Loopback create failure clears handle and releases channels", "[bs]")
|
||||||
|
{
|
||||||
|
bitscrambler_handle_t failed_bs = (bitscrambler_handle_t)0x1;
|
||||||
|
|
||||||
|
esp_err_t err = bitscrambler_loopback_create(&failed_bs, SOC_BITSCRAMBLER_ATTACH_GPSPI2, SIZE_MAX / 2);
|
||||||
|
TEST_ASSERT_NOT_EQUAL(ESP_OK, err);
|
||||||
|
TEST_ASSERT_NULL(failed_bs);
|
||||||
|
|
||||||
|
bitscrambler_handle_t bs = NULL;
|
||||||
|
TEST_ESP_OK(bitscrambler_loopback_create(&bs, SOC_BITSCRAMBLER_ATTACH_GPSPI2, 4096));
|
||||||
|
bitscrambler_free(bs);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("BitScrambler with EOF counted on upstream", "[bs]")
|
TEST_CASE("BitScrambler with EOF counted on upstream", "[bs]")
|
||||||
{
|
{
|
||||||
const size_t len = 32;
|
const size_t len = 32;
|
||||||
|
|||||||
Reference in New Issue
Block a user