Skip to content

Commit ae8750f

Browse files
committed
Refactor service changed handling
This makes the services changes notification more accurate by waiting until the changes have taken effect and the server re-started before indicating the change.
1 parent a85b600 commit ae8750f

File tree

2 files changed

+56
-58
lines changed

2 files changed

+56
-58
lines changed

src/NimBLEServer.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,12 @@ NimBLEAdvertising* NimBLEServer::getAdvertising() const {
153153
# endif
154154

155155
/**
156-
* @brief Sends a service changed notification and resets the GATT server.
156+
* @brief Called when the services are added/removed and sets a flag to indicate they should be reloaded.
157+
* @details This has no effect if the GATT server was not already started.
157158
*/
158159
void NimBLEServer::serviceChanged() {
159160
if (m_gattsStarted) {
160161
m_svcChanged = true;
161-
ble_svc_gatt_changed(0x0001, 0xffff);
162-
resetGATT();
163162
}
164163
} // serviceChanged
165164

@@ -205,6 +204,12 @@ void NimBLEServer::start() {
205204
}
206205
}
207206

207+
// If the services have changed indicate it now
208+
if (m_svcChanged) {
209+
m_svcChanged = false;
210+
ble_svc_gatt_changed(0x0001, 0xffff);
211+
}
212+
208213
m_gattsStarted = true;
209214
} // start
210215

@@ -876,7 +881,6 @@ void NimBLEServer::resetGATT() {
876881
++it;
877882
}
878883

879-
m_svcChanged = false;
880884
m_gattsStarted = false;
881885
} // resetGATT
882886

src/NimBLEService.cpp

Lines changed: 48 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -90,84 +90,78 @@ void NimBLEService::dump() const {
9090
*/
9191
bool NimBLEService::start() {
9292
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: %s", toString().c_str());
93+
// If started previously, clear everything and start over
94+
if (m_pSvcDef->characteristics) {
95+
if (m_pSvcDef->characteristics->descriptors) {
96+
delete[] m_pSvcDef->characteristics->descriptors;
97+
}
98+
delete[] m_pSvcDef->characteristics;
99+
}
93100

94-
// Rebuild the service definition if the server attributes have changed.
95-
if (getServer()->m_svcChanged) {
96-
if (m_pSvcDef->characteristics) {
97-
if (m_pSvcDef->characteristics->descriptors) {
98-
delete[] m_pSvcDef->characteristics->descriptors;
99-
}
100-
delete[] m_pSvcDef->characteristics;
101+
size_t numChrs = 0;
102+
for (const auto& chr : m_vChars) {
103+
if (chr->getRemoved()) {
104+
continue;
101105
}
102-
m_pSvcDef->type = 0;
106+
++numChrs;
103107
}
104108

105-
if (!m_pSvcDef->type) {
106-
m_pSvcDef->type = BLE_GATT_SVC_TYPE_PRIMARY;
107-
size_t numChrs = 0;
109+
NIMBLE_LOGD(LOG_TAG, "Adding %d characteristics for service %s", numChrs, toString().c_str());
110+
if (numChrs) {
111+
int i = 0;
112+
113+
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
114+
// of the characteristics for the service. We create 1 extra and set it to null
115+
// for this purpose.
116+
ble_gatt_chr_def* pChrs = new ble_gatt_chr_def[numChrs + 1]{};
108117
for (const auto& chr : m_vChars) {
109118
if (chr->getRemoved()) {
110119
continue;
111120
}
112-
++numChrs;
113-
}
114-
115-
NIMBLE_LOGD(LOG_TAG, "Adding %d characteristics for service %s", numChrs, toString().c_str());
116-
if (numChrs) {
117-
int i = 0;
118121

119-
// Nimble requires the last characteristic to have it's uuid = 0 to indicate the end
120-
// of the characteristics for the service. We create 1 extra and set it to null
121-
// for this purpose.
122-
ble_gatt_chr_def* pChrs = new ble_gatt_chr_def[numChrs + 1]{};
123-
for (const auto& chr : m_vChars) {
124-
if (chr->getRemoved()) {
122+
size_t numDscs = 0;
123+
for (const auto& dsc : chr->m_vDescriptors) {
124+
if (dsc->getRemoved()) {
125125
continue;
126126
}
127+
++numDscs;
128+
}
129+
130+
if (numDscs) {
131+
int j = 0;
127132

128-
size_t numDscs = 0;
133+
// Must have last descriptor uuid = 0 so we have to create 1 extra
134+
ble_gatt_dsc_def* pDscs = new ble_gatt_dsc_def[numDscs + 1]{};
129135
for (const auto& dsc : chr->m_vDescriptors) {
130136
if (dsc->getRemoved()) {
131137
continue;
132138
}
133-
++numDscs;
134-
}
135-
136-
if (numDscs) {
137-
int j = 0;
138-
139-
// Must have last descriptor uuid = 0 so we have to create 1 extra
140-
ble_gatt_dsc_def* pDscs = new ble_gatt_dsc_def[numDscs + 1]{};
141-
for (const auto& dsc : chr->m_vDescriptors) {
142-
if (dsc->getRemoved()) {
143-
continue;
144-
}
145-
146-
pDscs[j].uuid = dsc->getUUID().getBase();
147-
pDscs[j].att_flags = dsc->getProperties();
148-
pDscs[j].min_key_size = 0;
149-
pDscs[j].access_cb = NimBLEServer::handleGattEvent;
150-
pDscs[j].arg = dsc;
151-
++j;
152-
}
153139

154-
pChrs[i].descriptors = pDscs;
140+
pDscs[j].uuid = dsc->getUUID().getBase();
141+
pDscs[j].att_flags = dsc->getProperties();
142+
pDscs[j].min_key_size = 0;
143+
pDscs[j].access_cb = NimBLEServer::handleGattEvent;
144+
pDscs[j].arg = dsc;
145+
++j;
155146
}
156147

157-
pChrs[i].uuid = chr->getUUID().getBase();
158-
pChrs[i].access_cb = NimBLEServer::handleGattEvent;
159-
pChrs[i].arg = chr;
160-
pChrs[i].flags = chr->getProperties();
161-
pChrs[i].min_key_size = 0;
162-
pChrs[i].val_handle = &chr->m_handle;
163-
++i;
148+
pChrs[i].descriptors = pDscs;
164149
}
165150

166-
m_pSvcDef->characteristics = pChrs;
151+
pChrs[i].uuid = chr->getUUID().getBase();
152+
pChrs[i].access_cb = NimBLEServer::handleGattEvent;
153+
pChrs[i].arg = chr;
154+
pChrs[i].flags = chr->getProperties();
155+
pChrs[i].min_key_size = 0;
156+
pChrs[i].val_handle = &chr->m_handle;
157+
++i;
167158
}
159+
160+
m_pSvcDef->characteristics = pChrs;
168161
}
169162

170-
int rc = ble_gatts_count_cfg(m_pSvcDef);
163+
m_pSvcDef->type = BLE_GATT_SVC_TYPE_PRIMARY;
164+
int rc = ble_gatts_count_cfg(m_pSvcDef);
171165
if (rc != 0) {
172166
NIMBLE_LOGE(LOG_TAG, "ble_gatts_count_cfg failed, rc= %d, %s", rc, NimBLEUtils::returnCodeToString(rc));
173167
return false;

0 commit comments

Comments
 (0)