improve & fix BLEScan when wantDuplicates (#3995)
* improve & fix BLEScan when too many BLE devices - when wantDuplicates, no need to check duplicate and no more insert into vector - delete advertisedDevice when not insert into vector, fix memory leak - add showParse when you just want raw advertised data
This commit is contained in:
parent
c2346c37da
commit
dccb4e8608
@ -388,6 +388,15 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
|
||||
} // !finished
|
||||
} // parseAdvertisement
|
||||
|
||||
/**
|
||||
* @brief Parse the advertising payload.
|
||||
* @param [in] payload The payload of the advertised device.
|
||||
* @param [in] total_len The length of payload
|
||||
*/
|
||||
void BLEAdvertisedDevice::setPayload(uint8_t* payload, size_t total_len) {
|
||||
m_payload = payload;
|
||||
m_payloadLength = total_len;
|
||||
} // setPayload
|
||||
|
||||
/**
|
||||
* @brief Set the address of the advertised device.
|
||||
|
@ -64,6 +64,7 @@ private:
|
||||
friend class BLEScan;
|
||||
|
||||
void parseAdvertisement(uint8_t* payload, size_t total_len=62);
|
||||
void setPayload(uint8_t* payload, size_t total_len=62);
|
||||
void setAddress(BLEAddress address);
|
||||
void setAdFlag(uint8_t adFlag);
|
||||
void setAdvertizementResult(uint8_t* payload);
|
||||
|
@ -30,6 +30,7 @@ BLEScan::BLEScan() {
|
||||
m_pAdvertisedDeviceCallbacks = nullptr;
|
||||
m_stopped = true;
|
||||
m_wantDuplicates = false;
|
||||
m_shouldParse = true;
|
||||
setInterval(100);
|
||||
setWindow(100);
|
||||
} // BLEScan
|
||||
@ -90,15 +91,18 @@ void BLEScan::handleGAPEvent(
|
||||
// ignore it.
|
||||
BLEAddress advertisedAddress(param->scan_rst.bda);
|
||||
bool found = false;
|
||||
bool shouldDelete = true;
|
||||
|
||||
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
|
||||
found = true;
|
||||
}
|
||||
if (!m_wantDuplicates) {
|
||||
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (found && !m_wantDuplicates) { // If we found a previous entry AND we don't want duplicates, then we are done.
|
||||
log_d("Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
|
||||
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
|
||||
break;
|
||||
if (found) { // If we found a previous entry AND we don't want duplicates, then we are done.
|
||||
log_d("Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
|
||||
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// We now construct a model of the advertised device that we have just found for the first
|
||||
@ -109,19 +113,23 @@ void BLEScan::handleGAPEvent(
|
||||
advertisedDevice->setAddress(advertisedAddress);
|
||||
advertisedDevice->setRSSI(param->scan_rst.rssi);
|
||||
advertisedDevice->setAdFlag(param->scan_rst.flag);
|
||||
advertisedDevice->parseAdvertisement((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
|
||||
if (m_shouldParse) {
|
||||
advertisedDevice->parseAdvertisement((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
|
||||
} else {
|
||||
advertisedDevice->setPayload((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
|
||||
}
|
||||
advertisedDevice->setScan(this);
|
||||
advertisedDevice->setAddressType(param->scan_rst.ble_addr_type);
|
||||
|
||||
if (!found) { // If we have previously seen this device, don't record it again.
|
||||
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
|
||||
}
|
||||
|
||||
if (m_pAdvertisedDeviceCallbacks) {
|
||||
if (m_pAdvertisedDeviceCallbacks) { // if has callback, no need to record to vector
|
||||
m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
|
||||
} else if (!m_wantDuplicates && !found) { // if no callback and not want duplicate, and not already in vector, record it
|
||||
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
|
||||
shouldDelete = false;
|
||||
}
|
||||
if(found)
|
||||
if (shouldDelete) {
|
||||
delete advertisedDevice;
|
||||
}
|
||||
|
||||
break;
|
||||
} // ESP_GAP_SEARCH_INQ_RES_EVT
|
||||
@ -161,13 +169,14 @@ void BLEScan::setActiveScan(bool active) {
|
||||
* @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.
|
||||
* @param [in] shouldParse True if we wish to parse advertised package or raw payload. Default is true.
|
||||
*/
|
||||
void BLEScan::setAdvertisedDeviceCallbacks(BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates) {
|
||||
void BLEScan::setAdvertisedDeviceCallbacks(BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates, bool shouldParse) {
|
||||
m_wantDuplicates = wantDuplicates;
|
||||
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
|
||||
m_shouldParse = shouldParse;
|
||||
} // setAdvertisedDeviceCallbacks
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the interval to scan.
|
||||
* @param [in] The interval in msecs.
|
||||
|
@ -51,7 +51,8 @@ public:
|
||||
void setActiveScan(bool active);
|
||||
void setAdvertisedDeviceCallbacks(
|
||||
BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
|
||||
bool wantDuplicates = false);
|
||||
bool wantDuplicates = false,
|
||||
bool shouldParse = true);
|
||||
void setInterval(uint16_t intervalMSecs);
|
||||
void setWindow(uint16_t windowMSecs);
|
||||
bool start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue = false);
|
||||
@ -73,6 +74,7 @@ private:
|
||||
esp_ble_scan_params_t m_scan_params;
|
||||
BLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr;
|
||||
bool m_stopped = true;
|
||||
bool m_shouldParse = true;
|
||||
FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd");
|
||||
BLEScanResults m_scanResults;
|
||||
bool m_wantDuplicates;
|
||||
|
Loading…
Reference in New Issue
Block a user