From a55489fee2b2f314ce4068ae4af59b265a046259 Mon Sep 17 00:00:00 2001 From: h2zero <32826625+h2zero@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:46:33 -0700 Subject: [PATCH] Add a workaround for esp32s3 and esp32c3 tx power bug (#252) * 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 | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index 2a5eb0d..6f99ec3 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 /** @@ -479,15 +488,19 @@ 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 # 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); + int pwr = getPowerLevel(); + 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); }