Add onDiscovered scan callback.

This adds a callback that is called when a device is initially discovered.
It is always called wether scanning in passive or active mode. This allows
for active scanning to receive device detection information in the case where
the scan response is not sent/received.

This callback is optional, the application may decide to implement it or not.
This commit is contained in:
h2zero 2023-04-06 15:56:53 -06:00 committed by h2zero
parent 559a26b74b
commit 46e7bb9302
5 changed files with 73 additions and 20 deletions

View file

@ -0,0 +1,48 @@
/*
* NimBLE Scan active/passive switching demo
*
* Demonstrates the use of the scan callbacks while alternating between passive and active scanning.
*/
#include "NimBLEDevice.h"
int scanTime = 5 * 1000; // In milliseconds, 0 = scan forever
BLEScan* pBLEScan;
bool active = false;
class scanCallbacks: public NimBLEScanCallbacks {
void onDiscovered(NimBLEAdvertisedDevice* advertisedDevice) {
Serial.printf("Discovered Advertised Device: %s \n", advertisedDevice->toString().c_str());
}
void onResult(NimBLEAdvertisedDevice* advertisedDevice) {
Serial.printf("Advertised Device Result: %s \n", advertisedDevice->toString().c_str());
}
void onScanEnd(NimBLEScanResults results){
Serial.println("Scan Ended");
active = !active;
pBLEScan->setActiveScan(active);
Serial.printf("scan start, active = %u\n", active);
pBLEScan->start(scanTime);
}
};
void setup() {
Serial.begin(115200);
Serial.println("Scanning...");
NimBLEDevice::init("");
pBLEScan = NimBLEDevice::getScan();
pBLEScan->setScanCallbacks(new scanCallbacks());
pBLEScan->setActiveScan(active);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99);
pBLEScan->start(scanTime);
}
void loop() {
}

View file

@ -33,7 +33,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice() :
{
m_advType = 0;
m_rssi = -9999;
m_callbackSent = false;
m_callbackSent = 0;
m_timestamp = 0;
m_advLength = 0;
} // NimBLEAdvertisedDevice

View file

@ -164,7 +164,7 @@ private:
uint8_t m_advType;
int m_rssi;
time_t m_timestamp;
bool m_callbackSent;
uint8_t m_callbackSent;
uint8_t m_advLength;
#if CONFIG_BT_NIMBLE_EXT_ADV
bool m_isLegacyAdv;

View file

@ -135,7 +135,12 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP));
if (pScan->m_pScanCallbacks) {
if (pScan->m_scan_params.filter_duplicates && advertisedDevice->m_callbackSent) {
if (advertisedDevice->m_callbackSent == 0 || !pScan->m_scan_params.filter_duplicates) {
advertisedDevice->m_callbackSent = 1;
pScan->m_pScanCallbacks->onDiscovered(advertisedDevice);
}
if (pScan->m_scan_params.filter_duplicates && advertisedDevice->m_callbackSent >= 2) {
return 0;
}
@ -145,16 +150,16 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
(advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_IND &&
advertisedDevice->getAdvType() != BLE_HCI_ADV_TYPE_ADV_SCAN_IND))
{
advertisedDevice->m_callbackSent = true;
advertisedDevice->m_callbackSent = 2;
pScan->m_pScanCallbacks->onResult(advertisedDevice);
// Otherwise, wait for the scan response so we can report the complete data.
} else if (isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
advertisedDevice->m_callbackSent = true;
advertisedDevice->m_callbackSent = 2;
pScan->m_pScanCallbacks->onResult(advertisedDevice);
}
// If not storing results and we have invoked the callback, delete the device.
if(pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent) {
if(pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent >= 2) {
pScan->erase(advertisedAddress);
}
}
@ -165,16 +170,6 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
NIMBLE_LOGD(LOG_TAG, "discovery complete; reason=%d",
event->disc_complete.reason);
// If a device advertised with scan response available and it was not received
// the callback would not have been invoked, so do it here.
if(pScan->m_pScanCallbacks) {
for(auto &it : pScan->m_scanResults.m_advertisedDevicesVector) {
if(!it->m_callbackSent) {
pScan->m_pScanCallbacks->onResult(it);
}
}
}
if(pScan->m_maxResults == 0) {
pScan->clearResults();
}

View file

@ -104,13 +104,23 @@ private:
class NimBLEScanCallbacks {
public:
virtual ~NimBLEScanCallbacks() {}
/**
* @brief Called when a new scan result is detected.
*
* As we are scanning, we will find new devices. When found, this call back is invoked with a reference to the
* device that was found. During any individual scan, a device will only be detected one time.
* @brief Called when a new device is discovered, before the scan result is received (if applicable).
* @param [in] advertisedDevice The device which was discovered.
*/
virtual void onDiscovered(NimBLEAdvertisedDevice* advertisedDevice) {};
/**
* @brief Called when a new scan result is complete, including scan response data (if applicable).
* @param [in] advertisedDevice The device for which the complete result is available.
*/
virtual void onResult(NimBLEAdvertisedDevice* advertisedDevice) {};
/**
* @brief Called when a scan operation ends.
* @param [in] scanResults The results of the scan that ended.
*/
virtual void onScanEnd(NimBLEScanResults scanResults) {};
};