Skip to content

Commit 0ff8474

Browse files
authored
[Server] Add ability to create static attributes. (#234)
This allows creating instances of services/characteristics and decriptors without needing to call the parent createX() methods. This allows creation of the attibutes within a class or other structure and the attributes can be linked to the parent by calling the parent addX() method. Additonally this increases the backward compatibility with the original bluedroid library to further support user migration.
1 parent 40c98b2 commit 0ff8474

File tree

8 files changed

+103
-52
lines changed

8 files changed

+103
-52
lines changed

src/NimBLE2904.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct BLE2904_Data {
4242
*/
4343
class NimBLE2904: public NimBLEDescriptor {
4444
public:
45+
NimBLE2904(NimBLECharacteristic* pCharacterisitic = nullptr);
4546
static const uint8_t FORMAT_BOOLEAN = 1;
4647
static const uint8_t FORMAT_UINT2 = 2;
4748
static const uint8_t FORMAT_UINT4 = 3;
@@ -77,7 +78,6 @@ class NimBLE2904: public NimBLEDescriptor {
7778
void setUnit(uint16_t unit);
7879

7980
private:
80-
NimBLE2904(NimBLECharacteristic* pCharacterisitic);
8181
friend class NimBLECharacteristic;
8282
BLE2904_Data m_data;
8383
}; // BLE2904

src/NimBLECharacteristic.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,20 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const NimBLEUUID &uuid,
9494
pDescriptor = new NimBLEDescriptor(uuid, properties, max_len, this);
9595
}
9696

97-
m_dscVec.push_back(pDescriptor);
97+
addDescriptor(pDescriptor);
98+
9899
return pDescriptor;
99-
} // createCharacteristic
100+
} // createDescriptor
101+
102+
103+
/**
104+
* @brief Add a descriptor to the characteristic.
105+
* @param [in] A pointer to the descriptor to add.
106+
*/
107+
void NimBLECharacteristic::addDescriptor(NimBLEDescriptor *pDescriptor) {
108+
pDescriptor->setCharacteristic(this);
109+
m_dscVec.push_back(pDescriptor);
110+
}
100111

101112

102113
/**
@@ -164,6 +175,11 @@ NimBLEService* NimBLECharacteristic::getService() {
164175
} // getService
165176

166177

178+
void NimBLECharacteristic::setService(NimBLEService *pService) {
179+
m_pService = pService;
180+
}
181+
182+
167183
/**
168184
* @brief Get the UUID of the characteristic.
169185
* @return The UUID of the characteristic.

src/NimBLECharacteristic.h

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ class NimBLECharacteristicCallbacks;
5959
*/
6060
class NimBLECharacteristic {
6161
public:
62+
NimBLECharacteristic(const char* uuid,
63+
uint16_t properties =
64+
NIMBLE_PROPERTY::READ |
65+
NIMBLE_PROPERTY::WRITE,
66+
NimBLEService* pService = nullptr);
67+
NimBLECharacteristic(const NimBLEUUID &uuid,
68+
uint16_t properties =
69+
NIMBLE_PROPERTY::READ |
70+
NIMBLE_PROPERTY::WRITE,
71+
NimBLEService* pService = nullptr);
72+
73+
~NimBLECharacteristic();
6274

6375
uint16_t getHandle();
6476
NimBLEUUID getUUID();
@@ -83,6 +95,7 @@ class NimBLECharacteristic {
8395
NIMBLE_PROPERTY::WRITE,
8496
uint16_t max_len = 100);
8597

98+
void addDescriptor(NimBLEDescriptor *pDescriptor);
8699
NimBLEDescriptor* getDescriptorByUUID(const char* uuid);
87100
NimBLEDescriptor* getDescriptorByUUID(const NimBLEUUID &uuid);
88101
NimBLEDescriptor* getDescriptorByHandle(uint16_t handle);
@@ -117,30 +130,15 @@ class NimBLECharacteristic {
117130
setValue((uint8_t*)&s, sizeof(T));
118131
}
119132

120-
121-
122-
133+
NimBLEService* getService();
134+
uint16_t getProperties();
123135

124136
private:
125137

126-
friend class NimBLEServer;
127-
friend class NimBLEService;
128-
129-
NimBLECharacteristic(const char* uuid,
130-
uint16_t properties =
131-
NIMBLE_PROPERTY::READ |
132-
NIMBLE_PROPERTY::WRITE,
133-
NimBLEService* pService = nullptr);
134-
NimBLECharacteristic(const NimBLEUUID &uuid,
135-
uint16_t properties =
136-
NIMBLE_PROPERTY::READ |
137-
NIMBLE_PROPERTY::WRITE,
138-
NimBLEService* pService = nullptr);
139-
140-
~NimBLECharacteristic();
138+
friend class NimBLEServer;
139+
friend class NimBLEService;
141140

142-
NimBLEService* getService();
143-
uint16_t getProperties();
141+
void setService(NimBLEService *pService);
144142
void setSubscribe(struct ble_gap_event *event);
145143
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
146144
struct ble_gatt_access_ctxt *ctxt, void *arg);

src/NimBLEDescriptor.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ NimBLEDescriptor::NimBLEDescriptor(const char* uuid, uint16_t properties, uint16
3737
: NimBLEDescriptor(NimBLEUUID(uuid), max_len, properties, pCharacteristic) {
3838
}
3939

40+
4041
/**
4142
* @brief NimBLEDescriptor constructor.
4243
*/
@@ -47,7 +48,7 @@ NimBLEDescriptor::NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties, uint16_
4748
m_value.attr_len = 0; // Initial length is 0.
4849
m_value.attr_max_len = max_len; // Maximum length of the data.
4950
m_handle = NULL_HANDLE; // Handle is initially unknown.
50-
m_pCharacteristic = nullptr; // No initial characteristic.
51+
m_pCharacteristic = pCharacteristic;
5152
m_pCallbacks = &defaultCallbacks; // No initial callback.
5253
m_value.attr_value = (uint8_t*) calloc(max_len,1); // Allocate storage for the value.
5354
m_valMux = portMUX_INITIALIZER_UNLOCKED;
@@ -122,6 +123,7 @@ uint8_t* NimBLEDescriptor::getValue() {
122123
return m_value.attr_value;
123124
} // getValue
124125

126+
125127
/**
126128
* @brief Get the value of this descriptor as a string.
127129
* @return A std::string instance containing a copy of the descriptor's value.
@@ -130,9 +132,18 @@ std::string NimBLEDescriptor::getStringValue() {
130132
return std::string((char *) m_value.attr_value, m_value.attr_len);
131133
}
132134

135+
136+
/**
137+
* @brief Get the characteristic this descriptor belongs to.
138+
* @return A pointer to the characteristic this descriptor belongs to.
139+
*/
140+
NimBLECharacteristic* NimBLEDescriptor::getCharacteristic() {
141+
return m_pCharacteristic;
142+
} // getCharacteristic
143+
144+
133145
int NimBLEDescriptor::handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
134-
struct ble_gatt_access_ctxt *ctxt,
135-
void *arg) {
146+
struct ble_gatt_access_ctxt *ctxt, void *arg) {
136147
const ble_uuid_t *uuid;
137148
int rc;
138149
NimBLEDescriptor* pDescriptor = (NimBLEDescriptor*)arg;
@@ -237,6 +248,14 @@ void NimBLEDescriptor::setValue(const std::string &value) {
237248
setValue((uint8_t*) value.data(), value.length());
238249
} // setValue
239250

251+
/**
252+
* @brief Set the characteristic this descriptor belongs to.
253+
* @param [in] pChar A pointer to the characteristic this descriptior belongs to.
254+
*/
255+
void NimBLEDescriptor::setCharacteristic(NimBLECharacteristic* pChar) {
256+
m_pCharacteristic = pChar;
257+
} // setCharacteristic
258+
240259

241260
/**
242261
* @brief Return a string representation of the descriptor.

src/NimBLEDescriptor.h

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,46 +43,48 @@ class NimBLEDescriptorCallbacks;
4343
*/
4444
class NimBLEDescriptor {
4545
public:
46-
uint16_t getHandle();
47-
NimBLEUUID getUUID();
48-
std::string toString();
46+
NimBLEDescriptor(const char* uuid, uint16_t properties,
47+
uint16_t max_len,
48+
NimBLECharacteristic* pCharacteristic = nullptr);
49+
50+
NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
51+
uint16_t max_len,
52+
NimBLECharacteristic* pCharacteristic = nullptr);
53+
54+
~NimBLEDescriptor();
55+
56+
uint16_t getHandle();
57+
NimBLEUUID getUUID();
58+
std::string toString();
59+
60+
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks);
4961

50-
void setCallbacks(NimBLEDescriptorCallbacks* pCallbacks);
62+
size_t getLength();
63+
uint8_t* getValue();
64+
std::string getStringValue();
5165

52-
size_t getLength();
53-
uint8_t* getValue();
54-
std::string getStringValue();
66+
void setValue(const uint8_t* data, size_t size);
67+
void setValue(const std::string &value);
68+
NimBLECharacteristic* getCharacteristic();
5569

56-
void setValue(const uint8_t* data, size_t size);
57-
void setValue(const std::string &value);
5870
/**
5971
* @brief Convenience template to set the descriptor value to <type\>val.
6072
* @param [in] s The value to set.
6173
*/
6274
template<typename T>
63-
void setValue(const T &s) {
75+
void setValue(const T &s) {
6476
setValue((uint8_t*)&s, sizeof(T));
6577
}
6678

6779
private:
6880
friend class NimBLECharacteristic;
6981
friend class NimBLEService;
70-
friend class NimBLE2902;
7182
friend class NimBLE2904;
7283

73-
NimBLEDescriptor(const char* uuid, uint16_t properties,
74-
uint16_t max_len,
75-
NimBLECharacteristic* pCharacteristic);
76-
77-
NimBLEDescriptor(NimBLEUUID uuid, uint16_t properties,
78-
uint16_t max_len,
79-
NimBLECharacteristic* pCharacteristic);
80-
81-
~NimBLEDescriptor();
82-
8384
static int handleGapEvent(uint16_t conn_handle, uint16_t attr_handle,
8485
struct ble_gatt_access_ctxt *ctxt, void *arg);
8586
void setHandle(uint16_t handle);
87+
void setCharacteristic(NimBLECharacteristic* pChar);
8688

8789
NimBLEUUID m_uuid;
8890
uint16_t m_handle;

src/NimBLEServer.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,14 +650,23 @@ void NimBLEServer::removeService(NimBLEService* service, bool deleteSvc) {
650650

651651

652652
/**
653-
* @brief Adds a service which was already created, but removed from availability.
653+
* @brief Adds a service which was either already created but removed from availability,\n
654+
* or created and later added to services list.
654655
* @param [in] service The service object to add.
655656
* @note If it is desired to advertise the service it must be added by
656657
* calling NimBLEAdvertising::addServiceUUID.
657658
*/
658659
void NimBLEServer::addService(NimBLEService* service) {
659-
// If adding a service that was not removed just return.
660+
// Check that a service with the supplied UUID does not already exist.
661+
if(getServiceByUUID(service->getUUID()) != nullptr) {
662+
NIMBLE_LOGW(LOG_TAG, "Warning creating a duplicate service UUID: %s",
663+
std::string(service->getUUID()).c_str());
664+
}
665+
666+
// If adding a service that was not removed add it and return.
667+
// Else reset GATT and send service changed notification.
660668
if(service->m_removed == 0) {
669+
m_svcVec.push_back(service);
661670
return;
662671
}
663672

src/NimBLEService.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ NimBLECharacteristic* NimBLEService::createCharacteristic(const NimBLEUUID &uuid
246246
} // createCharacteristic
247247

248248

249+
void NimBLEService::addCharacteristic(NimBLECharacteristic* pCharacteristic) {
250+
pCharacteristic->setService(this);
251+
m_chrVec.push_back(pCharacteristic);
252+
}
253+
249254
/**
250255
* @brief Get a pointer to the characteristic object with the specified UUID.
251256
* @param [in] uuid The UUID of the characteristic.

src/NimBLEService.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class NimBLECharacteristic;
3636
class NimBLEService {
3737
public:
3838

39+
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
40+
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
41+
~NimBLEService();
42+
3943
NimBLEServer* getServer();
4044

4145
NimBLEUUID getUUID();
@@ -55,6 +59,7 @@ class NimBLEService {
5559
NIMBLE_PROPERTY::READ |
5660
NIMBLE_PROPERTY::WRITE);
5761

62+
void addCharacteristic(NimBLECharacteristic* pCharacteristic);
5863
NimBLECharacteristic* getCharacteristic(const char* uuid, uint16_t instanceId = 0);
5964
NimBLECharacteristic* getCharacteristic(const NimBLEUUID &uuid, uint16_t instanceId = 0);
6065
NimBLECharacteristic* getCharacteristicByHandle(uint16_t handle);
@@ -65,9 +70,6 @@ class NimBLEService {
6570

6671

6772
private:
68-
NimBLEService(const char* uuid, uint16_t numHandles, NimBLEServer* pServer);
69-
NimBLEService(const NimBLEUUID &uuid, uint16_t numHandles, NimBLEServer* pServer);
70-
~NimBLEService();
7173

7274
friend class NimBLEServer;
7375
friend class NimBLEDevice;

0 commit comments

Comments
 (0)