From 53c8addc696da31496e32949d0c642d1be0a0b42 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Fri, 8 Sep 2017 08:46:37 -0600 Subject: [PATCH 1/2] Add ability to update connection params after connect --- src/BLEDevice.h | 2 ++ src/BLEPeripheral.cpp | 16 ++++++++++++++++ src/BLEPeripheral.h | 7 +++++-- src/nRF51822.cpp | 25 +++++++++++++++++-------- src/nRF51822.h | 2 ++ src/nRF8001.cpp | 9 +++++++++ src/nRF8001.h | 2 ++ 7 files changed, 53 insertions(+), 10 deletions(-) diff --git a/src/BLEDevice.h b/src/BLEDevice.h index fb38781..b9e5b37 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -27,6 +27,7 @@ class BLEDeviceEventListener virtual void BLEDeviceDisconnected(BLEDevice& /*device*/) { } virtual void BLEDeviceBonded(BLEDevice& /*device*/) { } virtual void BLEDeviceRemoteServicesDiscovered(BLEDevice& /*device*/) { } + virtual void BLEDeviceConnectionParamsUpdated(BLEDevice& /*device*/) { } virtual void BLEDeviceCharacteristicValueChanged(BLEDevice& /*device*/, BLECharacteristic& /*characteristic*/, const unsigned char* /*value*/, unsigned char /*valueLength*/) { } virtual void BLEDeviceCharacteristicSubscribedChanged(BLEDevice& /*device*/, BLECharacteristic& /*characteristic*/, bool /*subscribed*/) { } @@ -53,6 +54,7 @@ class BLEDevice void setAdvertisingInterval(unsigned short advertisingInterval); void setConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval); + virtual void updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval) { } void setConnectable(bool connectable); void setBondStore(BLEBondStore& bondStore); diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index a730a81..df0e5b8 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -241,6 +241,10 @@ void BLEPeripheral::setConnectionInterval(unsigned short minimumConnectionInterv this->_device->setConnectionInterval(minimumConnectionInterval, maximumConnectionInterval); } +void BLEPeripheral::updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval) { + this->_device->updateConnectionInterval(minimumConnectionInterval, maximumConnectionInterval); +} + void BLEPeripheral::disconnect() { this->_device->disconnect(); } @@ -363,6 +367,18 @@ void BLEPeripheral::BLEDeviceRemoteServicesDiscovered(BLEDevice& /*device*/) { } } +void BLEPeripheral::BLEDeviceConnectionParamsUpdated(BLEDevice& /*device*/) { +#ifdef BLE_PERIPHERAL_DEBUG + Serial.print(F("Updated connection parameters from central: ")); + Serial.println(this->_central.address()); +#endif + + BLEPeripheralEventHandler eventHandler = this->_eventHandlers[BLEConnectionParamsUpdated]; + if (eventHandler) { + eventHandler(this->_central); + } +} + void BLEPeripheral::BLEDeviceCharacteristicValueChanged(BLEDevice& /*device*/, BLECharacteristic& characteristic, const unsigned char* value, unsigned char valueLength) { characteristic.setValue(this->_central, value, valueLength); } diff --git a/src/BLEPeripheral.h b/src/BLEPeripheral.h index 23293dd..8c2cf8f 100644 --- a/src/BLEPeripheral.h +++ b/src/BLEPeripheral.h @@ -44,7 +44,8 @@ enum BLEPeripheralEvent { BLEConnected = 0, BLEDisconnected = 1, BLEBonded = 2, - BLERemoteServicesDiscovered = 3 + BLERemoteServicesDiscovered = 3, + BLEConnectionParamsUpdated = 4 }; typedef void (*BLEPeripheralEventHandler)(BLECentral& central); @@ -71,6 +72,7 @@ class BLEPeripheral : public BLEDeviceEventListener, // connection intervals in 1.25 ms increments, // must be between 0x0006 (7.5 ms) and 0x0c80 (4 s), values outside of this range will be ignored void setConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval); + void updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval); bool setTxPower(int txPower); void setConnectable(bool connectable); void setBondStore(BLEBondStore& bondStore); @@ -109,6 +111,7 @@ class BLEPeripheral : public BLEDeviceEventListener, virtual void BLEDeviceDisconnected(BLEDevice& device); virtual void BLEDeviceBonded(BLEDevice& device); virtual void BLEDeviceRemoteServicesDiscovered(BLEDevice& device); + virtual void BLEDeviceConnectionParamsUpdated(BLEDevice& device); virtual void BLEDeviceCharacteristicValueChanged(BLEDevice& device, BLECharacteristic& characteristic, const unsigned char* value, unsigned char valueLength); virtual void BLEDeviceCharacteristicSubscribedChanged(BLEDevice& device, BLECharacteristic& characteristic, bool subscribed); @@ -152,7 +155,7 @@ class BLEPeripheral : public BLEDeviceEventListener, BLERemoteCharacteristic _remoteServicesChangedCharacteristic; BLECentral _central; - BLEPeripheralEventHandler _eventHandlers[4]; + BLEPeripheralEventHandler _eventHandlers[5]; }; #endif diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 2929205..94e8519 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -558,14 +558,7 @@ void nRF51822::poll() { if (this->_minimumConnectionInterval >= BLE_GAP_CP_MIN_CONN_INTVL_MIN && this->_maximumConnectionInterval <= BLE_GAP_CP_MAX_CONN_INTVL_MAX) { - ble_gap_conn_params_t gap_conn_params; - - gap_conn_params.min_conn_interval = this->_minimumConnectionInterval; // in 1.25ms units - gap_conn_params.max_conn_interval = this->_maximumConnectionInterval; // in 1.25ms unit - gap_conn_params.slave_latency = 0; - gap_conn_params.conn_sup_timeout = 4000 / 10; // in 10ms unit - - sd_ble_gap_conn_param_update(this->_connectionHandle, &gap_conn_params); + updateConnectionInterval(this->_minimumConnectionInterval, this->_maximumConnectionInterval); } if (this->_numRemoteServices > 0) { @@ -624,6 +617,9 @@ void nRF51822::poll() { Serial.print(bleEvt->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout, HEX); Serial.println(); #endif + if (this->_eventListener) { + this->_eventListener->BLEDeviceConnectionParamsUpdated(*this); + } break; case BLE_GAP_EVT_SEC_PARAMS_REQUEST: @@ -1035,6 +1031,19 @@ void nRF51822::end() { this->_numRemoteCharacteristics = 0; } +void nRF51822::updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval) { + setConnectionInterval(minimumConnectionInterval, maximumConnectionInterval); + + ble_gap_conn_params_t gap_conn_params; + + gap_conn_params.min_conn_interval = this->_minimumConnectionInterval; // in 1.25ms units + gap_conn_params.max_conn_interval = this->_maximumConnectionInterval; // in 1.25ms unit + gap_conn_params.slave_latency = 0; + gap_conn_params.conn_sup_timeout = 4000 / 10; // in 10ms unit + + sd_ble_gap_conn_param_update(this->_connectionHandle, &gap_conn_params); +} + bool nRF51822::updateCharacteristicValue(BLECharacteristic& characteristic) { bool success = true; diff --git a/src/nRF51822.h b/src/nRF51822.h index f3b09dc..3ec87a2 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -52,6 +52,8 @@ class nRF51822 : public BLEDevice virtual ~nRF51822(); + virtual void updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval); + virtual void begin(unsigned char advertisementDataSize, BLEEirData *advertisementData, unsigned char scanDataSize, diff --git a/src/nRF8001.cpp b/src/nRF8001.cpp index a82d7d2..102f7c3 100644 --- a/src/nRF8001.cpp +++ b/src/nRF8001.cpp @@ -1057,6 +1057,9 @@ void nRF8001::poll() { Serial.print(F("Timing change received conn Interval: 0x")); Serial.println(aciEvt->params.timing.conn_rf_interval, HEX); #endif + if (this->_eventListener) { + this->_eventListener->BLEDeviceConnectionParamsUpdated(*this); + } break; case ACI_EVT_DISCONNECTED: @@ -1208,6 +1211,12 @@ void nRF8001::end() { this->_numRemotePipeInfo = 0; } +void nRF8001::updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval) { + setConnectionInterval(minimumConnectionInterval, maximumConnectionInterval); + + lib_aci_change_timing(this->_minimumConnectionInterval, this->_maximumConnectionInterval, 0, 4000 / 10); +} + bool nRF8001::updateCharacteristicValue(BLECharacteristic& characteristic) { bool success = true; diff --git a/src/nRF8001.h b/src/nRF8001.h index 9db02fe..47d1f0d 100644 --- a/src/nRF8001.h +++ b/src/nRF8001.h @@ -46,6 +46,8 @@ class nRF8001 : protected BLEDevice virtual ~nRF8001(); + virtual void updateConnectionInterval(unsigned short minimumConnectionInterval, unsigned short maximumConnectionInterval); + virtual void begin(unsigned char advertisementDataSize, BLEEirData *advertisementData, unsigned char scanDataSize, From e6117755e841db643211a1836d16565eacbee4a1 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Sun, 10 Sep 2017 06:54:00 -0600 Subject: [PATCH 2/2] Fix indication deadlock --- src/nRF51822.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 94e8519..3d512a0 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -1081,15 +1081,9 @@ bool nRF51822::updateCharacteristicValue(BLECharacteristic& characteristic) { } if (localCharacteristicInfo->indicateSubscribed) { - if (this->_txBufferCount > 0) { - this->_txBufferCount--; + hvxParams.type = BLE_GATT_HVX_INDICATION; - hvxParams.type = BLE_GATT_HVX_INDICATION; - - sd_ble_gatts_hvx(this->_connectionHandle, &hvxParams); - } else { - success = false; - } + success = sd_ble_gatts_hvx(this->_connectionHandle, &hvxParams) == NRF_SUCCESS; } } } @@ -1140,7 +1134,7 @@ bool nRF51822::canNotifyCharacteristic(BLECharacteristic& /*characteristic*/) { } bool nRF51822::canIndicateCharacteristic(BLECharacteristic& /*characteristic*/) { - return (this->_txBufferCount > 0); + return true; } bool nRF51822::canReadRemoteCharacteristic(BLERemoteCharacteristic& characteristic) {