Set a time for scan responses so that callbacks are triggered.

This commit is contained in:
h2zero 2024-11-18 13:41:49 -07:00
parent a9a79233bd
commit ec488aae55
4 changed files with 66 additions and 5 deletions

View file

@ -35,6 +35,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice(const ble_gap_event* event, uint8
m_rssi{event->ext_disc.rssi}, m_rssi{event->ext_disc.rssi},
m_callbackSent{0}, m_callbackSent{0},
m_advLength{event->ext_disc.length_data}, m_advLength{event->ext_disc.length_data},
m_srTimeout{0},
m_isLegacyAdv{!!(event->ext_disc.props & BLE_HCI_ADV_LEGACY_MASK)}, m_isLegacyAdv{!!(event->ext_disc.props & BLE_HCI_ADV_LEGACY_MASK)},
m_sid{event->ext_disc.sid}, m_sid{event->ext_disc.sid},
m_primPhy{event->ext_disc.prim_phy}, m_primPhy{event->ext_disc.prim_phy},
@ -47,6 +48,7 @@ NimBLEAdvertisedDevice::NimBLEAdvertisedDevice(const ble_gap_event* event, uint8
m_rssi{event->disc.rssi}, m_rssi{event->disc.rssi},
m_callbackSent{0}, m_callbackSent{0},
m_advLength{event->disc.length_data}, m_advLength{event->disc.length_data},
m_srTimeout{0},
m_payload(event->disc.data, event->disc.data + event->disc.length_data) { m_payload(event->disc.data, event->disc.data + event->disc.length_data) {
# endif # endif
} // NimBLEAdvertisedDevice } // NimBLEAdvertisedDevice

View file

@ -157,6 +157,7 @@ class NimBLEAdvertisedDevice {
int8_t m_rssi{}; int8_t m_rssi{};
uint8_t m_callbackSent{}; uint8_t m_callbackSent{};
uint8_t m_advLength{}; uint8_t m_advLength{};
uint32_t m_srTimeout{};
# if CONFIG_BT_NIMBLE_EXT_ADV # if CONFIG_BT_NIMBLE_EXT_ADV
bool m_isLegacyAdv{}; bool m_isLegacyAdv{};

View file

@ -19,6 +19,12 @@
# include "NimBLEDevice.h" # include "NimBLEDevice.h"
# include "NimBLELog.h" # include "NimBLELog.h"
# if defined(CONFIG_NIMBLE_CPP_IDF)
# include "nimble/nimble_port.h"
# else
# include "nimble/porting/nimble/include/nimble/nimble_port.h"
# endif
# include <string> # include <string>
# include <climits> # include <climits>
@ -33,13 +39,16 @@ NimBLEScan::NimBLEScan()
.itvl{0}, .window{0}, .filter_policy{BLE_HCI_SCAN_FILT_NO_WL}, .limited{0}, .passive{1}, .filter_duplicates{1}}, .itvl{0}, .window{0}, .filter_policy{BLE_HCI_SCAN_FILT_NO_WL}, .limited{0}, .passive{1}, .filter_duplicates{1}},
m_duration{BLE_HS_FOREVER}, m_duration{BLE_HS_FOREVER},
m_pTaskData{nullptr}, m_pTaskData{nullptr},
m_maxResults{0xFF} {} m_maxResults{0xFF} {
ble_npl_callout_init(&m_srTimer, nimble_port_get_dflt_eventq(), NimBLEScan::srTimerCb, nullptr);
}
/** /**
* @brief Scan destructor, release any allocated resources. * @brief Scan destructor, release any allocated resources.
*/ */
NimBLEScan::~NimBLEScan() { NimBLEScan::~NimBLEScan() {
clearResults(); clearResults();
ble_npl_callout_deinit(&m_srTimer);
} }
/** /**
@ -133,7 +142,15 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
} else if (isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) { } else if (isLegacyAdv && event_type == BLE_HCI_ADV_RPT_EVTYPE_SCAN_RSP) {
advertisedDevice->m_callbackSent = 2; advertisedDevice->m_callbackSent = 2;
pScan->m_pScanCallbacks->onResult(advertisedDevice); pScan->m_pScanCallbacks->onResult(advertisedDevice);
} else if (isLegacyAdv) {
ble_npl_time_t ticks;
ble_npl_time_ms_to_ticks(500, &ticks); // more than 500ms for scan response = not coming
advertisedDevice->m_srTimeout = ble_npl_time_get() + ticks;
if (!ble_npl_callout_is_active(&pScan->m_srTimer)) {
ble_npl_callout_reset(&pScan->m_srTimer, ticks);
} }
}
// If not storing results and we have invoked the callback, delete the device. // If not storing results and we have invoked the callback, delete the device.
if (pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent >= 2) { if (pScan->m_maxResults == 0 && advertisedDevice->m_callbackSent >= 2) {
pScan->erase(advertisedAddress); pScan->erase(advertisedAddress);
@ -166,6 +183,41 @@ int NimBLEScan::handleGapEvent(ble_gap_event* event, void* arg) {
} }
} // handleGapEvent } // handleGapEvent
/**
* @brief This will call the scan result callback when a scan response is not received
* and will delete the device from the vector when maxResults is 0.
*/
void NimBLEScan::srTimerCb(ble_npl_event* event) {
NimBLEScan* pScan = NimBLEDevice::getScan();
ble_npl_time_t now = ble_npl_time_get();
ble_npl_time_t nextTimeout = BLE_NPL_TIME_FOREVER;
for (auto& ad : pScan->m_scanResults.m_deviceVec) {
if (!ad->m_srTimeout) {
continue;
}
if (ad->m_callbackSent == 1 && now > ad->m_srTimeout) {
ad->m_callbackSent = 2;
pScan->m_pScanCallbacks->onResult(ad);
if (pScan->m_maxResults == 0) {
pScan->erase(ad->getAddress());
}
continue;
}
if (ad->m_callbackSent == 1 && ad->m_srTimeout < nextTimeout) {
nextTimeout = ad->m_srTimeout;
}
}
if (nextTimeout != BLE_NPL_TIME_FOREVER) {
ble_npl_callout_reset(&pScan->m_srTimer, nextTimeout);
}
} // srTimerCb
/** /**
* @brief Should we perform an active or passive scan? * @brief Should we perform an active or passive scan?
* The default is a passive scan. An active scan means that we will request a scan response. * The default is a passive scan. An active scan means that we will request a scan response.
@ -357,6 +409,10 @@ bool NimBLEScan::stop() {
return false; return false;
} }
if (m_pScanCallbacks) {
ble_npl_callout_stop(&m_srTimer);
}
if (m_maxResults == 0) { if (m_maxResults == 0) {
clearResults(); clearResults();
} }

View file

@ -84,6 +84,7 @@ class NimBLEScan {
NimBLEScan(); NimBLEScan();
~NimBLEScan(); ~NimBLEScan();
static int handleGapEvent(ble_gap_event* event, void* arg); static int handleGapEvent(ble_gap_event* event, void* arg);
static void srTimerCb(ble_npl_event* event);
void onHostSync(); void onHostSync();
NimBLEScanCallbacks* m_pScanCallbacks; NimBLEScanCallbacks* m_pScanCallbacks;
@ -92,6 +93,7 @@ class NimBLEScan {
uint32_t m_duration; uint32_t m_duration;
NimBLETaskData* m_pTaskData; NimBLETaskData* m_pTaskData;
uint8_t m_maxResults; uint8_t m_maxResults;
ble_npl_callout m_srTimer;
}; };
/** /**