Implement scan wantDuplicates parameter in callback registration.

Also adds:
* NimBLEScan::setDuplicateFilter() to tell the controller to filter duplicates
before sending the result to the host.

* NimBLEScan::setLimitedOnly() to tell the controller only report scan results
from devices advertising in limited discovery mode, i.e. directed advertising.

* NimBLEScan::setFilterPolicy() to set the filter policy i.e whitelist only devices.
This commit is contained in:
h2zero 2020-07-01 17:26:44 -06:00
parent e936070464
commit 745f9c00ed
5 changed files with 75 additions and 45 deletions

View file

@ -37,6 +37,8 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
m_serviceData = "";
m_txPower = 0;
m_pScan = nullptr;
m_payloadLength = 0;
m_payload = nullptr;
m_haveAppearance = false;
m_haveManufacturerData = false;
@ -45,6 +47,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() {
m_haveServiceData = false;
m_haveServiceUUID = false;
m_haveTXPower = false;
m_callbackSent = false;
} // NimBLEAdvertisedDevice

View file

@ -128,9 +128,10 @@ private:
std::string m_serviceData;
NimBLEUUID m_serviceDataUUID;
uint8_t* m_payload;
size_t m_payloadLength = 0;
size_t m_payloadLength;
uint8_t m_addressType;
time_t m_timestamp;
bool m_callbackSent;
};
/**

View file

@ -71,9 +71,9 @@ public:
return *((T *)pData);
}
uint8_t readUInt8() __attribute__ ((deprecated));
uint16_t readUInt16() __attribute__ ((deprecated));
uint32_t readUInt32() __attribute__ ((deprecated));
uint8_t readUInt8() __attribute__ ((deprecated("Use template readValue<uint8_t>()")));
uint16_t readUInt16() __attribute__ ((deprecated("Use template readValue<uint16_t>()")));
uint32_t readUInt32() __attribute__ ((deprecated("Use template readValue<uint32_t>()")));
std::string getValue(time_t *timestamp = nullptr);
template<typename T>
@ -90,7 +90,8 @@ public:
bool unsubscribe(bool response = true);
bool registerForNotify(notify_callback notifyCallback,
bool notifications = true,
bool response = true) __attribute__ ((deprecated));
bool response = true)
__attribute__ ((deprecated("Use subscribe()/unsubscribe()")));
bool writeValue(const uint8_t* data,
size_t length,
bool response = false);

View file

@ -25,41 +25,12 @@
static const char* LOG_TAG = "NimBLEScan";
/*
* Scanning filter policy
* NO_WL:
* Scanner processes all advertising packets (white list not used) except
* directed, connectable advertising packets not sent to the scanner.
* USE_WL:
* Scanner processes advertisements from white list only. A connectable,
* directed advertisment is ignored unless it contains scanners address.
* NO_WL_INITA:
* Scanner process all advertising packets (white list not used). A
* connectable, directed advertisement shall not be ignored if the InitA
* is a resolvable private address.
* USE_WL_INITA:
* Scanner process advertisements from white list only. A connectable,
* directed advertisement shall not be ignored if the InitA is a
* resolvable private address.
*/
//#define BLE_HCI_SCAN_FILT_NO_WL (0)
//#define BLE_HCI_SCAN_FILT_USE_WL (1)
//#define BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
//#define BLE_HCI_SCAN_FILT_USE_WL_INITA (3)
//#define BLE_HCI_SCAN_FILT_MAX (3)
/**
* @brief Scan constuctor.
*/
NimBLEScan::NimBLEScan() {
uint8_t own_addr_type;
if(ble_hs_id_infer_auto(0, &own_addr_type) !=0){
NIMBLE_LOGE(LOG_TAG, "error determining address type\n");
return;
}
m_own_addr_type = own_addr_type;
m_own_addr_type = 0;
m_scan_params.filter_policy = BLE_HCI_SCAN_FILT_NO_WL;
m_scan_params.passive = 1; // If set, dont send scan requests to advertisers (i.e., dont request additional advertising data).
m_scan_params.itvl = 0; // This is defined as the time interval from when the Controller started its last LE scan until it begins the subsequent LE scan. (units=0.625 msec)
@ -137,14 +108,19 @@ NimBLEScan::NimBLEScan() {
advertisedDevice->m_timestamp = time(nullptr);
if (pScan->m_pAdvertisedDeviceCallbacks) {
if(pScan->m_wantDuplicates || !advertisedDevice->m_callbackSent) {
// If not active scanning report the result to the listener.
if(pScan->m_scan_params.passive || event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) {
advertisedDevice->m_callbackSent = true;
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
// Otherwise wait for the scan response so we can report all of the data at once.
} else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
advertisedDevice->m_callbackSent = true;
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
}
}
}
return 0;
}
@ -186,13 +162,59 @@ void NimBLEScan::setActiveScan(bool active) {
} // setActiveScan
/**
* @brief Set whether or not the BLE controller should only report results
* from devices it has not already seen.
* @param [in] active If true, scanned devices will only be reported once.
* @details The controller has a limited buffer and will start reporting
* dupicate devices once the limit is reached.
*/
void NimBLEScan::setDuplicateFilter(bool active) {
m_scan_params.filter_duplicates = active;
} // setDuplicateFilter
/**
* @brief Set whether or not the BLE controller only report scan results
* from devices advertising in limited discovery mode, i.e. directed advertising.
* @param [in] active If true, only limited discovery devices will be in scan results.
*/
void NimBLEScan::setLimitedOnly(bool active) {
m_scan_params.limited = active;
} // setLimited
/**
* @brief Sets the scan filter policy.
* @param [in] filter Can be one of:
* BLE_HCI_SCAN_FILT_NO_WL (0)
* Scanner processes all advertising packets (white list not used) except
* directed, connectable advertising packets not sent to the scanner.
* BLE_HCI_SCAN_FILT_USE_WL (1)
* Scanner processes advertisements from white list only. A connectable,
* directed advertisment is ignored unless it contains scanners address.
* BLE_HCI_SCAN_FILT_NO_WL_INITA (2)
* Scanner process all advertising packets (white list not used). A
* connectable, directed advertisement shall not be ignored if the InitA
* is a resolvable private address.
* BLE_HCI_SCAN_FILT_USE_WL_INITA (3)
* Scanner process advertisements from white list only. A connectable,
* directed advertisement shall not be ignored if the InitA is a
* resolvable private address.
*/
void NimBLEScan::setFilterPolicy(uint8_t filter) {
m_scan_params.filter_policy = filter;
} // setFilterPolicy
/**
* @brief Set the call backs to be invoked.
* @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked.
* @param [in] wantDuplicates True if we wish to be called back with duplicates. Default is false.
*/
void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks/*, bool wantDuplicates*/) {
//m_wantDuplicates = wantDuplicates;
void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
bool wantDuplicates) {
m_wantDuplicates = wantDuplicates;
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
} // setAdvertisedDeviceCallbacks

View file

@ -62,10 +62,13 @@ class NimBLEScan {
public:
bool start(uint32_t duration, void (*scanCompleteCB)(NimBLEScanResults), bool is_continue = false);
NimBLEScanResults start(uint32_t duration, bool is_continue = false);
void setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks/*, bool wantDuplicates = false*/);
void setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates = false);
void setActiveScan(bool active);
void setInterval(uint16_t intervalMSecs);
void setWindow(uint16_t windowMSecs);
void setDuplicateFilter(bool active);
void setLimitedOnly(bool active);
void setFilterPolicy(uint8_t filter);
bool stop();
void clearResults();
NimBLEScanResults getResults();