Skip to content

Commit 4da6670

Browse files
committed
[Bugfix] NimBLEDevice::createServer can crash if stack not initialized.
This removes the gatts/gap reset calls from NimBLEDevice::createServer so that it can be safely used before initializing the stack. This also deprecates NimBLEService::start the the services will now be added/created only when the server is started.
1 parent 66522ce commit 4da6670

4 files changed

Lines changed: 19 additions & 27 deletions

File tree

src/NimBLEDevice.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,6 @@ extern "C" int ble_vhci_disc_duplicate_mode_enable(int mode);
125125
NimBLEServer* NimBLEDevice::createServer() {
126126
if (NimBLEDevice::m_pServer == nullptr) {
127127
NimBLEDevice::m_pServer = new NimBLEServer();
128-
ble_gatts_reset();
129-
ble_svc_gap_init();
130-
ble_svc_gatt_init();
131128
}
132129

133130
return m_pServer;

src/NimBLEServer.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -272,13 +272,15 @@ void NimBLEServer::gattRegisterCallback(ble_gatt_register_ctxt* ctxt, void* arg)
272272
void NimBLEServer::start() {
273273
if (m_svcChanged && !getConnectedCount()) {
274274
NIMBLE_LOGD(LOG_TAG, "Services have changed since last start, resetting GATT server");
275-
resetGATT();
275+
m_gattsStarted = false;
276276
}
277277

278278
if (m_gattsStarted) {
279279
return; // already started
280280
}
281281

282+
resetGATT();
283+
282284
ble_hs_cfg.gatts_register_cb = NimBLEServer::gattRegisterCallback;
283285
gattRegisterCallbackArgs args{};
284286
ble_hs_cfg.gatts_register_arg = &args;
@@ -873,8 +875,6 @@ void NimBLEServer::resetGATT() {
873875
ble_svc_gap_init();
874876
ble_svc_gatt_init();
875877

876-
m_gattsStarted = false;
877-
878878
for (auto svcIt = m_svcVec.begin(); svcIt != m_svcVec.end();) {
879879
auto* pSvc = *svcIt;
880880
if (pSvc->getRemoved() == NIMBLE_ATT_REMOVE_DELETE) {
@@ -908,7 +908,7 @@ void NimBLEServer::resetGATT() {
908908
}
909909

910910
if (pSvc->getRemoved() == 0) {
911-
pSvc->start();
911+
pSvc->start_internal();
912912
}
913913

914914
pSvc->m_handle = 0;

src/NimBLEService.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,8 @@ void NimBLEService::dump() const {
8383
* and registers it with the NimBLE stack.
8484
* @return bool success/failure .
8585
*/
86-
bool NimBLEService::start() {
86+
bool NimBLEService::start_internal() {
8787
NIMBLE_LOGD(LOG_TAG, ">> start(): Starting service: UUID: %s", getUUID().toString().c_str());
88-
// If the server has started before then we need to reset the GATT server
89-
// to update the service/characteristic/descriptor definitions. If characteristics or descriptors
90-
// have been added/removed since the last server start then this service will be started on gatt reset.
91-
if (getServer()->m_svcChanged && getServer()->m_gattsStarted) {
92-
NIMBLE_LOGW(LOG_TAG, "<< start(): GATT change pending, cannot start service");
93-
return false;
94-
}
95-
96-
// If started previously and no characteristics have been added or removed,
97-
// then we can skip the service registration process.
98-
if (m_pSvcDef->characteristics && !getServer()->m_svcChanged) {
99-
return true;
100-
}
101-
10288
// Make sure the definitions are cleared first
10389
clearServiceDefinitions();
10490

src/NimBLEService.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,19 @@ class NimBLEService : public NimBLELocalAttribute {
3737
NimBLEService(const NimBLEUUID& uuid);
3838
~NimBLEService();
3939

40-
NimBLEServer* getServer() const;
41-
std::string toString() const;
42-
void dump() const;
43-
bool isStarted() const;
44-
bool start();
40+
NimBLEServer* getServer() const;
41+
std::string toString() const;
42+
void dump() const;
43+
bool isStarted() const;
44+
45+
/**
46+
* @brief Dummy function to start the service. Services are started when the server is started.
47+
* This will be removed in a future release. Use `NimBLEServer::start()` to start the server and all associated services.
48+
*/
49+
__attribute__((deprecated("NimBLEService::start() has no effect. "
50+
"Services are started when the server is started.")))
51+
bool start() { return true; }
52+
4553
NimBLECharacteristic* createCharacteristic(const char* uuid,
4654
uint32_t properties = NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE,
4755
uint16_t max_len = BLE_ATT_ATTR_MAX_LEN);
@@ -61,6 +69,7 @@ class NimBLEService : public NimBLELocalAttribute {
6169

6270
private:
6371
friend class NimBLEServer;
72+
bool start_internal();
6473
void clearServiceDefinitions();
6574

6675
std::vector<NimBLECharacteristic*> m_vChars{};

0 commit comments

Comments
 (0)