diff --git a/docs/api.md b/docs/api.md index 636fe52c..81c9623f 100644 --- a/docs/api.md +++ b/docs/api.md @@ -120,7 +120,7 @@ BLE.setEventHandler(eventType, callback) #### Parameters -- **eventType**: event type (BLEConnected, BLEDisconnected) +- **eventType**: event type (BLEConnected, BLEDisconnected, BLEDiscovered, BLEAdvertised) - **callback**: function to call when event occurs #### Returns Nothing. @@ -812,12 +812,14 @@ Start scanning for Bluetooth® Low Energy devices that are advertising. ``` BLE.scan() BLE.scan(withDuplicates) +BLE.scan(withDuplicates, activeScan) ``` #### Parameters - **withDuplicates:** optional, defaults to **false**. If **true**, advertisements received more than once will not be filtered +- **activeScan:** optional, defaults to **true**. If **true**, an active scan is performed. Otherwise a passive scan is performed. #### Returns - 1 on success, @@ -859,6 +861,7 @@ Start scanning for Bluetooth® Low Energy devices that are advertising with a pa ``` BLE.scanForName(name) BLE.scanForName(name, withDuplicates) +BLE.scanForName(name, withDuplicates, activeScan) ``` @@ -866,6 +869,8 @@ BLE.scanForName(name, withDuplicates) - **name:** (local) name of device (as a **String**) to filter for - **withDuplicates:** optional, defaults to **false**. If **true**, advertisements received more than once will not be filtered. +- **activeScan:** optional, defaults to **true**. If **true**, an active scan is performed. Otherwise a passive scan is performed. +Note that it is not common to include the name is a passive advertisement. For most device an active scan should be used when scanning for name. #### Returns - 1 on success, @@ -907,6 +912,7 @@ Start scanning for Bluetooth® Low Energy devices that are advertising with a pa ``` BLE.scanForAddress(address) BLE.scanForAddress(address, withDuplicates) +BLE.scanForAddress(address, withDuplicates, activeScan) ``` @@ -914,6 +920,7 @@ BLE.scanForAddress(address, withDuplicates) - **address:** (Bluetooth®) address (as a String) to filter for - **withDuplicates:** optional, defaults to **false**. If **true**, advertisements received more than once will not be filtered +- **activeScan:** optional, defaults to **true**. If **true**, an active scan is performed. Otherwise a passive scan is performed. #### Returns - 1 on success, @@ -955,6 +962,7 @@ Start scanning for Bluetooth® Low Energy devices that are advertising with a pa ``` BLE.scanForUuid(uuid) BLE.scanForUuid(uuid, withDuplicates) +BLE.scanForUuid(uuid, withDuplicates, activeScan) ``` @@ -962,6 +970,7 @@ BLE.scanForUuid(uuid, withDuplicates) - **uuid:** (service) UUID (as a **String**) to filter for - **withDuplicates:** optional, defaults to **false**. If **true**, advertisements received more than once will not be filtered. +- **activeScan:** optional, defaults to **true**. If **true**, an active scan is performed. Otherwise a passive scan is performed. #### Returns - 1 on success, @@ -1042,12 +1051,13 @@ Query for a discovered Bluetooth® Low Energy device that was found during scann ``` BLE.available() +BLE.available(includeAdvertised) ``` #### Parameters -Nothing +- **includeAdvertised:** optional, defaults to **false**. If **true**, also devices for which only the passive advertise data is known are returned. #### Returns - **BLEDevice** representing the discovered device. diff --git a/src/BLEDevice.h b/src/BLEDevice.h index bf710744..8adc72e9 100644 --- a/src/BLEDevice.h +++ b/src/BLEDevice.h @@ -28,6 +28,7 @@ enum BLEDeviceEvent { BLEConnected = 0, BLEDisconnected = 1, BLEDiscovered = 2, + BLEAdvertised = 3, BLEDeviceLastEvent }; diff --git a/src/local/BLELocalDevice.cpp b/src/local/BLELocalDevice.cpp index 91cc8695..baac890a 100644 --- a/src/local/BLELocalDevice.cpp +++ b/src/local/BLELocalDevice.cpp @@ -335,24 +335,24 @@ void BLELocalDevice::stopAdvertise() GAP.stopAdvertise(); } -int BLELocalDevice::scan(bool withDuplicates) +int BLELocalDevice::scan(bool withDuplicates, bool activeScan) { - return GAP.scan(withDuplicates); + return GAP.scan(withDuplicates, activeScan); } -int BLELocalDevice::scanForName(String name, bool withDuplicates) +int BLELocalDevice::scanForName(String name, bool withDuplicates, bool activeScan) { - return GAP.scanForName(name, withDuplicates); + return GAP.scanForName(name, withDuplicates, activeScan); } -int BLELocalDevice::scanForUuid(String uuid, bool withDuplicates) +int BLELocalDevice::scanForUuid(String uuid, bool withDuplicates, bool activeScan) { - return GAP.scanForUuid(uuid, withDuplicates); + return GAP.scanForUuid(uuid, withDuplicates, activeScan); } -int BLELocalDevice::scanForAddress(String address, bool withDuplicates) +int BLELocalDevice::scanForAddress(String address, bool withDuplicates, bool activeScan) { - return GAP.scanForAddress(address, withDuplicates); + return GAP.scanForAddress(address, withDuplicates, activeScan); } void BLELocalDevice::stopScan() @@ -367,16 +367,16 @@ BLEDevice BLELocalDevice::central() return ATT.central(); } -BLEDevice BLELocalDevice::available() +BLEDevice BLELocalDevice::available(bool includeAdvertised) { HCI.poll(); - return GAP.available(); + return GAP.available(includeAdvertised); } void BLELocalDevice::setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler eventHandler) { - if (event == BLEDiscovered) { + if (event == BLEDiscovered || event == BLEAdvertised) { GAP.setEventHandler(event, eventHandler); } else { ATT.setEventHandler(event, eventHandler); diff --git a/src/local/BLELocalDevice.h b/src/local/BLELocalDevice.h index 6c45c063..4feeae33 100644 --- a/src/local/BLELocalDevice.h +++ b/src/local/BLELocalDevice.h @@ -66,14 +66,14 @@ class BLELocalDevice { virtual int advertise(); virtual void stopAdvertise(); - virtual int scan(bool withDuplicates = false); - virtual int scanForName(String name, bool withDuplicates = false); - virtual int scanForUuid(String uuid, bool withDuplicates = false); - virtual int scanForAddress(String address, bool withDuplicates = false); + virtual int scan(bool withDuplicates = false, bool activeScan = true); + virtual int scanForName(String name, bool withDuplicates = false, bool activeScan = true); + virtual int scanForUuid(String uuid, bool withDuplicates = false, bool activeScan = true); + virtual int scanForAddress(String address, bool withDuplicates = false, bool activeScan = true); virtual void stopScan(); virtual BLEDevice central(); - virtual BLEDevice available(); + virtual BLEDevice available(bool includeAdvertised = false); virtual void setAdvertisingInterval(uint16_t advertisingInterval); virtual void setConnectionInterval(uint16_t minimumConnectionInterval, uint16_t maximumConnectionInterval); diff --git a/src/utility/GAP.cpp b/src/utility/GAP.cpp index f1bf02fe..b22533c8 100644 --- a/src/utility/GAP.cpp +++ b/src/utility/GAP.cpp @@ -33,7 +33,8 @@ GAPClass::GAPClass() : _scanning(false), _advertisingInterval(160), _connectable(true), - _discoverEventHandler(NULL) + _discoverEventHandler(NULL), + _advertiseEventHandler(NULL) { } @@ -82,7 +83,7 @@ void GAPClass::stopAdvertise() HCI.leSetAdvertiseEnable(0x00); } -int GAPClass::scan(bool withDuplicates) +int GAPClass::scan(bool withDuplicates, bool activeScan) { HCI.leSetScanEnable(false, true); @@ -93,7 +94,7 @@ int GAPClass::scan(bool withDuplicates) - scan window: mandatory range from 0x0011 to 0x1000 - The scan window can only be less than or equal to the scan interval */ - if (HCI.leSetScanParameters(0x01, 0x0020, 0x0020, 0x00, 0x00) != 0) { + if (HCI.leSetScanParameters(activeScan ? 0x01 : 0x00, 0x0020, 0x0020, 0x00, 0x00) != 0) { return false; } @@ -106,31 +107,31 @@ int GAPClass::scan(bool withDuplicates) return 1; } -int GAPClass::scanForName(String name, bool withDuplicates) +int GAPClass::scanForName(String name, bool withDuplicates, bool activeScan) { _scanNameFilter = name; _scanUuidFilter = ""; _scanAddressFilter = ""; - return scan(withDuplicates); + return scan(withDuplicates, activeScan); } -int GAPClass::scanForUuid(String uuid, bool withDuplicates) +int GAPClass::scanForUuid(String uuid, bool withDuplicates, bool activeScan) { _scanNameFilter = ""; _scanUuidFilter = uuid; _scanAddressFilter = ""; - return scan(withDuplicates); + return scan(withDuplicates, activeScan); } -int GAPClass::scanForAddress(String address, bool withDuplicates) +int GAPClass::scanForAddress(String address, bool withDuplicates, bool activeScan) { _scanNameFilter = ""; _scanUuidFilter = ""; _scanAddressFilter = address; - return scan(withDuplicates); + return scan(withDuplicates, activeScan); } void GAPClass::stopScan() @@ -148,12 +149,12 @@ void GAPClass::stopScan() _discoveredDevices.clear(); } -BLEDevice GAPClass::available() +BLEDevice GAPClass::available(bool includeAdvertised) { for (unsigned int i = 0; i < _discoveredDevices.size(); i++) { BLEDevice* device = _discoveredDevices.get(i); - if (device->discovered()) { + if (device->discovered() || includeAdvertised) { BLEDevice result = *device; _discoveredDevices.remove(i); @@ -185,6 +186,9 @@ void GAPClass::setEventHandler(BLEDeviceEvent event, BLEDeviceEventHandler event if (event == BLEDiscovered) { _discoverEventHandler = eventHandler; } + else if (event == BLEAdvertised) { + _advertiseEventHandler = eventHandler; + } } void GAPClass::handleLeAdvertisingReport(uint8_t type, uint8_t addressType, uint8_t address[6], @@ -201,6 +205,9 @@ void GAPClass::handleLeAdvertisingReport(uint8_t type, uint8_t addressType, uint device.setAdvertisementData(type, eirLength, eirData, rssi); if (matchesScanFilter(device)) { + if (_advertiseEventHandler) { + _advertiseEventHandler(device); + } _discoverEventHandler(device); } return; @@ -236,6 +243,9 @@ void GAPClass::handleLeAdvertisingReport(uint8_t type, uint8_t addressType, uint if (type != 0x04) { discoveredDevice->setAdvertisementData(type, eirLength, eirData, rssi); + if (_advertiseEventHandler && matchesScanFilter(*discoveredDevice)) { + _advertiseEventHandler(*discoveredDevice); + } } else { discoveredDevice->setScanResponseData(eirLength, eirData, rssi); } diff --git a/src/utility/GAP.h b/src/utility/GAP.h index 2ea22938..e48becfe 100644 --- a/src/utility/GAP.h +++ b/src/utility/GAP.h @@ -33,12 +33,12 @@ class GAPClass { virtual int advertise(uint8_t* advData, uint8_t advDataLength, uint8_t* scanData, uint8_t scanDataLength); virtual void stopAdvertise(); - virtual int scan(bool withDuplicates); - virtual int scanForName(String name, bool withDuplicates); - virtual int scanForUuid(String uuid, bool withDuplicates); - virtual int scanForAddress(String address, bool withDuplicates); + virtual int scan(bool withDuplicates, bool activeScan = true); + virtual int scanForName(String name, bool withDuplicates, bool activeScan = true); + virtual int scanForUuid(String uuid, bool withDuplicates, bool activeScan = true); + virtual int scanForAddress(String address, bool withDuplicates, bool activeScan = true); virtual void stopScan(); - virtual BLEDevice available(); + virtual BLEDevice available(bool includeAdvertised = false); virtual void setAdvertisingInterval(uint16_t advertisingInterval); virtual void setConnectable(bool connectable); @@ -62,6 +62,7 @@ class GAPClass { bool _connectable; BLEDeviceEventHandler _discoverEventHandler; + BLEDeviceEventHandler _advertiseEventHandler; BLELinkedList _discoveredDevices; String _scanNameFilter;