Skip to content

Add support for passive scans #283

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -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,13 +861,16 @@ 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)

```

#### Parameters

- **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,13 +912,15 @@ 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)

```

#### Parameters

- **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,13 +962,15 @@ 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)

```

#### Parameters

- **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.
1 change: 1 addition & 0 deletions src/BLEDevice.h
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ enum BLEDeviceEvent {
BLEConnected = 0,
BLEDisconnected = 1,
BLEDiscovered = 2,
BLEAdvertised = 3,

BLEDeviceLastEvent
};
22 changes: 11 additions & 11 deletions src/local/BLELocalDevice.cpp
Original file line number Diff line number Diff line change
@@ -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);
10 changes: 5 additions & 5 deletions src/local/BLELocalDevice.h
Original file line number Diff line number Diff line change
@@ -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);
32 changes: 21 additions & 11 deletions src/utility/GAP.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
11 changes: 6 additions & 5 deletions src/utility/GAP.h
Original file line number Diff line number Diff line change
@@ -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<BLEDevice*> _discoveredDevices;

String _scanNameFilter;