20 Commits

Author SHA1 Message Date
a5a70ac4b0 Fix crash when retrieving descriptors.
If more than one descriptor is found the task would be released beofore the process completed causing a race condition.
2025-01-06 15:28:20 -07:00
2feaedb755 Release 2.0.3 2025-01-05 15:10:41 -07:00
60290cd75c Increase timeout paramter in server example. 2025-01-05 15:00:54 -07:00
2f6ab7589b Add missing migration information to docs. 2025-01-05 15:00:51 -07:00
ed51076d0c NimBLEAdvertisementData emit error on failure, remove magic numbers. 2025-01-05 15:00:48 -07:00
4972f3e08b Fix characteristic value unable to be updated in callback 2025-01-05 15:00:45 -07:00
95a35ec081 Fix advertising data not set if scan response enabled later. 2025-01-05 15:00:41 -07:00
a127aba925 Add checks in case NIMBLE_CPP_DEBUG_ASSERT is not defined. 2025-01-05 15:00:31 -07:00
c655b21590 Allow the same report ID in multiple input/output/feature reports 2025-01-05 15:00:28 -07:00
d10ffa19db Fix build error when using platformio library 2025-01-05 15:00:24 -07:00
dc53052411 NimBLEScan increment m_callbackSent before callback.
Fixes heap corruption observed on CONFIG_HEAP_POISONING_COMPREHENSIVE.
2025-01-05 15:00:20 -07:00
da48844e2f Release 2.0.2 2024-12-21 17:03:08 -07:00
ea1c055826 Fix compile error for advertiser only config. 2024-12-21 16:53:29 -07:00
65f6ee18ca Fix NimBLEHIDDevice not being able to create more than one in/out/feature report + temporal coupling 2024-12-21 16:53:23 -07:00
fd0187bfc9 Fix crash that could occur when server reconnects
* Update to not change services if they have not actually changed when starting the server
Closes #270
2024-12-21 16:53:20 -07:00
275def333c Release 2.0.1 2024-12-16 18:48:00 -07:00
ec4d4c43e1 Add missing NimBLEUtils and NimBLEConnInfo includes to NimBLEDevice.h
In some cases compilation of examples would fail due to missing these headers so they should be included in NimBLEDevice.h
2024-12-16 18:27:45 -07:00
3e0ce87a94 Update changelog. 2024-12-16 18:27:45 -07:00
3743eb954e Fix NimBLEHIDDevice output report returning incorrect characteristic. (#805)
The input and output report characteristics share the same UUID and the `getOutputReport` was returning the input report characteristic.
This change will return the correct characteristic by finding it with the index parameter.
2024-12-16 18:27:45 -07:00
6357a0dbea Fix compiling errors when central is disabled.
* Fix missing member error 'm_pClient' in NimBLEServer
2024-12-16 18:27:45 -07:00
59 changed files with 273 additions and 635 deletions

View File

@ -1,35 +1,6 @@
# Changelog
All notable changes to this project will be documented in this file.
## [2.2.0] 2025-02-24
## Added
- Conditional macros for logging.
- `NimBLEDevicecallbacks` class with a callback for handling bond storage.
## [2.1.1] 2025-01-26
## Fixed
- remote descriptor discovery error when no descriptors exist.
- scan filter settings not enabled for esp32s3/c3.
- remote descriptor discovery returning more than the desired descriptor.
## [2.1.0] 2025-01-12
## Fixed
- Crash when retrieving descriptors if more than one exists.
- Incorrect TX power value being advertised.
- New user guide code for 2.x
- Potential race condition if `NimBLEScan::clearResults1 is called from multiple tasks.
## Changed
- If privacy is not enabled identity keys will not be shared.
- `NimBLEDevice::setPower` and `NimBLEDevice::getPower` now take an additional parameter `NimBLETxPowerType` to set/get the power level for different operations.
## Added
- Config option `CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER`, if defined will remove the ":" delimiter from the BLE address string.
- Config option `CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE` if defined will make the BLE address strings uppercase.
## [2.0.3] 2025-01-05
## Fixed

127
Kconfig
View File

@ -26,113 +26,6 @@ config NIMBLE_CPP_LOG_LEVEL
default 3 if NIMBLE_CPP_LOG_LEVEL_INFO
default 4 if NIMBLE_CPP_LOG_LEVEL_DEBUG
config NIMBLE_CPP_LOG_OVERRIDE_COLOR
bool "Enable log color override."
default "n"
help
Enabling this option will allow NimBLE log levels to have
specific colors assigned.
menu "NIMBLE Log Override Colors"
depends on NIMBLE_CPP_LOG_OVERRIDE_COLOR
choice NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR
prompt "NimBLE CPP log override color Error"
default NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_NONE
help
Select NimBLE CPP log override error color.
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_NONE
bool "None"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_BLACK
bool "Black"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_RED
bool "Red"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_GREEN
bool "Green"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_YELLOW
bool "Yellow"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_BLUE
bool "Blue"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_PURPLE
bool "Purple"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_CYAN
bool "Cyan"
endchoice #NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR
choice NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN
prompt "NimBLE CPP log override color Warning"
default NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_NONE
help
Select NimBLE CPP log override warning color.
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_NONE
bool "None"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_BLACK
bool "Black"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_RED
bool "Red"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_GREEN
bool "Green"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_YELLOW
bool "Yellow"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_BLUE
bool "Blue"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_PURPLE
bool "Purple"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_CYAN
bool "Cyan"
endchoice #NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN
choice NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO
prompt "NimBLE CPP log override color Info"
default NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_NONE
help
Select NimBLE CPP log override info color.
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_NONE
bool "None"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_BLACK
bool "Black"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_RED
bool "Red"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_GREEN
bool "Green"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_YELLOW
bool "Yellow"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_BLUE
bool "Blue"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_PURPLE
bool "Purple"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_CYAN
bool "Cyan"
endchoice #NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO
choice NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG
prompt "NimBLE CPP log override color Debug"
default NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_NONE
help
Select NimBLE CPP log override debug color.
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_NONE
bool "None"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_BLACK
bool "Black"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_RED
bool "Red"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_GREEN
bool "Green"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_YELLOW
bool "Yellow"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_BLUE
bool "Blue"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_PURPLE
bool "Purple"
config NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_CYAN
bool "Cyan"
endchoice #NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG
endmenu
config NIMBLE_CPP_ENABLE_RETURN_CODE_TEXT
bool "Show NimBLE return codes as text in debug log."
default "n"
@ -157,20 +50,6 @@ config NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT
while scanning as text messages in the debug log.
This will use approximately 250 bytes of flash memory.
config NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER
bool "Exclude colon characters when printing address."
default "n"
help
Enabling this option will format MAC addresses without
colon characters when printing.
config NIMBLE_CPP_ADDR_FMT_UPPERCASE
bool "Use uppercase letters when printing address."
default "n"
help
Enabling this option will format MAC addresses in
uppercase letters when printing.
config NIMBLE_CPP_ATT_VALUE_TIMESTAMP_ENABLED
bool "Enable timestamps to be stored with attribute values."
default "n"
@ -198,12 +77,12 @@ config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
This will use approximately 1kB of flash memory.
config NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT
int "FreeRTOS task block bit."
int "FreeRTOS task block bit"
default 31
help
Configure the bit to set in the task notification value when a task is blocked waiting for an event.
This should be set to a bit that is not used by other notifications in the system.
#
# BT config
#
@ -251,4 +130,4 @@ if IDF_TARGET_ESP32P4
endchoice
endif
endmenu
endmenu

2
NOTICE
View File

@ -1,6 +1,6 @@
esp-nimble-cpp
NimBLE-Arduino
Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
esp-nimble-cpp, NimBLE-Arduino contributors.
The Initial Developer of some parts of this library, which are copied from,

View File

@ -48,7 +48,7 @@ PROJECT_NAME = esp-nimble-cpp
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 2.2.0
PROJECT_NUMBER = 2.0.3
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@ -37,7 +37,9 @@ For this example we will keep it simple and use a 16 bit value: ABCD.
```
#include "NimBLEDevice.h"
extern "C" void app_main(void) {
// void setup() in Arduino
void app_main(void)
{
NimBLEDevice::init("NimBLE");
NimBLEServer *pServer = NimBLEDevice::createServer();
@ -77,7 +79,9 @@ The function call will simply be `pService->createCharacteristic("1234");`
```
#include "NimBLEDevice.h"
extern "C" void app_main(void) {
// void setup() in Arduino
void app_main(void)
{
NimBLEDevice::init("NimBLE");
NimBLEServer *pServer = NimBLEDevice::createServer();
@ -95,13 +99,12 @@ There are many different types you can send as parameters for the value but for
`pCharacteristic->setValue("Hello BLE");`
Next we need to advertise for connections.
To do this we create an instance of `NimBLEAdvertising` add our service to it (optional) and start advertising.
To do this we create an instance of `NimBLEAdvertising` add our service to it (optional) and start advertisng.
**The code for this will be:**
```
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); // create advertising instance
pAdvertising->addServiceUUID("ABCD"); // advertise the UUID of our service
pAdvertising->setName("NimBLE"); // advertise the device name
pAdvertising->addServiceUUID("ABCD"); // tell advertising the UUID of our service
pAdvertising->start(); // start advertising
```
That's it, this will be enough to create a BLE server with a service and a characteristic and advertise for client connections.
@ -110,7 +113,9 @@ That's it, this will be enough to create a BLE server with a service and a chara
```
#include "NimBLEDevice.h"
extern "C" void app_main(void) {
// void setup() in Arduino
void app_main(void)
{
NimBLEDevice::init("NimBLE");
NimBLEServer *pServer = NimBLEDevice::createServer();
@ -121,8 +126,7 @@ extern "C" void app_main(void) {
pCharacteristic->setValue("Hello BLE");
NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();
pAdvertising->addServiceUUID("ABCD"); // advertise the UUID of our service
pAdvertising->setName("NimBLE"); // advertise the device name
pAdvertising->addServiceUUID("ABCD");
pAdvertising->start();
}
```
@ -140,7 +144,7 @@ After initializing the NimBLE stack we create a scan instance by calling `NimBLE
Once we have created the scan we can start looking for advertising servers.
To do this we call `NimBLEScan::getResults(duration)`, the duration parameter is a uint32_t that specifies the number of milliseconds to scan for,
To do this we call `NimBLEScan::start(duration)`, the duration parameter is a uint32_t that specifies the number of milliseconds to scan for,
passing 0 will scan forever.
In this example we will scan for 10 seconds. This is a blocking function (a non blocking overload is also available).
@ -150,7 +154,9 @@ This call returns an instance of `NimBLEScanResults` when the scan completes whi
```
#include "NimBLEDevice.h"
extern "C" void app_main(void) {
// void setup() in Arduino
void app_main(void)
{
NimBLEDevice::init("");
NimBLEScan *pScan = NimBLEDevice::getScan();
@ -162,7 +168,7 @@ extern "C" void app_main(void) {
Now that we have scanned we need to check the results for any advertisers we are interested in connecting to.
To do this we iterate through the results and check if any of the devices found are advertising the service we want `ABCD`.
Each result in `NimBLEScanResults` is a `const NimBLEAdvertisedDevice*` that we can access data from.
Each result in `NimBLEScanResults` is a `NimBLEAdvertisedDevice` instance that we can access data from.
We will check each device found for the `ABCD` service by calling `NimBLEAdvertisedDevice::isAdvertisingService`.
This takes an instance of `NimBLEUUID` as a parameter so we will need to create one.
@ -171,11 +177,11 @@ This takes an instance of `NimBLEUUID` as a parameter so we will need to create
```
NimBLEUUID serviceUuid("ABCD");
for (int i = 0; i < results.getCount(); i++) {
const NimBLEAdvertisedDevice *device = results.getDevice(i);
for(int i = 0; i < results.getCount(); i++) {
NimBLEAdvertisedDevice device = results.getDevice(i);
if (device->isAdvertisingService(serviceUuid)) {
// create a client and connect
if (device.isAdvertisingService(serviceUuid)) {
// create a client and connect
}
}
```
@ -192,16 +198,16 @@ This takes a pointer to the `NimBLEAdvertisedDevice` and returns `true` if succe
```
NimBLEUUID serviceUuid("ABCD");
for (int i = 0; i < results.getCount(); i++) {
const NimBLEAdvertisedDevice *device = results.getDevice(i);
for(int i = 0; i < results.getCount(); i++) {
NimBLEAdvertisedDevice device = results.getDevice(i);
if (device->isAdvertisingService(serviceUuid)) {
if (device.isAdvertisingService(serviceUuid)) {
NimBLEClient *pClient = NimBLEDevice::createClient();
if (pClient->connect(&device)) {
//success
if(pClient->connect(&device)) {
//success
} else {
// failed to connect
// failed to connect
}
}
}
@ -223,15 +229,11 @@ Finally we will read the characteristic value with `NimBLERemoteCharacteristic::
```
NimBLEUUID serviceUuid("ABCD");
for (int i = 0; i < results.getCount(); i++) {
const NimBLEAdvertisedDevice *device = results.getDevice(i);
for(int i = 0; i < results.getCount(); i++) {
NimBLEAdvertisedDevice device = results.getDevice(i);
if (device->isAdvertisingService(serviceUuid)) {
if (device.isAdvertisingService(serviceUuid)) {
NimBLEClient *pClient = NimBLEDevice::createClient();
if (!pClient) { // Make sure the client was created
break;
}
if (pClient->connect(&device)) {
NimBLERemoteService *pService = pClient->getService(serviceUuid);
@ -245,7 +247,7 @@ for (int i = 0; i < results.getCount(); i++) {
}
}
} else {
// failed to connect
// failed to connect
}
}
}
@ -260,16 +262,12 @@ This is done by calling `NimBLEDevice::deleteClient`.
```
NimBLEUUID serviceUuid("ABCD");
for (int i = 0; i < results.getCount(); i++) {
const NimBLEAdvertisedDevice *device = results.getDevice(i);
for(int i = 0; i < results.getCount(); i++) {
NimBLEAdvertisedDevice device = results.getDevice(i);
if (device->isAdvertisingService(serviceUuid)) {
if (device.isAdvertisingService(serviceUuid)) {
NimBLEClient *pClient = NimBLEDevice::createClient();
if (!pClient) { // Make sure the client was created
break;
}
if (pClient->connect(&device)) {
NimBLERemoteService *pService = pClient->getService(serviceUuid);
@ -282,7 +280,7 @@ for (int i = 0; i < results.getCount(); i++) {
}
}
} else {
// failed to connect
// failed to connect
}
NimBLEDevice::deleteClient(pClient);
@ -296,39 +294,37 @@ Note that there is no need to disconnect as that will be done when deleting the
```
#include "NimBLEDevice.h"
extern "C" void app_main(void) {
// void setup() in Arduino
void app_main(void)
{
NimBLEDevice::init("");
NimBLEScan *pScan = NimBLEDevice::getScan();
NimBLEScanResults results = pScan->getResults(10 * 1000);
NimBLEScanResults results = pScan->start(10 * 1000);
NimBLEUUID serviceUuid("ABCD");
for (int i = 0; i < results.getCount(); i++) {
const NimBLEAdvertisedDevice *device = results.getDevice(i);
if (device->isAdvertisingService(serviceUuid)) {
for(int i = 0; i < results.getCount(); i++) {
NimBLEAdvertisedDevice device = results.getDevice(i);
if (device.isAdvertisingService(serviceUuid)) {
NimBLEClient *pClient = NimBLEDevice::createClient();
if (!pClient) { // Make sure the client was created
break;
}
if (pClient->connect(&device)) {
NimBLERemoteService *pService = pClient->getService(serviceUuid);
if (pService != nullptr) {
NimBLERemoteCharacteristic *pCharacteristic = pService->getCharacteristic("1234");
if (pCharacteristic != nullptr) {
std::string value = pCharacteristic->readValue();
// print or do whatever you need with the value
}
}
} else {
// failed to connect
// failed to connect
}
NimBLEDevice::deleteClient(pClient);
}
}
@ -338,3 +334,4 @@ extern "C" void app_main(void) {
For more advanced features and options please see the client examples in the examples folder.
<br/>

View File

@ -1,5 +1,5 @@
## IDF Component Manager Manifest File
version: "2.2.0"
version: "2.0.3"
license: "Apache-2.0"
description: "C++ wrapper for the NimBLE BLE stack"
url: "https://github.com/h2zero/esp-nimble-cpp"
@ -16,7 +16,7 @@ dependencies:
rules:
- if: "target in [esp32p4]"
espressif/esp_wifi_remote:
version: "<0.5.4"
version: "*"
rules:
- if: "target in [esp32p4]"
idf:

View File

@ -1,6 +1,6 @@
{
"name": "esp-nimble-cpp",
"version": "2.2.0",
"version": "2.0.3",
"description": "C++ wrapper for the NimBLE BLE stack",
"keywords": [
"BLE",

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -68,7 +68,7 @@ class NimBLE2904 : public NimBLEDescriptor {
static const uint8_t FORMAT_OPAQUE = 27;
static const uint8_t FORMAT_MEDASN1 = 28;
void setDescription(uint16_t description);
void setDescription(uint16_t);
void setExponent(int8_t exponent);
void setFormat(uint8_t format);
void setNamespace(uint8_t namespace_value);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -23,18 +23,6 @@
# include <algorithm>
# ifdef CONFIG_NIMBLE_CPP_ADDR_FMT_EXCLUDE_DELIMITER
# define NIMBLE_CPP_ADDR_DELIMITER ""
# else
# define NIMBLE_CPP_ADDR_DELIMITER ":"
# endif
# ifdef CONFIG_NIMBLE_CPP_ADDR_FMT_UPPERCASE
# define NIMBLE_CPP_ADDR_FMT "%02X%s%02X%s%02X%s%02X%s%02X%s%02X"
# else
# define NIMBLE_CPP_ADDR_FMT "%02x%s%02x%s%02x%s%02x%s%02x%s%02x"
# endif
static const char* LOG_TAG = "NimBLEAddress";
/*************************************************
@ -73,7 +61,7 @@ NimBLEAddress::NimBLEAddress(const std::string& addr, uint8_t type) {
std::string mac{addr};
mac.erase(std::remove(mac.begin(), mac.end(), ':'), mac.end());
uint64_t address = std::stoull(mac, nullptr, 16);
memcpy(this->val, &address, sizeof(this->val));
memcpy(this->val, &address, sizeof this->val);
return;
}
@ -102,7 +90,7 @@ NimBLEAddress::NimBLEAddress(const uint8_t address[BLE_DEV_ADDR_LEN], uint8_t ty
* * BLE_ADDR_RANDOM (1)
*/
NimBLEAddress::NimBLEAddress(const uint64_t& address, uint8_t type) {
memcpy(this->val, &address, sizeof(this->val));
memcpy(this->val, &address, sizeof this->val);
this->type = type;
} // NimBLEAddress
@ -205,7 +193,7 @@ bool NimBLEAddress::operator==(const NimBLEAddress& rhs) const {
return false;
}
return memcmp(rhs.val, this->val, sizeof(this->val)) == 0;
return memcmp(rhs.val, this->val, sizeof this->val) == 0;
} // operator ==
/**
@ -223,12 +211,12 @@ NimBLEAddress::operator std::string() const {
char buffer[18];
snprintf(buffer,
sizeof(buffer),
NIMBLE_CPP_ADDR_FMT,
this->val[5], NIMBLE_CPP_ADDR_DELIMITER,
this->val[4], NIMBLE_CPP_ADDR_DELIMITER,
this->val[3], NIMBLE_CPP_ADDR_DELIMITER,
this->val[2], NIMBLE_CPP_ADDR_DELIMITER,
this->val[1], NIMBLE_CPP_ADDR_DELIMITER,
"%02x:%02x:%02x:%02x:%02x:%02x",
this->val[5],
this->val[4],
this->val[3],
this->val[2],
this->val[1],
this->val[0]);
return std::string{buffer};
} // operator std::string
@ -238,7 +226,7 @@ NimBLEAddress::operator std::string() const {
*/
NimBLEAddress::operator uint64_t() const {
uint64_t address = 0;
memcpy(&address, this->val, sizeof(this->val));
memcpy(&address, this->val, sizeof this->val);
return address;
} // operator uint64_t

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -780,16 +780,6 @@ bool NimBLEAdvertisedDevice::isLegacyAdvertisement() const {
# endif
} // isLegacyAdvertisement
/**
* @brief Convenience operator to convert this NimBLEAdvertisedDevice to NimBLEAddress representation.
* @details This allows passing NimBLEAdvertisedDevice to functions
* that accept NimBLEAddress and/or or it's methods as a parameter.
*/
NimBLEAdvertisedDevice::operator NimBLEAddress() const {
NimBLEAddress address(getAddress());
return address;
} // operator NimBLEAddress
/**
* @brief Get the payload advertised by the device.
* @return The advertisement payload.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -93,7 +93,6 @@ class NimBLEAdvertisedDevice {
uint8_t getSecondaryPhy() const;
uint16_t getPeriodicInterval() const;
# endif
operator NimBLEAddress() const;
const std::vector<uint8_t>& getPayload() const;
const std::vector<uint8_t>::const_iterator begin() const;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -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(NimBLETxPowerType::Advertise);
data[2] = NimBLEDevice::getPower();
# else
data[2] = 0;
# endif

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -38,7 +38,7 @@ class NimBLEAdvertisementData {
bool addData(const uint8_t* data, size_t length);
bool addData(const std::vector<uint8_t>& data);
bool setAppearance(uint16_t appearance);
bool setFlags(uint8_t flag);
bool setFlags(uint8_t);
bool addTxPower();
bool setPreferredParams(uint16_t minInterval, uint16_t maxInterval);
bool addServiceUUID(const NimBLEUUID& serviceUUID);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -141,6 +141,22 @@ bool NimBLEClient::connect(bool deleteAttributes, bool asyncConnect, bool exchan
return connect(m_peerAddress, deleteAttributes, asyncConnect, exchangeMTU);
} // connect
/**
* @brief Connect to an advertising device.
* @param [in] device The device to connect to.
* @param [in] deleteAttributes If true this will delete any attribute objects this client may already\n
* have created when last connected.
* @param [in] asyncConnect If true, the connection will be made asynchronously and this function will return immediately.\n
* If false, this function will block until the connection is established or the connection attempt times out.
* @param [in] exchangeMTU If true, the client will attempt to exchange MTU with the server after connection.\n
* If false, the client will use the default MTU size and the application will need to call exchangeMTU() later.
* @return true on success.
*/
bool NimBLEClient::connect(const NimBLEAdvertisedDevice* device, bool deleteAttributes, bool asyncConnect, bool exchangeMTU) {
NimBLEAddress address(device->getAddress());
return connect(address, deleteAttributes, asyncConnect, exchangeMTU);
} // connect
/**
* @brief Connect to a BLE Server by address.
* @param [in] address The address of the server.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -48,6 +48,10 @@ struct NimBLETaskData;
*/
class NimBLEClient {
public:
bool connect(const NimBLEAdvertisedDevice* device,
bool deleteAttributes = true,
bool asyncConnect = false,
bool exchangeMTU = true);
bool connect(const NimBLEAddress& address, bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true);
bool connect(bool deleteAttributes = true, bool asyncConnect = false, bool exchangeMTU = true);
bool disconnect(uint8_t reason = BLE_ERR_REM_USER_CONN_TERM);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -76,9 +76,6 @@ extern "C" void ble_store_config_init(void);
/**
* Singletons for the NimBLEDevice.
*/
NimBLEDeviceCallbacks NimBLEDevice::defaultDeviceCallbacks{};
NimBLEDeviceCallbacks* NimBLEDevice::m_pDeviceCallbacks = &defaultDeviceCallbacks;
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
NimBLEScan* NimBLEDevice::m_pScan = nullptr;
# endif
@ -467,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, NimBLETxPowerType type) {
bool NimBLEDevice::setPower(int8_t dbm) {
# ifdef ESP_PLATFORM
# ifdef CONFIG_IDF_TARGET_ESP32P4
return false; // CONFIG_IDF_TARGET_ESP32P4 does not support esp_ble_tx_power_set
@ -475,25 +472,9 @@ bool NimBLEDevice::setPower(int8_t dbm, NimBLETxPowerType type) {
if (dbm % 3 == 2) {
dbm++; // round up to the next multiple of 3 to be able to target 20dbm
}
bool success = false;
esp_power_level_t espPwr = static_cast<esp_power_level_t>(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;
return setPowerLevel(static_cast<esp_power_level_t>(dbm / 3 + ESP_PWR_LVL_N0));
# 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};
@ -512,16 +493,12 @@ bool NimBLEDevice::setPower(int8_t dbm, NimBLETxPowerType type) {
* @brief Get the transmission power.
* @return The power level currently used in dbm or 0xFF on error.
*/
int NimBLEDevice::getPower(NimBLETxPowerType type) {
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
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);
int pwr = getPowerLevel();
if (pwr < 0) {
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_get failed rc=%d", pwr);
return 0xFF;
@ -538,7 +515,6 @@ int NimBLEDevice::getPower(NimBLETxPowerType type) {
return 0;
# endif
# else
(void)type; // unused
return ble_phy_txpwr_get();
# endif
} // getPower
@ -901,23 +877,17 @@ bool NimBLEDevice::init(const std::string& deviceName) {
nimble_port_init();
// Setup callbacks for host events
ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
ble_hs_cfg.store_status_cb = [](struct ble_store_status_event* event, void* arg) {
return m_pDeviceCallbacks->onStoreStatus(event, arg);
};
ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
// Set initial security capabilities
ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
ble_hs_cfg.sm_bonding = 0;
ble_hs_cfg.sm_mitm = 0;
ble_hs_cfg.sm_sc = 1;
ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC;
# if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
ble_hs_cfg.sm_our_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_their_key_dist |= BLE_SM_PAIR_KEY_DIST_ID;
# endif
ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr; /*TODO: Implement handler for this*/
setDeviceName(deviceName);
ble_store_config_init();
@ -1267,13 +1237,4 @@ void nimble_cpp_assert(const char* file, unsigned line) {
}
# endif // CONFIG_NIMBLE_CPP_DEBUG_ASSERT_ENABLED
void NimBLEDevice::setDeviceCallbacks(NimBLEDeviceCallbacks* cb) {
m_pDeviceCallbacks = cb ? cb : &defaultDeviceCallbacks;
}
int NimBLEDeviceCallbacks::onStoreStatus(struct ble_store_status_event* event, void* arg) {
NIMBLE_LOGD("NimBLEDeviceCallbacks", "onStoreStatus: default");
return ble_store_util_status_rr(event, arg);
}
#endif // CONFIG_BT_ENABLED

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -66,7 +66,6 @@ class NimBLEConnInfo;
# endif
class NimBLEAddress;
class NimBLEDeviceCallbacks;
# define BLEDevice NimBLEDevice
# define BLEClient NimBLEClient
@ -102,13 +101,6 @@ class NimBLEDeviceCallbacks;
# 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);
/**
@ -130,7 +122,6 @@ class NimBLEDevice {
static bool setOwnAddrType(uint8_t type);
static bool setOwnAddr(const NimBLEAddress& addr);
static bool setOwnAddr(const uint8_t* addr);
static void setDeviceCallbacks(NimBLEDeviceCallbacks* cb);
static void setScanDuplicateCacheSize(uint16_t cacheSize);
static void setScanFilterMode(uint8_t type);
static bool setCustomGapHandler(gap_event_handler handler);
@ -147,8 +138,8 @@ class NimBLEDevice {
static void onReset(int reason);
static void onSync(void);
static void host_task(void* param);
static int getPower(NimBLETxPowerType type = NimBLETxPowerType::All);
static bool setPower(int8_t dbm, NimBLETxPowerType type = NimBLETxPowerType::All);
static int getPower();
static bool setPower(int8_t dbm);
# ifdef ESP_PLATFORM
# ifndef CONFIG_IDF_TARGET_ESP32P4
@ -215,8 +206,6 @@ class NimBLEDevice {
static ble_gap_event_listener m_listener;
static uint8_t m_ownAddrType;
static std::vector<NimBLEAddress> m_whiteList;
static NimBLEDeviceCallbacks* m_pDeviceCallbacks;
static NimBLEDeviceCallbacks defaultDeviceCallbacks;
# if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
static NimBLEScan* m_pScan;
@ -299,27 +288,5 @@ class NimBLEDevice {
# include "NimBLEUtils.h"
/**
* @brief Callbacks associated with a BLE device.
*/
class NimBLEDeviceCallbacks {
public:
virtual ~NimBLEDeviceCallbacks() {};
/**
* @brief Indicates an inability to perform a store operation.
* This callback should do one of two things:
* -Address the problem and return 0, indicating that the store operation
* should proceed.
* -Return nonzero to indicate that the store operation should be aborted.
* @param event Describes the store event being reported.
* BLE_STORE_EVENT_FULL; or
* BLE_STORE_EVENT_OVERFLOW
* @return 0 if the store operation should proceed;
* nonzero if the store operation should be aborted.
*/
virtual int onStoreStatus(struct ble_store_status_event* event, void* arg);
};
#endif // CONFIG_BT_ENABLED
#endif // NIMBLE_CPP_DEVICE_H_

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -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 = NimBLEDevice::getPower(NimBLETxPowerType::Advertise);
m_params.tx_power = 127;
} // NimBLEExtAdvertisement
/**
@ -1014,22 +1014,8 @@ bool NimBLEExtAdvertisement::setPreferredParams(uint16_t minInterval, uint16_t m
/**
* @brief Adds Tx power level to the advertisement data.
*/
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);
}
void NimBLEExtAdvertisement::addTxPower() {
m_params.include_tx_power = 1;
return true;
} // addTxPower
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -46,33 +46,34 @@ 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<NimBLEUUID>& uuids);
bool setCompleteServices32(const std::vector<NimBLEUUID>& 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<uint8_t>& 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<NimBLEUUID>& uuids);
bool setPartialServices32(const std::vector<NimBLEUUID>& 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<uint8_t>& 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();
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<NimBLEUUID>& uuids);
bool setCompleteServices32(const std::vector<NimBLEUUID>& 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<uint8_t>& 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<NimBLEUUID>& uuids);
bool setPartialServices32(const std::vector<NimBLEUUID>& 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<uint8_t>& 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();
void setLegacyAdvertising(bool enable);
void setConnectable(bool enable);
void setScannable(bool enable);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -28,109 +28,11 @@
# define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
# endif
# if defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR)
# if CONFIG_LOG_COLORS
# if defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_BLACK)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_BLACK)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_RED)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_RED)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_GREEN)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_GREEN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_YELLOW)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_BROWN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_BLUE)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_BLUE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_PURPLE)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_PURPLE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_DEBUG_CYAN)
# define NIMBLE_CPP_LOG_COLOR_D LOG_COLOR(LOG_COLOR_CYAN)
# else
# define NIMBLE_CPP_LOG_COLOR_D
# endif
# if defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_BLACK)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_BLACK)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_RED)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_RED)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_GREEN)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_YELLOW)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_BROWN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_BLUE)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_BLUE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_PURPLE)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_PURPLE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_INFO_CYAN)
# define NIMBLE_CPP_LOG_COLOR_I LOG_COLOR(LOG_COLOR_CYAN)
# else
# define NIMBLE_CPP_LOG_COLOR_I
# endif
# if defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_BLACK)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_BLACK)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_RED)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_RED)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_GREEN)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_GREEN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_YELLOW)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_BLUE)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_BLUE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_PURPLE)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_PURPLE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_WARN_CYAN)
# define NIMBLE_CPP_LOG_COLOR_W LOG_COLOR(LOG_COLOR_CYAN)
# else
# define NIMBLE_CPP_LOG_COLOR_W
# endif
# if defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_BLACK)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_BLACK)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_RED)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_GREEN)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_GREEN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_YELLOW)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_BROWN)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_BLUE)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_BLUE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_PURPLE)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_PURPLE)
# elif defined(CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR_ERR_CYAN)
# define NIMBLE_CPP_LOG_COLOR_E LOG_COLOR(LOG_COLOR_CYAN)
# else
# define NIMBLE_CPP_LOG_COLOR_E
# endif
# else //CONFIG_LOG_COLORS
# define NIMBLE_CPP_LOG_COLOR_D
# define NIMBLE_CPP_LOG_COLOR_I
# define NIMBLE_CPP_LOG_COLOR_W
# define NIMBLE_CPP_LOG_COLOR_E
# endif //CONFIG_LOG_COLORS
# define NIMBLE_CPP_LOG_FORMAT(letter, format) NIMBLE_CPP_LOG_COLOR_##letter #letter " (%lu) %s: " format LOG_RESET_COLOR "\n"
# define NIMBLE_CPP_LOG_LEVEL_LOCAL(level, tag, format, ...) \
do { \
if (level==ESP_LOG_ERROR) { esp_log_write(ESP_LOG_ERROR, tag, NIMBLE_CPP_LOG_FORMAT(E, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
else if (level==ESP_LOG_WARN) { esp_log_write(ESP_LOG_WARN, tag, NIMBLE_CPP_LOG_FORMAT(W, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
else if (level==ESP_LOG_INFO) { esp_log_write(ESP_LOG_INFO, tag, NIMBLE_CPP_LOG_FORMAT(I, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
else { esp_log_write(ESP_LOG_DEBUG, tag, NIMBLE_CPP_LOG_FORMAT(D, format), esp_log_timestamp(), tag __VA_OPT__(,) __VA_ARGS__); } \
} while(0)
# define NIMBLE_CPP_LOG_PRINT(level, tag, format, ...) \
do { \
if (CONFIG_NIMBLE_CPP_LOG_LEVEL >= level) NIMBLE_CPP_LOG_LEVEL_LOCAL(level, tag, format, ##__VA_ARGS__); \
} while (0)
# else
# define NIMBLE_CPP_LOG_PRINT(level, tag, format, ...) \
# define NIMBLE_CPP_LOG_PRINT(level, tag, format, ...) \
do { \
if (CONFIG_NIMBLE_CPP_LOG_LEVEL >= level) ESP_LOG_LEVEL_LOCAL(level, tag, format, ##__VA_ARGS__); \
if (CONFIG_NIMBLE_CPP_LOG_LEVEL >= level) ESP_LOG_LEVEL_LOCAL(level, tag, format, ##__VA_ARGS__); \
} while (0)
# endif /* CONFIG_NIMBLE_CPP_LOG_OVERRIDE_COLOR */
# define NIMBLE_LOGD(tag, format, ...) NIMBLE_CPP_LOG_PRINT(ESP_LOG_DEBUG, tag, format, ##__VA_ARGS__)
# define NIMBLE_LOGI(tag, format, ...) NIMBLE_CPP_LOG_PRINT(ESP_LOG_INFO, tag, format, ##__VA_ARGS__)
# define NIMBLE_LOGW(tag, format, ...) NIMBLE_CPP_LOG_PRINT(ESP_LOG_WARN, tag, format, ##__VA_ARGS__)
@ -171,13 +73,6 @@
# define NIMBLE_LOGE(tag, format, ...) (void)tag
# endif
# endif /* CONFIG_NIMBLE_CPP_IDF */
# define NIMBLE_LOGD_IF(cond, tag, format, ...) { if (cond) { NIMBLE_LOGD(tag, format, ##__VA_ARGS__); }}
# define NIMBLE_LOGI_IF(cond, tag, format, ...) { if (cond) { NIMBLE_LOGI(tag, format, ##__VA_ARGS__); }}
# define NIMBLE_LOGW_IF(cond, tag, format, ...) { if (cond) { NIMBLE_LOGW(tag, format, ##__VA_ARGS__); }}
# define NIMBLE_LOGE_IF(cond, tag, format, ...) { if (cond) { NIMBLE_LOGE(tag, format, ##__VA_ARGS__); }}
# define NIMBLE_LOGE_RC(rc, tag, format, ...) { if (rc) { NIMBLE_LOGE(tag, format "; rc=%d %s", ##__VA_ARGS__, rc, NimBLEUtils::returnCodeToString(rc)); }}
#endif /* CONFIG_BT_ENABLED */
#endif /* NIMBLE_CPP_LOG_H_ */
# endif /* CONFIG_NIMBLE_CPP_IDF */
#endif /* CONFIG_BT_ENABLED */
#endif /* NIMBLE_CPP_LOG_H_ */

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -27,18 +27,17 @@
# include <climits>
struct NimBLEDescriptorFilter {
NimBLERemoteDescriptor* dsc;
const NimBLEUUID* uuid;
void* taskData;
};
typedef struct {
const NimBLEUUID* uuid;
void* task_data;
} desc_filter_t;
static const char* LOG_TAG = "NimBLERemoteCharacteristic";
/**
* @brief Constructor.
* @param [in] svc A pointer to the service this characteristic belongs to.
* @param [in] chr struct defined as:
* @param [in] ble_gatt_chr struct defined as:
* struct ble_gatt_chr {
* uint16_t def_handle;
* uint16_t val_handle;
@ -64,69 +63,66 @@ NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
* @brief Callback used by the API when a descriptor is discovered or search complete.
*/
int NimBLERemoteCharacteristic::descriptorDiscCB(
uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg) {
int rc = error->status;
auto filter = (NimBLEDescriptorFilter*)arg;
auto pTaskData = (NimBLETaskData*)filter->taskData;
const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance;
const auto uuid = filter->uuid; // UUID to filter for
uint16_t conn_handle, const ble_gatt_error* error, uint16_t chr_val_handle, const ble_gatt_dsc* dsc, void* arg) {
int rc = error->status;
NIMBLE_LOGD(LOG_TAG, "Descriptor Discovery >> status: %d handle: %d", rc, (rc == 0) ? dsc->handle : -1);
// Results for chrHandle added until rc != 0
// Must find specified UUID if filter is used
if (rc == 0 && pChr->getHandle() == chrHandle && (!uuid || 0 == ble_uuid_cmp(uuid->getBase(), &dsc->uuid.u))) {
// Return BLE_HS_EDONE if the descriptor was found, stop the search
pChr->m_vDescriptors.push_back(new NimBLERemoteDescriptor(pChr, dsc));
rc = !!uuid * BLE_HS_EDONE;
auto filter = (desc_filter_t*)arg;
auto pTaskData = (NimBLETaskData*)filter->task_data;
const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance;
const NimBLEUUID* uuidFilter = filter->uuid;
if (pChr->getHandle() != chr_val_handle) {
return 0; // Descriptor not for this characteristic
}
if (rc != 0) {
NimBLEUtils::taskRelease(*pTaskData, rc);
NIMBLE_LOGD(LOG_TAG, "<< Descriptor Discovery");
if (rc == 0) {
if (uuidFilter != nullptr) {
if (ble_uuid_cmp(uuidFilter->getBase(), &dsc->uuid.u) == 0) {
rc = BLE_HS_EDONE; // Found the descriptor, stop the search
} else {
return 0; // Not the descriptor we are looking for
}
}
pChr->m_vDescriptors.push_back(new NimBLERemoteDescriptor(pChr, dsc));
return 0;
}
NimBLEUtils::taskRelease(*pTaskData, rc);
NIMBLE_LOGD(LOG_TAG, "<< Descriptor Discovery");
return rc;
}
/**
* @brief Populate the descriptors (if any) for this characteristic.
* @param [in] pFilter Pointer to a filter containing pointers to descriptor, UUID, and task data.
* @return True if successfully retrieved, success = BLE_HS_EDONE.
* @param [in] the end handle of the characteristic, or the service, whichever comes first.
*/
bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFilter) const {
bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID* uuidFilter) const {
NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
// If this is the last handle then there are no descriptors
if (getHandle() == getRemoteService()->getEndHandle()) {
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found 0 descriptors.");
return true;
}
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
NimBLEDescriptorFilter defaultFilter{nullptr, nullptr, &taskData};
if (pFilter == nullptr) {
pFilter = &defaultFilter;
}
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
desc_filter_t filter = {uuidFilter, &taskData};
int rc = ble_gattc_disc_all_dscs(getClient()->getConnHandle(),
getHandle(),
getRemoteService()->getEndHandle(),
NimBLERemoteCharacteristic::descriptorDiscCB,
pFilter);
&filter);
if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_dscs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false;
}
NimBLEUtils::taskWait(pFilter->taskData, BLE_NPL_TIME_FOREVER);
rc = ((NimBLETaskData*)pFilter->taskData)->m_flags;
if (rc != BLE_HS_EDONE) {
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false;
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
rc = taskData.m_flags;
if (rc == 0 || rc == BLE_HS_EDONE) {
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found %d descriptors.", m_vDescriptors.size());
return true;
}
pFilter->dsc = m_vDescriptors.back();
NIMBLE_LOGD(LOG_TAG, "<< retrieveDescriptors(): found %d descriptors.", m_vDescriptors.size());
return true;
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
return false;
} // retrieveDescriptors
/**
@ -136,38 +132,51 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi
*/
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
NimBLEUUID uuidTmp{uuid};
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
NimBLEDescriptorFilter filter{nullptr, &uuidTmp, &taskData};
NimBLERemoteDescriptor* pDsc = nullptr;
size_t prev_size = m_vDescriptors.size();
for (const auto& dsc : m_vDescriptors) {
if (dsc->getUUID() == uuid) {
filter.dsc = dsc;
for (const auto& it : m_vDescriptors) {
if (it->getUUID() == uuid) {
pDsc = it;
goto Done;
}
}
if (!retrieveDescriptors(&filter) || filter.dsc) {
goto Done;
}
if (retrieveDescriptors(&uuid)) {
if (m_vDescriptors.size() > prev_size) {
pDsc = m_vDescriptors.back();
goto Done;
}
// Try again with 128 bit uuid if request succeeded but no descriptor found.
if (uuid.bitSize() != BLE_UUID_TYPE_128) {
uuidTmp.to128();
retrieveDescriptors(&filter);
goto Done;
}
// If the uuid was 128 bit, try again with 16 bit uuid.
uuidTmp.to16();
if (uuidTmp.bitSize() == BLE_UUID_TYPE_16) {
filter.uuid = &uuidTmp;
retrieveDescriptors(&filter);
// If the request was successful but 16/32 bit uuid not found
// try again with the 128 bit uuid.
if (uuid.bitSize() == BLE_UUID_TYPE_16 || uuid.bitSize() == BLE_UUID_TYPE_32) {
NimBLEUUID uuid128(uuid);
uuid128.to128();
if (retrieveDescriptors(&uuid128)) {
if (m_vDescriptors.size() > prev_size) {
pDsc = m_vDescriptors.back();
}
}
} else {
// If the request was successful but the 128 bit uuid not found
// try again with the 16 bit uuid.
NimBLEUUID uuid16(uuid);
uuid16.to16();
// if the uuid was 128 bit but not of the BLE base type this check will fail
if (uuid16.bitSize() == BLE_UUID_TYPE_16) {
if (retrieveDescriptors(&uuid16)) {
if (m_vDescriptors.size() > prev_size) {
pDsc = m_vDescriptors.back();
}
}
}
}
}
Done:
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: %sfound", filter.dsc ? "" : "not ");
return filter.dsc;
NIMBLE_LOGD(LOG_TAG, "<< getDescriptor: %sfound", pDsc ? "" : "not ");
return pDsc;
} // getDescriptor
/**
@ -296,7 +305,7 @@ size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID& uuid) cons
* @return True if supported.
*/
bool NimBLERemoteCharacteristic::canBroadcast() const {
return (m_properties & BLE_GATT_CHR_PROP_BROADCAST);
return (m_properties & BLE_GATT_CHR_PROP_BROADCAST) != 0;
};
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -25,10 +25,8 @@
# include <vector>
# include <functional>
class NimBLEUUID;
class NimBLERemoteService;
class NimBLERemoteDescriptor;
struct NimBLEDescriptorFilter;
/**
* @brief A model of a remote BLE characteristic.
@ -67,10 +65,10 @@ class NimBLERemoteCharacteristic : public NimBLERemoteValueAttribute {
~NimBLERemoteCharacteristic();
bool setNotify(uint16_t val, notify_callback notifyCallback = nullptr, bool response = true) const;
bool retrieveDescriptors(NimBLEDescriptorFilter* pFilter = nullptr) const;
bool retrieveDescriptors(const NimBLEUUID* uuidFilter = nullptr) const;
static int descriptorDiscCB(
uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg);
uint16_t conn_handle, const ble_gatt_error* error, uint16_t chr_val_handle, const ble_gatt_dsc* dsc, void* arg);
const NimBLERemoteService* m_pRemoteService{nullptr};
uint8_t m_properties{0};

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -468,26 +468,19 @@ NimBLEScanResults NimBLEScan::getResults() {
* @brief Clear the stored results of the scan.
*/
void NimBLEScan::clearResults() {
if (m_scanResults.m_deviceVec.size()) {
std::vector<NimBLEAdvertisedDevice*> vSwap{};
ble_npl_hw_enter_critical();
vSwap.swap(m_scanResults.m_deviceVec);
ble_npl_hw_exit_critical(0);
for (const auto& dev : vSwap) {
delete dev;
}
for (const auto& dev : m_scanResults.m_deviceVec) {
delete dev;
}
std::vector<NimBLEAdvertisedDevice*>().swap(m_scanResults.m_deviceVec);
} // clearResults
/**
* @brief Dump the scan results to the log.
*/
void NimBLEScanResults::dump() const {
#if CONFIG_NIMBLE_CPP_LOG_LEVEL >=3
for (const auto& dev : m_deviceVec) {
NIMBLE_LOGI(LOG_TAG, "- %s", dev->toString().c_str());
}
#endif
} // dump
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020-2025 Ryan Powell <ryan@nable-embedded.io> and
* Copyright 2020-2024 Ryan Powell <ryan@nable-embedded.io> and
* esp-nimble-cpp, NimBLE-Arduino contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");

View File

@ -63,19 +63,3 @@
#if defined(CONFIG_BT_NIMBLE_EXT_ADV_MAX_SIZE) && !defined(CONFIG_BT_NIMBLE_MAX_EXT_ADV_DATA_LEN)
#define CONFIG_BT_NIMBLE_MAX_EXT_ADV_DATA_LEN CONFIG_BT_NIMBLE_EXT_ADV_MAX_SIZE
#endif
#if !defined(CONFIG_BTDM_BLE_SCAN_DUPL) && defined(CONFIG_BT_CTRL_BLE_SCAN_DUPL)
#define CONFIG_BTDM_BLE_SCAN_DUPL CONFIG_BT_CTRL_BLE_SCAN_DUPL
#endif
#if !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE) && defined(CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE)
#define CONFIG_BTDM_SCAN_DUPL_TYPE_DEVICE CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DEVICE
#endif
#if !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA) && defined(CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA)
#define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA
#endif
#if !defined(CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE) && defined(CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE)
#define CONFIG_BTDM_SCAN_DUPL_TYPE_DATA_DEVICE CONFIG_BT_CTRL_SCAN_DUPL_TYPE_DATA_DEVICE
#endif