From a4f2f9628722f3867270813dc91bd0c94c950899 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Fri, 19 May 2017 15:10:11 +0200 Subject: [PATCH 01/16] add a bunch of hackish (but working) observer role functions --- src/BLEDevice.h | 3 +++ src/BLEPeripheral.cpp | 16 ++++++++++++++++ src/BLEPeripheral.h | 4 ++++ src/nRF51822.cpp | 38 +++++++++++++++++++++++++++++++++++++- src/nRF51822.h | 3 +++ 5 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/BLEDevice.h b/src/BLEDevice.h index fb38781..0de2533 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -72,6 +72,9 @@ class BLEDevice virtual bool setTxPower(int /*txPower*/) { return false; } virtual void startAdvertising() { } + virtual void stopAdvertising() { } + virtual void startScanning() { } + virtual void stopScanning() { } virtual void disconnect() { } virtual bool updateCharacteristicValue(BLECharacteristic& /*characteristic*/) { return false; } diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index a730a81..1771ed1 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -203,6 +203,22 @@ void BLEPeripheral::setBondStore(BLEBondStore& bondStore) { this->_device->setBondStore(bondStore); } +void BLEPeripheral::startAdvertising() { + this->_device->startAdvertising(); +} + +void BLEPeripheral::stopAdvertising() { + this->_device->stopAdvertising(); +} + +void BLEPeripheral::startScanning() { + this->_device->startScanning(); +} + +void BLEPeripheral::stopScanning() { + this->_device->stopScanning(); +} + void BLEPeripheral::setDeviceName(const char* deviceName) { this->_deviceNameCharacteristic.setValue(deviceName); } diff --git a/src/BLEPeripheral.h b/src/BLEPeripheral.h index e9e8705..496309f 100644 --- a/src/BLEPeripheral.h +++ b/src/BLEPeripheral.h @@ -80,6 +80,10 @@ class BLEPeripheral : public BLEDeviceEventListener, void setConnectable(bool connectable); void setBondStore(BLEBondStore& bondStore); + void startAdvertising(); + void stopAdvertising(); + void startScanning(); + void stopScanning(); void setDeviceName(const char* deviceName); void setAppearance(unsigned short appearance); diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index cfebb80..3ca1a7c 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -502,7 +502,7 @@ void nRF51822::begin(unsigned char advertisementDataSize, #endif } - this->startAdvertising(); + //this->startAdvertising(); #ifdef __RFduino__ RFduinoBLE_enabled = 1; @@ -516,6 +516,14 @@ void nRF51822::poll() { if (sd_ble_evt_get((uint8_t*)evtBuf, &evtLen) == NRF_SUCCESS) { switch (bleEvt->header.evt_id) { + case BLE_GAP_EVT_ADV_REPORT: +//#ifdef NRF_51822_DEBUG + Serial.print(F("Evt Adv Report, dlen = ")); + Serial.println(bleEvt->evt.gap_evt.params.adv_report.dlen); +//#endif + //this->_scanResult = &(bleEvt->evt.gap_evt.params.adv_report); + break; + case BLE_EVT_TX_COMPLETE: #ifdef NRF_51822_DEBUG Serial.print(F("Evt TX complete ")); @@ -1338,6 +1346,34 @@ void nRF51822::startAdvertising() { sd_ble_gap_adv_start(&advertisingParameters); } +void nRF51822::stopAdvertising() { + sd_ble_gap_adv_stop(); +} + +void nRF51822::startScanning() { +#ifdef NRF_51822_DEBUG + Serial.println(F("Start scanning")); +#endif + + // see https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s130.api.v2.0.1%2Fstructble__gap__scan__params__t.html + ble_gap_scan_params_t scanParameters; + + memset(&scanParameters, 0x00, sizeof(scanParameters)); + + scanParameters.active = 1; // send scan requests + scanParameters.interval = 0x40; // 40 ms in units of 0.625 ms + scanParameters.p_whitelist = NULL; // no whitelist + scanParameters.selective = 0; + scanParameters.timeout = 10; // 10 seconds timeout + scanParameters.window = 0x20; // 20 ms + + sd_ble_gap_scan_start(&scanParameters); +} + +void nRF51822::stopScanning() { + sd_ble_gap_scan_stop(); +} + void nRF51822::disconnect() { sd_ble_gap_disconnect(this->_connectionHandle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); } diff --git a/src/nRF51822.h b/src/nRF51822.h index f3b09dc..4eda4fb 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -67,6 +67,9 @@ class nRF51822 : public BLEDevice virtual bool setTxPower(int txPower); virtual void startAdvertising(); + virtual void stopAdvertising(); + virtual void startScanning(); + virtual void stopScanning(); virtual void disconnect(); virtual bool updateCharacteristicValue(BLECharacteristic& characteristic); From 9a963a7d9f10853605f3b168459a8051d1c15a16 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Tue, 23 May 2017 11:35:10 +0200 Subject: [PATCH 02/16] use proper adv data type when non-connectable, but scan data present --- src/nRF51822.cpp | 4 +++- src/nRF51822.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index cfebb80..174a03b 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -47,6 +47,7 @@ nRF51822::nRF51822() : BLEDevice(), _advDataLen(0), + _hasScanData(false), _broadcastCharacteristic(NULL), _connectionHandle(BLE_CONN_HANDLE_INVALID), @@ -215,6 +216,7 @@ void nRF51822::begin(unsigned char advertisementDataSize, memcpy(&srData[srDataLen], scanData[i].data, scanData[i].length); srDataLen += scanData[i].length; + _hasScanData = true; } } @@ -1328,7 +1330,7 @@ void nRF51822::startAdvertising() { memset(&advertisingParameters, 0x00, sizeof(advertisingParameters)); - advertisingParameters.type = this->_connectable ? BLE_GAP_ADV_TYPE_ADV_IND : BLE_GAP_ADV_TYPE_ADV_NONCONN_IND; + advertisingParameters.type = this->_connectable ? BLE_GAP_ADV_TYPE_ADV_IND : ( this->_hasScanData ? BLE_GAP_ADV_TYPE_ADV_SCAN_IND : BLE_GAP_ADV_TYPE_ADV_NONCONN_IND ); advertisingParameters.p_peer_addr = NULL; advertisingParameters.fp = BLE_GAP_ADV_FP_ANY; advertisingParameters.p_whitelist = NULL; diff --git a/src/nRF51822.h b/src/nRF51822.h index f3b09dc..3c66036 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -91,6 +91,7 @@ class nRF51822 : public BLEDevice unsigned char _advData[31]; unsigned char _advDataLen; + bool _hasScanData; BLECharacteristic* _broadcastCharacteristic; uint16_t _connectionHandle; From 6d937a0d10c391c2f53bb1671b66cbdb09a844d7 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Tue, 23 May 2017 11:47:09 +0200 Subject: [PATCH 03/16] add local scan response pointer --- src/nRF51822.cpp | 23 +++++++++++++++-------- src/nRF51822.h | 1 + 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 38c7fb1..ce4397b 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -48,6 +48,7 @@ nRF51822::nRF51822() : _advDataLen(0), _hasScanData(false), + _scanResult(NULL), _broadcastCharacteristic(NULL), _connectionHandle(BLE_CONN_HANDLE_INVALID), @@ -520,10 +521,12 @@ void nRF51822::poll() { switch (bleEvt->header.evt_id) { case BLE_GAP_EVT_ADV_REPORT: //#ifdef NRF_51822_DEBUG - Serial.print(F("Evt Adv Report, dlen = ")); - Serial.println(bleEvt->evt.gap_evt.params.adv_report.dlen); + char address[18]; + BLEUtil::addressToString(bleEvt->evt.gap_evt.params.adv_report.peer_addr.addr, address); + Serial.print(F("Evt Adv Report ")); + Serial.println(address); //#endif - //this->_scanResult = &(bleEvt->evt.gap_evt.params.adv_report); + this->_scanResult = &(bleEvt->evt.gap_evt.params.adv_report); break; case BLE_EVT_TX_COMPLETE: @@ -1021,6 +1024,10 @@ void nRF51822::poll() { // sd_app_evt_wait(); } +/*uint8_t* nRF51822::getScanResult() { + return _scanResult->data; +}*/ + void nRF51822::end() { sd_softdevice_disable(); @@ -1362,12 +1369,12 @@ void nRF51822::startScanning() { memset(&scanParameters, 0x00, sizeof(scanParameters)); - scanParameters.active = 1; // send scan requests - scanParameters.interval = 0x40; // 40 ms in units of 0.625 ms - scanParameters.p_whitelist = NULL; // no whitelist + scanParameters.active = 1; // send scan requests + scanParameters.interval = 0x140; // 200 ms in units of 0.625 ms + scanParameters.p_whitelist = NULL; // no whitelist scanParameters.selective = 0; - scanParameters.timeout = 10; // 10 seconds timeout - scanParameters.window = 0x20; // 20 ms + scanParameters.timeout = 10; // 10 seconds timeout + scanParameters.window = 0xA0; // 100 ms sd_ble_gap_scan_start(&scanParameters); } diff --git a/src/nRF51822.h b/src/nRF51822.h index 2c3f4bf..c9c6658 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -95,6 +95,7 @@ class nRF51822 : public BLEDevice unsigned char _advData[31]; unsigned char _advDataLen; bool _hasScanData; + ble_gap_evt_adv_report_t* _scanResult; BLECharacteristic* _broadcastCharacteristic; uint16_t _connectionHandle; From 7fd029e4cbcf908b506bae2dea25ad31092a3e09 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Tue, 23 May 2017 22:07:55 +0200 Subject: [PATCH 04/16] fix rfduino build --- src/nRF51822.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index ce4397b..1bb9ab9 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -519,6 +519,7 @@ void nRF51822::poll() { if (sd_ble_evt_get((uint8_t*)evtBuf, &evtLen) == NRF_SUCCESS) { switch (bleEvt->header.evt_id) { +#ifndef __RFduino__ case BLE_GAP_EVT_ADV_REPORT: //#ifdef NRF_51822_DEBUG char address[18]; @@ -528,6 +529,7 @@ void nRF51822::poll() { //#endif this->_scanResult = &(bleEvt->evt.gap_evt.params.adv_report); break; +#endif case BLE_EVT_TX_COMPLETE: #ifdef NRF_51822_DEBUG @@ -1364,6 +1366,7 @@ void nRF51822::startScanning() { Serial.println(F("Start scanning")); #endif +#ifndef __RFduino__ // see https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.s130.api.v2.0.1%2Fstructble__gap__scan__params__t.html ble_gap_scan_params_t scanParameters; @@ -1377,10 +1380,13 @@ void nRF51822::startScanning() { scanParameters.window = 0xA0; // 100 ms sd_ble_gap_scan_start(&scanParameters); +#endif } void nRF51822::stopScanning() { +#ifndef __RFduino__ sd_ble_gap_scan_stop(); +#endif } void nRF51822::disconnect() { From 7c93bbf07405341f2c790274a306fa42b8b2f3c4 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Wed, 9 Aug 2017 11:45:05 +0200 Subject: [PATCH 05/16] don't change default advertising behaviour --- src/nRF51822.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 1bb9ab9..ea22bce 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -505,7 +505,7 @@ void nRF51822::begin(unsigned char advertisementDataSize, #endif } - //this->startAdvertising(); + this->startAdvertising(); #ifdef __RFduino__ RFduinoBLE_enabled = 1; From 6f033c677c364ee246b2b18b8d286ae1abd2108d Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 23 Oct 2017 12:09:37 +0200 Subject: [PATCH 06/16] minor refactoring to prepare for advertisement updates --- src/BLEPeripheral.cpp | 11 +++++++---- src/BLEPeripheral.h | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index 1771ed1..1390197 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -68,12 +68,9 @@ BLEPeripheral::~BLEPeripheral() { } } -void BLEPeripheral::begin() { +unsigned char BLEPeripheral::updateAdvertismentData() { unsigned char advertisementDataSize = 0; - BLEEirData advertisementData[3]; - BLEEirData scanData; - scanData.length = 0; unsigned char remainingAdvertisementDataLength = BLE_ADVERTISEMENT_DATA_MAX_VALUE_LENGTH + 2; @@ -131,6 +128,11 @@ void BLEPeripheral::begin() { memcpy(scanData.data, this->_localName, scanData.length); } + return advertisementDataSize; +} + +void BLEPeripheral::begin() { + if (this->_localAttributes == NULL) { this->initLocalAttributes(); } @@ -158,6 +160,7 @@ void BLEPeripheral::begin() { this->addRemoteAttribute(this->_remoteServicesChangedCharacteristic); } + int advertisementDataSize = updateAdvertismentData(); this->_device->begin(advertisementDataSize, advertisementData, scanData.length > 0 ? 1 : 0, &scanData, this->_localAttributes, this->_numLocalAttributes, diff --git a/src/BLEPeripheral.h b/src/BLEPeripheral.h index 496309f..74758d5 100644 --- a/src/BLEPeripheral.h +++ b/src/BLEPeripheral.h @@ -130,6 +130,7 @@ class BLEPeripheral : public BLEDeviceEventListener, private: void initLocalAttributes(); + unsigned char updateAdvertismentData(); private: BLEDevice* _device; @@ -162,6 +163,9 @@ class BLEPeripheral : public BLEDeviceEventListener, BLECentral _central; BLEPeripheralEventHandler _eventHandlers[4]; + + BLEEirData advertisementData[3]; + BLEEirData scanData; }; #endif From 4563b1314fe17a70820e9375b87061aab2748eee Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 23 Oct 2017 13:05:09 +0200 Subject: [PATCH 07/16] refactor advertisements, part 2 --- src/nRF51822.cpp | 85 ++++++++++++++++++++++++++---------------------- src/nRF51822.h | 5 +++ 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 14541b0..01218ea 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -82,6 +82,52 @@ nRF51822::~nRF51822() { this->end(); } +void nRF51822::updateAdvertisementData(unsigned char advertisementDataSize, + BLEEirData *advertisementData, + unsigned char scanDataSize, + BLEEirData *scanData) +{ + unsigned char srData[31]; + unsigned char srDataLen = 0; + + this->_advDataLen = 0; + + // flags + this->_advData[this->_advDataLen + 0] = 2; + this->_advData[this->_advDataLen + 1] = 0x01; + this->_advData[this->_advDataLen + 2] = 0x06; + + this->_advDataLen += 3; + + if (advertisementDataSize && advertisementData) { + for (int i = 0; i < advertisementDataSize; i++) { + this->_advData[this->_advDataLen + 0] = advertisementData[i].length + 1; + this->_advData[this->_advDataLen + 1] = advertisementData[i].type; + this->_advDataLen += 2; + + memcpy(&this->_advData[this->_advDataLen], advertisementData[i].data, advertisementData[i].length); + + this->_advDataLen += advertisementData[i].length; + } + } + + if (scanDataSize && scanData) { + for (int i = 0; i < scanDataSize; i++) { + srData[srDataLen + 0] = scanData[i].length + 1; + srData[srDataLen + 1] = scanData[i].type; + srDataLen += 2; + + memcpy(&srData[srDataLen], scanData[i].data, scanData[i].length); + + srDataLen += scanData[i].length; + _hasScanData = true; + } + } + + sd_ble_gap_adv_data_set(this->_advData, this->_advDataLen, srData, srDataLen); +} + + void nRF51822::begin(unsigned char advertisementDataSize, BLEEirData *advertisementData, unsigned char scanDataSize, @@ -188,44 +234,7 @@ void nRF51822::begin(unsigned char advertisementDataSize, sd_ble_gap_ppcp_set(&gap_conn_params); sd_ble_gap_tx_power_set(0); - unsigned char srData[31]; - unsigned char srDataLen = 0; - - this->_advDataLen = 0; - - // flags - this->_advData[this->_advDataLen + 0] = 2; - this->_advData[this->_advDataLen + 1] = 0x01; - this->_advData[this->_advDataLen + 2] = 0x06; - - this->_advDataLen += 3; - - if (advertisementDataSize && advertisementData) { - for (int i = 0; i < advertisementDataSize; i++) { - this->_advData[this->_advDataLen + 0] = advertisementData[i].length + 1; - this->_advData[this->_advDataLen + 1] = advertisementData[i].type; - this->_advDataLen += 2; - - memcpy(&this->_advData[this->_advDataLen], advertisementData[i].data, advertisementData[i].length); - - this->_advDataLen += advertisementData[i].length; - } - } - - if (scanDataSize && scanData) { - for (int i = 0; i < scanDataSize; i++) { - srData[srDataLen + 0] = scanData[i].length + 1; - srData[srDataLen + 1] = scanData[i].type; - srDataLen += 2; - - memcpy(&srData[srDataLen], scanData[i].data, scanData[i].length); - - srDataLen += scanData[i].length; - _hasScanData = true; - } - } - - sd_ble_gap_adv_data_set(this->_advData, this->_advDataLen, srData, srDataLen); + updateAdvertisementData(advertisementDataSize, advertisementData, scanDataSize, scanData); sd_ble_gap_appearance_set(0); for (int i = 0; i < numLocalAttributes; i++) { diff --git a/src/nRF51822.h b/src/nRF51822.h index c9c6658..f4ece67 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -61,6 +61,11 @@ class nRF51822 : public BLEDevice BLERemoteAttribute** remoteAttributes, unsigned char numRemoteAttributes); + virtual void updateAdvertisementData(unsigned char advertisementDataSize, + BLEEirData *advertisementData, + unsigned char scanDataSize, + BLEEirData *scanData); + virtual void poll(); virtual void end(); From 6868505c077f8e3c94b874fefd5fa54efd156a3f Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 23 Oct 2017 13:11:06 +0200 Subject: [PATCH 08/16] update advertising data when startAdvertising is called --- src/BLEDevice.h | 5 +++++ src/BLEPeripheral.cpp | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/BLEDevice.h b/src/BLEDevice.h index 0de2533..ac2f200 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -65,6 +65,11 @@ class BLEDevice BLERemoteAttribute** /*remoteAttributes*/, unsigned char /*numRemoteAttributes*/) { } + virtual void updateAdvertisementData(unsigned char /*advertisementDataSize*/, + BLEEirData * /*advertisementData*/, + unsigned char /*scanDataSize*/, + BLEEirData * /*scanData*/) { } + virtual void poll() { } virtual void end() { } diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index 1390197..d34cc45 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -207,6 +207,10 @@ void BLEPeripheral::setBondStore(BLEBondStore& bondStore) { } void BLEPeripheral::startAdvertising() { + int advertisementDataSize = updateAdvertismentData(); + this->_device->updateAdvertisementData( + advertisementDataSize, advertisementData, + scanData.length > 0 ? 1 : 0, &scanData); this->_device->startAdvertising(); } From c0b1aff6e9e37d108c99aed88632af0d7885c7a6 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 23 Oct 2017 14:28:35 +0200 Subject: [PATCH 09/16] first iteration for proper device event handlers --- src/BLEDevice.h | 1 + src/BLEPeripheral.cpp | 26 ++++++++++++++++++++++++-- src/BLEPeripheral.h | 10 ++++++++++ src/nRF51822.cpp | 11 ++++++----- src/nRF51822.h | 1 - 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/BLEDevice.h b/src/BLEDevice.h index ac2f200..5416e58 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -37,6 +37,7 @@ class BLEDeviceEventListener virtual void BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsigned char* /*address*/) { } virtual void BLEDeviceTemperatureReceived(BLEDevice& /*device*/, float /*temperature*/) { } virtual void BLEDeviceBatteryLevelReceived(BLEDevice& /*device*/, float /*batteryLevel*/) { } + virtual void BLEDeviceAdvertisementReceived(BLEDevice& /*device*/, const unsigned char* /*advertisement*/) { } }; diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index d34cc45..6ef2582 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -49,6 +49,7 @@ BLEPeripheral::BLEPeripheral(unsigned char req, unsigned char rdy, unsigned char #endif memset(this->_eventHandlers, 0x00, sizeof(this->_eventHandlers)); + memset(this->_deviceEvents, 0x00, sizeof(this->_deviceEvents)); this->setDeviceName(DEFAULT_DEVICE_NAME); this->setAppearance(DEFAULT_APPEARANCE); @@ -286,6 +287,12 @@ void BLEPeripheral::setEventHandler(BLEPeripheralEvent event, BLEPeripheralEvent } } +void BLEPeripheral::setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler) { + if (event < sizeof(this->_deviceEvents)) { + this->_deviceEvents[event] = eventHandler; + } +} + bool BLEPeripheral::characteristicValueChanged(BLECharacteristic& characteristic) { return this->_device->updateCharacteristicValue(characteristic); } @@ -409,10 +416,25 @@ void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsign #endif } -void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& /*device*/, float /*temperature*/) { +void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& device, float temperature) { + BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLETemperatureReceived]; + if (eventHandler) { + eventHandler(&temperature); + } } -void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& /*device*/, float /*batteryLevel*/) { +void BLEPeripheral::BLEDeviceBatteryLevelReceived(BLEDevice& device, float batteryLevel) { + BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEBatteryLevelReceived]; + if (eventHandler) { + eventHandler(&batteryLevel); + } +} + +void BLEPeripheral::BLEDeviceAdvertisementReceived(BLEDevice& device, const unsigned char* advertisement) { + BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEAdvertisementReceived]; + if (eventHandler) { + eventHandler(advertisement); + } } void BLEPeripheral::initLocalAttributes() { diff --git a/src/BLEPeripheral.h b/src/BLEPeripheral.h index 74758d5..a5e7958 100644 --- a/src/BLEPeripheral.h +++ b/src/BLEPeripheral.h @@ -54,6 +54,13 @@ enum BLEPeripheralEvent { typedef void (*BLEPeripheralEventHandler)(BLECentral& central); +enum BLEDeviceEvent { + BLETemperatureReceived = 0, + BLEBatteryLevelReceived = 1, + BLEAdvertisementReceived = 2 +}; + +typedef void (*BLEDeviceEventHandler)(const void* parameter); class BLEPeripheral : public BLEDeviceEventListener, public BLECharacteristicValueChangeListener, @@ -98,6 +105,7 @@ class BLEPeripheral : public BLEDeviceEventListener, bool connected(); void setEventHandler(BLEPeripheralEvent event, BLEPeripheralEventHandler eventHandler); + void setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler); protected: bool characteristicValueChanged(BLECharacteristic& characteristic); @@ -127,6 +135,7 @@ class BLEPeripheral : public BLEDeviceEventListener, virtual void BLEDeviceAddressReceived(BLEDevice& device, const unsigned char* address); virtual void BLEDeviceTemperatureReceived(BLEDevice& device, float temperature); virtual void BLEDeviceBatteryLevelReceived(BLEDevice& device, float batteryLevel); + virtual void BLEDeviceAdvertisementReceived(BLEDevice& device, const unsigned char* advertisement); private: void initLocalAttributes(); @@ -163,6 +172,7 @@ class BLEPeripheral : public BLEDeviceEventListener, BLECentral _central; BLEPeripheralEventHandler _eventHandlers[4]; + BLEDeviceEventHandler _deviceEvents[3]; BLEEirData advertisementData[3]; BLEEirData scanData; diff --git a/src/nRF51822.cpp b/src/nRF51822.cpp index 01218ea..27e1f79 100644 --- a/src/nRF51822.cpp +++ b/src/nRF51822.cpp @@ -52,7 +52,6 @@ nRF51822::nRF51822() : _advDataLen(0), _hasScanData(false), - _scanResult(NULL), _broadcastCharacteristic(NULL), _connectionHandle(BLE_CONN_HANDLE_INVALID), @@ -534,13 +533,15 @@ void nRF51822::poll() { switch (bleEvt->header.evt_id) { #ifndef __RFduino__ case BLE_GAP_EVT_ADV_REPORT: -//#ifdef NRF_51822_DEBUG +#ifdef NRF_51822_DEBUG char address[18]; BLEUtil::addressToString(bleEvt->evt.gap_evt.params.adv_report.peer_addr.addr, address); - Serial.print(F("Evt Adv Report ")); + Serial.print(F("Evt Adv Report from ")); Serial.println(address); -//#endif - this->_scanResult = &(bleEvt->evt.gap_evt.params.adv_report); +#endif + if (this->_eventListener) { + this->_eventListener->BLEDeviceAdvertisementReceived(*this, (const unsigned char*)&(bleEvt->evt.gap_evt.params.adv_report)); + } break; #endif diff --git a/src/nRF51822.h b/src/nRF51822.h index f4ece67..e19c543 100644 --- a/src/nRF51822.h +++ b/src/nRF51822.h @@ -100,7 +100,6 @@ class nRF51822 : public BLEDevice unsigned char _advData[31]; unsigned char _advDataLen; bool _hasScanData; - ble_gap_evt_adv_report_t* _scanResult; BLECharacteristic* _broadcastCharacteristic; uint16_t _connectionHandle; From 4820c0eafe9397043b5bbe52e3d29a8f7fb84614 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Thu, 7 Dec 2017 16:07:10 +0100 Subject: [PATCH 10/16] observer/advertiser example --- examples/observer/observer.ino | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 examples/observer/observer.ino diff --git a/examples/observer/observer.ino b/examples/observer/observer.ino new file mode 100644 index 0000000..6bb6081 --- /dev/null +++ b/examples/observer/observer.ino @@ -0,0 +1,50 @@ +// Copyright (c) Sandeep Mistry. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#define NRF51 +#undef __RFduino__ +// Import libraries (BLEPeripheral depends on SPI) +#include +#include +#include +#include + +//custom boards may override default pin definitions with BLEPeripheral(PIN_REQ, PIN_RDY, PIN_RST) +BLEPeripheral blePeripheral = BLEPeripheral(); + +void setup() { + Serial.begin(115200); +#if defined (__AVR_ATmega32U4__) + delay(5000); //5 seconds delay for enabling to see the start up comments on the serial board +#endif + + blePeripheral.setLocalName("foobaz"); // optional + + // begin initialization + blePeripheral.begin(); + blePeripheral.setConnectable(false); + blePeripheral.setAdvertisingInterval(500); + blePeripheral.startAdvertising(); + blePeripheral.setEventHandler(BLEAdvertisementReceived, advHandler); +} + +void advHandler(const void* adv) { + ble_gap_evt_adv_report_t* report = (ble_gap_evt_adv_report_t*)adv; + char address[18]; + BLEUtil::addressToString(report->peer_addr.addr, address); + Serial.print(F("Evt Adv Report from ")); + Serial.println(address); + Serial.print(F("got adv with payload ")); + Serial.println(report->dlen); +} + +void loop() { + if (Serial.available() > 0) { + Serial.read(); + Serial.println("start scanning"); + blePeripheral.startScanning(); + blePeripheral.setLocalName("foobarg"); // optional + blePeripheral.startAdvertising(); + } + blePeripheral.poll(); +} From 5bbabed435249b28c17d79779a535621cb498596 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 11 Dec 2017 14:46:42 +0100 Subject: [PATCH 11/16] add handler for local address --- src/BLEPeripheral.cpp | 6 +++++- src/BLEPeripheral.h | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/BLEPeripheral.cpp b/src/BLEPeripheral.cpp index 6ef2582..ff46b41 100644 --- a/src/BLEPeripheral.cpp +++ b/src/BLEPeripheral.cpp @@ -405,7 +405,7 @@ void BLEPeripheral::BLEDeviceRemoteCharacteristicValueChanged(BLEDevice& /*devic remoteCharacteristic.setValue(this->_central, value, valueLength); } -void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsigned char* /*address*/) { +void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& device, const unsigned char* address) { #ifdef BLE_PERIPHERAL_DEBUG char addressStr[18]; @@ -414,6 +414,10 @@ void BLEPeripheral::BLEDeviceAddressReceived(BLEDevice& /*device*/, const unsign Serial.print(F("Peripheral address: ")); Serial.println(addressStr); #endif + BLEDeviceEventHandler eventHandler = this->_deviceEvents[BLEAddressReceived]; + if (eventHandler) { + eventHandler(address); + } } void BLEPeripheral::BLEDeviceTemperatureReceived(BLEDevice& device, float temperature) { diff --git a/src/BLEPeripheral.h b/src/BLEPeripheral.h index a5e7958..5476576 100644 --- a/src/BLEPeripheral.h +++ b/src/BLEPeripheral.h @@ -57,7 +57,8 @@ typedef void (*BLEPeripheralEventHandler)(BLECentral& central); enum BLEDeviceEvent { BLETemperatureReceived = 0, BLEBatteryLevelReceived = 1, - BLEAdvertisementReceived = 2 + BLEAdvertisementReceived = 2, + BLEAddressReceived = 3 }; typedef void (*BLEDeviceEventHandler)(const void* parameter); From 9289b661166cbd274ed8ae74044b11cc9963afc4 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 11 Dec 2017 14:49:25 +0100 Subject: [PATCH 12/16] update example --- examples/observer/observer.ino | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/observer/observer.ino b/examples/observer/observer.ino index 6bb6081..2d52265 100644 --- a/examples/observer/observer.ino +++ b/examples/observer/observer.ino @@ -20,12 +20,22 @@ void setup() { blePeripheral.setLocalName("foobaz"); // optional + blePeripheral.setEventHandler(BLEAddressReceived, addrHandler); + blePeripheral.setEventHandler(BLEAdvertisementReceived, advHandler); + // begin initialization blePeripheral.begin(); blePeripheral.setConnectable(false); blePeripheral.setAdvertisingInterval(500); blePeripheral.startAdvertising(); - blePeripheral.setEventHandler(BLEAdvertisementReceived, advHandler); +} + +void addrHandler(const void* _addr) { + unsigned char* addr = (unsigned char*)_addr; + char address[18]; + BLEUtil::addressToString(addr, address); + Serial.print(F("Got own addr: ")); + Serial.println(address); } void advHandler(const void* adv) { From dcc385bb219731038ff225d246d32bbf54e49249 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 18 Dec 2017 19:27:00 +0100 Subject: [PATCH 13/16] Update library.properties --- library.properties | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library.properties b/library.properties index 186506f..0d3367d 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=BLEPeripheral +name=BLEPeripheralObserver version=0.4.0 -author=Sandeep Mistry -maintainer=Sandeep Mistry -sentence=An Arduino library for creating custom BLE peripherals. -paragraph=Supports nRF8001 and nRF51822 based boards/shields +author=Sandeep Mistry , Florian Echtler +maintainer=Florian Echtler +sentence=An Arduino library for creating custom BLE peripherals and observers. +paragraph=Supports nRF51 and nRF52 based boards category=Communication -url=https://github.com/sandeepmistry/arduino-BLEPeripheral +url=https://github.com/floe/BLEPeripheralObserver architectures=* includes=BLEPeripheral.h From f648e596c4781a865e88322cf18eaf3a13102667 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Mon, 18 Dec 2017 19:33:24 +0100 Subject: [PATCH 14/16] Update library.json --- library.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library.json b/library.json index 6c3adb6..bf9e753 100644 --- a/library.json +++ b/library.json @@ -1,13 +1,13 @@ { - "name": "BLEPeripheral", + "name": "BLEPeripheralObserver", "version": "0.4.0", - "keywords": "BLE, bluetooth, peripheral", - "description": "Arduino library for creating custom BLE peripherals. Supports nRF8001 and nRF51822 based boards/shields.", + "keywords": "BLE, bluetooth, peripheral, observer", + "description": "Arduino library for creating custom BLE peripherals. Supports nRF51 based boards.", "repository": { "type": "git", - "url": "https://github.com/sandeepmistry/arduino-BLEPeripheral.git" + "url": "https://github.com/floe/BLEPeripheralObserver.git" }, "frameworks": "arduino", - "platforms": "nordicnrf51, atmelavr, atmelsam, teensy" + "platforms": "nordicnrf51" } From 7f735eeb81e45cf4a91301372ff1d85db6191b1d Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Tue, 19 Dec 2017 11:06:43 +0100 Subject: [PATCH 15/16] Update README.md --- README.md | 77 ++++--------------------------------------------------- 1 file changed, 5 insertions(+), 72 deletions(-) diff --git a/README.md b/README.md index 3a5d934..3857f9c 100644 --- a/README.md +++ b/README.md @@ -3,34 +3,12 @@ [![Build Status](https://travis-ci.org/sandeepmistry/arduino-BLEPeripheral.svg?branch=master)](https://travis-ci.org/sandeepmistry/arduino-BLEPeripheral) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/sandeepmistry/arduino-BLEPeripheral?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -An [Arduino](http://arduino.cc) library for creating custom BLE peripherals with [Nordic Semiconductor](http://www.nordicsemi.com)'s [nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001) or [nR51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822). +An [Arduino](http://arduino.cc) library for creating custom BLE peripherals and observers with [Nordic Semiconductor](http://www.nordicsemi.com)'s [nR51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822). -Enables you to create more customized BLE Peripheral's compared to the basic UART most other Arduino BLE libraries provide. - -[nRFgo Studio](http://www.nordicsemi.com/chi/node_176/2.4GHz-RF/nRFgo-Studio) (and Windows) is not required when using the [nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001). +This is heavily based on @sandeepmistry's [arduino-BLEPeripheral](https://github.com/sandeepmistry/arduino-BLEPeripheral) library. This fork adds support for the observer role (i.e. receiving Bluetooth advertisements), but consequently can't support the nRF8001 anymore. ## Compatible Hardware -### [Nordic Semiconductor nRF8001](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF8001) - - * [Adafruit](http://www.adafruit.com) - * [Bluefruit LE - nRF8001 Breakout](http://www.adafruit.com/products/1697) - * [RedBearLab](http://redbearlab.com) - * [BLE Shield](http://redbearlab.com/bleshield/) - * [Blend Micro](http://redbearlab.com/blendmicro/) - * [Blend](http://redbearlab.com/blend/) - * [Femtoduino](http://www.femtoduino.com) - * [IMUduino BTLE](http://www.femtoduino.com/spex/imuduino-btle) - * [Olimex](https://www.olimex.com) - * [MOD-nRF8001](https://www.olimex.com/Products/Modules/RF/MOD-nRF8001/) - * [OLIMEXINO-NANO-BLE](https://www.olimex.com/Products/Duino/AVR/OLIMEXINO-NANO-BLE/) - * [Jaycon Systems](http://www.jayconsystems.com) - * [nRF8001 Bluetooth Breakout Board](http://www.jayconsystems.com/nrf8001-breakout-board.html) - * [TinyCircuits](https://www.tiny-circuits.com) - * [TinyShield Bluetooth Low Energy - Nordic](https://www.tiny-circuits.com/tiny-shield-bluetooth-low-energy-nordic.html) - -**Note:** Does not require use of [nRFgo Studio](http://www.nordicsemi.com/chi/node_176/2.4GHz-RF/nRFgo-Studio)! However, uses more code space. - ### [Nordic Semiconductor nRF51822](http://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822) * [RedBearLab](http://redbearlab.com) with [Arduino Add-on](https://github.com/RedBearLab/nRF51822-Arduino) @@ -44,39 +22,6 @@ Enables you to create more customized BLE Peripheral's compared to the basic UAR * Various, see [arduino-nRF5 supported boards](https://github.com/sandeepmistry/arduino-nRF5#supported-boards) via [nRF5 Arduino Add-on](https://github.com/sandeepmistry/arduino-nRF5) -#### Pinouts - -| Chip | Shield/Board | REQ Pin | RDY Pin | RST Pin | -| ---- | ------------ | ------- | ------- | ------- | -| nRF8001| -| | Bluefruit LE | 10 | 2 | 9 | -| | BLE Shield 1.x | 9 | 8 | UNUSED | -| | BLE Shield 2.x | 9 | 8 | UNUSED or 4/7 via jumper| -| | Blend | 9 | 8 | UNUSED or 4/5 via jumper | -| | Blend Micro | 6 | 7 | UNUSED or 4 | -| | IMUduino BTLE | 10 | 7 | 9 | -| | TinyShield Bluetooth Low Energy | 10 | 2 | 9 | -| nRF51822 | -| | RedBearLab nRF51822 | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) | -| | BLE Nano | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) | -| | RFduino | -1 (UNUSED) | -1 (UNUSED) | -1 (UNUSED) | - -## Compatible IDE's and MCU's - - * [Arduino IDE](http://arduino.cc/en/Main/Software#toc1) - * AVR (Uno, Lenoardo, Mega, etc.) - * SAM3X8E (Due) - * SAMD21G18A (Zero) - * [Teensy](https://www.pjrc.com/teensy/) (via [Teensyduino](https://www.pjrc.com/teensy/td_download.html)) - * 2.0 - * 3.0 - * 3.1 - * LC - -**Warning**: For more advanced sketches an MCU with more than 2kB of RAM and 32kB of flash space is recommended. Advance sketches include: - * Multiple services and characteristics - * HID API usage - ## Usage ### Download Library @@ -86,20 +31,20 @@ Enables you to create more customized BLE Peripheral's compared to the basic UAR #### Using the Arduino IDE Library Manager 1. Choose ```Sketch``` -> ```Include Library``` -> ```Manage Libraries...``` -2. Type ```BLEPeripheral``` into the search box. +2. Type ```BLEPeripheralObserver``` into the search box. 3. Click the row to select the library. 4. Click the ```Install``` button to install the library. #### Using Git ```sh cd ~/Documents/Arduino/libraries/ -git clone https://github.com/sandeepmistry/arduino-BLEPeripheral BLEPeripheral +git clone https://github.com/floe/BLEPeripheralObserver BLEPeripheralObserver ``` #### MPIDE ``` cd ~/Documents/mpide/libraries/ -git clone https://github.com/sandeepmistry/arduino-BLEPeripheral BLEPeripheral +git clone https://github.com/floe/BLEPeripheralObserver BLEPeripheralObserver ``` ### [arduino-nRF5x core](https://github.com/sandeepmistry/arduino-nRF5) users @@ -120,15 +65,3 @@ See [examples](examples) folder. ## License This libary is [licensed](LICENSE) under the [MIT Licence](http://en.wikipedia.org/wiki/MIT_License). - -## Useful Links - * [@lizardo](https://github.com/lizardo)'s [nRF8001 Experiments](https://github.com/lizardo/nrf8001) - * used as a starting point to reverse engineer the proprietary setup message format for the chips - * [@NordicSemiconductor](https://github.com/NordicSemiconductor)'s [ble-sdk-arduino](https://github.com/NordicSemiconductor/ble-sdk-arduino) - * Original Arduino SDK for nRF8001 - * [@guanix](https://github.com/guanix)'s [arduino-nrf8001](https://github.com/guanix/arduino-nrf8001) - * nRF8001 support for Arduino - - -[![Analytics](https://ga-beacon.appspot.com/UA-56089547-1/sandeepmistry/arduino-BLEPeripheral?pixel)](https://github.com/igrigorik/ga-beacon) - From 29b4b6db5655c0c60d45ad647d9044d1a01bc980 Mon Sep 17 00:00:00 2001 From: Florian Echtler Date: Tue, 27 Feb 2018 13:54:30 +0100 Subject: [PATCH 16/16] rename include --- library.properties | 2 +- src/BLEPeripheralObserver.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 src/BLEPeripheralObserver.h diff --git a/library.properties b/library.properties index 0d3367d..970c99c 100644 --- a/library.properties +++ b/library.properties @@ -7,4 +7,4 @@ paragraph=Supports nRF51 and nRF52 based boards category=Communication url=https://github.com/floe/BLEPeripheralObserver architectures=* -includes=BLEPeripheral.h +includes=BLEPeripheralObserver.h diff --git a/src/BLEPeripheralObserver.h b/src/BLEPeripheralObserver.h new file mode 100644 index 0000000..bddb52c --- /dev/null +++ b/src/BLEPeripheralObserver.h @@ -0,0 +1 @@ +#include "BLEPeripheral.h"