Skip to content

Commit f4a1880

Browse files
sgbihuSidLeung
authored andcommitted
Jira 802, BLE Central scan() to filter Peripheral adv, git #369
New feature: - Request from Arduino to make our Central BLE library to scan Peripheral similar to an Apple device. - When filter is set, advertisement from a Peripheral will only show up once (until scan is stop and start again) with the available() call. Otherwise, a Peripheral will appear as often as the Central can detect its advertisement. - Unlike an Apple device, the 101 operates under memory constraints. Thus, the maximum number of filter entries is limited to 20. In other words, if ther are more than 20 Peripherals, the filter will NOT be able to filter out all the advertisement all the time. A Peripherla WILL show up multiple times when available() is called. Code mods: 1. BLECommon.h: - Definition of the filter entries size. 2. BLEDeviceManager.cpp: - Peripheral filtering initialization at startScanningWithDuplicates(). - Added deviceInDuplicateFilterBuffer() for search a newly detected Peripheral against a recorded list of devices. - Added updateDuplicateFilter() to record any newly detected Peripoheral. - At available(), check for duplicated Peripheral prior to return it to caller. Discard any reported Peripheral. Record any newly detected one prior to return it to caller.
1 parent 07f4de2 commit f4a1880

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

libraries/CurieBLE/src/BLECommon.h

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ typedef ble_status_t BleStatus;
103103

104104
#define BLE_MAX_CONN_CFG 2
105105
#define BLE_MAX_ADV_BUFFER_CFG 3
106+
#define BLE_MAX_ADV_FILTER_SIZE_CFG 20
106107

107108
typedef bool (*ble_advertise_handle_cb_t)(uint8_t type, const uint8_t *dataPtr,
108109
uint8_t data_len, const bt_addr_le_t *addrPtr);

libraries/CurieBLE/src/internal/BLEDeviceManager.cpp

+54-3
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ BLEDeviceManager::BLEDeviceManager():
4747
_local_name(""),
4848
_state(BLE_PERIPH_STATE_NOT_READY),
4949
_local_ble(NULL),
50-
_peer_peripheral_index(0)
50+
_peer_peripheral_index(0),
51+
_duplicate_filter_header(0),
52+
_duplicate_filter_tail(0),
53+
_adv_duplicate_filter_enabled(false)
5154
{
5255
memset(&_local_bda, 0, sizeof(_local_bda));
5356
memset(&_wait_for_connect_peripheral, 0, sizeof(_wait_for_connect_peripheral));
@@ -530,7 +533,8 @@ BLEDevice BLEDeviceManager::peripheral()
530533

531534
bool BLEDeviceManager::startScanning()
532535
{
533-
_scan_param.filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_ENABLE;//BT_HCI_LE_SCAN_FILTER_DUP_DISABLE;
536+
_adv_duplicate_filter_enabled = false;
537+
_scan_param.filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_ENABLE;
534538
int err = bt_le_scan_start(&_scan_param, ble_central_device_found);
535539
if (err)
536540
{
@@ -542,14 +546,18 @@ bool BLEDeviceManager::startScanning()
542546

543547
bool BLEDeviceManager::startScanningWithDuplicates()
544548
{
549+
_adv_duplicate_filter_enabled = true;
550+
memset(_peer_duplicate_address_buffer, 0, sizeof(_peer_duplicate_address_buffer));
551+
_duplicate_filter_header = _duplicate_filter_tail = 0;
552+
545553
_scan_param.filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_ENABLE;
546554
int err = bt_le_scan_start(&_scan_param, ble_central_device_found);
547555
if (err)
548556
{
549557
pr_info(LOG_MODULE_BLE, "Scanning failed to start (err %d)\n", err);
550558
return false;
551559
}
552-
return false;
560+
return true;
553561
}
554562

555563
bool BLEDeviceManager::stopScanning()
@@ -1164,6 +1172,38 @@ bool BLEDeviceManager::advertiseDataProc(uint8_t type,
11641172
return false;
11651173
}
11661174

1175+
bool BLEDeviceManager::deviceInDuplicateFilterBuffer(const bt_addr_le_t* addr)
1176+
{
1177+
bool retVal = false;
1178+
for (uint8_t i = 0;
1179+
i < (sizeof(_peer_duplicate_address_buffer) / sizeof(bt_addr_le_t));
1180+
i++)
1181+
{
1182+
if (0 == bt_addr_le_cmp(addr, &_peer_duplicate_address_buffer[i]))
1183+
{
1184+
retVal = true;
1185+
break;
1186+
}
1187+
}
1188+
return retVal;
1189+
}
1190+
1191+
void BLEDeviceManager::updateDuplicateFilter(const bt_addr_le_t* addr)
1192+
{
1193+
uint8_t i = (_duplicate_filter_header + 1) % (ARRAY_SIZE(_peer_duplicate_address_buffer));
1194+
if (deviceInDuplicateFilterBuffer(addr))
1195+
{
1196+
return;
1197+
}
1198+
bt_addr_le_copy(&_peer_duplicate_address_buffer[_duplicate_filter_header],
1199+
addr);
1200+
if (i == _duplicate_filter_tail)
1201+
{
1202+
_duplicate_filter_tail = (_duplicate_filter_tail + 1) % (ARRAY_SIZE(_peer_duplicate_address_buffer));
1203+
}
1204+
_duplicate_filter_header = i;
1205+
}
1206+
11671207
BLEDevice BLEDeviceManager::available()
11681208
{
11691209
BLEDevice tempdevice;
@@ -1179,6 +1219,13 @@ BLEDevice BLEDeviceManager::available()
11791219
temp = &_peer_adv_buffer[i];
11801220
if ((timestamp_delta <= 2000) && (max_delta < timestamp_delta))
11811221
{
1222+
// Eable the duplicate filter
1223+
if (_adv_duplicate_filter_enabled &&
1224+
true == deviceInDuplicateFilterBuffer(temp))
1225+
{
1226+
_peer_adv_mill[i] -= 2000; // Invalid the item
1227+
continue;
1228+
}
11821229
max_delta = timestamp_delta;
11831230
index = i;
11841231
}
@@ -1198,6 +1245,10 @@ BLEDevice BLEDeviceManager::available()
11981245

11991246
pr_debug(LOG_MODULE_BLE, "%s-%d:Con addr-%s", __FUNCTION__, __LINE__, BLEUtils::macAddressBT2String(*temp).c_str());
12001247
_peer_adv_mill[index] -= 2000; // Set it as expired
1248+
if (_adv_duplicate_filter_enabled)
1249+
{
1250+
updateDuplicateFilter(temp);
1251+
}
12011252
}
12021253
}
12031254
return tempdevice;

libraries/CurieBLE/src/internal/BLEDeviceManager.h

+6
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,8 @@ class BLEDeviceManager
362362
const uint8_t* &adv_data,
363363
uint8_t &adv_len) const;
364364
bool disconnectSingle(const bt_addr_le_t *peer);
365+
void updateDuplicateFilter(const bt_addr_le_t* addr);
366+
bool deviceInDuplicateFilterBuffer(const bt_addr_le_t* addr);
365367

366368
private:
367369
uint16_t _min_conn_interval;
@@ -432,6 +434,10 @@ class BLEDeviceManager
432434
uint8_t _peer_peripheral_adv_data[BLE_MAX_CONN_CFG][BLE_MAX_ADV_SIZE];
433435
uint8_t _peer_peripheral_adv_data_len[BLE_MAX_CONN_CFG];
434436
uint8_t _peer_peripheral_adv_rssi[BLE_MAX_CONN_CFG];
437+
bt_addr_le_t _peer_duplicate_address_buffer[BLE_MAX_ADV_FILTER_SIZE_CFG];
438+
uint8_t _duplicate_filter_header;
439+
uint8_t _duplicate_filter_tail;
440+
bool _adv_duplicate_filter_enabled;
435441

436442
BLEDeviceEventHandler _device_events[BLEDeviceLastEvent];
437443
};

0 commit comments

Comments
 (0)