mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-12-22 19:10:46 +01:00
[NimBLEScan] Use controller duplicate filter and add max result limit.
* Adds setMaxResults to NimBLEScan to limit the number of advertised devices stored. If set to 0 no devices will be stored in memory and only the callback will be invoked. If set to 0xFF (default) stored devices will be unlimited. Any other value will be the limit. * Uses the controller to filter duplicate devices from the scan results when wantDuplicates == false.
This commit is contained in:
parent
9527c41486
commit
82524c80e3
2 changed files with 54 additions and 34 deletions
|
@ -38,9 +38,9 @@ NimBLEScan::NimBLEScan() {
|
|||
m_scan_params.filter_duplicates = 0; // If set, the controller ignores all but the first advertisement from each device.
|
||||
m_pAdvertisedDeviceCallbacks = nullptr;
|
||||
m_ignoreResults = false;
|
||||
m_wantDuplicates = false;
|
||||
m_pTaskData = nullptr;
|
||||
m_duration = BLE_HS_FOREVER; // make sure this is non-zero in the event of a host reset
|
||||
m_maxResults = 0xFF;
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,44 +88,49 @@ NimBLEScan::~NimBLEScan() {
|
|||
|
||||
// If we haven't seen this device before; create a new instance and insert it in the vector.
|
||||
// Otherwise just update the relevant parameters of the already known device.
|
||||
if(advertisedDevice == nullptr){
|
||||
if(advertisedDevice == nullptr && event->disc.event_type != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP){
|
||||
// Check if we have reach the scan results limit, ignore this one if so.
|
||||
// We still need to store each device when maxResults is 0 to be able to append the scan results
|
||||
if(pScan->m_maxResults > 0 && pScan->m_maxResults < 0xFF &&
|
||||
(pScan->m_scanResults.m_advertisedDevicesVector.size() >= pScan->m_maxResults))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
advertisedDevice = new NimBLEAdvertisedDevice();
|
||||
advertisedDevice->setAddress(advertisedAddress);
|
||||
advertisedDevice->setAdvType(event->disc.event_type);
|
||||
pScan->m_scanResults.m_advertisedDevicesVector.push_back(advertisedDevice);
|
||||
NIMBLE_LOGI(LOG_TAG, "New advertiser: %s", advertisedAddress.toString().c_str());
|
||||
} else {
|
||||
} else if(advertisedDevice != nullptr) {
|
||||
NIMBLE_LOGI(LOG_TAG, "Updated advertiser: %s", advertisedAddress.toString().c_str());
|
||||
} else {
|
||||
// Scan response from unknown device
|
||||
return 0;
|
||||
}
|
||||
|
||||
advertisedDevice->m_timestamp = time(nullptr);
|
||||
advertisedDevice->setRSSI(event->disc.rssi);
|
||||
|
||||
if(event->disc.length_data > 0) {
|
||||
if(event->disc.event_type != BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
|
||||
advertisedDevice->setPayload(event->disc.data, event->disc.length_data, false);
|
||||
} else {
|
||||
advertisedDevice->setPayload(event->disc.data, event->disc.length_data, true);
|
||||
}
|
||||
}
|
||||
|
||||
advertisedDevice->setPayload(event->disc.data, event->disc.length_data,
|
||||
event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP);
|
||||
|
||||
if (pScan->m_pAdvertisedDeviceCallbacks) {
|
||||
if(pScan->m_wantDuplicates || !advertisedDevice->m_callbackSent) {
|
||||
// If not active scanning or scan response is not available
|
||||
// report the result to the callback now.
|
||||
if(pScan->m_scan_params.passive ||
|
||||
(event->disc.event_type != BLE_HCI_ADV_TYPE_ADV_IND &&
|
||||
event->disc.event_type != BLE_HCI_ADV_TYPE_ADV_SCAN_IND))
|
||||
{
|
||||
advertisedDevice->m_callbackSent = true;
|
||||
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
|
||||
// If not active scanning or scan response is not available
|
||||
// report the result to the callback now.
|
||||
if(pScan->m_scan_params.passive ||
|
||||
(advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_IND &&
|
||||
advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_SCAN_IND))
|
||||
{
|
||||
advertisedDevice->m_callbackSent = true;
|
||||
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
|
||||
|
||||
// Otherwise, wait for the scan response so we can report the complete data.
|
||||
} else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
|
||||
advertisedDevice->m_callbackSent = true;
|
||||
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
|
||||
}
|
||||
// Otherwise, wait for the scan response so we can report the complete data.
|
||||
} else if (event->disc.event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
|
||||
advertisedDevice->m_callbackSent = true;
|
||||
pScan->m_pAdvertisedDeviceCallbacks->onResult(advertisedDevice);
|
||||
}
|
||||
// If not storing results and we have invoked the callback, delete the device.
|
||||
if(pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent) {
|
||||
pScan->erase(advertisedAddress);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,6 +150,10 @@ NimBLEScan::~NimBLEScan() {
|
|||
}
|
||||
}
|
||||
|
||||
if(pScan->m_maxResults == 0) {
|
||||
pScan->clearResults();
|
||||
}
|
||||
|
||||
if (pScan->m_scanCompleteCB != nullptr) {
|
||||
pScan->m_scanCompleteCB(pScan->m_scanResults);
|
||||
}
|
||||
|
@ -165,15 +174,11 @@ NimBLEScan::~NimBLEScan() {
|
|||
|
||||
/**
|
||||
* @brief Should we perform an active or passive scan?
|
||||
* The default is a passive scan. An active scan means that we will wish a scan response.
|
||||
* The default is a passive scan. An active scan means that we will request a scan response.
|
||||
* @param [in] active If true, we perform an active scan otherwise a passive scan.
|
||||
*/
|
||||
void NimBLEScan::setActiveScan(bool active) {
|
||||
if (active) {
|
||||
m_scan_params.passive = 0;
|
||||
} else {
|
||||
m_scan_params.passive = 1;
|
||||
}
|
||||
m_scan_params.passive = !active;
|
||||
} // setActiveScan
|
||||
|
||||
|
||||
|
@ -222,6 +227,16 @@ void NimBLEScan::setFilterPolicy(uint8_t filter) {
|
|||
} // setFilterPolicy
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets the max number of results to store.
|
||||
* @param [in] maxResults The number of results to limit storage to\n
|
||||
* 0 == none (callbacks only) 0xFF == unlimited, any other value is the limit.
|
||||
*/
|
||||
void NimBLEScan::setMaxResults(uint8_t maxResults) {
|
||||
m_maxResults = maxResults;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the call backs to be invoked.
|
||||
* @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked.
|
||||
|
@ -229,7 +244,7 @@ void NimBLEScan::setFilterPolicy(uint8_t filter) {
|
|||
*/
|
||||
void NimBLEScan::setAdvertisedDeviceCallbacks(NimBLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
|
||||
bool wantDuplicates) {
|
||||
m_wantDuplicates = wantDuplicates;
|
||||
setDuplicateFilter(!wantDuplicates);
|
||||
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
|
||||
} // setAdvertisedDeviceCallbacks
|
||||
|
||||
|
@ -366,6 +381,10 @@ bool NimBLEScan::stop() {
|
|||
return false;
|
||||
}
|
||||
|
||||
if(m_maxResults == 0) {
|
||||
clearResults();
|
||||
}
|
||||
|
||||
if (rc != BLE_HS_EALREADY && m_scanCompleteCB != nullptr) {
|
||||
m_scanCompleteCB(m_scanResults);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public:
|
|||
bool stop();
|
||||
void clearResults();
|
||||
NimBLEScanResults getResults();
|
||||
void setMaxResults(uint8_t maxResults);
|
||||
void erase(const NimBLEAddress &address);
|
||||
|
||||
|
||||
|
@ -89,10 +90,10 @@ private:
|
|||
void (*m_scanCompleteCB)(NimBLEScanResults scanResults);
|
||||
ble_gap_disc_params m_scan_params;
|
||||
bool m_ignoreResults;
|
||||
bool m_wantDuplicates;
|
||||
NimBLEScanResults m_scanResults;
|
||||
uint32_t m_duration;
|
||||
ble_task_data_t *m_pTaskData;
|
||||
uint8_t m_maxResults;
|
||||
};
|
||||
|
||||
#endif // #if defined(CONFIG_BT_NIMBLE_ROLE_OBSERVER)
|
||||
|
|
Loading…
Reference in a new issue