diff --git a/components/esp_driver_bitscrambler/src/bitscrambler_loopback.c b/components/esp_driver_bitscrambler/src/bitscrambler_loopback.c index 7cf0c7b1ca1..8b9d78fc3f4 100644 --- a/components/esp_driver_bitscrambler/src/bitscrambler_loopback.c +++ b/components/esp_driver_bitscrambler/src/bitscrambler_loopback.c @@ -72,11 +72,13 @@ esp_err_t bitscrambler_loopback_create(bitscrambler_handle_t *handle, int attach if (!handle) { return ESP_ERR_INVALID_ARG; } + *handle = NULL; if (attach_to < 0 || attach_to > SOC_BITSCRAMBLER_ATTACH_MAX) { return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; + bool bs_initialized = false; bitscrambler_loopback_t *bs = calloc(1, sizeof(bitscrambler_loopback_t)); if (!bs) { 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 }; 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 bitscrambler_register_extra_clean_up(&bs->bs, bitscrambler_loopback_cleanup, bs); bs->sema_done = xSemaphoreCreateBinary(); - if (!bs->sema_done) { - goto err; - } + ESP_GOTO_ON_FALSE(bs->sema_done, ESP_ERR_NO_MEM, err, TAG, "failed to create semaphore"); 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); @@ -137,8 +138,11 @@ esp_err_t bitscrambler_loopback_create(bitscrambler_handle_t *handle, int attach return ESP_OK; err: - bitscrambler_loopback_free(bs); - free(bs); + if (bs_initialized) { + bitscrambler_free(&bs->bs); + } else { + free(bs); + } return ret; } diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c index 87f292f47f2..805b89408e2 100644 --- a/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/main/test_bitscrambler.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include +#include #include "sdkconfig.h" #include "unity.h" #include "unity_test_utils.h" @@ -59,6 +60,19 @@ TEST_CASE("Timeout on stuck program", "[bs]") 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]") { const size_t len = 32;