diff --git a/src/NimBLEAdvertisementData.cpp b/src/NimBLEAdvertisementData.cpp index f084e79..3474ecc 100644 --- a/src/NimBLEAdvertisementData.cpp +++ b/src/NimBLEAdvertisementData.cpp @@ -110,7 +110,7 @@ bool NimBLEAdvertisementData::addTxPower() { data[0] = BLE_HS_ADV_TX_PWR_LVL_LEN + 1; data[1] = BLE_HS_ADV_TYPE_TX_PWR_LVL; # ifndef CONFIG_IDF_TARGET_ESP32P4 - data[2] = NimBLEDevice::getPower(); + data[2] = NimBLEDevice::getPower(NimBLETxPowerType::Advertise); # else data[2] = 0; # endif diff --git a/src/NimBLEDevice.cpp b/src/NimBLEDevice.cpp index c457a54..01cc079 100644 --- a/src/NimBLEDevice.cpp +++ b/src/NimBLEDevice.cpp @@ -464,7 +464,7 @@ bool NimBLEDevice::setPowerLevel(esp_power_level_t powerLevel, esp_ble_power_typ * @param [in] dbm The power level to set in dBm. * @return True if the power level was set successfully. */ -bool NimBLEDevice::setPower(int8_t dbm) { +bool NimBLEDevice::setPower(int8_t dbm, NimBLETxPowerType type) { # ifdef ESP_PLATFORM # ifdef CONFIG_IDF_TARGET_ESP32P4 return false; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_set @@ -472,9 +472,25 @@ bool NimBLEDevice::setPower(int8_t dbm) { if (dbm % 3 == 2) { dbm++; // round up to the next multiple of 3 to be able to target 20dbm } - return setPowerLevel(static_cast(dbm / 3 + ESP_PWR_LVL_N0)); + + bool success = false; + esp_power_level_t espPwr = static_cast(dbm / 3 + ESP_PWR_LVL_N0); + if (type == NimBLETxPowerType::All) { + success = setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_ADV); + success &= setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_SCAN); + success &= setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_DEFAULT); + } else if (type == NimBLETxPowerType::Advertise) { + success = setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_ADV); + } else if (type == NimBLETxPowerType::Scan) { + success = setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_SCAN); + } else if (type == NimBLETxPowerType::Connection) { + success = setPowerLevel(espPwr, ESP_BLE_PWR_TYPE_DEFAULT); + } + + return success; # endif # else + (void)type; // unused NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", dbm); ble_hci_vs_set_tx_pwr_cp cmd{dbm}; ble_hci_vs_set_tx_pwr_rp rsp{0}; @@ -493,12 +509,16 @@ bool NimBLEDevice::setPower(int8_t dbm) { * @brief Get the transmission power. * @return The power level currently used in dbm or 0xFF on error. */ -int NimBLEDevice::getPower() { +int NimBLEDevice::getPower(NimBLETxPowerType type) { # 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 = getPowerLevel(); + esp_ble_power_type_t espPwr = type == NimBLETxPowerType::Advertise ? ESP_BLE_PWR_TYPE_ADV + : type == NimBLETxPowerType::Scan ? ESP_BLE_PWR_TYPE_SCAN + : ESP_BLE_PWR_TYPE_DEFAULT; + + int pwr = getPowerLevel(espPwr); if (pwr < 0) { NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_get failed rc=%d", pwr); return 0xFF; @@ -515,6 +535,7 @@ int NimBLEDevice::getPower() { return 0; # endif # else + (void)type; // unused return ble_phy_txpwr_get(); # endif } // getPower diff --git a/src/NimBLEDevice.h b/src/NimBLEDevice.h index 8ad17ee..9f9f52b 100644 --- a/src/NimBLEDevice.h +++ b/src/NimBLEDevice.h @@ -101,6 +101,13 @@ class NimBLEAddress; # define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS # endif +enum class NimBLETxPowerType { + All = 0, + Advertise = 1, + Scan = 2, + Connection = 3 +}; + typedef int (*gap_event_handler)(ble_gap_event* event, void* arg); /** @@ -138,8 +145,8 @@ class NimBLEDevice { static void onReset(int reason); static void onSync(void); static void host_task(void* param); - static int getPower(); - static bool setPower(int8_t dbm); + static int getPower(NimBLETxPowerType type = NimBLETxPowerType::All); + static bool setPower(int8_t dbm, NimBLETxPowerType type = NimBLETxPowerType::All); # ifdef ESP_PLATFORM # ifndef CONFIG_IDF_TARGET_ESP32P4 diff --git a/src/NimBLEExtAdvertising.cpp b/src/NimBLEExtAdvertising.cpp index e67fbf5..16d5a9e 100644 --- a/src/NimBLEExtAdvertising.cpp +++ b/src/NimBLEExtAdvertising.cpp @@ -359,7 +359,7 @@ NimBLEExtAdvertisement::NimBLEExtAdvertisement(uint8_t priPhy, uint8_t secPhy) { m_params.own_addr_type = NimBLEDevice::m_ownAddrType; m_params.primary_phy = priPhy; m_params.secondary_phy = secPhy; - m_params.tx_power = 127; + m_params.tx_power = NimBLEDevice::getPower(NimBLETxPowerType::Advertise); } // NimBLEExtAdvertisement /** @@ -1014,8 +1014,22 @@ bool NimBLEExtAdvertisement::setPreferredParams(uint16_t minInterval, uint16_t m /** * @brief Adds Tx power level to the advertisement data. */ -void NimBLEExtAdvertisement::addTxPower() { +bool NimBLEExtAdvertisement::addTxPower() { + if (m_params.legacy_pdu) { + m_params.include_tx_power = 0; + uint8_t data[3]; + data[0] = BLE_HS_ADV_TX_PWR_LVL_LEN + 1; + data[1] = BLE_HS_ADV_TYPE_TX_PWR_LVL; +# ifndef CONFIG_IDF_TARGET_ESP32P4 + data[2] = NimBLEDevice::getPower(NimBLETxPowerType::Advertise); +# else + data[2] = 0; +# endif + return addData(data, 3); + } + m_params.include_tx_power = 1; + return true; } // addTxPower /** diff --git a/src/NimBLEExtAdvertising.h b/src/NimBLEExtAdvertising.h index ecfd4ed..463eaa3 100644 --- a/src/NimBLEExtAdvertising.h +++ b/src/NimBLEExtAdvertising.h @@ -46,34 +46,33 @@ class NimBLEUUID; class NimBLEExtAdvertisement { public: NimBLEExtAdvertisement(uint8_t priPhy = BLE_HCI_LE_PHY_1M, uint8_t secPhy = BLE_HCI_LE_PHY_1M); - bool setAppearance(uint16_t appearance); - bool addServiceUUID(const NimBLEUUID& serviceUUID); - bool addServiceUUID(const char* serviceUUID); - bool removeServiceUUID(const NimBLEUUID& serviceUUID); - bool removeServiceUUID(const char* serviceUUID); - bool removeServices(); - bool setCompleteServices(const NimBLEUUID& uuid); - bool setCompleteServices16(const std::vector& uuids); - bool setCompleteServices32(const std::vector& uuids); - bool setFlags(uint8_t flag); - bool setManufacturerData(const uint8_t* data, size_t length); - bool setManufacturerData(const std::string& data); - bool setManufacturerData(const std::vector& data); - bool setURI(const std::string& uri); - bool setName(const std::string& name, bool isComplete = true); - bool setPartialServices(const NimBLEUUID& uuid); - bool setPartialServices16(const std::vector& uuids); - bool setPartialServices32(const std::vector& uuids); - bool setServiceData(const NimBLEUUID& uuid, const uint8_t* data, size_t length); - bool setServiceData(const NimBLEUUID& uuid, const std::string& data); - bool setServiceData(const NimBLEUUID& uuid, const std::vector& data); - bool setShortName(const std::string& name); - bool setData(const uint8_t* data, size_t length); - bool addData(const uint8_t* data, size_t length); - bool addData(const std::string& data); - bool setPreferredParams(uint16_t min, uint16_t max); - - void addTxPower(); + bool setAppearance(uint16_t appearance); + bool addServiceUUID(const NimBLEUUID& serviceUUID); + bool addServiceUUID(const char* serviceUUID); + bool removeServiceUUID(const NimBLEUUID& serviceUUID); + bool removeServiceUUID(const char* serviceUUID); + bool removeServices(); + bool setCompleteServices(const NimBLEUUID& uuid); + bool setCompleteServices16(const std::vector& uuids); + bool setCompleteServices32(const std::vector& uuids); + bool setFlags(uint8_t flag); + bool setManufacturerData(const uint8_t* data, size_t length); + bool setManufacturerData(const std::string& data); + bool setManufacturerData(const std::vector& data); + bool setURI(const std::string& uri); + bool setName(const std::string& name, bool isComplete = true); + bool setPartialServices(const NimBLEUUID& uuid); + bool setPartialServices16(const std::vector& uuids); + bool setPartialServices32(const std::vector& uuids); + bool setServiceData(const NimBLEUUID& uuid, const uint8_t* data, size_t length); + bool setServiceData(const NimBLEUUID& uuid, const std::string& data); + bool setServiceData(const NimBLEUUID& uuid, const std::vector& data); + bool setShortName(const std::string& name); + bool setData(const uint8_t* data, size_t length); + bool addData(const uint8_t* data, size_t length); + bool addData(const std::string& data); + bool setPreferredParams(uint16_t min, uint16_t max); + bool addTxPower(); void setLegacyAdvertising(bool enable); void setConnectable(bool enable); void setScannable(bool enable);