mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-12-22 19:10:46 +01:00
Replace semaphores with task notifications. (#9)
* Replace all semaphores with task notifications. * use critical sections to prevent concurrent data access. * Ensure scan stop has been called before connecting. * Optimize and cleanup * Add template casting to NimBLERemoteDescriptor::readValue() * Removed storage of the descriptor value read as it did not serve any purpose.
This commit is contained in:
parent
5bc9d59646
commit
f5541d18de
11 changed files with 368 additions and 401 deletions
|
@ -18,7 +18,6 @@
|
|||
#if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
||||
#include "NimBLEClient.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEDevice.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
|
@ -54,7 +53,10 @@ NimBLEClient::NimBLEClient()
|
|||
m_pClientCallbacks = &defaultCallbacks;
|
||||
m_conn_id = BLE_HS_CONN_HANDLE_NONE;
|
||||
m_isConnected = false;
|
||||
m_waitingToConnect = false;
|
||||
m_connectTimeout = 30000;
|
||||
m_deleteCallbacks = false;
|
||||
m_pTaskData = nullptr;
|
||||
|
||||
m_pConnParams.scan_itvl = 16; // Scan interval in 0.625ms units (NimBLE Default)
|
||||
m_pConnParams.scan_window = 16; // Scan window in 0.625ms units (NimBLE Default)
|
||||
|
@ -157,6 +159,10 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
return false;
|
||||
}
|
||||
|
||||
if(!NimBLEDevice::getScan()->stop()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
m_peerAddress = address;
|
||||
|
||||
|
@ -164,7 +170,8 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
memcpy(&peerAddrt.val, address.getNative(),6);
|
||||
peerAddrt.type = type;
|
||||
|
||||
m_semaphoreOpenEvt.take("connect");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
m_pTaskData = &taskData;
|
||||
|
||||
/** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
|
||||
* timeout (default value of m_connectTimeout).
|
||||
|
@ -174,7 +181,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peerAddrt, m_connectTimeout, &m_pConnParams,
|
||||
NimBLEClient::handleGapEvent, this);
|
||||
if(rc == BLE_HS_EBUSY) {
|
||||
vTaskDelay(1);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}while(rc == BLE_HS_EBUSY);
|
||||
|
||||
|
@ -184,17 +191,17 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
type,
|
||||
m_peerAddress.toString().c_str(),
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
|
||||
m_semaphoreOpenEvt.give();
|
||||
m_pTaskData = nullptr;
|
||||
m_waitingToConnect = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_waitingToConnect = true;
|
||||
|
||||
rc = m_semaphoreOpenEvt.wait("connect"); // Wait for the connection to complete.
|
||||
// Wait for the connection to complete.
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if(rc != 0){
|
||||
if(taskData.rc != 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -216,17 +223,18 @@ bool NimBLEClient::connect(const NimBLEAddress &address, uint8_t type, bool refr
|
|||
* @return True on success.
|
||||
*/
|
||||
bool NimBLEClient::secureConnection() {
|
||||
|
||||
m_semeaphoreSecEvt.take("secureConnection");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
m_pTaskData = &taskData;
|
||||
|
||||
int rc = NimBLEDevice::startSecurity(m_conn_id);
|
||||
if(rc != 0){
|
||||
m_semeaphoreSecEvt.give();
|
||||
m_pTaskData = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = m_semeaphoreSecEvt.wait("secureConnection");
|
||||
if(rc != 0){
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if(taskData.rc != 0){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -458,30 +466,31 @@ bool NimBLEClient::retrieveServices(const NimBLEUUID *uuid_filter) {
|
|||
*/
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, ">> retrieveServices");
|
||||
int rc = 0;
|
||||
|
||||
if(!m_isConnected){
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected, could not retrieve services -aborting");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_semaphoreSearchCmplEvt.take("retrieveServices");
|
||||
int rc = 0;
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
|
||||
if(uuid_filter == nullptr) {
|
||||
rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, this);
|
||||
rc = ble_gattc_disc_all_svcs(m_conn_id, NimBLEClient::serviceDiscoveredCB, &taskData);
|
||||
} else {
|
||||
rc = ble_gattc_disc_svc_by_uuid(m_conn_id, &uuid_filter->getNative()->u,
|
||||
NimBLEClient::serviceDiscoveredCB, this);
|
||||
NimBLEClient::serviceDiscoveredCB, &taskData);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_svcs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_semaphoreSearchCmplEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
// wait until we have all the services
|
||||
if(m_semaphoreSearchCmplEvt.wait("retrieveServices") == 0){
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if(taskData.rc == 0){
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveServices");
|
||||
return true;
|
||||
}
|
||||
|
@ -505,41 +514,34 @@ int NimBLEClient::serviceDiscoveredCB(
|
|||
NIMBLE_LOGD(LOG_TAG,"Service Discovered >> status: %d handle: %d",
|
||||
error->status, (error->status == 0) ? service->start_handle : -1);
|
||||
|
||||
NimBLEClient *peer = (NimBLEClient*)arg;
|
||||
int rc=0;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLEClient *client = (NimBLEClient*)pTaskData->pATT;
|
||||
|
||||
// Make sure the service discovery is for this device
|
||||
if(peer->getConnId() != conn_handle){
|
||||
if(client->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a service - add it to the vector
|
||||
NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service);
|
||||
peer->m_servicesVector.push_back(pRemoteService);
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
// All services discovered; start discovering characteristics.
|
||||
|
||||
//NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed");
|
||||
peer->m_semaphoreSearchCmplEvt.give(0);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// Error; abort discovery.
|
||||
rc = error->status;
|
||||
break;
|
||||
if(error->status == 0) {
|
||||
// Found a service - add it to the vector
|
||||
NimBLERemoteService* pRemoteService = new NimBLERemoteService(client, service);
|
||||
client->m_servicesVector.push_back(pRemoteService);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
// pass non-zero to semaphore on error to indicate an error finding services
|
||||
peer->m_semaphoreSearchCmplEvt.give(1);
|
||||
if(error->status == BLE_HS_EDONE) {
|
||||
pTaskData->rc = 0;
|
||||
} else {
|
||||
NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s",
|
||||
error->status,
|
||||
NimBLEUtils::returnCodeToString(error->status));
|
||||
pTaskData->rc = error->status;
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Service Discovered. status: %d", rc);
|
||||
return rc;
|
||||
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG,"<< << Service Discovered");
|
||||
return error->status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -611,15 +613,11 @@ uint16_t NimBLEClient::getMTU() {
|
|||
* @param [in] arg = pointer to the client instance
|
||||
*/
|
||||
/*STATIC*/ int NimBLEClient::handleGapEvent(struct ble_gap_event *event, void *arg) {
|
||||
|
||||
NimBLEClient* client = (NimBLEClient*)arg;
|
||||
//struct ble_gap_conn_desc desc;
|
||||
//struct ble_hs_adv_fields fields;
|
||||
int rc;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Got Client event %s", NimBLEUtils::gapEventToString(event->type));
|
||||
|
||||
// Execute handler code based on the type of event received.
|
||||
switch(event->type) {
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT: {
|
||||
|
@ -636,9 +634,6 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason,
|
||||
NimBLEUtils::returnCodeToString(event->disconnect.reason));
|
||||
//print_conn_desc(&event->disconnect.conn);
|
||||
//MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
|
||||
// If Host reset tell the device now before returning to prevent
|
||||
// any errors caused by calling host functions before resyncing.
|
||||
|
@ -655,15 +650,9 @@ uint16_t NimBLEClient::getMTU() {
|
|||
}
|
||||
|
||||
//client->m_conn_id = BLE_HS_CONN_HANDLE_NONE;
|
||||
|
||||
// Indicate a non-success return value to any semaphores waiting
|
||||
client->m_semaphoreOpenEvt.give(1);
|
||||
client->m_semaphoreSearchCmplEvt.give(1);
|
||||
client->m_semeaphoreSecEvt.give(1);
|
||||
|
||||
client->m_pClientCallbacks->onDisconnect(client);
|
||||
|
||||
return 0;
|
||||
rc = event->disconnect.reason;
|
||||
break;
|
||||
} // BLE_GAP_EVENT_DISCONNECT
|
||||
|
||||
case BLE_GAP_EVENT_CONNECT: {
|
||||
|
@ -683,31 +672,24 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
client->m_conn_id = event->connect.conn_handle;
|
||||
|
||||
// rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
|
||||
// assert(rc == 0);
|
||||
// print_conn_desc(&desc);
|
||||
// MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
|
||||
// In the case of a multiconnecting device we ignore this device when
|
||||
// scanning since we are already connected to it
|
||||
NimBLEDevice::addIgnored(client->m_peerAddress);
|
||||
|
||||
rc = ble_gattc_exchange_mtu(client->m_conn_id, NULL,NULL);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_exchange_mtu: rc=%d %s",rc,
|
||||
NimBLEUtils::returnCodeToString(rc));
|
||||
// if error getting mtu indicate a connection error.
|
||||
client->m_semaphoreOpenEvt.give(rc);
|
||||
break;
|
||||
}
|
||||
|
||||
// In the case of a multiconnecting device we ignore this device when
|
||||
// scanning since we are already connected to it
|
||||
NimBLEDevice::addIgnored(client->m_peerAddress);
|
||||
} else {
|
||||
// Connection attempt failed
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s",
|
||||
event->connect.status,
|
||||
NimBLEUtils::returnCodeToString(event->connect.status));
|
||||
|
||||
client->m_isConnected = false;
|
||||
client->m_semaphoreOpenEvt.give(event->connect.status);
|
||||
rc = event->connect.status;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_CONNECT
|
||||
|
@ -719,7 +701,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
NIMBLE_LOGD(LOG_TAG, "Notify Recieved for handle: %d",event->notify_rx.attr_handle);
|
||||
|
||||
for(auto &it: client->m_servicesVector) {
|
||||
// Dont waste cycles searching services without this handle in their range
|
||||
// Dont waste cycles searching services without this handle in its range
|
||||
if(it->getEndHandle() < event->notify_rx.attr_handle) {
|
||||
continue;
|
||||
}
|
||||
|
@ -738,11 +720,10 @@ uint16_t NimBLEClient::getMTU() {
|
|||
if(characteristic != cVector->cend()) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Got Notification for characteristic %s", (*characteristic)->toString().c_str());
|
||||
|
||||
if((*characteristic)->m_semaphoreReadCharEvt.take(0, "notifyValue")) {
|
||||
(*characteristic)->m_value = std::string((char *)event->notify_rx.om->om_data, event->notify_rx.om->om_len);
|
||||
(*characteristic)->m_timestamp = time(nullptr);
|
||||
(*characteristic)->m_semaphoreReadCharEvt.give();
|
||||
}
|
||||
portENTER_CRITICAL(&(*characteristic)->m_valMux);
|
||||
(*characteristic)->m_value = std::string((char *)event->notify_rx.om->om_data, event->notify_rx.om->om_len);
|
||||
(*characteristic)->m_timestamp = time(nullptr);
|
||||
portEXIT_CRITICAL(&(*characteristic)->m_valMux);
|
||||
|
||||
if ((*characteristic)->m_notifyCallback != nullptr) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Invoking callback for notification on characteristic %s",
|
||||
|
@ -761,7 +742,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
||||
case BLE_GAP_EVENT_L2CAP_UPDATE_REQ: {
|
||||
if(client->m_conn_id != event->conn_update_req.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
return 0;
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG, "Peer requesting to update connection parameters");
|
||||
NIMBLE_LOGD(LOG_TAG, "MinInterval: %d, MaxInterval: %d, Latency: %d, Timeout: %d",
|
||||
|
@ -787,7 +768,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
case BLE_GAP_EVENT_CONN_UPDATE: {
|
||||
if(client->m_conn_id != event->conn_update.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
return 0;
|
||||
}
|
||||
if(event->conn_update.status == 0) {
|
||||
NIMBLE_LOGI(LOG_TAG, "Connection parameters updated.");
|
||||
|
@ -799,7 +780,7 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
case BLE_GAP_EVENT_ENC_CHANGE: {
|
||||
if(client->m_conn_id != event->enc_change.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(event->enc_change.status == 0) {
|
||||
|
@ -814,23 +795,23 @@ uint16_t NimBLEClient::getMTU() {
|
|||
}
|
||||
}
|
||||
|
||||
client->m_semeaphoreSecEvt.give(event->enc_change.status);
|
||||
return 0;
|
||||
rc = event->enc_change.status;
|
||||
break;
|
||||
} //BLE_GAP_EVENT_ENC_CHANGE
|
||||
|
||||
case BLE_GAP_EVENT_MTU: {
|
||||
if(client->m_conn_id != event->mtu.conn_handle){
|
||||
return 0; //BLE_HS_ENOTCONN BLE_ATT_ERR_INVALID_HANDLE
|
||||
return 0;
|
||||
}
|
||||
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
return 0;
|
||||
rc = 0;
|
||||
break;
|
||||
} // BLE_GAP_EVENT_MTU
|
||||
|
||||
case BLE_GAP_EVENT_PASSKEY_ACTION: {
|
||||
struct ble_sm_io pkey = {0};
|
||||
struct ble_sm_io pkey = {0,0};
|
||||
|
||||
if(client->m_conn_id != event->passkey.conn_handle)
|
||||
return 0;
|
||||
|
@ -891,6 +872,14 @@ uint16_t NimBLEClient::getMTU() {
|
|||
return 0;
|
||||
}
|
||||
} // Switch
|
||||
|
||||
if(client->m_pTaskData != nullptr) {
|
||||
client->m_pTaskData->rc = rc;
|
||||
xTaskNotifyGive(client->m_pTaskData->task);
|
||||
client->m_pTaskData = nullptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // handleGapEvent
|
||||
|
||||
|
||||
|
|
|
@ -22,17 +22,13 @@
|
|||
|
||||
#include "NimBLEAddress.h"
|
||||
#include "NimBLEUUID.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEAdvertisedDevice.h"
|
||||
#include "NimBLERemoteService.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
typedef struct {
|
||||
const NimBLEUUID *uuid;
|
||||
const void *attribute;
|
||||
} disc_filter_t;
|
||||
|
||||
class NimBLERemoteService;
|
||||
class NimBLEClientCallbacks;
|
||||
class NimBLEAdvertisedDevice;
|
||||
|
@ -89,14 +85,12 @@ private:
|
|||
|
||||
NimBLEAddress m_peerAddress = NimBLEAddress("");
|
||||
uint16_t m_conn_id;
|
||||
bool m_isConnected = false;
|
||||
bool m_waitingToConnect =false;
|
||||
bool m_deleteCallbacks = true;
|
||||
bool m_isConnected;
|
||||
bool m_waitingToConnect;
|
||||
bool m_deleteCallbacks;
|
||||
int32_t m_connectTimeout;
|
||||
NimBLEClientCallbacks* m_pClientCallbacks = nullptr;
|
||||
FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt");
|
||||
FreeRTOS::Semaphore m_semaphoreSearchCmplEvt = FreeRTOS::Semaphore("SearchCmplEvt");
|
||||
FreeRTOS::Semaphore m_semeaphoreSecEvt = FreeRTOS::Semaphore("Security");
|
||||
NimBLEClientCallbacks* m_pClientCallbacks;
|
||||
ble_task_data_t *m_pTaskData;
|
||||
|
||||
std::vector<NimBLERemoteService*> m_servicesVector;
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
|||
m_pRemoteService = pRemoteService;
|
||||
m_notifyCallback = nullptr;
|
||||
m_timestamp = 0;
|
||||
m_valMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
} // NimBLERemoteCharacteristic
|
||||
|
||||
|
||||
|
@ -67,7 +68,7 @@ static const char* LOG_TAG = "NimBLERemoteCharacteristic";
|
|||
*@brief Destructor.
|
||||
*/
|
||||
NimBLERemoteCharacteristic::~NimBLERemoteCharacteristic() {
|
||||
deleteDescriptors(); // Release resources for any descriptor information we may have allocated.
|
||||
deleteDescriptors();
|
||||
} // ~NimBLERemoteCharacteristic
|
||||
|
||||
/*
|
||||
|
@ -147,12 +148,12 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
|||
NIMBLE_LOGD(LOG_TAG,"Descriptor Discovered >> status: %d handle: %d",
|
||||
error->status, (error->status == 0) ? dsc->handle : -1);
|
||||
|
||||
disc_filter_t *filter = (disc_filter_t*)arg;
|
||||
NimBLEUUID *uuid_filter = (NimBLEUUID*)filter->uuid;
|
||||
NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)filter->attribute;
|
||||
desc_filter_t *filter = (desc_filter_t*)arg;
|
||||
const NimBLEUUID *uuid_filter = filter->uuid;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)filter->task_data;
|
||||
NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
|
||||
int rc=0;
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,7 +173,7 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
|||
rc = BLE_HS_EDONE;
|
||||
}
|
||||
}
|
||||
// Found a descriptor - add it to the vector
|
||||
|
||||
NimBLERemoteDescriptor* pNewRemoteDescriptor = new NimBLERemoteDescriptor(characteristic, dsc);
|
||||
characteristic->m_descriptorVector.push_back(pNewRemoteDescriptor);
|
||||
break;
|
||||
|
@ -182,18 +183,20 @@ int NimBLERemoteCharacteristic::descriptorDiscCB(uint16_t conn_handle,
|
|||
break;
|
||||
}
|
||||
|
||||
/** If rc == BLE_HS_EDONE, release the semaphore with a success error code and stop the discovery process.
|
||||
/** If rc == BLE_HS_EDONE, resume the task with a success error code and stop the discovery process.
|
||||
* 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 semaphore 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) {
|
||||
characteristic->m_semaphoreGetDescEvt.give(0);
|
||||
pTaskData->rc = 0;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
} else if(rc != 0) {
|
||||
/* Error; abort discovery. */
|
||||
// pass error code to semaphore waiting
|
||||
characteristic->m_semaphoreGetDescEvt.give(rc);
|
||||
// Error; abort discovery.
|
||||
pTaskData->rc = rc;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", rc);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Descriptor Discovered. status: %d", pTaskData->rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -206,11 +209,8 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
|
|||
NIMBLE_LOGD(LOG_TAG, ">> retrieveDescriptors() for characteristic: %s", getUUID().toString().c_str());
|
||||
|
||||
int rc = 0;
|
||||
disc_filter_t filter;
|
||||
filter.uuid = uuid_filter;
|
||||
filter.attribute = this;
|
||||
|
||||
m_semaphoreGetDescEvt.take("retrieveDescriptors");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
desc_filter_t filter = {uuid_filter, &taskData};
|
||||
|
||||
rc = ble_gattc_disc_all_dscs(getRemoteService()->getClient()->getConnId(),
|
||||
m_handle,
|
||||
|
@ -219,11 +219,12 @@ bool NimBLERemoteCharacteristic::retrieveDescriptors(const NimBLEUUID *uuid_filt
|
|||
&filter);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_semaphoreGetDescEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_semaphoreGetDescEvt.wait("retrieveDescriptors") != 0) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if(taskData.rc != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -337,6 +338,22 @@ NimBLEUUID NimBLERemoteCharacteristic::getUUID() {
|
|||
} // getUUID
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the value of the remote characteristic.
|
||||
* @return The value of the remote characteristic.
|
||||
*/
|
||||
std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
|
||||
portENTER_CRITICAL(&m_valMux);
|
||||
std::string value = m_value;
|
||||
if(timestamp != nullptr) {
|
||||
*timestamp = m_timestamp;
|
||||
}
|
||||
portEXIT_CRITICAL(&m_valMux);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read an unsigned 16 bit value
|
||||
* @return The unsigned 16 bit value.
|
||||
|
@ -384,33 +401,31 @@ std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
|
|||
NIMBLE_LOGD(LOG_TAG, ">> readValue(): uuid: %s, handle: %d 0x%.2x",
|
||||
getUUID().toString().c_str(), getHandle(), getHandle());
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
|
||||
NimBLEClient* pClient = getRemoteService()->getClient();
|
||||
std::string value;
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return "";
|
||||
return value;
|
||||
}
|
||||
|
||||
do {
|
||||
m_semaphoreReadCharEvt.take("readValue");
|
||||
// Clear the value before reading.
|
||||
m_value = "";
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value};
|
||||
|
||||
do {
|
||||
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
|
||||
NimBLERemoteCharacteristic::onReadCB,
|
||||
this);
|
||||
&taskData);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_semaphoreReadCharEvt.give(0);
|
||||
return "";
|
||||
return value;
|
||||
}
|
||||
|
||||
rc = m_semaphoreReadCharEvt.wait("readValue");
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
rc = taskData.rc;
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
case BLE_HS_EDONE:
|
||||
|
@ -428,39 +443,24 @@ std::string NimBLERemoteCharacteristic::readValue(time_t *timestamp) {
|
|||
break;
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return "";
|
||||
NIMBLE_LOGE(LOG_TAG, "<< readValue rc=%d", rc);
|
||||
return value;
|
||||
}
|
||||
} while(rc != 0 && retryCount--);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< readValue(): length: %d", m_value.length());
|
||||
|
||||
m_semaphoreReadCharEvt.take("returnValue");
|
||||
std::string value = m_value;
|
||||
portENTER_CRITICAL(&m_valMux);
|
||||
m_value = value;
|
||||
m_timestamp = time(nullptr);
|
||||
if(timestamp != nullptr) {
|
||||
*timestamp = m_timestamp;
|
||||
}
|
||||
m_semaphoreReadCharEvt.give();
|
||||
portEXIT_CRITICAL(&m_valMux);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< readValue length: %d rc=%d", value.length(), rc);
|
||||
return value;
|
||||
} // readValue
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the value of the remote characteristic.
|
||||
* @return The value of the remote characteristic.
|
||||
*/
|
||||
std::string NimBLERemoteCharacteristic::getValue(time_t *timestamp) {
|
||||
m_semaphoreReadCharEvt.take("getValue");
|
||||
std::string value = m_value;
|
||||
if(timestamp != nullptr) {
|
||||
*timestamp = m_timestamp;
|
||||
}
|
||||
|
||||
m_semaphoreReadCharEvt.give();
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback for characteristic read operation.
|
||||
* @return 0 or error code.
|
||||
|
@ -469,27 +469,35 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
|||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
|
||||
uint16_t conn_id = characteristic->getRemoteService()->getClient()->getConnId();
|
||||
|
||||
// Make sure the read is for this client
|
||||
if(conn_id != conn_handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
if(error->status == 0) {
|
||||
if(attr) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len);
|
||||
std::string *strBuf = (std::string*)pTaskData->buf;
|
||||
int rc = error->status;
|
||||
|
||||
characteristic->m_value += std::string((char*) attr->om->om_data, attr->om->om_len);
|
||||
characteristic->m_timestamp = time(nullptr);
|
||||
return 0;
|
||||
if(rc == 0) {
|
||||
if(attr) {
|
||||
if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) {
|
||||
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||
} else {
|
||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len);
|
||||
(*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Read complete release semaphore and let the app can continue.
|
||||
characteristic->m_semaphoreReadCharEvt.give(error->status);
|
||||
return 0;
|
||||
|
||||
pTaskData->rc = rc;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
@ -509,7 +517,7 @@ bool NimBLERemoteCharacteristic::setNotify(uint16_t val, bool response, notify_c
|
|||
return false;
|
||||
}
|
||||
|
||||
m_notifyCallback = notifyCallback; // Save the notification callback.
|
||||
m_notifyCallback = notifyCallback;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< setNotify()");
|
||||
|
||||
|
@ -572,7 +580,7 @@ bool NimBLERemoteCharacteristic::registerForNotify(notify_callback notifyCallbac
|
|||
*/
|
||||
void NimBLERemoteCharacteristic::deleteDescriptors() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptors");
|
||||
// Iterate through all the descriptors releasing their storage and erasing them from the vector.
|
||||
|
||||
for(auto &it: m_descriptorVector) {
|
||||
delete it;
|
||||
}
|
||||
|
@ -588,7 +596,7 @@ void NimBLERemoteCharacteristic::deleteDescriptors() {
|
|||
*/
|
||||
size_t NimBLERemoteCharacteristic::deleteDescriptor(const NimBLEUUID &uuid) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> deleteDescriptor");
|
||||
// Delete the requested descriptor.
|
||||
|
||||
for(auto it = m_descriptorVector.begin(); it != m_descriptorVector.end(); ++it) {
|
||||
if((*it)->getUUID() == uuid) {
|
||||
delete *it;
|
||||
|
@ -665,47 +673,45 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
|
|||
NIMBLE_LOGD(LOG_TAG, ">> writeValue(), length: %d", length);
|
||||
|
||||
NimBLEClient* pClient = getRemoteService()->getClient();
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu;
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return false;
|
||||
}
|
||||
|
||||
mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
|
||||
// Check if the data length is longer than we can write in 1 connection event.
|
||||
// Check if the data length is longer than we can write in one connection event.
|
||||
// If so we must do a long write which requires a response.
|
||||
if(length <= mtu && !response) {
|
||||
rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
|
||||
return (rc==0);
|
||||
}
|
||||
|
||||
do {
|
||||
m_semaphoreWriteCharEvt.take("writeValue");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
|
||||
do {
|
||||
if(length > mtu) {
|
||||
NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
|
||||
os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
|
||||
rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om,
|
||||
NimBLERemoteCharacteristic::onWriteCB,
|
||||
this);
|
||||
&taskData);
|
||||
} else {
|
||||
rc = ble_gattc_write_flat(pClient->getConnId(), m_handle,
|
||||
data, length,
|
||||
NimBLERemoteCharacteristic::onWriteCB,
|
||||
this);
|
||||
&taskData);
|
||||
}
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc);
|
||||
m_semaphoreWriteCharEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = m_semaphoreWriteCharEvt.wait("writeValue");
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
rc = taskData.rc;
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
|
@ -725,11 +731,12 @@ bool NimBLERemoteCharacteristic::writeValue(const uint8_t* data, size_t length,
|
|||
break;
|
||||
/* Else falls through. */
|
||||
default:
|
||||
NIMBLE_LOGE(LOG_TAG, "<< writeValue, rc: %d", rc);
|
||||
return false;
|
||||
}
|
||||
} while(rc != 0 && retryCount--);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d",rc);
|
||||
NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d", rc);
|
||||
return (rc == 0);
|
||||
} // writeValue
|
||||
|
||||
|
@ -742,29 +749,21 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
|
|||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteCharacteristic* characteristic = (NimBLERemoteCharacteristic*)arg;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLERemoteCharacteristic *characteristic = (NimBLERemoteCharacteristic*)pTaskData->pATT;
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
NIMBLE_LOGI(LOG_TAG, "Write complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
characteristic->m_semaphoreWriteCharEvt.give(error->status);
|
||||
pTaskData->rc = error->status;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void NimBLERemoteCharacteristic::releaseSemaphores() {
|
||||
for (auto &it: m_descriptorVector) {
|
||||
it->releaseSemaphores();
|
||||
}
|
||||
m_semaphoreWriteCharEvt.give(1);
|
||||
m_semaphoreGetDescEvt.give(1);
|
||||
m_semaphoreReadCharEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -32,6 +32,12 @@ class NimBLERemoteDescriptor;
|
|||
typedef void (*notify_callback)(NimBLERemoteCharacteristic* pBLERemoteCharacteristic,
|
||||
uint8_t* pData, size_t length, bool isNotify);
|
||||
|
||||
typedef struct {
|
||||
const NimBLEUUID *uuid;
|
||||
void *task_data;
|
||||
} desc_filter_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief A model of a remote %BLE characteristic.
|
||||
*/
|
||||
|
@ -110,7 +116,6 @@ private:
|
|||
struct ble_gatt_attr *attr, void *arg);
|
||||
static int onWriteCB(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg);
|
||||
void releaseSemaphores();
|
||||
static int descriptorDiscCB(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
|
||||
void *arg);
|
||||
|
@ -121,12 +126,10 @@ private:
|
|||
uint16_t m_handle;
|
||||
uint16_t m_defHandle;
|
||||
NimBLERemoteService* m_pRemoteService;
|
||||
FreeRTOS::Semaphore m_semaphoreGetDescEvt = FreeRTOS::Semaphore("GetDescEvt");
|
||||
FreeRTOS::Semaphore m_semaphoreReadCharEvt = FreeRTOS::Semaphore("ReadCharEvt");
|
||||
FreeRTOS::Semaphore m_semaphoreWriteCharEvt = FreeRTOS::Semaphore("WriteCharEvt");
|
||||
std::string m_value;
|
||||
notify_callback m_notifyCallback;
|
||||
time_t m_timestamp;
|
||||
portMUX_TYPE m_valMux;
|
||||
|
||||
// We maintain a vector of descriptors owned by this characteristic.
|
||||
std::vector<NimBLERemoteDescriptor*> m_descriptorVector;
|
||||
|
|
|
@ -45,9 +45,9 @@ NimBLERemoteDescriptor::NimBLERemoteDescriptor(NimBLERemoteCharacteristic* pRemo
|
|||
m_uuid = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
m_handle = dsc->handle;
|
||||
m_pRemoteCharacteristic = pRemoteCharacteristic;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,96 +78,6 @@ NimBLEUUID NimBLERemoteDescriptor::getUUID() {
|
|||
} // getUUID
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback for Descriptor read operation.
|
||||
* @return 0 or error code.
|
||||
*/
|
||||
int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)arg;
|
||||
uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(conn_id != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
if(error->status == 0){
|
||||
if(attr){
|
||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len);
|
||||
|
||||
desc->m_value += std::string((char*) attr->om->om_data, attr->om->om_len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Read complete release semaphore and let the app can continue.
|
||||
desc->m_semaphoreReadDescrEvt.give(error->status);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
std::string NimBLERemoteDescriptor::readValue() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
// Clear the value before reading.
|
||||
m_value = "";
|
||||
|
||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return "";
|
||||
}
|
||||
|
||||
do {
|
||||
m_semaphoreReadDescrEvt.take("ReadDescriptor");
|
||||
|
||||
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
|
||||
NimBLERemoteDescriptor::onReadCB,
|
||||
this);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_semaphoreReadDescrEvt.give(0);
|
||||
return "";
|
||||
}
|
||||
|
||||
rc = m_semaphoreReadDescrEvt.wait("ReadDescriptor");
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
case BLE_HS_EDONE:
|
||||
rc = 0;
|
||||
break;
|
||||
// Descriptor is not long-readable, return with what we have.
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
|
||||
NIMBLE_LOGI(LOG_TAG, "Attribute not long");
|
||||
rc = 0;
|
||||
break;
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
} while(rc != 0 && retryCount--);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d", m_value.length());
|
||||
return m_value;
|
||||
} // readValue
|
||||
|
||||
|
||||
uint8_t NimBLERemoteDescriptor::readUInt8() {
|
||||
std::string value = readValue();
|
||||
if (value.length() >= 1) {
|
||||
|
@ -195,6 +105,100 @@ uint32_t NimBLERemoteDescriptor::readUInt32() {
|
|||
} // readUInt32
|
||||
|
||||
|
||||
std::string NimBLERemoteDescriptor::readValue() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> Descriptor readValue: %s", toString().c_str());
|
||||
|
||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||
std::string value;
|
||||
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return value;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(),0, &value};
|
||||
|
||||
do {
|
||||
rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
|
||||
NimBLERemoteDescriptor::onReadCB,
|
||||
&taskData);
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to read descriptor; rc=%d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
return value;
|
||||
}
|
||||
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
rc = taskData.rc;
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
case BLE_HS_EDONE:
|
||||
rc = 0;
|
||||
break;
|
||||
// Descriptor is not long-readable, return with what we have.
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_ATTR_NOT_LONG):
|
||||
NIMBLE_LOGI(LOG_TAG, "Attribute not long");
|
||||
rc = 0;
|
||||
break;
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHEN):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_AUTHOR):
|
||||
case BLE_HS_ATT_ERR(BLE_ATT_ERR_INSUFFICIENT_ENC):
|
||||
if (retryCount && pClient->secureConnection())
|
||||
break;
|
||||
/* Else falls through. */
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
} while(rc != 0 && retryCount--);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< Descriptor readValue(): length: %d rc=%d", value.length(), rc);
|
||||
return value;
|
||||
} // readValue
|
||||
|
||||
|
||||
/**
|
||||
* @brief Callback for Descriptor read operation.
|
||||
* @return 0 or error code.
|
||||
*/
|
||||
int NimBLERemoteDescriptor::onReadCB(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLERemoteDescriptor* desc = (NimBLERemoteDescriptor*)pTaskData->pATT;
|
||||
uint16_t conn_id = desc->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId();
|
||||
|
||||
if(conn_id != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
|
||||
|
||||
std::string *strBuf = (std::string*)pTaskData->buf;
|
||||
int rc = error->status;
|
||||
|
||||
if(rc == 0) {
|
||||
if(attr) {
|
||||
if(((*strBuf).length() + attr->om->om_len) > BLE_ATT_ATTR_MAX_LEN) {
|
||||
rc = BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
|
||||
} else {
|
||||
NIMBLE_LOGD(LOG_TAG, "Got %d bytes", attr->om->om_len);
|
||||
(*strBuf) += std::string((char*) attr->om->om_data, attr->om->om_len);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pTaskData->rc = rc;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return a string representation of this BLE Remote Descriptor.
|
||||
* @retun A string representation of this BLE Remote Descriptor.
|
||||
|
@ -218,16 +222,17 @@ int NimBLERemoteDescriptor::onWriteCB(uint16_t conn_handle,
|
|||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)arg;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLERemoteDescriptor* descriptor = (NimBLERemoteDescriptor*)pTaskData->pATT;
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(descriptor->getRemoteCharacteristic()->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(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);
|
||||
|
||||
descriptor->m_semaphoreDescWrite.give(error->status);
|
||||
pTaskData->rc = error->status;
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -245,17 +250,15 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
|||
|
||||
NimBLEClient* pClient = getRemoteCharacteristic()->getRemoteService()->getClient();
|
||||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu;
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Disconnected");
|
||||
return false;
|
||||
}
|
||||
|
||||
mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
uint16_t mtu = ble_att_mtu(pClient->getConnId()) - 3;
|
||||
|
||||
// Check if the data length is longer than we can write in 1 connection event.
|
||||
// If so we must do a long write which requires a response.
|
||||
|
@ -264,31 +267,31 @@ bool NimBLERemoteDescriptor::writeValue(const uint8_t* data, size_t length, bool
|
|||
return (rc == 0);
|
||||
}
|
||||
|
||||
do {
|
||||
m_semaphoreDescWrite.take("WriteDescriptor");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
|
||||
do {
|
||||
if(length > mtu) {
|
||||
NIMBLE_LOGI(LOG_TAG,"long write %d bytes", length);
|
||||
os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
|
||||
rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om,
|
||||
NimBLERemoteDescriptor::onWriteCB,
|
||||
this);
|
||||
&taskData);
|
||||
} else {
|
||||
rc = ble_gattc_write_flat(pClient->getConnId(), m_handle,
|
||||
data, length,
|
||||
NimBLERemoteDescriptor::onWriteCB,
|
||||
this);
|
||||
&taskData);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to write descriptor; rc=%d", rc);
|
||||
m_semaphoreDescWrite.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = m_semaphoreDescWrite.wait("WriteDescriptor");
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
rc = taskData.rc;
|
||||
|
||||
switch(rc){
|
||||
switch(rc) {
|
||||
case 0:
|
||||
case BLE_HS_EDONE:
|
||||
rc = 0;
|
||||
|
@ -335,13 +338,5 @@ bool NimBLERemoteDescriptor::writeValue(uint8_t newValue, bool response) {
|
|||
} // writeValue
|
||||
|
||||
|
||||
/**
|
||||
* @brief In the event of an error this is called to make sure we don't block.
|
||||
*/
|
||||
void NimBLERemoteDescriptor::releaseSemaphores() {
|
||||
m_semaphoreDescWrite.give(1);
|
||||
m_semaphoreReadDescrEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -31,16 +31,24 @@ public:
|
|||
uint16_t getHandle();
|
||||
NimBLERemoteCharacteristic* getRemoteCharacteristic();
|
||||
NimBLEUUID getUUID();
|
||||
std::string readValue(void);
|
||||
uint8_t readUInt8(void);
|
||||
uint16_t readUInt16(void);
|
||||
uint32_t readUInt32(void);
|
||||
std::string readValue();
|
||||
|
||||
template<typename T>
|
||||
T readValue(bool skipSizeCheck = false) {
|
||||
std::string value = readValue();
|
||||
if(!skipSizeCheck && value.size() < sizeof(T)) return T();
|
||||
const char *pData = value.data();
|
||||
return *((T *)pData);
|
||||
}
|
||||
|
||||
uint8_t readUInt8() __attribute__ ((deprecated));
|
||||
uint16_t readUInt16() __attribute__ ((deprecated));
|
||||
uint32_t readUInt32() __attribute__ ((deprecated));
|
||||
std::string toString(void);
|
||||
bool writeValue(const uint8_t* data, size_t length, bool response = false);
|
||||
bool writeValue(const std::string &newValue, bool response = false);
|
||||
bool writeValue(uint8_t newValue, bool response = false);
|
||||
|
||||
|
||||
private:
|
||||
friend class NimBLERemoteCharacteristic;
|
||||
|
||||
|
@ -50,16 +58,10 @@ private:
|
|||
struct ble_gatt_attr *attr, void *arg);
|
||||
static int onReadCB(uint16_t conn_handle, const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg);
|
||||
void releaseSemaphores();
|
||||
|
||||
uint16_t m_handle;
|
||||
NimBLEUUID m_uuid;
|
||||
std::string m_value;
|
||||
NimBLERemoteCharacteristic* m_pRemoteCharacteristic;
|
||||
FreeRTOS::Semaphore m_semaphoreReadDescrEvt = FreeRTOS::Semaphore("ReadDescrEvt");
|
||||
FreeRTOS::Semaphore m_semaphoreDescWrite = FreeRTOS::Semaphore("WriteDescEvt");
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
|
|
|
@ -148,43 +148,34 @@ int NimBLERemoteService::characteristicDiscCB(uint16_t conn_handle,
|
|||
NIMBLE_LOGD(LOG_TAG,"Characteristic Discovered >> status: %d handle: %d",
|
||||
error->status, (error->status == 0) ? chr->val_handle : -1);
|
||||
|
||||
NimBLERemoteService *service = (NimBLERemoteService*)arg;
|
||||
int rc=0;
|
||||
ble_task_data_t *pTaskData = (ble_task_data_t*)arg;
|
||||
NimBLERemoteService *service = (NimBLERemoteService*)pTaskData->pATT;
|
||||
|
||||
// Make sure the discovery is for this device
|
||||
if(service->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (error->status) {
|
||||
case 0: {
|
||||
// Found a service - add it to the vector
|
||||
NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr);
|
||||
service->m_characteristicVector.push_back(pRemoteCharacteristic);
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
/** All characteristics in this service discovered; start discovering
|
||||
* characteristics in the next service.
|
||||
*/
|
||||
service->m_semaphoreGetCharEvt.give(0);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rc = error->status;
|
||||
break;
|
||||
if(error->status == 0) {
|
||||
// Found a service - add it to the vector
|
||||
NimBLERemoteCharacteristic* pRemoteCharacteristic = new NimBLERemoteCharacteristic(service, chr);
|
||||
service->m_characteristicVector.push_back(pRemoteCharacteristic);
|
||||
return 0;
|
||||
}
|
||||
if (rc != 0) {
|
||||
/* Error; abort discovery. */
|
||||
// pass non-zero to semaphore on error to indicate an error finding characteristics
|
||||
// release memory from any characteristics we created
|
||||
//service->deleteCharacteristics(); --this will now be done when we clear services on returning with error
|
||||
NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
service->m_semaphoreGetCharEvt.give(1);
|
||||
|
||||
if(error->status == BLE_HS_EDONE) {
|
||||
pTaskData->rc = 0;
|
||||
} else {
|
||||
NIMBLE_LOGE(LOG_TAG, "characteristicDiscCB() rc=%d %s",
|
||||
error->status,
|
||||
NimBLEUtils::returnCodeToString(error->status));
|
||||
pTaskData->rc = error->status;
|
||||
}
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered. status: %d", rc);
|
||||
return rc;
|
||||
|
||||
xTaskNotifyGive(pTaskData->task);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG,"<< Characteristic Discovered");
|
||||
return error->status;
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,32 +188,31 @@ bool NimBLERemoteService::retrieveCharacteristics(const NimBLEUUID *uuid_filter)
|
|||
NIMBLE_LOGD(LOG_TAG, ">> retrieveCharacteristics() for service: %s", getUUID().toString().c_str());
|
||||
|
||||
int rc = 0;
|
||||
//deleteCharacteristics(); // Forget any previous characteristics.
|
||||
|
||||
m_semaphoreGetCharEvt.take("retrieveCharacteristics");
|
||||
ble_task_data_t taskData = {this, xTaskGetCurrentTaskHandle(), 0, nullptr};
|
||||
|
||||
if(uuid_filter == nullptr) {
|
||||
rc = ble_gattc_disc_all_chrs(m_pClient->getConnId(),
|
||||
m_startHandle,
|
||||
m_endHandle,
|
||||
NimBLERemoteService::characteristicDiscCB,
|
||||
this);
|
||||
&taskData);
|
||||
} else {
|
||||
rc = ble_gattc_disc_chrs_by_uuid(m_pClient->getConnId(),
|
||||
m_startHandle,
|
||||
m_endHandle,
|
||||
&uuid_filter->getNative()->u,
|
||||
NimBLERemoteService::characteristicDiscCB,
|
||||
this);
|
||||
&taskData);
|
||||
}
|
||||
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "ble_gattc_disc_all_chrs: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_semaphoreGetCharEvt.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_semaphoreGetCharEvt.wait("retrieveCharacteristics") == 0){
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
|
||||
if(taskData.rc == 0){
|
||||
NIMBLE_LOGD(LOG_TAG, "<< retrieveCharacteristics()");
|
||||
return true;
|
||||
}
|
||||
|
@ -319,7 +309,7 @@ void NimBLERemoteService::deleteCharacteristics() {
|
|||
for(auto &it: m_characteristicVector) {
|
||||
delete it;
|
||||
}
|
||||
m_characteristicVector.clear(); // Clear the vector
|
||||
m_characteristicVector.clear();
|
||||
NIMBLE_LOGD(LOG_TAG, "<< deleteCharacteristics");
|
||||
} // deleteCharacteristics
|
||||
|
||||
|
@ -331,7 +321,7 @@ void NimBLERemoteService::deleteCharacteristics() {
|
|||
*/
|
||||
size_t NimBLERemoteService::deleteCharacteristic(const NimBLEUUID &uuid) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> deleteCharacteristic");
|
||||
// Delete the requested characteristic.
|
||||
|
||||
for(auto it = m_characteristicVector.begin(); it != m_characteristicVector.end(); ++it) {
|
||||
if((*it)->getUUID() == uuid) {
|
||||
delete *it;
|
||||
|
@ -374,16 +364,5 @@ std::string NimBLERemoteService::toString() {
|
|||
} // toString
|
||||
|
||||
|
||||
/**
|
||||
* @brief called when an error occurrs and we need to release the semaphores to resume operations.
|
||||
* Will release all characteristic and subsequently all descriptor semaphores for this service.
|
||||
*/
|
||||
void NimBLERemoteService::releaseSemaphores() {
|
||||
for(auto &it: m_characteristicVector) {
|
||||
it->releaseSemaphores();
|
||||
}
|
||||
m_semaphoreGetCharEvt.give(1);
|
||||
}
|
||||
|
||||
#endif // #if defined( CONFIG_BT_NIMBLE_ROLE_CENTRAL)
|
||||
#endif /* CONFIG_BT_ENABLED */
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "NimBLEClient.h"
|
||||
#include "NimBLEUUID.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "NimBLERemoteCharacteristic.h"
|
||||
|
||||
#include <vector>
|
||||
|
@ -79,7 +78,6 @@ private:
|
|||
std::vector<NimBLERemoteCharacteristic*> m_characteristicVector;
|
||||
|
||||
NimBLEClient* m_pClient;
|
||||
FreeRTOS::Semaphore m_semaphoreGetCharEvt = FreeRTOS::Semaphore("GetCharEvt");
|
||||
NimBLEUUID m_uuid;
|
||||
uint16_t m_startHandle;
|
||||
uint16_t m_endHandle;
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEScan.h"
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLEDevice.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
|
@ -70,6 +69,7 @@ NimBLEScan::NimBLEScan() {
|
|||
m_pAdvertisedDeviceCallbacks = nullptr;
|
||||
m_stopped = true;
|
||||
m_wantDuplicates = false;
|
||||
m_pTaskData = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,14 +101,6 @@ NimBLEScan::NimBLEScan() {
|
|||
|
||||
NimBLEAddress advertisedAddress(event->disc.addr);
|
||||
|
||||
// Print advertisement data
|
||||
// print_adv_fields(&fields);
|
||||
|
||||
// If we are not scanning, nothing to do with the extra results.
|
||||
if (pScan->m_stopped) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Examine our list of ignored addresses and stop processing if we don't want to see it or are already connected
|
||||
if(NimBLEDevice::isIgnored(advertisedAddress)) {
|
||||
NIMBLE_LOGI(LOG_TAG, "Ignoring device: address: %s", advertisedAddress.toString().c_str());
|
||||
|
@ -131,7 +123,6 @@ NimBLEScan::NimBLEScan() {
|
|||
advertisedDevice = new NimBLEAdvertisedDevice();
|
||||
advertisedDevice->setAddressType(event->disc.addr.type);
|
||||
advertisedDevice->setAddress(advertisedAddress);
|
||||
//NIMBLE_LOGE(LOG_TAG, "advertisement type: %d, %s",event->disc.event_type, NimBLEUtils::advTypeToString(event->disc.event_type));
|
||||
advertisedDevice->setAdvType(event->disc.event_type);
|
||||
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
||||
NIMBLE_LOGI(LOG_TAG, "NEW DEVICE FOUND: %s", advertisedAddress.toString().c_str());
|
||||
|
@ -153,7 +144,6 @@ NimBLEScan::NimBLEScan() {
|
|||
} else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
|
||||
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
|
||||
}
|
||||
//m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -167,7 +157,11 @@ NimBLEScan::NimBLEScan() {
|
|||
}
|
||||
|
||||
pScan->m_stopped = true;
|
||||
pScan->m_semaphoreScanEnd.give();
|
||||
if(pScan->m_pTaskData != nullptr) {
|
||||
pScan->m_pTaskData->rc = event->disc_complete.reason;
|
||||
xTaskNotifyGive(pScan->m_pTaskData->task);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -249,7 +243,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
}
|
||||
|
||||
m_stopped = false;
|
||||
m_semaphoreScanEnd.take("start");
|
||||
|
||||
// Save the callback to be invoked when the scan completes.
|
||||
m_scanCompleteCB = scanCompleteCB;
|
||||
|
@ -275,7 +268,7 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params,
|
||||
NimBLEScan::handleGapEvent, this);
|
||||
if(rc == BLE_HS_EBUSY) {
|
||||
vTaskDelay(2);
|
||||
vTaskDelay(1 / portTICK_PERIOD_MS);
|
||||
}
|
||||
} while(rc == BLE_HS_EBUSY);
|
||||
|
||||
|
@ -283,7 +276,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_stopped = true;
|
||||
m_semaphoreScanEnd.give();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -298,9 +290,18 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
* @return The BLEScanResults.
|
||||
*/
|
||||
NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
|
||||
if(start(duration, nullptr, is_continue)) {
|
||||
m_semaphoreScanEnd.wait("start"); // Wait for the semaphore to release.
|
||||
if(duration == 0) {
|
||||
NIMBLE_LOGW(LOG_TAG, "Blocking scan called with duration = forever");
|
||||
}
|
||||
|
||||
ble_task_data_t taskData = {nullptr, xTaskGetCurrentTaskHandle(),0, nullptr};
|
||||
m_pTaskData = &taskData;
|
||||
|
||||
if(start(duration, nullptr, is_continue)) {
|
||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
|
||||
}
|
||||
|
||||
m_pTaskData = nullptr;
|
||||
return m_scanResults;
|
||||
} // start
|
||||
|
||||
|
@ -309,13 +310,13 @@ NimBLEScanResults NimBLEScan::start(uint32_t duration, bool is_continue) {
|
|||
* @brief Stop an in progress scan.
|
||||
* @return N/A.
|
||||
*/
|
||||
void NimBLEScan::stop() {
|
||||
bool NimBLEScan::stop() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> stop()");
|
||||
|
||||
int rc = ble_gap_disc_cancel();
|
||||
if (rc != 0 && rc != BLE_HS_EALREADY) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Failed to cancel scan; rc=%d\n", rc);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stopped = true;
|
||||
|
@ -324,9 +325,12 @@ void NimBLEScan::stop() {
|
|||
m_scanCompleteCB(m_scanResults);
|
||||
}
|
||||
|
||||
m_semaphoreScanEnd.give();
|
||||
if(m_pTaskData != nullptr) {
|
||||
xTaskNotifyGive(m_pTaskData->task);
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< stop()");
|
||||
return true;
|
||||
} // stop
|
||||
|
||||
|
||||
|
@ -350,7 +354,6 @@ void NimBLEScan::erase(const NimBLEAddress &address) {
|
|||
*/
|
||||
void NimBLEScan::onHostReset() {
|
||||
m_stopped = true;
|
||||
m_semaphoreScanEnd.give();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
||||
#include "NimBLEAdvertisedDevice.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "NimBLEUtils.h"
|
||||
|
||||
#include "host/ble_gap.h"
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
void setActiveScan(bool active);
|
||||
void setInterval(uint16_t intervalMSecs);
|
||||
void setWindow(uint16_t windowMSecs);
|
||||
void stop();
|
||||
bool stop();
|
||||
void clearResults();
|
||||
NimBLEScanResults getResults();
|
||||
void erase(const NimBLEAddress &address);
|
||||
|
@ -85,8 +85,8 @@ private:
|
|||
bool m_stopped;
|
||||
bool m_wantDuplicates;
|
||||
NimBLEScanResults m_scanResults;
|
||||
FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd");
|
||||
uint32_t m_duration;
|
||||
ble_task_data_t *m_pTaskData;
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
|
|
@ -502,8 +502,13 @@ void print_bytes(const uint8_t *bytes, int len)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
|
||||
MODLOG_DFLT(ERROR, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
|
||||
if(i % 30 == 0){
|
||||
MODLOG_DFLT(ERROR, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
MODLOG_DFLT(ERROR, "\n");
|
||||
}
|
||||
|
||||
void print_mbuf(const struct os_mbuf *om)
|
||||
|
|
Loading…
Reference in a new issue