Skip to content

Commit 780b935

Browse files
authored
Server: Add onSubscribe() callback for characteristics. (#91)
* Server: Add onSubscribe() callback for characteristics. Adds a new method to NimBLECharacteristicCallbacks that gets called when a client changes it's subscription status. * Remove NimBLE2902 class. As the NimBLE2902 class usefulness was only related to callback functions that were replaced by the NimBLECharacteristicCallbacks:onSubscribe() method this removes the NimBLE2902 class and moves all subscription handling to NimBLECharacteristic. * Update documents and examples to reflect this change. * Add getSubscribedCount() to get the number of subscribed clients.
1 parent bad29ee commit 780b935

File tree

12 files changed

+128
-275
lines changed

12 files changed

+128
-275
lines changed

docs/BREAKING_API_CHANGES.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,18 @@ When creating a characteristic the properties are now set with `NIMBLE_PROPERTY:
3333
### Descriptors
3434
Descriptors are now created using the `NimBLECharacteristic::createDescriptor()` method.
3535

36-
The previous method `BLECharacteristic::addDescriptor()` is now a private function in the library.
36+
The previous method `BLECharacteristic::addDescriptor()` has been removed.
3737

38-
This was done because the NimBLE host automatically creates a 0x2902 descriptor if a characteristic has NOTIFY or INDICATE properties applied.
39-
Due to this fact, the library also creates one automatically for your application.
40-
The only reason to manually create this descriptor now is to assign callback functions.
41-
If you do not require this functionality you can safely exclude the manual creation of the 0x2902 descriptor.
38+
0x2902 Descriptor class: formerly known as BLE2902 or NimBLE2902 has been removed.
39+
It was no longer useful as a new callback `NimBLECharacteristicCallbacks::onSubscribe` was added
40+
to handle callback functionality and the client subscription status is handled internally.
4241

43-
For any other descriptor, (except 0x2904, see below) it should now be created just as characteristics are
44-
by using the `NimBLECharacteristic::createDescriptor` method.
42+
NimBLE automatically creates the 0x2902 descriptor if a characteristic has a notification or indication property assigned to it.
43+
44+
**Note** Attempting to create a 0x2902 descriptor will trigger an assert to notify the error,
45+
allowing the creation of it would cause a fault in the NimBLE stack.
46+
47+
All other desctiptors are now created just as characteristics are by using the `NimBLECharacteristic::createDescriptor` methods (except 0x2904, see below).
4548
Which are defined as:
4649
```
4750
NimBLEDescriptor* createDescriptor(const char* uuid,
@@ -67,15 +70,14 @@ pDescriptor = pCharacteristic->createDescriptor("ABCD",
6770
Would create a descriptor with the UUID 0xABCD, publicly readable but only writable if paired/bonded (encrypted) and has a max value length of 25 bytes.
6871
<br/>
6972

70-
For the 0x2904 and 0x2902 descriptor, there is a special class that is created when you call `createDescriptor("2904")`or `createDescriptor("2902")`.
73+
For the 0x2904, there is a special class that is created when you call `createDescriptor("2904").
7174

72-
The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` or `NimBLE2902` so you must cast the returned pointer to
73-
`NimBLE2904` or `NimBLE2902` to access the specific class methods.
75+
The pointer returned is of the base class `NimBLEDescriptor` but the call will create the derived class of `NimBLE2904` so you must cast the returned pointer to
76+
`NimBLE2904` to access the specific class methods.
7477

7578
##### Example
7679
```
7780
p2904 = (NimBLE2904*)pCharacteristic->createDescriptor("2904");
78-
p2902 = (NimBLE2902*)pCharacteristic->createDescriptor("2902");
7981
```
8082
<br/>
8183

@@ -91,7 +93,6 @@ Security is set on the characteristic or descriptor properties by applying one o
9193
When a peer wants to read or write a characteristic or descriptor with any of these properties applied
9294
it will trigger the pairing process. By default the "just-works" pairing will be performed automatically.
9395
This can be changed to use passkey authentication or numeric comparison. See [Security Differences](#security-differences) for details.
94-
9596
<br/>
9697

9798
# Client API Differences

examples/NimBLE_Server/NimBLE_Server.ino

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -100,26 +100,33 @@ class CharacteristicCallbacks: public NimBLECharacteristicCallbacks {
100100
str += NimBLEUtils::returnCodeToString(code);
101101
Serial.println(str);
102102
};
103+
104+
void onSubscribe(NimBLECharacteristic* pCharacteristic, ble_gap_conn_desc* desc, uint16_t subValue) {
105+
String str = "Client ID: ";
106+
str += desc->conn_handle;
107+
str += " Address: ";
108+
str += std::string(NimBLEAddress(desc->peer_ota_addr)).c_str();
109+
if(subValue == 0) {
110+
str += " Unsubscribed to ";
111+
}else if(subValue == 1) {
112+
str += " Subscribed to notfications for ";
113+
} else if(subValue == 2) {
114+
str += " Subscribed to indications for ";
115+
} else if(subValue == 3) {
116+
str += " Subscribed to notifications and indications for ";
117+
}
118+
str += std::string(pCharacteristic->getUUID()).c_str();
119+
120+
Serial.println(str);
121+
};
103122
};
104123

105124
/** Handler class for descriptor actions */
106125
class DescriptorCallbacks : public NimBLEDescriptorCallbacks {
107126
void onWrite(NimBLEDescriptor* pDescriptor) {
108-
if(pDescriptor->getUUID().equals(NimBLEUUID("2902"))) {
109-
/** Cast to NimBLE2902 to use the class specific functions. **/
110-
NimBLE2902* p2902 = (NimBLE2902*)pDescriptor;
111-
if(p2902->getNotifications()) {
112-
Serial.println("Client Subscribed to notfications");
113-
} else if(p2902->getIndications()) {
114-
Serial.println("Client Subscribed to indications");
115-
} else {
116-
Serial.println("Client Unubscribed");
117-
}
118-
} else {
119-
std::string dscVal((char*)pDescriptor->getValue(), pDescriptor->getLength());
120-
Serial.print("Descriptor witten value:");
121-
Serial.println(dscVal.c_str());
122-
}
127+
std::string dscVal((char*)pDescriptor->getValue(), pDescriptor->getLength());
128+
Serial.print("Descriptor witten value:");
129+
Serial.println(dscVal.c_str());
123130
};
124131

125132
void onRead(NimBLEDescriptor* pDescriptor) {
@@ -176,9 +183,9 @@ void setup() {
176183
pBeefCharacteristic->setValue("Burger");
177184
pBeefCharacteristic->setCallbacks(&chrCallbacks);
178185

179-
/** 2902 and 2904 descriptors are a special case, when createDescriptor is called with
180-
* either of those uuid's it will create the associated class with the correct properties
181-
* and sizes. However we must cast the returned reference to the correct type as the method
186+
/** 2904 descriptors are a special case, when createDescriptor is called with
187+
* 0x2904 a NimBLE2904 class is created with the correct properties and sizes.
188+
* However we must cast the returned reference to the correct type as the method
182189
* only returns a pointer to the base NimBLEDescriptor class.
183190
*/
184191
NimBLE2904* pBeef2904 = (NimBLE2904*)pBeefCharacteristic->createDescriptor("2904");
@@ -197,6 +204,10 @@ void setup() {
197204
pFoodCharacteristic->setValue("Fries");
198205
pFoodCharacteristic->setCallbacks(&chrCallbacks);
199206

207+
/** Note a 0x2902 descriptor MUST NOT be created as NimBLE will create one automatically
208+
* if notification or indication properties are assigned to a characteristic.
209+
*/
210+
200211
/** Custom descriptor: Arguments are UUID, Properties, max length in bytes of the value */
201212
NimBLEDescriptor* pC01Ddsc = pFoodCharacteristic->createDescriptor(
202213
"C01D",
@@ -208,14 +219,6 @@ void setup() {
208219
pC01Ddsc->setValue("Send it back!");
209220
pC01Ddsc->setCallbacks(&dscCallbacks);
210221

211-
/** Note a 2902 descriptor does NOT need to be created as any chactateristic with
212-
* notification or indication properties will have one created autmatically.
213-
* Manually creating it is only useful if you wish to handle callback functions
214-
* as shown here. Otherwise this can be removed without loss of functionality.
215-
*/
216-
NimBLE2902* pFood2902 = (NimBLE2902*)pFoodCharacteristic->createDescriptor("2902");
217-
pFood2902->setCallbacks(&dscCallbacks);
218-
219222
/** Start the services when finished creating all Characteristics and Descriptors */
220223
pDeadService->start();
221224
pBaadService->start();
@@ -247,4 +250,4 @@ void loop() {
247250
}
248251

249252
delay(2000);
250-
}
253+
}

examples/Refactored_original_examples/BLE_notify/BLE_notify.ino

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,13 @@ void setup() {
102102

103103
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
104104
// Create a BLE Descriptor
105-
/*********** New createDescriptor method ************
106-
NOTE: There is no need to create the 2902 descriptor
107-
as it will be created automatically if notifications
105+
/***************************************************
106+
NOTE: DO NOT create a 2902 descriptor.
107+
it will be created automatically if notifications
108108
or indications are enabled on a characteristic.
109109
110110
pCharacteristic->addDescriptor(new BLE2902());
111111
****************************************************/
112-
/** Add properties the same way as characteristics now **/
113-
114-
pCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/);
115112
// Start the service
116113
pService->start();
117114

examples/Refactored_original_examples/BLE_server_multiconnect/BLE_server_multiconnect.ino

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,13 @@ void setup() {
105105

106106
// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
107107
// Create a BLE Descriptor
108-
/*********** New createDescriptor method ************
109-
NOTE: There is no need to create the 2902 descriptor
110-
as it will be created automatically if notifications
108+
/***************************************************
109+
NOTE: DO NOT create a 2902 descriptor
110+
it will be created automatically if notifications
111111
or indications are enabled on a characteristic.
112112
113113
pCharacteristic->addDescriptor(new BLE2902());
114114
****************************************************/
115-
/** Add properties the same way as characteristics now **/
116-
117-
pCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/);
118115

119116
// Start the service
120117
pService->start();

examples/Refactored_original_examples/BLE_uart/BLE_uart.ino

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,13 @@ void setup() {
112112
NIMBLE_PROPERTY::NOTIFY
113113
);
114114

115-
/******* New createDescriptor method ********
116-
NOTE: There is no need to create the 2902 descriptor
117-
as it will be created automatically if notifications or
118-
indications are enabled on a characteristic.
115+
/***************************************************
116+
NOTE: DO NOT create a 2902 descriptor
117+
it will be created automatically if notifications
118+
or indications are enabled on a characteristic.
119119
120-
pCharacteristic->addDescriptor(new BLE2902());
121-
********************************************/
122-
/** Add properties the same way as characteristics now **/
123-
pTxCharacteristic->createDescriptor("2902" /** , NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE **/);
120+
pCharacteristic->addDescriptor(new BLE2902());
121+
****************************************************/
124122

125123
BLECharacteristic * pRxCharacteristic = pService->createCharacteristic(
126124
CHARACTERISTIC_UUID_RX,

src/NimBLE2902.cpp

Lines changed: 0 additions & 79 deletions
This file was deleted.

src/NimBLE2902.h

Lines changed: 0 additions & 59 deletions
This file was deleted.

0 commit comments

Comments
 (0)