Merge bugfix branch into master

This commit is contained in:
h2zero 2020-04-13 19:13:51 -06:00
parent 359d2885e1
commit 3327a32341
13 changed files with 225 additions and 161 deletions

View file

@ -1,9 +1,9 @@
# *** UPDATE *** # *** UPDATE ***
Server now handles long reads and writes, still work to do on client.
This library is now ready with (mostly) all original BLE library compatiblity. NEW Client callback created - ```bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params)```
Check the examples and API_DIFFERENCES document for details of using this library. Called when the server wants to change the connection parameters, return true to accept them or false if not.
Check NimBLE_Client.ino example for a demonstration.
3 simultaneous connections tested stable so far on both client and server.
# esp-nimble-cpp # esp-nimble-cpp

View file

@ -24,9 +24,9 @@
NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic) NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic)
: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902), : NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902),
BLE_GATT_CHR_PROP_READ | BLE_GATT_CHR_F_READ |
BLE_GATT_CHR_PROP_WRITE, BLE_GATT_CHR_F_WRITE,
2, pCharacterisitic) 2, pCharacterisitic)
{ {
uint8_t data[2] = { 0, 0 }; uint8_t data[2] = { 0, 0 };
setValue(data, 2); setValue(data, 2);

View file

@ -39,7 +39,7 @@ NimBLEAdvertising::NimBLEAdvertising() {
m_advData.name_len = strlen(name); m_advData.name_len = strlen(name);
m_advData.name_is_complete = 1; m_advData.name_is_complete = 1;
m_scanData.tx_pwr_lvl_is_present = 1; m_scanData.tx_pwr_lvl_is_present = 1;
m_scanData.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; m_scanData.tx_pwr_lvl = NimBLEDevice::getPower();
m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP); m_advData.flags = (BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP);
m_advData.appearance = 0; m_advData.appearance = 0;
m_advData.appearance_is_present = 0; m_advData.appearance_is_present = 0;
@ -228,11 +228,6 @@ void NimBLEAdvertising::start() {
&m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t)); &m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t));
m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16; m_advData.uuids16[m_advData.num_uuids16].u.type = BLE_UUID_TYPE_16;
/*
char buf[BLE_UUID_STR_LEN];
ble_uuid_to_str(&m_advData.uuids16[m_advData.num_uuids16].u, buf);
NIMBLE_LOGI(LOG_TAG, "Advertising UUID: %s", buf);
*/
m_advData.uuids16_is_complete = 1; m_advData.uuids16_is_complete = 1;
m_advData.num_uuids16++; m_advData.num_uuids16++;
} }
@ -254,11 +249,6 @@ void NimBLEAdvertising::start() {
&m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t)); &m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t));
m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32; m_advData.uuids32[m_advData.num_uuids32].u.type = BLE_UUID_TYPE_32;
/*
char buf[BLE_UUID_STR_LEN];
ble_uuid_to_str(&m_advData.uuids32[m_advData.num_uuids32].u, buf);
NIMBLE_LOGI(LOG_TAG, "Advertising UUID: %s", buf);
*/
m_advData.uuids32_is_complete = 1; m_advData.uuids32_is_complete = 1;
m_advData.num_uuids32++; m_advData.num_uuids32++;
} }
@ -279,11 +269,6 @@ void NimBLEAdvertising::start() {
&m_serviceUUIDs[i].getNative()->u128.value, 16); &m_serviceUUIDs[i].getNative()->u128.value, 16);
m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128; m_advData.uuids128[m_advData.num_uuids128].u.type = BLE_UUID_TYPE_128;
/*
char buf[BLE_UUID_STR_LEN];
ble_uuid_to_str(&m_advData.uuids128[m_advData.num_uuids128].u, buf);
NIMBLE_LOGI(LOG_TAG, "Advertising UUID: %s", buf);
*/
m_advData.uuids128_is_complete = 1; m_advData.uuids128_is_complete = 1;
m_advData.num_uuids128++; m_advData.num_uuids128++;
} }
@ -331,7 +316,7 @@ void NimBLEAdvertising::start() {
// throw the tx power data into the advertisment // throw the tx power data into the advertisment
} else if (payloadLen < 29) { } else if (payloadLen < 29) {
m_advData.tx_pwr_lvl_is_present = 1; m_advData.tx_pwr_lvl_is_present = 1;
m_advData.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO; m_advData.tx_pwr_lvl = NimBLEDevice::getPower();
} }
rc = ble_gap_adv_set_fields(&m_advData); rc = ble_gap_adv_set_fields(&m_advData);
@ -394,11 +379,15 @@ void NimBLEAdvertising::stop() {
NIMBLE_LOGD(LOG_TAG, "<< stop"); NIMBLE_LOGD(LOG_TAG, "<< stop");
} // stop } // stop
/*
void NimBLEAdvertising::onHostReset() { /**
// m_advSvcsSet = false; * Host reset seems to clear advertising data,
} * we need clear the flag so it reloads it.
*/ */
void NimBLEAdvertising::onHostReset() {
m_advSvcsSet = false;
}
/** /**
* @brief Add data to the payload to be advertised. * @brief Add data to the payload to be advertised.

View file

@ -90,7 +90,7 @@ public:
private: private:
friend class NimBLEDevice; friend class NimBLEDevice;
// void onHostReset(); void onHostReset();
ble_hs_adv_fields m_advData; ble_hs_adv_fields m_advData;
ble_hs_adv_fields m_scanData; ble_hs_adv_fields m_scanData;
ble_gap_adv_params m_advParams; ble_gap_adv_params m_advParams;

View file

@ -102,7 +102,16 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32_t properties, uint16_t max_len) { NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32_t properties, uint16_t max_len) {
NimBLEDescriptor* pDescriptor = nullptr; NimBLEDescriptor* pDescriptor = nullptr;
if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) { if(uuid.equals(NimBLEUUID((uint16_t)0x2902))) {
pDescriptor = new NimBLE2902(this); if(!(m_properties & BLE_GATT_CHR_F_NOTIFY) && !(m_properties & BLE_GATT_CHR_F_INDICATE)) {
assert(0 && "Cannot create 2902 descriptior without characteristic notification or indication property set");
}
// We cannot have more than one 2902 descriptor, if it's already been created just return a pointer to it.
pDescriptor = m_descriptorMap.getByUUID(uuid);
if(pDescriptor == nullptr) {
pDescriptor = new NimBLE2902(this);
} else {
return pDescriptor;
}
} else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) { } else if (uuid.equals(NimBLEUUID((uint16_t)0x2904))) {
pDescriptor = new NimBLE2904(this); pDescriptor = new NimBLE2904(this);
@ -204,18 +213,34 @@ int NimBLECharacteristic::handleGapEvent(uint16_t conn_handle, uint16_t attr_han
if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){ if(ble_uuid_cmp(uuid, &pCharacteristic->getUUID().getNative()->u) == 0){
switch(ctxt->op) { switch(ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR: { case BLE_GATT_ACCESS_OP_READ_CHR: {
pCharacteristic->m_pCallbacks->onRead(pCharacteristic); //NIMBLE_LOGD(LOG_TAG, "read char pkthdr len:%d flags:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_flags);
// If the packet header is only 8 bytes this is a follow up of a long read
// so we don't want to call the onRead() callback again.
if(ctxt->om->om_pkthdr_len > 8) {
pCharacteristic->m_pCallbacks->onRead(pCharacteristic);
}
rc = os_mbuf_append(ctxt->om, pCharacteristic->getData(), pCharacteristic->m_value.getLength()); rc = os_mbuf_append(ctxt->om, pCharacteristic->getData(), pCharacteristic->m_value.getLength());
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} }
case BLE_GATT_ACCESS_OP_WRITE_CHR: { case BLE_GATT_ACCESS_OP_WRITE_CHR: {
//NIMBLE_LOGD(LOG_TAG, "write char pkthdr len:%d datalen:%d", ctxt->om->om_pkthdr_len, ctxt->om->om_len);
if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) { if (ctxt->om->om_len > BLE_ATT_ATTR_MAX_LEN) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
} }
pCharacteristic->setValue(ctxt->om->om_data, ctxt->om->om_len); //pCharacteristic->setValue(ctxt->om->om_data, ctxt->om->om_len);
pCharacteristic->m_value.addPart(ctxt->om->om_data, ctxt->om->om_len);
os_mbuf *next;
next = SLIST_NEXT(ctxt->om, om_next);
while(next != NULL){
//NIMBLE_LOGD(LOG_TAG, "Found long write data, len:%d", next->om_len);
pCharacteristic->m_value.addPart(next->om_data, next->om_len);
next = SLIST_NEXT(next, om_next);
}
pCharacteristic->m_value.commit();
pCharacteristic->m_pCallbacks->onWrite(pCharacteristic); pCharacteristic->m_pCallbacks->onWrite(pCharacteristic);
return 0; return 0;
} }
default: default:

View file

@ -53,7 +53,15 @@ NimBLEClient::NimBLEClient()
m_haveServices = false; m_haveServices = false;
m_isConnected = false; m_isConnected = false;
m_connectTimeout = 30000; m_connectTimeout = 30000;
m_pConnParams = 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)
m_pConnParams.itvl_min = BLE_GAP_INITIAL_CONN_ITVL_MIN; // min_int = 0x10*1.25ms = 20ms
m_pConnParams.itvl_max = BLE_GAP_INITIAL_CONN_ITVL_MAX; // max_int = 0x20*1.25ms = 40ms
m_pConnParams.latency = BLE_GAP_INITIAL_CONN_LATENCY; // number of packets allowed to skip (extends max interval)
m_pConnParams.supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT; // timeout = 400*10ms = 4000ms
m_pConnParams.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN; // Minimum 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
} // NimBLEClient } // NimBLEClient
@ -70,9 +78,6 @@ NimBLEClient::~NimBLEClient() {
delete m_pClientCallbacks; delete m_pClientCallbacks;
} }
if(m_pConnParams != nullptr) {
free(m_pConnParams);
}
} // ~NimBLEClient } // ~NimBLEClient
@ -134,24 +139,27 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ
ble_addr_t peerAddrt; ble_addr_t peerAddrt;
memcpy(&peerAddrt.val, address.getNative(),6); memcpy(&peerAddrt.val, address.getNative(),6);
peerAddrt.type = type; peerAddrt.type = type;
NIMBLE_LOGE(LOG_TAG, "taking connect semaphore");
m_semaphoreOpenEvt.take("connect"); m_semaphoreOpenEvt.take("connect");
NIMBLE_LOGE(LOG_TAG, "taken");
/** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for /** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
* timeout (default value of m_connectTimeout). * timeout (default value of m_connectTimeout).
* Loop on BLE_HS_EBUSY if the scan hasn't stopped yet. * Loop on BLE_HS_EBUSY if the scan hasn't stopped yet.
*/ */
do{ do{
rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peerAddrt, m_connectTimeout, m_pConnParams, rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &peerAddrt, m_connectTimeout, &m_pConnParams,
NimBLEClient::handleGapEvent, this); NimBLEClient::handleGapEvent, this);
if(rc == BLE_HS_EBUSY) {
vTaskDelay(1);
}
}while(rc == BLE_HS_EBUSY); }while(rc == BLE_HS_EBUSY);
if (rc != 0) { if (rc != 0 && rc != BLE_HS_EDONE) {
NIMBLE_LOGE(LOG_TAG, "Error: Failed to connect to device; addr_type=%d " NIMBLE_LOGE(LOG_TAG, "Error: Failed to connect to device; addr_type=%d "
"addr=%s, rc=%d; %s", "addr=%s, rc=%d; %s",
type, type,
m_peerAddress.toString().c_str(), m_peerAddress.toString().c_str(),
rc, NimBLEUtils::returnCodeToString(BLE_HS_ATT_ERR(rc))); rc, NimBLEUtils::returnCodeToString(rc));
m_semaphoreOpenEvt.give(); m_semaphoreOpenEvt.give();
m_waitingToConnect = false; m_waitingToConnect = false;
@ -225,12 +233,16 @@ int NimBLEClient::disconnect(uint8_t reason) {
m_isConnected = false; // flag the disconnect now so no calls are performed after m_isConnected = false; // flag the disconnect now so no calls are performed after
rc = ble_gap_terminate(m_conn_id, reason); rc = ble_gap_terminate(m_conn_id, reason);
if(rc != 0){ if(rc != 0){
NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc, NimBLEUtils::returnCodeToString(rc)); NIMBLE_LOGE(LOG_TAG, "ble_gap_terminate failed: rc=%d %s", rc,
NimBLEUtils::returnCodeToString(rc));
} }
// Sometimes a disconnect event is not sent so we need to make sure
// the device can be found again.
NimBLEDevice::removeIgnored(m_peerAddress);
} }
return rc;
NIMBLE_LOGD(LOG_TAG, "<< disconnect()"); NIMBLE_LOGD(LOG_TAG, "<< disconnect()");
return rc;
} // disconnect } // disconnect
@ -239,34 +251,23 @@ int NimBLEClient::disconnect(uint8_t reason) {
*/ */
void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval, void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout, uint16_t latency, uint16_t timeout,
uint16_t minConnTime, uint16_t maxConnTime) uint16_t scanInterval, uint16_t scanWindow)/*,
uint16_t minConnTime, uint16_t maxConnTime)*/
{ {
if(m_pConnParams == nullptr) {
m_pConnParams = (ble_gap_conn_params*)calloc(1, sizeof(ble_gap_conn_params));
if(m_pConnParams == nullptr) {
NIMBLE_LOGE(LOG_TAG, "setConnectionParams: Error No Mem");
return;
}
}else if(0 == (minInterval | maxInterval | latency | timeout)) {
free(m_pConnParams);
m_pConnParams = nullptr;
return;
}
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)
m_pConnParams->itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
m_pConnParams->itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
m_pConnParams->latency = latency; // number of packets allowed to skip (extends max interval)
m_pConnParams->supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units
m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units
int rc = NimBLEUtils::checkConnParams(m_pConnParams); m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units
if(rc != 0) { m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units
NIMBLE_LOGE(LOG_TAG,"setConnectionParams : %s", NimBLEUtils::returnCodeToString(rc)); m_pConnParams.itvl_min = minInterval; // min_int = 0x10*1.25ms = 20ms
free(m_pConnParams); m_pConnParams.itvl_max = maxInterval; // max_int = 0x20*1.25ms = 40ms
m_pConnParams = nullptr; m_pConnParams.latency = latency; // number of packets allowed to skip (extends max interval)
} m_pConnParams.supervision_timeout = timeout; // timeout = 400*10ms = 4000ms
// These are not used by NimBLE at this time - Must leave at defaults
//m_pConnParams->min_ce_len = minConnTime; // Minimum length of connection event in 0.625ms units
//m_pConnParams->max_ce_len = maxConnTime; // Maximum length of connection event in 0.625ms units
int rc = NimBLEUtils::checkConnParams(&m_pConnParams);
assert(rc == 0 && "Invalid Connection parameters");
} }
@ -274,21 +275,17 @@ void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterva
* Update connection parameters can be called only after connection has been established * Update connection parameters can be called only after connection has been established
*/ */
void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval, void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout, uint16_t latency, uint16_t timeout)
uint16_t minConnTime, uint16_t maxConnTime)
{ {
if(m_pConnParams == nullptr) {
setConnectionParams(minInterval, maxInterval, latency, timeout, minConnTime, maxConnTime);
}
ble_gap_upd_params params; ble_gap_upd_params params;
params.latency = latency; params.latency = latency;
params.itvl_max = maxInterval; params.itvl_max = maxInterval;
params.itvl_min = minInterval; params.itvl_min = minInterval;
params.supervision_timeout = timeout; params.supervision_timeout = timeout;
params.min_ce_len = minConnTime; // These are not used by NimBLE at this time - Must leave at defaults
params.max_ce_len = maxConnTime; params.min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN;
params.max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN;
int rc = ble_gap_update_params(m_conn_id, &params); int rc = ble_gap_update_params(m_conn_id, &params);
if(rc != 0) { if(rc != 0) {
@ -331,7 +328,7 @@ NimBLEAddress NimBLEClient::getPeerAddress() {
int NimBLEClient::getRssi() { int NimBLEClient::getRssi() {
NIMBLE_LOGD(LOG_TAG, ">> getRssi()"); NIMBLE_LOGD(LOG_TAG, ">> getRssi()");
if (!isConnected()) { if (!isConnected()) {
NIMBLE_LOGD(LOG_TAG, "<< getRssi(): Not connected"); NIMBLE_LOGE(LOG_TAG, "<< getRssi(): Not connected");
return 0; return 0;
} }
@ -466,13 +463,12 @@ int NimBLEClient::serviceDiscoveredCB(
// Found a service - add it to the map // Found a service - add it to the map
NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service); NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service);
peer->m_servicesMap.insert(std::pair<std::string, NimBLERemoteService*>(pRemoteService->getUUID().toString(), pRemoteService)); peer->m_servicesMap.insert(std::pair<std::string, NimBLERemoteService*>(pRemoteService->getUUID().toString(), pRemoteService));
break; break;
} }
case BLE_HS_EDONE:{ case BLE_HS_EDONE:{
// All services discovered; start discovering characteristics. // All services discovered; start discovering characteristics.
NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed"); //NIMBLE_LOGD(LOG_TAG,"Giving search semaphore - completed");
peer->m_semaphoreSearchCmplEvt.give(0); peer->m_semaphoreSearchCmplEvt.give(0);
rc = 0; rc = 0;
break; break;
@ -576,6 +572,8 @@ uint16_t NimBLEClient::getMTU() {
client->m_isConnected = false; client->m_isConnected = false;
client->m_waitingToConnect=false; client->m_waitingToConnect=false;
// Remove the device from ignore list so we will scan it again
NimBLEDevice::removeIgnored(client->m_peerAddress);
NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason, NIMBLE_LOGI(LOG_TAG, "disconnect; reason=%d, %s", event->disconnect.reason,
NimBLEUtils::returnCodeToString(event->disconnect.reason)); NimBLEUtils::returnCodeToString(event->disconnect.reason));
@ -604,8 +602,6 @@ uint16_t NimBLEClient::getMTU() {
client->m_semaphoreSearchCmplEvt.give(1); client->m_semaphoreSearchCmplEvt.give(1);
client->m_semeaphoreSecEvt.give(1); client->m_semeaphoreSecEvt.give(1);
// Remove the device from ignore list so we will scan it again
NimBLEDevice::removeIgnored(client->m_peerAddress);
client->m_pClientCallbacks->onDisconnect(client); client->m_pClientCallbacks->onDisconnect(client);
return 0; return 0;
@ -633,7 +629,6 @@ uint16_t NimBLEClient::getMTU() {
// print_conn_desc(&desc); // print_conn_desc(&desc);
// MODLOG_DFLT(INFO, "\n"); // MODLOG_DFLT(INFO, "\n");
//client->m_pClientCallbacks->onConnect(client);
// In the case of a multiconnecting device we ignore this device when // In the case of a multiconnecting device we ignore this device when
// scanning since we are already connected to it // scanning since we are already connected to it
@ -645,18 +640,14 @@ uint16_t NimBLEClient::getMTU() {
NimBLEUtils::returnCodeToString(rc)); NimBLEUtils::returnCodeToString(rc));
// if error getting mtu indicate a connection error. // if error getting mtu indicate a connection error.
client->m_semaphoreOpenEvt.give(rc); client->m_semaphoreOpenEvt.give(rc);
} /*else { }
client->m_semaphoreOpenEvt.give(0);
}*/
} else { } else {
// Connection attempt failed // Connection attempt failed
NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s", NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s",
event->connect.status, event->connect.status,
NimBLEUtils::returnCodeToString(event->connect.status)); NimBLEUtils::returnCodeToString(event->connect.status));
client->m_semaphoreOpenEvt.give(event->connect.status);
} }
client->m_semaphoreOpenEvt.give(event->connect.status);
return 0; return 0;
} // BLE_GAP_EVENT_CONNECT } // BLE_GAP_EVENT_CONNECT
@ -702,22 +693,19 @@ uint16_t NimBLEClient::getMTU() {
event->conn_update_req.peer_params->itvl_max, event->conn_update_req.peer_params->itvl_max,
event->conn_update_req.peer_params->latency, event->conn_update_req.peer_params->latency,
event->conn_update_req.peer_params->supervision_timeout); event->conn_update_req.peer_params->supervision_timeout);
rc = 0;
// if we set connection params and the peer is asking for new ones, reject them.
if(client->m_pConnParams != nullptr) {
if(event->conn_update_req.peer_params->itvl_min != client->m_pConnParams->itvl_min || rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client,
event->conn_update_req.peer_params->itvl_max != client->m_pConnParams->itvl_max || event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS;
event->conn_update_req.peer_params->latency != client->m_pConnParams->latency ||
event->conn_update_req.peer_params->supervision_timeout != client->m_pConnParams->supervision_timeout)
{ if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) {
//event->conn_update_req.self_params->itvl_min = 6;//client->m_pConnParams->itvl_min; event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min;
rc = BLE_ERR_CONN_PARMS; event->conn_update_req.self_params->itvl_max = client->m_pConnParams.itvl_max;
} event->conn_update_req.self_params->latency = client->m_pConnParams.latency;
} event->conn_update_req.self_params->supervision_timeout = client->m_pConnParams.supervision_timeout;
if(rc != 0) {
NIMBLE_LOGD(LOG_TAG, "Rejected peer params");
} }
NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected");
return rc; return rc;
} // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ } // BLE_GAP_EVENT_CONN_UPDATE_REQ, BLE_GAP_EVENT_L2CAP_UPDATE_REQ
@ -761,7 +749,7 @@ uint16_t NimBLEClient::getMTU() {
NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d", NIMBLE_LOGI(LOG_TAG, "mtu update event; conn_handle=%d mtu=%d",
event->mtu.conn_handle, event->mtu.conn_handle,
event->mtu.value); event->mtu.value);
client->m_semaphoreOpenEvt.give(0); client->m_semaphoreOpenEvt.give(0);
//client->m_mtu = event->mtu.value; //client->m_mtu = event->mtu.value;
return 0; return 0;
} // BLE_GAP_EVENT_MTU } // BLE_GAP_EVENT_MTU
@ -868,14 +856,19 @@ std::string NimBLEClient::toString() {
} // toString } // toString
void NimBLEClientCallbacks::onConnect(NimBLEClient *pClient) { void NimBLEClientCallbacks::onConnect(NimBLEClient* pClient) {
NIMBLE_LOGD("NimBLEClientCallbacks", "onConnect: default"); NIMBLE_LOGD("NimBLEClientCallbacks", "onConnect: default");
} }
void NimBLEClientCallbacks::onDisconnect(NimBLEClient *pClient) { void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient) {
NIMBLE_LOGD("NimBLEClientCallbacks", "onDisconnect: default"); NIMBLE_LOGD("NimBLEClientCallbacks", "onDisconnect: default");
} }
bool NimBLEClientCallbacks::onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params) {
NIMBLE_LOGD("NimBLEClientCallbacks", "onConnParamsUpdateRequest: default");
return true;
}
uint32_t NimBLEClientCallbacks::onPassKeyRequest(){ uint32_t NimBLEClientCallbacks::onPassKeyRequest(){
NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456"); NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456");
return 123456; return 123456;
@ -889,7 +882,7 @@ bool NimBLEClientCallbacks::onSecurityRequest(){
NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true"); NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true");
return true; return true;
} }
void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){ void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){
NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default"); NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default");
} }
bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){ bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){

View file

@ -52,12 +52,9 @@ public:
void setConnectTimeout(uint8_t timeout); void setConnectTimeout(uint8_t timeout);
void setConnectionParams(uint16_t minInterval, uint16_t maxInterval, void setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout, uint16_t latency, uint16_t timeout,
uint16_t minConnTime=16, uint16_t maxConnTime=768); uint16_t scanInterval=16, uint16_t scanWindow=16); // NimBLE default scan settings
void updateConnParams(uint16_t minInterval, uint16_t maxInterval, void updateConnParams(uint16_t minInterval, uint16_t maxInterval,
uint16_t latency, uint16_t timeout, uint16_t latency, uint16_t timeout);
uint16_t minConnTime=16, uint16_t maxConnTime=768);
private: private:
@ -79,10 +76,8 @@ private:
bool m_waitingToConnect =false; bool m_waitingToConnect =false;
bool m_deleteCallbacks = true; bool m_deleteCallbacks = true;
int32_t m_connectTimeout; int32_t m_connectTimeout;
ble_gap_conn_params* m_pConnParams;
//uint16_t m_mtu = 23; //uint16_t m_mtu = 23;
NimBLEClientCallbacks* m_pClientCallbacks = nullptr; NimBLEClientCallbacks* m_pClientCallbacks = nullptr;
FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt"); FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt");
@ -91,6 +86,10 @@ private:
std::map<std::string, NimBLERemoteService*> m_servicesMap; std::map<std::string, NimBLERemoteService*> m_servicesMap;
private:
friend class NimBLEClientCallbacks;
ble_gap_conn_params m_pConnParams;
}; // class NimBLEClient }; // class NimBLEClient
@ -100,13 +99,14 @@ private:
class NimBLEClientCallbacks { class NimBLEClientCallbacks {
public: public:
virtual ~NimBLEClientCallbacks() {}; virtual ~NimBLEClientCallbacks() {};
virtual void onConnect(NimBLEClient *pClient); // = 0; virtual void onConnect(NimBLEClient* pClient);
virtual void onDisconnect(NimBLEClient *pClient); // = 0; virtual void onDisconnect(NimBLEClient* pClient);
virtual uint32_t onPassKeyRequest(); //{return 0;} virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params);
virtual void onPassKeyNotify(uint32_t pass_key); //{} virtual uint32_t onPassKeyRequest();
virtual bool onSecurityRequest(); //{return false;} virtual void onPassKeyNotify(uint32_t pass_key);
virtual void onAuthenticationComplete(ble_gap_conn_desc*); //{}; virtual bool onSecurityRequest();
virtual bool onConfirmPIN(uint32_t pin); //{return false;} virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
virtual bool onConfirmPIN(uint32_t pin);
}; };
#endif // CONFIG_BT_ENABLED #endif // CONFIG_BT_ENABLED

View file

@ -239,17 +239,41 @@ void NimBLEDevice::stopAdvertising() {
* * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm * * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm
* @param [in] powerLevel. * @param [in] powerLevel.
*/ */
/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel) { /* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", powerLevel); NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType);
esp_err_t errRc = ::esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, powerLevel); esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
if (errRc != ESP_OK) { if (errRc != ESP_OK) {
//NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc); NIMBLE_LOGE(LOG_TAG, "esp_ble_tx_power_set: rc=%d", errRc);
}; }
NIMBLE_LOGD(LOG_TAG, "<< setPower"); NIMBLE_LOGD(LOG_TAG, "<< setPower");
} // setPower } // setPower
/* STATIC */ int NimBLEDevice::getPower(esp_ble_power_type_t powerType) {
switch(esp_ble_tx_power_get(powerType)) {
case ESP_PWR_LVL_N12:
return -12;
case ESP_PWR_LVL_N9:
return -9;
case ESP_PWR_LVL_N6:
return -6;
case ESP_PWR_LVL_N3:
return -6;
case ESP_PWR_LVL_N0:
return 0;
case ESP_PWR_LVL_P3:
return 3;
case ESP_PWR_LVL_P6:
return 6;
case ESP_PWR_LVL_P9:
return 9;
default:
return BLE_HS_ADV_TX_PWR_LVL_AUTO;
}
} // setPower
/** /**
* @brief Get our device address. * @brief Get our device address.
* @return A NimBLEAddress object of our public address if we have one, * @return A NimBLEAddress object of our public address if we have one,
@ -327,11 +351,11 @@ void NimBLEDevice::stopAdvertising() {
for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) { for(auto it = m_cList.cbegin(); it != m_cList.cend(); ++it) {
(*it)->onHostReset(); (*it)->onHostReset();
} }
*/
if(m_bleAdvertising != nullptr) { if(m_bleAdvertising != nullptr) {
m_bleAdvertising->onHostReset(); m_bleAdvertising->onHostReset();
} }
*/
NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason, NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason,
NimBLEUtils::returnCodeToString(reason)); NimBLEUtils::returnCodeToString(reason));
} // onReset } // onReset
@ -414,7 +438,7 @@ void NimBLEDevice::stopAdvertising() {
ble_hs_cfg.sync_cb = NimBLEDevice::onSync; ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
// Set initial security capabilities // Set initial security capabilities
ble_hs_cfg.sm_io_cap = BLE_SM_IO_CAP_NO_IO; ble_hs_cfg.sm_io_cap = BLE_HS_IO_NO_INPUT_OUTPUT;
ble_hs_cfg.sm_bonding = 0; ble_hs_cfg.sm_bonding = 0;
ble_hs_cfg.sm_mitm = 0; ble_hs_cfg.sm_mitm = 0;
ble_hs_cfg.sm_sc = 1; ble_hs_cfg.sm_sc = 1;

View file

@ -59,7 +59,11 @@
#define BLEEddystoneTLM NimBLEEddystoneTLM #define BLEEddystoneTLM NimBLEEddystoneTLM
#define BLEEddystoneURL NimBLEEddystoneURL #define BLEEddystoneURL NimBLEEddystoneURL
#ifdef CONFIG_BT_NIMBLE_MAX_CONNECTIONS
#define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS #define NIMBLE_MAX_CONNECTIONS CONFIG_BT_NIMBLE_MAX_CONNECTIONS
#else
#define NIMBLE_MAX_CONNECTIONS CONFIG_NIMBLE_MAX_CONNECTIONS
#endif
/** /**
* @brief BLE functions. * @brief BLE functions.
@ -81,7 +85,8 @@ public:
static NimBLEClient* createClient(); static NimBLEClient* createClient();
static NimBLEServer* createServer(); static NimBLEServer* createServer();
static bool deleteClient(NimBLEClient* pClient); static bool deleteClient(NimBLEClient* pClient);
static void setPower(esp_power_level_t powerLevel); static void setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
static int getPower(esp_ble_power_type_t powerType=ESP_BLE_PWR_TYPE_DEFAULT);
static void setCustomGapHandler(gap_event_handler handler); static void setCustomGapHandler(gap_event_handler handler);
static void setSecurityAuth(bool bonding, bool mitm, bool sc); static void setSecurityAuth(bool bonding, bool mitm, bool sc);
static void setSecurityAuth(uint8_t auth_req); static void setSecurityAuth(uint8_t auth_req);
@ -110,6 +115,7 @@ private:
friend class NimBLEClient; friend class NimBLEClient;
friend class NimBLEScan; friend class NimBLEScan;
friend class NimBLEAdvertising; friend class NimBLEAdvertising;
friend class NimBLECharacteristic;
static void onReset(int reason); static void onReset(int reason);
static void onSync(void); static void onSync(void);

View file

@ -18,6 +18,9 @@
// Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR // Note: because CONFIG_LOG_DEFAULT_LEVEL is set at ERROR in Arduino we must use MODLOG_DFLT(ERROR
// otherwise no messages will be printed above that level. // otherwise no messages will be printed above that level.
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#ifndef CORE_DEBUG_LEVEL
#define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL
#endif
#if CORE_DEBUG_LEVEL >= 4 #if CORE_DEBUG_LEVEL >= 4
#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__) #define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__)

View file

@ -16,8 +16,6 @@
#if defined(CONFIG_BT_ENABLED) #if defined(CONFIG_BT_ENABLED)
#include "NimBLERemoteCharacteristic.h" #include "NimBLERemoteCharacteristic.h"
#include <esp_err.h>
#include "NimBLEUtils.h" #include "NimBLEUtils.h"
#include "NimBLELog.h" #include "NimBLELog.h"
@ -321,6 +319,7 @@ std::string NimBLERemoteCharacteristic::readValue() {
int rc = 0; int rc = 0;
int retryCount = 1; int retryCount = 1;
NimBLEClient* pClient = getRemoteService()->getClient(); NimBLEClient* pClient = getRemoteService()->getClient();
// Check to see that we are connected. // Check to see that we are connected.
@ -334,15 +333,18 @@ std::string NimBLERemoteCharacteristic::readValue() {
rc = ble_gattc_read(pClient->getConnId(), m_handle, rc = ble_gattc_read(pClient->getConnId(), m_handle,
NimBLERemoteCharacteristic::onReadCB, this); NimBLERemoteCharacteristic::onReadCB, this);
// long read experiment
/* rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
NimBLERemoteCharacteristic::onReadCB, this);
*/
if (rc != 0) { if (rc != 0) {
NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d", rc); NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d", rc);
//goto err;
m_semaphoreReadCharEvt.give(); m_semaphoreReadCharEvt.give();
return ""; return "";
} }
rc = m_semaphoreReadCharEvt.wait("readValue"); rc = m_semaphoreReadCharEvt.wait("readValue");
switch(rc){ switch(rc){
case 0: case 0:
break; break;
@ -377,8 +379,13 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){ if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
return 0; return 0;
} }
NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle); NIMBLE_LOGI(LOG_TAG, "Read complete; status=%d conn_handle=%d", error->status, conn_handle);
// long read experiment
/* if(attr && (attr->om->om_len >= (ble_att_mtu(characteristic->getRemoteService()->getClient()->getConnId()) - 1))){
return 0;
}
*/
if(characteristic->m_rawData != nullptr) { if(characteristic->m_rawData != nullptr) {
free(characteristic->m_rawData); free(characteristic->m_rawData);
@ -386,16 +393,17 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
if (error->status == 0) { if (error->status == 0) {
characteristic->m_value = std::string((char*) attr->om->om_data, attr->om->om_len); characteristic->m_value = std::string((char*) attr->om->om_data, attr->om->om_len);
characteristic->m_semaphoreReadCharEvt.give(0);
characteristic->m_rawData = (uint8_t*) calloc(attr->om->om_len, sizeof(uint8_t)); characteristic->m_rawData = (uint8_t*) calloc(attr->om->om_len, sizeof(uint8_t));
memcpy(characteristic->m_rawData, attr->om->om_data, attr->om->om_len); memcpy(characteristic->m_rawData, attr->om->om_data, attr->om->om_len);
characteristic->m_semaphoreReadCharEvt.give(0);
} else { } else {
characteristic->m_rawData = nullptr; characteristic->m_rawData = nullptr;
characteristic->m_value = ""; characteristic->m_value = "";
characteristic->m_semaphoreReadCharEvt.give(error->status); characteristic->m_semaphoreReadCharEvt.give(error->status);
} }
return 0; // characteristic->m_semaphoreReadCharEvt.give(error->status);
return 0; //1
} }
@ -515,6 +523,7 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r
NimBLEClient* pClient = getRemoteService()->getClient(); NimBLEClient* pClient = getRemoteService()->getClient();
int rc = 0; int rc = 0;
int retryCount = 1; int retryCount = 1;
// uint16_t mtu;
// Check to see that we are connected. // Check to see that we are connected.
if (!pClient->isConnected()) { if (!pClient->isConnected()) {
@ -522,18 +531,29 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r
return false; return false;
} }
if(!response) { // mtu = ble_att_mtu(pClient->getConnId()) - 3;
if(/*!length > mtu &&*/ !response) {
rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length); rc = ble_gattc_write_no_rsp_flat(pClient->getConnId(), m_handle, data, length);
return (rc==0); return (rc==0);
} }
do { do {
m_semaphoreWriteCharEvt.take("writeValue"); m_semaphoreWriteCharEvt.take("writeValue");
// long write experiment
/* if(length > mtu) {
NIMBLE_LOGD(LOG_TAG,"long write");
os_mbuf *om = ble_hs_mbuf_from_flat(data, length);
rc = ble_gattc_write_long(pClient->getConnId(), m_handle, 0, om,
NimBLERemoteCharacteristic::onWriteCB,
this);
} else {
*/
rc = ble_gattc_write_flat(pClient->getConnId(), m_handle, rc = ble_gattc_write_flat(pClient->getConnId(), m_handle,
data, length, data, length,
NimBLERemoteCharacteristic::onWriteCB, NimBLERemoteCharacteristic::onWriteCB,
this);; this);
// }
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);
m_semaphoreWriteCharEvt.give(); m_semaphoreWriteCharEvt.give();
@ -558,7 +578,7 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r
} while(rc != 0 && retryCount--); } while(rc != 0 && retryCount--);
NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d",rc); NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d",rc);
return (rc == 0); //true; return (rc == 0);
} // writeValue } // writeValue
@ -587,7 +607,7 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
characteristic->m_semaphoreWriteCharEvt.give(error->status); characteristic->m_semaphoreWriteCharEvt.give(error->status);
} }
return error->status; return 0;
} }

View file

@ -231,14 +231,18 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
return false; return false;
} }
if(ble_gap_conn_active()) {
NIMBLE_LOGE(LOG_TAG, "Connection in progress - must wait.");
return false;
}
// If we are already scanning don't start again or we will get stuck on the semaphore. // If we are already scanning don't start again or we will get stuck on the semaphore.
if(!m_stopped || ble_gap_disc_active()) { // double check - can cause host reset. if(!m_stopped || ble_gap_disc_active()) { // double check - can cause host reset.
NIMBLE_LOGE(LOG_TAG, "Scan already in progress"); NIMBLE_LOGE(LOG_TAG, "Scan already in progress");
return false; return false;
} }
m_stopped = false; m_stopped = false;
m_semaphoreScanEnd.take("start"); m_semaphoreScanEnd.take("start");
// Save the callback to be invoked when the scan completes. // Save the callback to be invoked when the scan completes.
@ -261,13 +265,15 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
} }
int rc = 0; int rc = 0;
do{ do{
rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params, rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params,
NimBLEScan::handleGapEvent, this); NimBLEScan::handleGapEvent, this);
}while(rc == BLE_HS_EBUSY); if(rc == BLE_HS_EBUSY) {
vTaskDelay(2);
}
} while(rc == BLE_HS_EBUSY);
if (rc != 0) { if (rc != 0 && rc != BLE_HS_EDONE) {
NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s", NIMBLE_LOGE(LOG_TAG, "Error initiating GAP discovery procedure; rc=%d, %s",
rc, NimBLEUtils::returnCodeToString(rc)); rc, NimBLEUtils::returnCodeToString(rc));
m_stopped = true; m_stopped = true;
@ -275,8 +281,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
return false; return false;
} }
// m_stopped = false;
NIMBLE_LOGD(LOG_TAG, "<< start()"); NIMBLE_LOGD(LOG_TAG, "<< start()");
return true; return true;
} // start } // start

View file

@ -137,7 +137,7 @@ void NimBLEServer::start() {
abort(); abort();
} }
#if CONFIG_LOG_DEFAULT_LEVEL > 3 || ARDUHAL_LOG_LEVEL_INFO > 3 #if CONFIG_LOG_DEFAULT_LEVEL > 3 || (ARDUINO_ARCH_ESP32 && CORE_DEBUG_LEVEL >= 4)
ble_gatts_show_local(); ble_gatts_show_local();
#endif #endif