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
|
} // !finished
|
||||||
} // parseAdvertisement
|
} // 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.
|
* @brief Set the address of the advertised device.
|
||||||
|
@ -64,6 +64,7 @@ private:
|
|||||||
friend class BLEScan;
|
friend class BLEScan;
|
||||||
|
|
||||||
void parseAdvertisement(uint8_t* payload, size_t total_len=62);
|
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 setAddress(BLEAddress address);
|
||||||
void setAdFlag(uint8_t adFlag);
|
void setAdFlag(uint8_t adFlag);
|
||||||
void setAdvertizementResult(uint8_t* payload);
|
void setAdvertizementResult(uint8_t* payload);
|
||||||
|
@ -30,6 +30,7 @@ BLEScan::BLEScan() {
|
|||||||
m_pAdvertisedDeviceCallbacks = nullptr;
|
m_pAdvertisedDeviceCallbacks = nullptr;
|
||||||
m_stopped = true;
|
m_stopped = true;
|
||||||
m_wantDuplicates = false;
|
m_wantDuplicates = false;
|
||||||
|
m_shouldParse = true;
|
||||||
setInterval(100);
|
setInterval(100);
|
||||||
setWindow(100);
|
setWindow(100);
|
||||||
} // BLEScan
|
} // BLEScan
|
||||||
@ -90,15 +91,18 @@ void BLEScan::handleGAPEvent(
|
|||||||
// ignore it.
|
// ignore it.
|
||||||
BLEAddress advertisedAddress(param->scan_rst.bda);
|
BLEAddress advertisedAddress(param->scan_rst.bda);
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
bool shouldDelete = true;
|
||||||
|
|
||||||
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
|
if (!m_wantDuplicates) {
|
||||||
found = true;
|
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.
|
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());
|
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
|
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We now construct a model of the advertised device that we have just found for the first
|
// 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->setAddress(advertisedAddress);
|
||||||
advertisedDevice->setRSSI(param->scan_rst.rssi);
|
advertisedDevice->setRSSI(param->scan_rst.rssi);
|
||||||
advertisedDevice->setAdFlag(param->scan_rst.flag);
|
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->setScan(this);
|
||||||
advertisedDevice->setAddressType(param->scan_rst.ble_addr_type);
|
advertisedDevice->setAddressType(param->scan_rst.ble_addr_type);
|
||||||
|
|
||||||
if (!found) { // If we have previously seen this device, don't record it again.
|
if (m_pAdvertisedDeviceCallbacks) { // if has callback, no need to record to vector
|
||||||
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pAdvertisedDeviceCallbacks) {
|
|
||||||
m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
|
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;
|
delete advertisedDevice;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} // ESP_GAP_SEARCH_INQ_RES_EVT
|
} // ESP_GAP_SEARCH_INQ_RES_EVT
|
||||||
@ -161,13 +169,14 @@ void BLEScan::setActiveScan(bool active) {
|
|||||||
* @brief Set the call backs to be invoked.
|
* @brief Set the call backs to be invoked.
|
||||||
* @param [in] pAdvertisedDeviceCallbacks 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] 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_wantDuplicates = wantDuplicates;
|
||||||
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
|
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
|
||||||
|
m_shouldParse = shouldParse;
|
||||||
} // setAdvertisedDeviceCallbacks
|
} // setAdvertisedDeviceCallbacks
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the interval to scan.
|
* @brief Set the interval to scan.
|
||||||
* @param [in] The interval in msecs.
|
* @param [in] The interval in msecs.
|
||||||
|
@ -51,7 +51,8 @@ public:
|
|||||||
void setActiveScan(bool active);
|
void setActiveScan(bool active);
|
||||||
void setAdvertisedDeviceCallbacks(
|
void setAdvertisedDeviceCallbacks(
|
||||||
BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
|
BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
|
||||||
bool wantDuplicates = false);
|
bool wantDuplicates = false,
|
||||||
|
bool shouldParse = true);
|
||||||
void setInterval(uint16_t intervalMSecs);
|
void setInterval(uint16_t intervalMSecs);
|
||||||
void setWindow(uint16_t windowMSecs);
|
void setWindow(uint16_t windowMSecs);
|
||||||
bool start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue = false);
|
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;
|
esp_ble_scan_params_t m_scan_params;
|
||||||
BLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr;
|
BLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr;
|
||||||
bool m_stopped = true;
|
bool m_stopped = true;
|
||||||
|
bool m_shouldParse = true;
|
||||||
FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd");
|
FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd");
|
||||||
BLEScanResults m_scanResults;
|
BLEScanResults m_scanResults;
|
||||||
bool m_wantDuplicates;
|
bool m_wantDuplicates;
|
||||||
|
Loading…
Reference in New Issue
Block a user