Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/NimBLEClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
goto error;
}

if (!asyncConnect && NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "Cannot connect synchronously from host task");
rc = BLE_HS_EREJECT;
goto error;
}

m_connStatus = CONNECTING;
m_peerAddress = address;
m_config.asyncConnect = asyncConnect;
Expand Down Expand Up @@ -334,6 +340,11 @@ bool NimBLEClient::connect(const NimBLEAddress& address, bool deleteAttributes,
*/
bool NimBLEClient::secureConnection(bool async) const {
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
if (!async && NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "Cannot secure connection synchronously from host task");
m_lastErr = BLE_HS_EREJECT;
return false;
}

int rc = 0;
if (async && !NimBLEDevice::startSecurity(m_connHandle, &rc)) {
Expand Down Expand Up @@ -669,6 +680,10 @@ NimBLERemoteService* NimBLEClient::getService(const char* uuid) {
*/
NimBLERemoteService* NimBLEClient::getService(const NimBLEUUID& uuid) {
NIMBLE_LOGD(LOG_TAG, ">> getService: uuid: %s", uuid.toString().c_str());
if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "getService cannot be called from host task");
return nullptr;
}

for (auto& it : m_svcVec) {
if (it->getUUID() == uuid) {
Expand Down
1 change: 1 addition & 0 deletions src/NimBLEDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ void NimBLEDevice::onSync(void) {
*/
void NimBLEDevice::host_task(void* param) {
NIMBLE_LOGI(LOG_TAG, "NimBLE Started!");
NimBLEUtils::m_hostTaskHandle = ble_npl_get_current_task_id();
nimble_port_run(); // This function will return only when nimble_port_stop() is executed
nimble_port_freertos_deinit();
} // host_task
Expand Down
5 changes: 5 additions & 0 deletions src/NimBLERemoteCharacteristic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(NimBLEDescriptorFilter* pFi
*/
NimBLERemoteDescriptor* NimBLERemoteCharacteristic::getDescriptor(const NimBLEUUID& uuid) const {
NIMBLE_LOGD(LOG_TAG, ">> getDescriptor: uuid: %s", uuid.toString().c_str());
if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "getDescriptor cannot be called from host task");
return nullptr;
}

NimBLEUUID uuidTmp{uuid};
NimBLETaskData taskData(const_cast<NimBLERemoteCharacteristic*>(this));
NimBLEDescriptorFilter filter{nullptr, &uuidTmp, &taskData};
Expand Down
10 changes: 10 additions & 0 deletions src/NimBLERemoteService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const char* u
*/
NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEUUID& uuid) const {
NIMBLE_LOGD(LOG_TAG, ">> getCharacteristic: uuid: %s", uuid.toString().c_str());
if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "getCharacteristic cannot be called from host task");
return nullptr;
}

NimBLERemoteCharacteristic* pChar = nullptr;

for (const auto& it : m_vChars) {
Expand Down Expand Up @@ -116,6 +121,11 @@ NimBLERemoteCharacteristic* NimBLERemoteService::getCharacteristic(const NimBLEU
* @return A read-only reference to the vector of characteristics retrieved for this service.
*/
const std::vector<NimBLERemoteCharacteristic*>& NimBLERemoteService::getCharacteristics(bool refresh) const {
if (refresh && NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "cannot refresh characteristics from host task");
return m_vChars;
}

if (refresh) {
deleteCharacteristics();
retrieveCharacteristics();
Expand Down
9 changes: 9 additions & 0 deletions src/NimBLERemoteValueAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ bool NimBLERemoteValueAttribute::writeValue(const uint8_t* data, size_t length,
goto Done;
}

if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "writeValue cannot be called from the host task");
return false;
}

do {
if (length > mtu) {
NIMBLE_LOGI(LOG_TAG, "writeValue: long write");
Expand Down Expand Up @@ -123,6 +128,10 @@ int NimBLERemoteValueAttribute::onWriteCB(uint16_t conn_handle, const ble_gatt_e
*/
NimBLEAttValue NimBLERemoteValueAttribute::readValue(time_t* timestamp) {
NIMBLE_LOGD(LOG_TAG, ">> readValue()");
if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "readValue cannot be called from the host task");
return NimBLEAttValue();
}

NimBLEAttValue value{};
const NimBLEClient* pClient = getClient();
Expand Down
5 changes: 5 additions & 0 deletions src/NimBLEScan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,11 @@ NimBLEScanResults NimBLEScan::getResults(uint32_t duration, bool is_continue) {
return m_scanResults;
}

if (NimBLEUtils::inHostTask()) {
NIMBLE_LOGE(LOG_TAG, "Cannot call blocking getResults from NimBLE host task");
return m_scanResults;
}

NimBLETaskData taskData;
m_pTaskData = &taskData;

Expand Down
19 changes: 19 additions & 0 deletions src/NimBLEUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@
constexpr uint32_t TASK_BLOCK_BIT = (1 << MYNEWT_VAL(NIMBLE_CPP_FREERTOS_TASK_BLOCK_BIT));
static const char* LOG_TAG = "NimBLEUtils";

void* NimBLEUtils::m_hostTaskHandle = nullptr;

/**
* @brief Construct a NimBLETaskData instance.
* @param [in] pInstance An instance of the class that will be waiting.
Expand Down Expand Up @@ -604,4 +606,21 @@ NimBLEAddress NimBLEUtils::generateAddr(bool nrpa) {
return NimBLEAddress{addr};
} // generateAddr


/**
* @brief Get the handle of the task that is running the NimBLE host.
* @return The task handle or nullptr if there was an error.
*/
void* NimBLEUtils::getHostTaskHandle() {
return m_hostTaskHandle;
} // getHostTaskHandle

/**
* @brief Check if the current task is the NimBLE host task.
* @return True if the current task is the host task, false otherwise.
*/
bool NimBLEUtils::inHostTask() {
return ble_npl_get_current_task_id() == NimBLEUtils::getHostTaskHandle();
}

#endif // CONFIG_BT_NIMBLE_ENABLED
29 changes: 18 additions & 11 deletions src/NimBLEUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@
# endif
# endif

#if MYNEWT_VAL(NIMBLE_CPP_DEBUG_ASSERT_ENABLED) && !defined NDEBUG
void nimble_cpp_assert(const char *file, unsigned line) __attribute((weak, noreturn));
# define NIMBLE_ATT_VAL_FILE (__builtin_strrchr(__FILE__, '/') ? \
__builtin_strrchr (__FILE__, '/') + 1 : __FILE__)
# define NIMBLE_CPP_DEBUG_ASSERT(cond) \
if (!(cond)) { \
nimble_cpp_assert(NIMBLE_ATT_VAL_FILE, __LINE__); \
}
#else
# define NIMBLE_CPP_DEBUG_ASSERT(cond) (void(0))
#endif
# if MYNEWT_VAL(NIMBLE_CPP_DEBUG_ASSERT_ENABLED) && !defined NDEBUG
void nimble_cpp_assert(const char* file, unsigned line) __attribute__((weak, noreturn));
# define NIMBLE_ATT_VAL_FILE (__builtin_strrchr(__FILE__, '/') ? __builtin_strrchr(__FILE__, '/') + 1 : __FILE__)
# define NIMBLE_CPP_DEBUG_ASSERT(cond) \
do { \
if (!(cond)) { \
nimble_cpp_assert(NIMBLE_ATT_VAL_FILE, __LINE__); \
} \
} while (0)
# else
# define NIMBLE_CPP_DEBUG_ASSERT(cond) (void(0))
# endif

# include <string>

Expand Down Expand Up @@ -74,6 +75,12 @@ class NimBLEUtils {
static NimBLEAddress generateAddr(bool nrpa);
static bool taskWait(const NimBLETaskData& taskData, uint32_t timeout);
static void taskRelease(const NimBLETaskData& taskData, int rc = 0);
static void* getHostTaskHandle();
static bool inHostTask();

private:
friend class NimBLEDevice;
static void* m_hostTaskHandle;
};

#endif // CONFIG_BT_NIMBLE_ENABLED
Expand Down
Loading