mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-11-24 14:10:55 +01:00
Merge bugfix branch into master
This commit is contained in:
parent
359d2885e1
commit
3327a32341
13 changed files with 225 additions and 161 deletions
|
@ -1,9 +1,9 @@
|
|||
# *** 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.
|
||||
Check the examples and API_DIFFERENCES document for details of using this library.
|
||||
|
||||
3 simultaneous connections tested stable so far on both client and server.
|
||||
NEW Client callback created - ```bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params)```
|
||||
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.
|
||||
|
||||
|
||||
# esp-nimble-cpp
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
NimBLE2902::NimBLE2902(NimBLECharacteristic* pCharacterisitic)
|
||||
: NimBLEDescriptor(NimBLEUUID((uint16_t) 0x2902),
|
||||
BLE_GATT_CHR_PROP_READ |
|
||||
BLE_GATT_CHR_PROP_WRITE,
|
||||
2, pCharacterisitic)
|
||||
BLE_GATT_CHR_F_READ |
|
||||
BLE_GATT_CHR_F_WRITE,
|
||||
2, pCharacterisitic)
|
||||
{
|
||||
uint8_t data[2] = { 0, 0 };
|
||||
setValue(data, 2);
|
||||
|
|
|
@ -39,7 +39,7 @@ NimBLEAdvertising::NimBLEAdvertising() {
|
|||
m_advData.name_len = strlen(name);
|
||||
m_advData.name_is_complete = 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.appearance = 0;
|
||||
m_advData.appearance_is_present = 0;
|
||||
|
@ -228,11 +228,6 @@ void NimBLEAdvertising::start() {
|
|||
&m_serviceUUIDs[i].getNative()->u16.value, sizeof(uint16_t));
|
||||
|
||||
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.num_uuids16++;
|
||||
}
|
||||
|
@ -254,11 +249,6 @@ void NimBLEAdvertising::start() {
|
|||
&m_serviceUUIDs[i].getNative()->u32.value, sizeof(uint32_t));
|
||||
|
||||
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.num_uuids32++;
|
||||
}
|
||||
|
@ -279,11 +269,6 @@ void NimBLEAdvertising::start() {
|
|||
&m_serviceUUIDs[i].getNative()->u128.value, 16);
|
||||
|
||||
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.num_uuids128++;
|
||||
}
|
||||
|
@ -331,7 +316,7 @@ void NimBLEAdvertising::start() {
|
|||
// throw the tx power data into the advertisment
|
||||
} else if (payloadLen < 29) {
|
||||
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);
|
||||
|
@ -394,11 +379,15 @@ void NimBLEAdvertising::stop() {
|
|||
NIMBLE_LOGD(LOG_TAG, "<< 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.
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class NimBLEDevice;
|
||||
// void onHostReset();
|
||||
void onHostReset();
|
||||
ble_hs_adv_fields m_advData;
|
||||
ble_hs_adv_fields m_scanData;
|
||||
ble_gap_adv_params m_advParams;
|
||||
|
|
|
@ -102,7 +102,16 @@ NimBLEDescriptor* NimBLECharacteristic::createDescriptor(const char* uuid, uint3
|
|||
NimBLEDescriptor* NimBLECharacteristic::createDescriptor(NimBLEUUID uuid, uint32_t properties, uint16_t max_len) {
|
||||
NimBLEDescriptor* pDescriptor = nullptr;
|
||||
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))) {
|
||||
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){
|
||||
switch(ctxt->op) {
|
||||
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());
|
||||
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -53,7 +53,15 @@ NimBLEClient::NimBLEClient()
|
|||
m_haveServices = false;
|
||||
m_isConnected = false;
|
||||
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
|
||||
|
||||
|
||||
|
@ -70,9 +78,6 @@ NimBLEClient::~NimBLEClient() {
|
|||
delete m_pClientCallbacks;
|
||||
}
|
||||
|
||||
if(m_pConnParams != nullptr) {
|
||||
free(m_pConnParams);
|
||||
}
|
||||
} // ~NimBLEClient
|
||||
|
||||
|
||||
|
@ -134,24 +139,27 @@ bool NimBLEClient::connect(NimBLEAddress address, uint8_t type, bool refreshServ
|
|||
ble_addr_t peerAddrt;
|
||||
memcpy(&peerAddrt.val, address.getNative(),6);
|
||||
peerAddrt.type = type;
|
||||
|
||||
NIMBLE_LOGE(LOG_TAG, "taking connect semaphore");
|
||||
m_semaphoreOpenEvt.take("connect");
|
||||
|
||||
NIMBLE_LOGE(LOG_TAG, "taken");
|
||||
/** Try to connect the the advertiser. Allow 30 seconds (30000 ms) for
|
||||
* timeout (default value of m_connectTimeout).
|
||||
* Loop on BLE_HS_EBUSY if the scan hasn't stopped yet.
|
||||
*/
|
||||
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);
|
||||
if(rc == BLE_HS_EBUSY) {
|
||||
vTaskDelay(1);
|
||||
}
|
||||
}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 "
|
||||
"addr=%s, rc=%d; %s",
|
||||
type,
|
||||
m_peerAddress.toString().c_str(),
|
||||
rc, NimBLEUtils::returnCodeToString(BLE_HS_ATT_ERR(rc)));
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
|
||||
m_semaphoreOpenEvt.give();
|
||||
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
|
||||
rc = ble_gap_terminate(m_conn_id, reason);
|
||||
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()");
|
||||
return rc;
|
||||
} // disconnect
|
||||
|
||||
|
||||
|
@ -239,34 +251,23 @@ int NimBLEClient::disconnect(uint8_t reason) {
|
|||
*/
|
||||
void NimBLEClient::setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
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);
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG,"setConnectionParams : %s", NimBLEUtils::returnCodeToString(rc));
|
||||
free(m_pConnParams);
|
||||
m_pConnParams = nullptr;
|
||||
}
|
||||
m_pConnParams.scan_itvl = scanInterval; // Scan interval in 0.625ms units
|
||||
m_pConnParams.scan_window = scanWindow; // Scan window in 0.625ms units
|
||||
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
|
||||
|
||||
// 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
|
||||
*/
|
||||
void NimBLEClient::updateConnParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t minConnTime, uint16_t maxConnTime)
|
||||
uint16_t latency, uint16_t timeout)
|
||||
{
|
||||
if(m_pConnParams == nullptr) {
|
||||
setConnectionParams(minInterval, maxInterval, latency, timeout, minConnTime, maxConnTime);
|
||||
}
|
||||
|
||||
ble_gap_upd_params params;
|
||||
|
||||
params.latency = latency;
|
||||
params.itvl_max = maxInterval;
|
||||
params.itvl_min = minInterval;
|
||||
params.supervision_timeout = timeout;
|
||||
params.min_ce_len = minConnTime;
|
||||
params.max_ce_len = maxConnTime;
|
||||
// These are not used by NimBLE at this time - Must leave at defaults
|
||||
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, ¶ms);
|
||||
if(rc != 0) {
|
||||
|
@ -331,7 +328,7 @@ NimBLEAddress NimBLEClient::getPeerAddress() {
|
|||
int NimBLEClient::getRssi() {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> getRssi()");
|
||||
if (!isConnected()) {
|
||||
NIMBLE_LOGD(LOG_TAG, "<< getRssi(): Not connected");
|
||||
NIMBLE_LOGE(LOG_TAG, "<< getRssi(): Not connected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -466,13 +463,12 @@ int NimBLEClient::serviceDiscoveredCB(
|
|||
// Found a service - add it to the map
|
||||
NimBLERemoteService* pRemoteService = new NimBLERemoteService(peer, service);
|
||||
peer->m_servicesMap.insert(std::pair<std::string, NimBLERemoteService*>(pRemoteService->getUUID().toString(), pRemoteService));
|
||||
|
||||
break;
|
||||
}
|
||||
case BLE_HS_EDONE:{
|
||||
// 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);
|
||||
rc = 0;
|
||||
break;
|
||||
|
@ -576,6 +572,8 @@ uint16_t NimBLEClient::getMTU() {
|
|||
|
||||
client->m_isConnected = 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,
|
||||
NimBLEUtils::returnCodeToString(event->disconnect.reason));
|
||||
|
@ -604,8 +602,6 @@ uint16_t NimBLEClient::getMTU() {
|
|||
client->m_semaphoreSearchCmplEvt.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);
|
||||
|
||||
return 0;
|
||||
|
@ -633,7 +629,6 @@ uint16_t NimBLEClient::getMTU() {
|
|||
// print_conn_desc(&desc);
|
||||
// MODLOG_DFLT(INFO, "\n");
|
||||
|
||||
//client->m_pClientCallbacks->onConnect(client);
|
||||
|
||||
// In the case of a multiconnecting device we ignore this device when
|
||||
// scanning since we are already connected to it
|
||||
|
@ -645,18 +640,14 @@ uint16_t NimBLEClient::getMTU() {
|
|||
NimBLEUtils::returnCodeToString(rc));
|
||||
// if error getting mtu indicate a connection error.
|
||||
client->m_semaphoreOpenEvt.give(rc);
|
||||
} /*else {
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
}*/
|
||||
|
||||
}
|
||||
} else {
|
||||
// Connection attempt failed
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Connection failed; status=%d %s",
|
||||
event->connect.status,
|
||||
NimBLEUtils::returnCodeToString(event->connect.status));
|
||||
client->m_semaphoreOpenEvt.give(event->connect.status);
|
||||
}
|
||||
|
||||
client->m_semaphoreOpenEvt.give(event->connect.status);
|
||||
return 0;
|
||||
} // 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->latency,
|
||||
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 ||
|
||||
event->conn_update_req.peer_params->itvl_max != client->m_pConnParams->itvl_max ||
|
||||
event->conn_update_req.peer_params->latency != client->m_pConnParams->latency ||
|
||||
event->conn_update_req.peer_params->supervision_timeout != client->m_pConnParams->supervision_timeout)
|
||||
{
|
||||
//event->conn_update_req.self_params->itvl_min = 6;//client->m_pConnParams->itvl_min;
|
||||
rc = BLE_ERR_CONN_PARMS;
|
||||
}
|
||||
}
|
||||
if(rc != 0) {
|
||||
NIMBLE_LOGD(LOG_TAG, "Rejected peer params");
|
||||
rc = client->m_pClientCallbacks->onConnParamsUpdateRequest(client,
|
||||
event->conn_update_req.peer_params) ? 0 : BLE_ERR_CONN_PARMS;
|
||||
|
||||
|
||||
if(!rc && event->type == BLE_GAP_EVENT_CONN_UPDATE_REQ ) {
|
||||
event->conn_update_req.self_params->itvl_min = client->m_pConnParams.itvl_min;
|
||||
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;
|
||||
}
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "%s peer params", (rc == 0) ? "Accepted" : "Rejected");
|
||||
return rc;
|
||||
} // 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",
|
||||
event->mtu.conn_handle,
|
||||
event->mtu.value);
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
client->m_semaphoreOpenEvt.give(0);
|
||||
//client->m_mtu = event->mtu.value;
|
||||
return 0;
|
||||
} // BLE_GAP_EVENT_MTU
|
||||
|
@ -868,14 +856,19 @@ std::string NimBLEClient::toString() {
|
|||
} // toString
|
||||
|
||||
|
||||
void NimBLEClientCallbacks::onConnect(NimBLEClient *pClient) {
|
||||
void NimBLEClientCallbacks::onConnect(NimBLEClient* pClient) {
|
||||
NIMBLE_LOGD("NimBLEClientCallbacks", "onConnect: default");
|
||||
}
|
||||
|
||||
void NimBLEClientCallbacks::onDisconnect(NimBLEClient *pClient) {
|
||||
void NimBLEClientCallbacks::onDisconnect(NimBLEClient* pClient) {
|
||||
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(){
|
||||
NIMBLE_LOGD("NimBLEClientCallbacks", "onPassKeyRequest: default: 123456");
|
||||
return 123456;
|
||||
|
@ -889,7 +882,7 @@ bool NimBLEClientCallbacks::onSecurityRequest(){
|
|||
NIMBLE_LOGD("NimBLEClientCallbacks", "onSecurityRequest: default: true");
|
||||
return true;
|
||||
}
|
||||
void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc*){
|
||||
void NimBLEClientCallbacks::onAuthenticationComplete(ble_gap_conn_desc* desc){
|
||||
NIMBLE_LOGD("NimBLEClientCallbacks", "onAuthenticationComplete: default");
|
||||
}
|
||||
bool NimBLEClientCallbacks::onConfirmPIN(uint32_t pin){
|
||||
|
|
|
@ -52,12 +52,9 @@ public:
|
|||
void setConnectTimeout(uint8_t timeout);
|
||||
void setConnectionParams(uint16_t minInterval, uint16_t maxInterval,
|
||||
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,
|
||||
uint16_t latency, uint16_t timeout,
|
||||
uint16_t minConnTime=16, uint16_t maxConnTime=768);
|
||||
|
||||
|
||||
uint16_t latency, uint16_t timeout);
|
||||
|
||||
|
||||
private:
|
||||
|
@ -79,10 +76,8 @@ private:
|
|||
bool m_waitingToConnect =false;
|
||||
bool m_deleteCallbacks = true;
|
||||
int32_t m_connectTimeout;
|
||||
ble_gap_conn_params* m_pConnParams;
|
||||
//uint16_t m_mtu = 23;
|
||||
|
||||
|
||||
NimBLEClientCallbacks* m_pClientCallbacks = nullptr;
|
||||
|
||||
FreeRTOS::Semaphore m_semaphoreOpenEvt = FreeRTOS::Semaphore("OpenEvt");
|
||||
|
@ -91,6 +86,10 @@ private:
|
|||
|
||||
std::map<std::string, NimBLERemoteService*> m_servicesMap;
|
||||
|
||||
private:
|
||||
friend class NimBLEClientCallbacks;
|
||||
ble_gap_conn_params m_pConnParams;
|
||||
|
||||
}; // class NimBLEClient
|
||||
|
||||
|
||||
|
@ -100,13 +99,14 @@ private:
|
|||
class NimBLEClientCallbacks {
|
||||
public:
|
||||
virtual ~NimBLEClientCallbacks() {};
|
||||
virtual void onConnect(NimBLEClient *pClient); // = 0;
|
||||
virtual void onDisconnect(NimBLEClient *pClient); // = 0;
|
||||
virtual uint32_t onPassKeyRequest(); //{return 0;}
|
||||
virtual void onPassKeyNotify(uint32_t pass_key); //{}
|
||||
virtual bool onSecurityRequest(); //{return false;}
|
||||
virtual void onAuthenticationComplete(ble_gap_conn_desc*); //{};
|
||||
virtual bool onConfirmPIN(uint32_t pin); //{return false;}
|
||||
virtual void onConnect(NimBLEClient* pClient);
|
||||
virtual void onDisconnect(NimBLEClient* pClient);
|
||||
virtual bool onConnParamsUpdateRequest(NimBLEClient* pClient, const ble_gap_upd_params* params);
|
||||
virtual uint32_t onPassKeyRequest();
|
||||
virtual void onPassKeyNotify(uint32_t pass_key);
|
||||
virtual bool onSecurityRequest();
|
||||
virtual void onAuthenticationComplete(ble_gap_conn_desc* desc);
|
||||
virtual bool onConfirmPIN(uint32_t pin);
|
||||
};
|
||||
|
||||
#endif // CONFIG_BT_ENABLED
|
||||
|
|
|
@ -239,17 +239,41 @@ void NimBLEDevice::stopAdvertising() {
|
|||
* * ESP_PWR_LVL_P9 = 7, !< Corresponding to +9dbm
|
||||
* @param [in] powerLevel.
|
||||
*/
|
||||
/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d", powerLevel);
|
||||
esp_err_t errRc = ::esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, powerLevel);
|
||||
/* STATIC */ void NimBLEDevice::setPower(esp_power_level_t powerLevel, esp_ble_power_type_t powerType) {
|
||||
NIMBLE_LOGD(LOG_TAG, ">> setPower: %d (type: %d)", powerLevel, powerType);
|
||||
esp_err_t errRc = esp_ble_tx_power_set(powerType, powerLevel);
|
||||
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_LOGD(LOG_TAG, "<< 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.
|
||||
* @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) {
|
||||
(*it)->onHostReset();
|
||||
}
|
||||
|
||||
*/
|
||||
if(m_bleAdvertising != nullptr) {
|
||||
m_bleAdvertising->onHostReset();
|
||||
}
|
||||
*/
|
||||
|
||||
NIMBLE_LOGC(LOG_TAG, "Resetting state; reason=%d, %s", reason,
|
||||
NimBLEUtils::returnCodeToString(reason));
|
||||
} // onReset
|
||||
|
@ -414,7 +438,7 @@ void NimBLEDevice::stopAdvertising() {
|
|||
ble_hs_cfg.sync_cb = NimBLEDevice::onSync;
|
||||
|
||||
// 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_mitm = 0;
|
||||
ble_hs_cfg.sm_sc = 1;
|
||||
|
|
|
@ -59,7 +59,11 @@
|
|||
#define BLEEddystoneTLM NimBLEEddystoneTLM
|
||||
#define BLEEddystoneURL NimBLEEddystoneURL
|
||||
|
||||
#ifdef 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.
|
||||
|
@ -81,7 +85,8 @@ public:
|
|||
static NimBLEClient* createClient();
|
||||
static NimBLEServer* createServer();
|
||||
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 setSecurityAuth(bool bonding, bool mitm, bool sc);
|
||||
static void setSecurityAuth(uint8_t auth_req);
|
||||
|
@ -110,6 +115,7 @@ private:
|
|||
friend class NimBLEClient;
|
||||
friend class NimBLEScan;
|
||||
friend class NimBLEAdvertising;
|
||||
friend class NimBLECharacteristic;
|
||||
|
||||
static void onReset(int reason);
|
||||
static void onSync(void);
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
// 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.
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
#ifndef CORE_DEBUG_LEVEL
|
||||
#define CORE_DEBUG_LEVEL CONFIG_ARDUHAL_LOG_DEFAULT_LEVEL
|
||||
#endif
|
||||
|
||||
#if CORE_DEBUG_LEVEL >= 4
|
||||
#define NIMBLE_LOGD( tag, format, ... ) MODLOG_DFLT(ERROR, "D %s: "#format"\n",tag,##__VA_ARGS__)
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
#if defined(CONFIG_BT_ENABLED)
|
||||
|
||||
#include "NimBLERemoteCharacteristic.h"
|
||||
|
||||
#include <esp_err.h>
|
||||
#include "NimBLEUtils.h"
|
||||
#include "NimBLELog.h"
|
||||
|
||||
|
@ -321,6 +319,7 @@ std::string NimBLERemoteCharacteristic::readValue() {
|
|||
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
|
||||
NimBLEClient* pClient = getRemoteService()->getClient();
|
||||
|
||||
// Check to see that we are connected.
|
||||
|
@ -334,15 +333,18 @@ std::string NimBLERemoteCharacteristic::readValue() {
|
|||
|
||||
rc = ble_gattc_read(pClient->getConnId(), m_handle,
|
||||
NimBLERemoteCharacteristic::onReadCB, this);
|
||||
|
||||
// long read experiment
|
||||
/* rc = ble_gattc_read_long(pClient->getConnId(), m_handle, 0,
|
||||
NimBLERemoteCharacteristic::onReadCB, this);
|
||||
*/
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to read characteristic; rc=%d", rc);
|
||||
//goto err;
|
||||
m_semaphoreReadCharEvt.give();
|
||||
return "";
|
||||
}
|
||||
|
||||
rc = m_semaphoreReadCharEvt.wait("readValue");
|
||||
|
||||
switch(rc){
|
||||
case 0:
|
||||
break;
|
||||
|
@ -377,8 +379,13 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
|||
if(characteristic->getRemoteService()->getClient()->getConnId() != conn_handle){
|
||||
return 0;
|
||||
}
|
||||
|
||||
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) {
|
||||
free(characteristic->m_rawData);
|
||||
|
@ -386,16 +393,17 @@ int NimBLERemoteCharacteristic::onReadCB(uint16_t conn_handle,
|
|||
|
||||
if (error->status == 0) {
|
||||
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));
|
||||
memcpy(characteristic->m_rawData, attr->om->om_data, attr->om->om_len);
|
||||
characteristic->m_semaphoreReadCharEvt.give(0);
|
||||
} else {
|
||||
characteristic->m_rawData = nullptr;
|
||||
characteristic->m_value = "";
|
||||
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();
|
||||
int rc = 0;
|
||||
int retryCount = 1;
|
||||
// uint16_t mtu;
|
||||
|
||||
// Check to see that we are connected.
|
||||
if (!pClient->isConnected()) {
|
||||
|
@ -522,18 +531,29 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r
|
|||
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);
|
||||
return (rc==0);
|
||||
}
|
||||
|
||||
do {
|
||||
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,
|
||||
data, length,
|
||||
NimBLERemoteCharacteristic::onWriteCB,
|
||||
this);;
|
||||
this);
|
||||
// }
|
||||
if (rc != 0) {
|
||||
NIMBLE_LOGE(LOG_TAG, "Error: Failed to write characteristic; rc=%d", rc);
|
||||
m_semaphoreWriteCharEvt.give();
|
||||
|
@ -558,7 +578,7 @@ bool NimBLERemoteCharacteristic::writeValue(uint8_t* data, size_t length, bool r
|
|||
} while(rc != 0 && retryCount--);
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< writeValue, rc: %d",rc);
|
||||
return (rc == 0); //true;
|
||||
return (rc == 0);
|
||||
} // writeValue
|
||||
|
||||
|
||||
|
@ -587,7 +607,7 @@ int NimBLERemoteCharacteristic::onWriteCB(uint16_t conn_handle,
|
|||
characteristic->m_semaphoreWriteCharEvt.give(error->status);
|
||||
}
|
||||
|
||||
return error->status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -231,14 +231,18 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
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(!m_stopped || ble_gap_disc_active()) { // double check - can cause host reset.
|
||||
NIMBLE_LOGE(LOG_TAG, "Scan already in progress");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stopped = false;
|
||||
|
||||
m_stopped = false;
|
||||
m_semaphoreScanEnd.take("start");
|
||||
|
||||
// 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;
|
||||
|
||||
do{
|
||||
rc = ble_gap_disc(m_own_addr_type, duration, &m_scan_params,
|
||||
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",
|
||||
rc, NimBLEUtils::returnCodeToString(rc));
|
||||
m_stopped = true;
|
||||
|
@ -275,8 +281,6 @@ bool NimBLEScan::start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResul
|
|||
return false;
|
||||
}
|
||||
|
||||
// m_stopped = false;
|
||||
|
||||
NIMBLE_LOGD(LOG_TAG, "<< start()");
|
||||
return true;
|
||||
} // start
|
||||
|
|
|
@ -137,7 +137,7 @@ void NimBLEServer::start() {
|
|||
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();
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue