WIP - compiles with mynewt

This commit is contained in:
h2zero 2022-04-11 21:34:06 -06:00 committed by Ryan Powell
parent 9e5db157f8
commit b1ae44774a
11 changed files with 192 additions and 139 deletions

20
pkg.yml Normal file
View file

@ -0,0 +1,20 @@
pkg.name: esp-nimble-cpp
pkg.type: lib
pkg.description: NimBLE CPP wrapper
pkg.author: "Ryan Powell"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
pkg.deps:
- "@apache-mynewt-nimble/nimble"
- "@apache-mynewt-nimble/nimble/host"
- "@apache-mynewt-nimble/nimble/host/services/gap"
- "@apache-mynewt-nimble/nimble/host/services/gatt"
- "@apache-mynewt-nimble/nimble/host/store/config"
- "@apache-mynewt-nimble/nimble/host/util"
pkg.source_dirs:
- src
pkg.include_dirs:
- src

View file

@ -23,7 +23,7 @@
#include <climits> #include <climits>
#if defined(CONFIG_NIMBLE_CPP_IDF) #if defined(CONFIG_NIMBLE_CPP_IDF)
#include "nimble/nimble_port.h" //#include "nimble/nimble_port.h"
#else #else
#include "nimble/porting/nimble/include/nimble/nimble_port.h" #include "nimble/porting/nimble/include/nimble/nimble_port.h"
#endif #endif
@ -81,7 +81,11 @@ NimBLEClient::NimBLEClient(const NimBLEAddress &peerAddress) : m_peerAddress(pee
m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units m_pConnParams.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN; // Maximum length of connection event in 0.625ms units
memset(&m_dcTimer, 0, sizeof(m_dcTimer)); memset(&m_dcTimer, 0, sizeof(m_dcTimer));
#ifndef MYNEWT
ble_npl_callout_init(&m_dcTimer, nimble_port_get_dflt_eventq(), ble_npl_callout_init(&m_dcTimer, nimble_port_get_dflt_eventq(),
#else
ble_npl_callout_init(&m_dcTimer, ble_npl_eventq_dflt_get(),
#endif
NimBLEClient::dcTimerCb, this); NimBLEClient::dcTimerCb, this);
} // NimBLEClient } // NimBLEClient
@ -99,7 +103,7 @@ NimBLEClient::~NimBLEClient() {
delete m_pClientCallbacks; delete m_pClientCallbacks;
} }
ble_npl_callout_deinit(&m_dcTimer); //ble_npl_callout_deinit(&m_dcTimer);
} // ~NimBLEClient } // ~NimBLEClient
@ -215,8 +219,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttibutes) {
m_peerAddress = address; m_peerAddress = address;
} }
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); ble_task_data_t taskData = {this, nullptr, -1, nullptr};
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
m_pTaskData = &taskData; m_pTaskData = &taskData;
int rc = 0; int rc = 0;
@ -282,12 +285,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttibutes) {
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(m_pTaskData, m_connectTimeout + 1000)) {
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear(cur_task, ULONG_MAX);
#endif
// Wait for the connect timeout time +1 second for the connection to complete
if(ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(m_connectTimeout + 1000)) == pdFALSE) {
m_pTaskData = nullptr; m_pTaskData = nullptr;
// If a connection was made but no response from MTU exchange; disconnect // If a connection was made but no response from MTU exchange; disconnect
if(isConnected()) { if(isConnected()) {
@ -303,6 +301,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttibutes) {
return false; return false;
} else if(taskData.rc != 0){ } else if(taskData.rc != 0){
m_pTaskData = nullptr;
m_lastErr = taskData.rc; m_lastErr = taskData.rc;
NIMBLE_LOGE(LOG_TAG, "Connection failed; status=%d %s", NIMBLE_LOGE(LOG_TAG, "Connection failed; status=%d %s",
taskData.rc, taskData.rc,
@ -314,6 +313,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttibutes) {
} }
return false; return false;
} else { } else {
m_pTaskData = nullptr;
NIMBLE_LOGI(LOG_TAG, "Connection established"); NIMBLE_LOGI(LOG_TAG, "Connection established");
} }
@ -336,12 +336,12 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttibutes) {
* @return True on success. * @return True on success.
*/ */
bool NimBLEClient::secureConnection() { bool NimBLEClient::secureConnection() {
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); ble_task_data_t taskData = {this, nullptr, -1, nullptr};
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
int retryCount = 1; int retryCount = 1;
do { do {
taskData.rc = -1;
m_pTaskData = &taskData; m_pTaskData = &taskData;
int rc = NimBLEDevice::startSecurity(m_conn_id); int rc = NimBLEDevice::startSecurity(m_conn_id);
@ -350,14 +350,14 @@ bool NimBLEClient::secureConnection() {
m_pTaskData = nullptr; m_pTaskData = nullptr;
return false; return false;
} }
\
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(m_pTaskData, 10 * 1000)) {
// Clear the task notification value to ensure we block break;
ulTaskNotifyValueClear(cur_task, ULONG_MAX); }
#endif
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
} while (taskData.rc == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING) && retryCount--); } while (taskData.rc == (BLE_HS_ERR_HCI_BASE + BLE_ERR_PINKEY_MISSING) && retryCount--);
m_pTaskData = nullptr;
if(taskData.rc != 0){ if(taskData.rc != 0){
m_lastErr = taskData.rc; m_lastErr = taskData.rc;
return false; return false;
@ -734,8 +734,7 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) {
} }
int rc = 0; int rc = 0;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); ble_task_data_t taskData = {this, nullptr, -1, nullptr};
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
if(uuid_filter == nullptr) { if(uuid_filter == nullptr) {
rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, &taskData); rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, &taskData);
@ -750,13 +749,12 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) {
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Retrieve services timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); m_lastErr = taskData.rc;
#endif return false;
}
// wait until we have all the services
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
m_lastErr = taskData.rc; m_lastErr = taskData.rc;
if(taskData.rc == 0){ if(taskData.rc == 0){
@ -791,26 +789,21 @@ int NimBLEClient::serviceDiscoveredCB(
return 0; return 0;
} }
if(error->status == 0) { int rc = error->status;
if (rc == 0) {
// Found a service - add it to the vector // Found a service - add it to the vector
NimBLERemoteService* pRemoteService = new NimBLERemoteService(client, service); NimBLERemoteService* pRemoteService = new NimBLERemoteService(client, service);
client->m_servicesVector.push_back(pRemoteService); client->m_servicesVector.push_back(pRemoteService);
return 0; } else if (rc != BLE_HS_EDONE) {
}
if(error->status == BLE_HS_EDONE) {
pTaskData->rc = 0;
} else {
NIMBLE_LOGE(LOG_TAG, "serviceDiscoveredCB() rc=%d %s", NIMBLE_LOGE(LOG_TAG, "serviceDiscoveredCB() rc=%d %s",
error->status, rc, NimBLEUtils::returnCodeToString(rc));
NimBLEUtils::returnCodeToString(error->status));
pTaskData->rc = error->status;
} }
xTaskNotifyGive(pTaskData->task); NimBLEDevice::taskComplete(pTaskData, rc == BLE_HS_EDONE ? 0 : rc);
NIMBLE_LOGD(LOG_TAG,"<< Service Discovered"); NIMBLE_LOGD(LOG_TAG,"<< Service Discovered");
return error->status; return rc;
} }
@ -1183,10 +1176,7 @@ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
} // Switch } // Switch
if(client->m_pTaskData != nullptr) { if(client->m_pTaskData != nullptr) {
client->m_pTaskData->rc = rc; NimBLEDevice::taskComplete(client->m_pTaskData, rc);
if(client->m_pTaskData->task) {
xTaskNotifyGive(client->m_pTaskData->task);
}
client->m_pTaskData = nullptr; client->m_pTaskData = nullptr;
} }

View file

@ -35,7 +35,15 @@
# include "nimble/esp_port/esp-hci/include/esp_nimble_hci.h" # include "nimble/esp_port/esp-hci/include/esp_nimble_hci.h"
# endif # endif
#else #else
# include "nimble/nimble/controller/include/controller/ble_phy.h" # include "controller/ble_phy.h"
# include "host/ble_hs.h"
# include "host/util/util.h"
# include "services/gap/ble_svc_gap.h"
# include "services/gatt/ble_svc_gatt.h"
//#include "porting/nimble/include/nimble/nimble_port.h"
#include "os/os.h"
#endif #endif
#ifndef CONFIG_NIMBLE_CPP_IDF #ifndef CONFIG_NIMBLE_CPP_IDF
@ -249,7 +257,7 @@ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) {
} }
while(pClient->isConnected()) { while(pClient->isConnected()) {
taskYIELD(); os_time_delay(1);
} }
// Since we set the flag to false the app will not get a callback // Since we set the flag to false the app will not get a callback
// in the disconnect event so we call it here for good measure. // in the disconnect event so we call it here for good measure.
@ -261,7 +269,7 @@ bool NimBLEDevice::deleteClient(NimBLEClient* pClient) {
return false; return false;
} }
while(pClient->m_pTaskData != nullptr) { while(pClient->m_pTaskData != nullptr) {
taskYIELD(); os_time_delay(1);
} }
} }
@ -424,12 +432,13 @@ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
#else #else
void NimBLEDevice::setPower(int dbm) { void NimBLEDevice::setPower(int dbm) {
ble_phy_txpwr_set(dbm); //ble_phy_txpwr_set(dbm);
} }
int NimBLEDevice::getPower() { int NimBLEDevice::getPower() {
return ble_phy_txpwr_get(); // return ble_phy_txpwr_get();
return 0;
} }
#endif #endif
@ -804,7 +813,8 @@ void NimBLEDevice::onSync(void)
// Yield for houskeeping before returning to operations. // Yield for houskeeping before returning to operations.
// Occasionally triggers exception without. // Occasionally triggers exception without.
taskYIELD(); //taskYIELD();
os_time_delay(1);
m_synced = true; m_synced = true;
@ -823,7 +833,6 @@ void NimBLEDevice::onSync(void)
} }
} // onSync } // onSync
/** /**
* @brief The main host task. * @brief The main host task.
*/ */
@ -833,12 +842,21 @@ void NimBLEDevice::host_task(void *param)
NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started"); NIMBLE_LOGI(LOG_TAG, "BLE Host Task Started");
/* This function will return only when nimble_port_stop() is executed */ /* This function will return only when nimble_port_stop() is executed */
#ifndef MYNEWT
nimble_port_run(); nimble_port_run();
nimble_port_freertos_deinit(); nimble_port_freertos_deinit();
#else
while (1) {
os_eventq_run(os_eventq_dflt_get());
}
#endif
} // host_task } // host_task
static struct os_task ble_nimble_task;
static os_stack_t ble_nimble_stack[1024];
/** /**
* @brief Initialize the %BLE environment. * @brief Initialize the %BLE environment.
* @param [in] deviceName The device name of the device. * @param [in] deviceName The device name of the device.
@ -880,7 +898,10 @@ void NimBLEDevice::init(const std::string &deviceName) {
ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE)); ESP_ERROR_CHECK(esp_bt_controller_enable(ESP_BT_MODE_BLE));
ESP_ERROR_CHECK(esp_nimble_hci_init()); ESP_ERROR_CHECK(esp_nimble_hci_init());
#endif #endif
#ifndef MYNEWT
nimble_port_init(); nimble_port_init();
#endif
// Setup callbacks for host events // Setup callbacks for host events
ble_hs_cfg.reset_cb = NimBLEDevice::onReset; ble_hs_cfg.reset_cb = NimBLEDevice::onReset;
@ -899,15 +920,18 @@ void NimBLEDevice::init(const std::string &deviceName) {
// Set the device name. // Set the device name.
rc = ble_svc_gap_device_name_set(deviceName.c_str()); rc = ble_svc_gap_device_name_set(deviceName.c_str());
assert(rc == 0); assert(rc == 0);
#ifndef MYNEWT
ble_store_config_init(); ble_store_config_init();
nimble_port_freertos_init(NimBLEDevice::host_task); nimble_port_freertos_init(NimBLEDevice::host_task);
#else
os_task_init(&ble_nimble_task, "ble_nimble_task", NimBLEDevice::host_task, NULL, 8,
OS_WAIT_FOREVER, ble_nimble_stack, 1024);
#endif
} }
// Wait for host and controller to sync before returning and accepting new tasks // Wait for host and controller to sync before returning and accepting new tasks
while(!m_synced){ while(!m_synced){
taskYIELD(); os_time_delay(1);
} }
initialized = true; // Set the initialization flag to ensure we are only initialized once. initialized = true; // Set the initialization flag to ensure we are only initialized once.
@ -921,9 +945,14 @@ void NimBLEDevice::init(const std::string &deviceName) {
*/ */
/* STATIC */ /* STATIC */
void NimBLEDevice::deinit(bool clearAll) { void NimBLEDevice::deinit(bool clearAll) {
#ifndef MYNEWT
int ret = nimble_port_stop(); int ret = nimble_port_stop();
if (ret == 0) { if (ret == 0) {
nimble_port_deinit(); nimble_port_deinit();
#else
int ret = ble_hs_shutdown(0);
if (ret == 0) {
#endif
#ifdef ESP_PLATFORM #ifdef ESP_PLATFORM
ret = esp_nimble_hci_and_controller_deinit(); ret = esp_nimble_hci_and_controller_deinit();
if (ret != ESP_OK) { if (ret != ESP_OK) {

View file

@ -175,6 +175,31 @@ public:
static NimBLEAddress getBondedAddress(int index); static NimBLEAddress getBondedAddress(int index);
#endif #endif
static bool taskWait(ble_task_data_t* td, uint32_t waitms ) {
#if 0 //defined INC_FREERTOS_H
td->task = xTaskGetCurrentTaskHandle();
# ifdef ulTaskNotifyValueClear
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear(td->task, ULONG_MAX);
# endif
// Wait for the connect timeout time +1 second for the connection to complete
return ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(waitms));
#else
ble_npl_time_t ticks = ble_npl_time_ms_to_ticks32(waitms);
while(td->rc < 0 && --ticks){
ble_npl_time_delay(1);
}
return (ticks > 0);
#endif
}
static void taskComplete(ble_task_data_t* td, int rc) {
td->rc = rc;
#if 0 //defined INC_FREERTOS_H
xTaskNotifyGive(td->task);
#endif
}
private: private:
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL) #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
friend class NimBLEClient; friend class NimBLEClient;

View file

@ -12,7 +12,7 @@
#if defined(CONFIG_BT_ENABLED) #if defined(CONFIG_BT_ENABLED)
#if defined(CONFIG_NIMBLE_CPP_IDF) // using esp-idf #if 0 // using esp-idf
# include "esp_log.h" # include "esp_log.h"
# ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL # ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
# define CONFIG_NIMBLE_CPP_LOG_LEVEL 0 # define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
@ -39,8 +39,8 @@
NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__) NIMBLE_CPP_LOG_PRINT(ESP_LOG_ERROR, tag, format, ##__VA_ARGS__)
#else // using Arduino #else // using Arduino
# include "nimble/porting/nimble/include/syscfg/syscfg.h" # include "syscfg/syscfg.h"
# include "nimble/console/console.h" # include "console/console.h"
# ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL # ifndef CONFIG_NIMBLE_CPP_LOG_LEVEL
# if defined(ARDUINO_ARCH_ESP32) && defined(CORE_DEBUG_LEVEL) # if defined(ARDUINO_ARCH_ESP32) && defined(CORE_DEBUG_LEVEL)
# define CONFIG_NIMBLE_CPP_LOG_LEVEL CORE_DEBUG_LEVEL # define CONFIG_NIMBLE_CPP_LOG_LEVEL CORE_DEBUG_LEVEL

View file

@ -16,6 +16,7 @@
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#include "NimBLERemoteCharacteristic.h" #include "NimBLERemoteCharacteristic.h"
#include "NimBLEDevice.h"
#include "NimBLEUtils.h" #include "NimBLEUtils.h"
#include "NimBLELog.h" #include "NimBLELog.h"
@ -179,14 +180,7 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
* Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE. * Else if rc == 0, just return 0 to continue the discovery until we get BLE_HS_EDONE.
* If we get any other error code tell the application to abort by returning non-zero in the rc. * If we get any other error code tell the application to abort by returning non-zero in the rc.
*/ */
if (rc == BLE_HS_EDONE) { NimBLEDevice::taskComplete(pTaskData, rc == BLE_HS_EDONE ? 0 : rc);
pTaskData->rc = 0;
xTaskNotifyGive(pTaskData->task);
} else if(rc != 0) {
// Error; abort discovery.
pTaskData->rc = rc;
xTaskNotifyGive(pTaskData->task);
}
NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc); NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc);
return rc; return rc;
@ -216,11 +210,9 @@ int NimBLERemoteCharacteristic::nextCharCB(uint16_t conn_handle,
rc = BLE_HS_EDONE; rc = BLE_HS_EDONE;
} else if (rc == BLE_HS_EDONE) { } else if (rc == BLE_HS_EDONE) {
pChar->m_endHandle = pChar->getRemoteService()->getEndHandle(); pChar->m_endHandle = pChar->getRemoteService()->getEndHandle();
} else {
pTaskData->rc = rc;
} }
xTaskNotifyGive(pTaskData->task); NimBLEDevice::taskComplete(pTaskData, rc == BLE_HS_EDONE ? 0 : rc);
return rc; return rc;
} }
@ -238,8 +230,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
} }
int rc = 0; int rc = 0;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); ble_task_data_t taskData = {this, nullptr, -1, nullptr};
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
// If we don't know the end handle of this characteristic retrieve the next one in the service // If we don't know the end handle of this characteristic retrieve the next one in the service
// The end handle is the next characteristic definition handle -1. // The end handle is the next characteristic definition handle -1.
@ -254,11 +245,10 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Find end handle timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
if (taskData.rc != 0) { if (taskData.rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Could not retrieve end handle rc=%d", taskData.rc); NIMBLE_LOGE(LOG_TAG, "Could not retrieve end handle rc=%d", taskData.rc);
@ -270,6 +260,7 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
return true; return true;
} }
taskData.rc = -1;
desc_filter_t filter = {uuid_filter, &taskData}; desc_filter_t filter = {uuid_filter, &taskData};
rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(), rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(),
@ -283,11 +274,10 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Discover Descriptors timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
if (taskData.rc != 0) { if (taskData.rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Failed to retrieve descriptors; startHandle:%d endHandle:%d taskData.rc=%d", NIMBLE_LOGE(LOG_TAG, "Failed to retrieve descriptors; startHandle:%d endHandle:%d taskData.rc=%d",
@ -501,10 +491,8 @@ NimBLEAttValue NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
int rc = 0; int rc = 0;
int retryCount = 1; int retryCount = 1;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, &value};
do { do {
ble_task_data_t taskData = {this, nullptr, -1, &value};
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
NimBLERemoteCharacteristic::onReadCB, NimBLERemoteCharacteristic::onReadCB,
&taskData); &taskData);
@ -514,11 +502,10 @@ NimBLEAttValue NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
return value; return value;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "readValue timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return value;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
rc = taskData.rc; rc = taskData.rc;
switch(rc){ switch(rc){
@ -588,9 +575,7 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
} }
} }
pTaskData->rc = rc; NimBLEDevice::taskComplete(pTaskData, rc);
xTaskNotifyGive(pTaskData->task);
return rc; return rc;
} }
@ -783,10 +768,8 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
return (rc==0); return (rc==0);
} }
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
do { do {
ble_task_data_t taskData = {this, nullptr, -1, nullptr};
if(length > mtu) { if(length > mtu) {
NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
os_mbuf *om = ble_hs_mbuf_from_flat(data, length); os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
@ -799,16 +782,17 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
NimBLERemoteCharacteristic::onWriteCB, NimBLERemoteCharacteristic::onWriteCB,
&taskData); &taskData);
} }
if (rc != 0) { if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc); NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc);
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Write value timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
rc = taskData.rc; rc = taskData.rc;
switch(rc){ switch(rc){
@ -854,11 +838,10 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
return 0; return 0;
} }
NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); int rc = error->status;
NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", rc, conn_handle);
pTaskData->rc = error->status;
xTaskNotifyGive(pTaskData->task);
NimBLEDevice::taskComplete(pTaskData, rc == BLE_HS_EDONE ? 0 : rc);
return 0; return 0;
} }

View file

@ -16,6 +16,7 @@
#if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL) #if defined(CONFIG_BT_ENABLED) && defined(CONFIG_BT_NIMBLE_ROLE_CENTRAL)
#include "NimBLERemoteDescriptor.h" #include "NimBLERemoteDescriptor.h"
#include "NimBLEDevice.h"
#include "NimBLEUtils.h" #include "NimBLEUtils.h"
#include "NimBLELog.h" #include "NimBLELog.h"
@ -127,10 +128,10 @@ NimBLEAttValue NimBLERemoteDescriptor::readValue() {
int rc = 0; int rc = 0;
int retryCount = 1; int retryCount = 1;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, &value};
do { do {
ble_task_data_t taskData = {this, nullptr, -1, &value};
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0, rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
NimBLERemoteDescriptor::onReadCB, NimBLERemoteDescriptor::onReadCB,
&taskData); &taskData);
@ -140,11 +141,11 @@ NimBLEAttValue NimBLERemoteDescriptor::readValue() {
return value; return value;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Read desc value timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
rc = taskData.rc; rc = taskData.rc;
switch(rc){ switch(rc){
@ -208,9 +209,7 @@ int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
} }
} }
pTaskData->rc = rc; NimBLEDevice::taskComplete(pTaskData, rc);
xTaskNotifyGive(pTaskData->task);
return rc; return rc;
} }
@ -247,8 +246,7 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle); NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle);
pTaskData->rc = error->status; NimBLEDevice::taskComplete(pTaskData, error->status);
xTaskNotifyGive(pTaskData->task);
return 0; return 0;
} }
@ -306,10 +304,9 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
return (rc == 0); return (rc == 0);
} }
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
do { do {
ble_task_data_t taskData = {this, nullptr, -1, nullptr};
if(length > mtu) { if(length > mtu) {
NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length); NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
os_mbuf *om = ble_hs_mbuf_from_flat(data, length); os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
@ -328,11 +325,11 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "Desc write value timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
rc = taskData.rc; rc = taskData.rc;
switch(rc) { switch(rc) {

View file

@ -199,7 +199,8 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
pTaskData->rc = error->status; pTaskData->rc = error->status;
} }
xTaskNotifyGive(pTaskData->task); //xTaskNotifyGive(pTaskData->task);
NimBLEDevice::taskComplete(pTaskData, pTaskData->rc);
NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered"); NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered");
return error->status; return error->status;
@ -215,8 +216,8 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter)
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str()); NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str());
int rc = 0; int rc = 0;
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); //TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, nullptr}; ble_task_data_t taskData = {this, nullptr, -1, nullptr};
if(uuid_filter == nullptr) { if(uuid_filter == nullptr) {
rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(), rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(),
@ -238,11 +239,10 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter)
return false; return false;
} }
#ifdef ulTaskNotifyValueClear if (!NimBLEDevice::taskWait(&taskData, 10 * 1000)) {
// Clear the task notification value to ensure we block NIMBLE_LOGE(LOG_TAG, "disc chars timeout");
ulTaskNotifyValueClear(cur_task, ULONG_MAX); return false;
#endif }
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
if(taskData.rc == 0){ if(taskData.rc == 0){
if (uuid_filter == nullptr) { if (uuid_filter == nullptr) {

View file

@ -180,7 +180,7 @@ NimBLEScan::~NimBLEScan() {
if(pScan->m_pTaskData != nullptr) { if(pScan->m_pTaskData != nullptr) {
pScan->m_pTaskData->rc = event->disc_complete.reason; pScan->m_pTaskData->rc = event->disc_complete.reason;
xTaskNotifyGive(pScan->m_pTaskData->task); NimBLEDevice::taskComplete(pScan->m_pTaskData , 0);
} }
return 0; return 0;
@ -397,16 +397,12 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever"); NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever");
} }
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle(); //TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {nullptr, cur_task, 0, nullptr}; ble_task_data_t taskData = {nullptr, nullptr, -1, nullptr};
m_pTaskData = &taskData; m_pTaskData = &taskData;
if(start(duration, nullptr, is_continue)) { if(start(duration, nullptr, is_continue)) {
#ifdef ulTaskNotifyValueClear NimBLEDevice::taskWait(&taskData, 10 * 1000);
// Clear the task notification value to ensure we block
ulTaskNotifyValueClear(cur_task, ULONG_MAX);
#endif
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
} }
m_pTaskData = nullptr; m_pTaskData = nullptr;
@ -436,7 +432,7 @@ bool NimBLEScan::stop() {
} }
if(m_pTaskData != nullptr) { if(m_pTaskData != nullptr) {
xTaskNotifyGive(m_pTaskData->task); NimBLEDevice::taskComplete(m_pTaskData, 0);
} }
NIMBLE_LOGD(LOG_TAG, "<< stop()"); NIMBLE_LOGD(LOG_TAG, "<< stop()");

View file

@ -27,7 +27,7 @@
typedef struct { typedef struct {
void *pATT; void *pATT;
TaskHandle_t task; void * task;
int rc; int rc;
void *buf; void *buf;
} ble_task_data_t; } ble_task_data_t;

View file

@ -6,6 +6,7 @@
*/ */
#pragma once #pragma once
#ifdef ESP_PLATFORM
#include "sdkconfig.h" #include "sdkconfig.h"
#include "nimconfig_rename.h" #include "nimconfig_rename.h"
@ -138,3 +139,15 @@
#define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096 #define CONFIG_BT_NIMBLE_TASK_STACK_SIZE 4096
#endif // _DOXYGEN_ #endif // _DOXYGEN_
#else
#include "syscfg/syscfg.h"
#define CONFIG_BT_ENABLED
#define CONFIG_BT_NIMBLE_ROLE_OBSERVER
#define CONFIG_BT_NIMBLE_ROLE_BROADCASTER
#define CONFIG_BT_NIMBLE_ROLE_CENTRAL
#define CONFIG_BT_NIMBLE_ROLE_PERIPHERAL
#define CONFIG_NIMBLE_CPP_IDF
#define CONFIG_BT_NIMBLE_MAX_CONNECTIONS 3
#define CONFIG_NIMBLE_CPP_LOG_LEVEL 0
#endif