Skip to content

improve & fix BLEScan when wantDuplicates #3995

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 2, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libraries/BLE/src/BLEAdvertisedDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions libraries/BLE/src/BLEAdvertisedDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class BLEAdvertisedDevice {
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);
Expand Down
39 changes: 25 additions & 14 deletions libraries/BLE/src/BLEScan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ BLEScan::BLEScan() {
m_pAdvertisedDeviceCallbacks = nullptr;
m_stopped = true;
m_wantDuplicates = false;
m_shouldParse = true;
setInterval(100);
setWindow(100);
} // BLEScan
Expand Down Expand Up @@ -88,15 +89,18 @@ void BLEScan::handleGAPEvent(
// ignore it.
BLEAddress advertisedAddress(param->scan_rst.bda);
bool found = false;

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;
bool shouldDelete = true;

if (!m_wantDuplicates) {
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
found = true;
}

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
Expand All @@ -107,19 +111,25 @@ 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.
if (!m_wantDuplicates && !found) { // If we have previously seen this device, don't record it again.
Copy link
Contributor

@chegewara chegewara May 13, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What will happen if you want duplicates?
m_wantDuplicates = true
In that case this will always return false and device will never be inserted to a vector:
if (!m_wantDuplicates && !found)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when start continuous scan with callback. vector add allocate without de-allocatted that cause ESP restart.

when not to keep in vector

  1. callback was defined.
    or 2. wantDuplicates = true
    or 3. already in vector (found = true)

m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
shouldDelete = false;
}

if (m_pAdvertisedDeviceCallbacks) {
m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
}
if(found)
if (shouldDelete) {
delete advertisedDevice;
}

break;
} // ESP_GAP_SEARCH_INQ_RES_EVT
Expand Down Expand Up @@ -159,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.
Expand Down
4 changes: 3 additions & 1 deletion libraries/BLE/src/BLEScan.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ class BLEScan {
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);
Expand All @@ -73,6 +74,7 @@ class BLEScan {
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;
Expand Down