From 749371599eaa443e8bbea9a87ab6884a3b8a26e2 Mon Sep 17 00:00:00 2001 From: h2zero Date: Mon, 2 Dec 2024 17:55:31 -0700 Subject: [PATCH 1/2] Add a workaround for esp32s3 and esp32c3 tx power bug This adds a workaround to get the tx power when the function returns error due to a bug introduced in some versions of esp-idf. * Added error checking, return value will be 0xFF if there was an error. --- src/NimBLEDevice.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 2a5eb0db..c62988ba 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -479,8 +479,7 @@ bool NimBLEDevice::setPower(int8_t dbm) { /** * @brief Get the transmission power. - * @return The power level currently used in dbm. - * @note ESP32S3 only returns 0xFF as of IDF 5, so this function will return 20dbm. + * @return The power level currently used in dbm or 0xFF on error. */ int NimBLEDevice::getPower() { # ifdef ESP_PLATFORM @@ -488,6 +487,19 @@ int NimBLEDevice::getPower() { return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get # else int pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT); + +# if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) + // workaround for bug when "enhanced tx power" was added + if (pwr == 0xFF) { + pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_CONN_HDL3); + } +# endif + + if (pwr < 0) { + NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_get failed rc=%d", pwr); + return 0xFF; + } + if (pwr < ESP_PWR_LVL_N0) { return -3 * (ESP_PWR_LVL_N0 - pwr); } From 861a0c1c79d8bdb2c3dcc911555ba47624549e37 Mon Sep 17 00:00:00 2001 From: h2zero Date: Wed, 4 Dec 2024 10:29:10 -0700 Subject: [PATCH 2/2] Move workaround to getPowerLevel and call it from getPower. --- src/NimBLEDevice.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index c62988ba..6f99ec3b 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -425,10 +425,19 @@ std::vector NimBLEDevice::getConnectedClients() { # ifndef CONFIG_IDF_TARGET_ESP32P4 /** * @brief Get the transmission power. - * @return The power level currently used in esp_power_level_t. + * @return The power level currently used in esp_power_level_t or a negative value on error. */ esp_power_level_t NimBLEDevice::getPowerLevel(esp_ble_power_type_t powerType) { - return esp_ble_tx_power_get(powerType); + esp_power_level_t pwr = esp_ble_tx_power_get(powerType); + +# if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) + // workaround for bug when "enhanced tx power" was added + if (pwr == 0xFF) { + pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_CONN_HDL3); + } +# endif + + return pwr; } // getPowerLevel /** @@ -486,15 +495,7 @@ int NimBLEDevice::getPower() { # ifdef CONFIG_IDF_TARGET_ESP32P4 return 0xFF; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_get # else - int pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_DEFAULT); - -# if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) - // workaround for bug when "enhanced tx power" was added - if (pwr == 0xFF) { - pwr = esp_ble_tx_power_get(ESP_BLE_PWR_TYPE_CONN_HDL3); - } -# endif - + int pwr = getPowerLevel(); if (pwr < 0) { NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_get failed rc=%d", pwr); return 0xFF;