Skip to content

Commit 16ab3f6

Browse files
committed
Replace task noitifcations with semaphores to avoid conflicts.
This will prevent a case where applications may notify a task that is blocking on a BLE operation before it completes. This can occur when writing to a characteristic in the application and blocking with task notifications until a notification occurs that releases it and the notification arrives before the write response.
1 parent 1c7fe71 commit 16ab3f6

13 files changed

Lines changed: 151 additions & 144 deletions

Kconfig

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,11 +197,4 @@ config NIMBLE_CPP_DEBUG_ASSERT_ENABLED
197197
Enabling this option will add debug asserts to the NimBLE CPP library.
198198
This will use approximately 1kB of flash memory.
199199

200-
config NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT
201-
int "FreeRTOS task block bit."
202-
default 31
203-
help
204-
Configure the bit to set in the task notification value when a task is blocked waiting for an event.
205-
This should be set to a bit that is not used by other notifications in the system.
206-
207200
endmenu

src/NimBLEClient.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ int NimBLEClient::startConnectionAttempt(const ble_addr_t* peerAddr) {
248248
*/
249249
bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes, bool asyncConnect, bool exchangeMTU) {
250250
NIMBLE_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str());
251-
NimBLETaskData taskData(this);
252-
const ble_addr_t* peerAddr = address.getBase();
253-
int rc = 0;
251+
NimBLEUtils::TaskData taskData(this);
252+
const ble_addr_t* peerAddr = address.getBase();
253+
int rc = 0;
254254

255255
if (!NimBLEDevice::m_synced) {
256256
NIMBLE_LOGE(LOG_TAG, "Host not synced with controller.");
@@ -347,7 +347,7 @@ bool NimBLEClient::secureConnection(bool async) const {
347347
return true;
348348
}
349349

350-
NimBLETaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
350+
NimBLEUtils::TaskData taskData(const_cast<NimBLEClient*>(this), BLE_HS_ENOTCONN);
351351
m_pTaskData = &taskData;
352352
int retryCount = 1;
353353
do {
@@ -769,8 +769,8 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID* uuidFilter) {
769769
return false;
770770
}
771771

772-
int rc = 0;
773-
NimBLETaskData taskData(this);
772+
int rc = 0;
773+
NimBLEUtils::TaskData taskData(this);
774774

775775
if (uuidFilter == nullptr) {
776776
rc = ble_gattc_disc_all_svcs(m_connHandle, NimBLEClient::serviceDiscoveredCB, &taskData);
@@ -809,8 +809,8 @@ int NimBLEClient::serviceDiscoveredCB(uint16_t connHandle,
809809
error->status,
810810
(error->status == 0) ? service->start_handle : -1);
811811

812-
NimBLETaskData* pTaskData = (NimBLETaskData*)arg;
813-
NimBLEClient* pClient = (NimBLEClient*)pTaskData->m_pInstance;
812+
NimBLEUtils::TaskData* pTaskData = (NimBLEUtils::TaskData*)arg;
813+
NimBLEClient* pClient = (NimBLEClient*)pTaskData->m_pInstance;
814814

815815
if (error->status == BLE_HS_ENOTCONN) {
816816
NIMBLE_LOGE(LOG_TAG, "<< Service Discovered; Disconnected");
@@ -1010,9 +1010,9 @@ void NimBLEClient::setConnectRetries(uint8_t numRetries) {
10101010
* @param [in] arg A pointer to the client instance that registered for this callback.
10111011
*/
10121012
int NimBLEClient::handleGapEvent(struct ble_gap_event* event, void* arg) {
1013-
NimBLEClient* pClient = (NimBLEClient*)arg;
1014-
int rc = 0;
1015-
NimBLETaskData* pTaskData = pClient->m_pTaskData; // save a copy in case client is deleted
1013+
NimBLEClient* pClient = (NimBLEClient*)arg;
1014+
int rc = 0;
1015+
NimBLEUtils::TaskData* pTaskData = pClient->m_pTaskData; // save a copy in case client is deleted
10161016

10171017
NIMBLE_LOGD(LOG_TAG, ">> handleGapEvent %s", NimBLEUtils::gapEventToString(event->type));
10181018

src/NimBLEClient.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# endif
2929

3030
# include "NimBLEAddress.h"
31+
# include "NimBLEUtils.h"
3132

3233
# include <stdint.h>
3334
# include <vector>
@@ -41,7 +42,6 @@ class NimBLEAdvertisedDevice;
4142
class NimBLEAttValue;
4243
class NimBLEClientCallbacks;
4344
class NimBLEConnInfo;
44-
struct NimBLETaskData;
4545

4646
/**
4747
* @brief A model of a BLE client.
@@ -155,7 +155,7 @@ class NimBLEClient {
155155
NimBLEAddress m_peerAddress;
156156
mutable int m_lastErr;
157157
int32_t m_connectTimeout;
158-
mutable NimBLETaskData* m_pTaskData;
158+
mutable NimBLEUtils::TaskData* m_pTaskData;
159159
std::vector<NimBLERemoteService*> m_svcVec;
160160
NimBLEClientCallbacks* m_pClientCallbacks;
161161
uint16_t m_connHandle;

src/NimBLEDevice.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,8 @@ bool NimBLEDevice::deinit(bool clearAll) {
10711071
deleteClient(clt);
10721072
}
10731073
# endif
1074+
1075+
NimBLEUtils::deleteTaskSems();
10741076
}
10751077

10761078
return rc == 0;

src/NimBLEL2CAPChannel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ int NimBLEL2CAPChannel::writeFragment(std::vector<uint8_t>::const_iterator begin
8888

8989
if (stalled) {
9090
NIMBLE_LOGD(LOG_TAG, "L2CAP Channel waiting for unstall...");
91-
NimBLETaskData taskData;
91+
NimBLEUtils::TaskData taskData;
9292
m_pTaskData = &taskData;
9393
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
9494
m_pTaskData = nullptr;

src/NimBLEL2CAPChannel.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
# undef max
2323
/**************************/
2424

25+
# include "NimBLEUtils.h"
26+
2527
# include <vector>
2628
# include <atomic>
2729

2830
class NimBLEClient;
2931
class NimBLEL2CAPChannelCallbacks;
30-
struct NimBLETaskData;
3132

3233
/**
3334
* @brief Encapsulates a L2CAP channel.
@@ -94,7 +95,7 @@ class NimBLEL2CAPChannel {
9495

9596
// Runtime handling
9697
std::atomic<bool> stalled{false};
97-
NimBLETaskData* m_pTaskData{nullptr};
98+
NimBLEUtils::TaskData* m_pTaskData{nullptr};
9899

99100
// Allocate / deallocate NimBLE memory pool
100101
bool setupMemPool();

src/NimBLERemoteCharacteristic.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(
6666
uint16_t connHandle, const ble_gatt_error* error, uint16_t chrHandle, const ble_gatt_dsc* dsc, void* arg) {
6767
int rc = error->status;
6868
auto filter = (NimBLEDescriptorFilter*)arg;
69-
auto pTaskData = (NimBLETaskData*)filter->taskData;
69+
auto pTaskData = (NimBLEUtils::TaskData*)filter->taskData;
7070
const auto pChr = (NimBLERemoteCharacteristic*)pTaskData->m_pInstance;
7171
const auto uuid = filter->uuid; // UUID to filter for
7272
NIMBLE_LOGD(LOG_TAG, "Descriptor Discovery >> status: %d handle: %d", rc, (rc == 0) ? dsc->handle : -1);
@@ -116,7 +116,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi
116116
return true;
117117
}
118118

119-
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
119+
NimBLEUtils::TaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
120120
NimBLEDescriptorFilter defaultFilter{nullptr, nullptr, &taskData};
121121
if (pFilter == nullptr) {
122122
pFilter = &defaultFilter;
@@ -134,7 +134,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi
134134

135135
auto prevDscCount = m_vDescriptors.size();
136136
NimBLEUtils::taskWait(taskData, BLE_NPL_TIME_FOREVER);
137-
rc = ((NimBLETaskData*)pFilter->taskData)->m_flags;
137+
rc = ((NimBLEUtils::TaskData*)pFilter->taskData)->m_flags;
138138
if (rc != BLE_HS_EDONE) {
139139
NIMBLE_LOGE(LOG_TAG, "<< retrieveDescriptors(): failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
140140
return false;
@@ -156,7 +156,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi
156156
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
157157
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
158158
NimBLEUUID uuidTmp{uuid};
159-
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
159+
NimBLEUtils::TaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
160160
NimBLEDescriptorFilter filter{nullptr, &uuidTmp, &taskData};
161161

162162
for (const auto& dsc : m_vDescriptors) {

src/NimBLERemoteService.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
7575
*/
7676
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const {
7777
NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
78-
NimBLERemoteCharacteristic* pChar = nullptr;
78+
NimBLERemoteCharacteristic* pChar = nullptr;
7979

8080
for (const auto& it : m_vChars) {
8181
if (it->getUUID() == uuid) {
@@ -136,7 +136,7 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
136136
"Characteristic Discovery >> status: %d handle: %d",
137137
error->status,
138138
(error->status == 0) ? chr->def_handle : -1);
139-
auto pTaskData = (NimBLETaskData*)arg;
139+
auto pTaskData = (NimBLEUtils::TaskData*)arg;
140140
const auto pSvc = (NimBLERemoteService*)pTaskData->m_pInstance;
141141

142142
if (error->status == BLE_HS_ENOTCONN) {
@@ -178,8 +178,8 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
178178
*/
179179
bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID* uuidFilter, NimBLERemoteCharacteristic** ppChar) const {
180180
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics()");
181-
int rc = 0;
182-
NimBLETaskData taskData(const_cast<NimBLERemoteService*>(this));
181+
int rc = 0;
182+
NimBLEUtils::TaskData taskData(const_cast<NimBLERemoteService*>(this));
183183

184184
if (uuidFilter == nullptr) {
185185
rc = ble_gattc_disc_all_chrs(m_pClient->getConnHandle(),

src/NimBLERemoteValueAttribute.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ static const char* LOG_TAG = "NimBLERemoteValueAttribute";
2929
bool NimBLERemoteValueAttribute::writeValue(const uint8_t* data, size_t length, bool response) const {
3030
NIMBLE_LOGD(LOG_TAG, ">> writeValue()");
3131

32-
const NimBLEClient* pClient = getClient();
33-
int retryCount = 1;
34-
int rc = 0;
35-
uint16_t mtu = pClient->getMTU() - 3;
36-
NimBLETaskData taskData(const_cast<NimBLERemoteValueAttribute*>(this));
32+
const NimBLEClient* pClient = getClient();
33+
int retryCount = 1;
34+
int rc = 0;
35+
uint16_t mtu = pClient->getMTU() - 3;
36+
NimBLEUtils::TaskData taskData(const_cast<NimBLERemoteValueAttribute*>(this));
3737

3838
// Check if the data length is longer than we can write in one connection event.
3939
// If so we must do a long write which requires a response.
@@ -98,7 +98,7 @@ bool NimBLERemoteValueAttribute::writeValue(const uint8_t* data, size_t length,
9898
* @return success == 0 or error code.
9999
*/
100100
int NimBLERemoteValueAttribute::onWriteCB(uint16_t conn_handle, const ble_gatt_error* error, ble_gatt_attr* attr, void* arg) {
101-
auto pTaskData = static_cast<NimBLETaskData*>(arg);
101+
auto pTaskData = static_cast<NimBLEUtils::TaskData*>(arg);
102102
const auto pAtt = static_cast<NimBLERemoteValueAttribute*>(pTaskData->m_pInstance);
103103

104104
if (error->status == BLE_HS_ENOTCONN) {
@@ -124,11 +124,11 @@ int NimBLERemoteValueAttribute::onWriteCB(uint16_t conn_handle, const ble_gatt_e
124124
NimBLEAttValue NimBLERemoteValueAttribute::readValue(time_t* timestamp) {
125125
NIMBLE_LOGD(LOG_TAG, ">> readValue()");
126126

127-
NimBLEAttValue value{};
128-
const NimBLEClient* pClient = getClient();
129-
int rc = 0;
130-
int retryCount = 1;
131-
NimBLETaskData taskData(const_cast<NimBLERemoteValueAttribute*>(this), 0, &value);
127+
NimBLEAttValue value{};
128+
const NimBLEClient* pClient = getClient();
129+
int rc = 0;
130+
int retryCount = 1;
131+
NimBLEUtils::TaskData taskData(const_cast<NimBLERemoteValueAttribute*>(this), 0, &value);
132132

133133
do {
134134
rc = ble_gattc_read_long(pClient->getConnHandle(), getHandle(), 0, NimBLERemoteValueAttribute::onReadCB, &taskData);
@@ -183,7 +183,7 @@ NimBLEAttValue NimBLERemoteValueAttribute::readValue(time_t* timestamp) {
183183
* @return success == 0 or error code.
184184
*/
185185
int NimBLERemoteValueAttribute::onReadCB(uint16_t conn_handle, const ble_gatt_error* error, ble_gatt_attr* attr, void* arg) {
186-
auto pTaskData = static_cast<NimBLETaskData*>(arg);
186+
auto pTaskData = static_cast<NimBLEUtils::TaskData*>(arg);
187187
const auto pAtt = static_cast<NimBLERemoteValueAttribute*>(pTaskData->m_pInstance);
188188

189189
if (error->status == BLE_HS_ENOTCONN) {

src/NimBLEScan.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ NimBLEScanResults NimBLEScan::getResults(uint32_t duration, bool is_continue) {
689689
return m_scanResults;
690690
}
691691

692-
NimBLETaskData taskData;
692+
NimBLEUtils::TaskData taskData;
693693
m_pTaskData = &taskData;
694694

695695
if (start(duration, is_continue)) {

0 commit comments

Comments
 (0)