Skip to content

Commit dccb4e8

Browse files
authored
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
1 parent c2346c3 commit dccb4e8

File tree

4 files changed

+40
-19
lines changed

4 files changed

+40
-19
lines changed

Diff for: libraries/BLE/src/BLEAdvertisedDevice.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,15 @@ void BLEAdvertisedDevice::parseAdvertisement(uint8_t* payload, size_t total_len)
388388
} // !finished
389389
} // parseAdvertisement
390390

391+
/**
392+
* @brief Parse the advertising payload.
393+
* @param [in] payload The payload of the advertised device.
394+
* @param [in] total_len The length of payload
395+
*/
396+
void BLEAdvertisedDevice::setPayload(uint8_t* payload, size_t total_len) {
397+
m_payload = payload;
398+
m_payloadLength = total_len;
399+
} // setPayload
391400

392401
/**
393402
* @brief Set the address of the advertised device.

Diff for: libraries/BLE/src/BLEAdvertisedDevice.h

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class BLEAdvertisedDevice {
6464
friend class BLEScan;
6565

6666
void parseAdvertisement(uint8_t* payload, size_t total_len=62);
67+
void setPayload(uint8_t* payload, size_t total_len=62);
6768
void setAddress(BLEAddress address);
6869
void setAdFlag(uint8_t adFlag);
6970
void setAdvertizementResult(uint8_t* payload);

Diff for: libraries/BLE/src/BLEScan.cpp

+27-18
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ BLEScan::BLEScan() {
3030
m_pAdvertisedDeviceCallbacks = nullptr;
3131
m_stopped = true;
3232
m_wantDuplicates = false;
33+
m_shouldParse = true;
3334
setInterval(100);
3435
setWindow(100);
3536
} // BLEScan
@@ -90,15 +91,18 @@ void BLEScan::handleGAPEvent(
9091
// ignore it.
9192
BLEAddress advertisedAddress(param->scan_rst.bda);
9293
bool found = false;
93-
94-
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
95-
found = true;
96-
}
97-
98-
if (found && !m_wantDuplicates) { // If we found a previous entry AND we don't want duplicates, then we are done.
99-
log_d("Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
100-
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
101-
break;
94+
bool shouldDelete = true;
95+
96+
if (!m_wantDuplicates) {
97+
if (m_scanResults.m_vectorAdvertisedDevices.count(advertisedAddress.toString()) != 0) {
98+
found = true;
99+
}
100+
101+
if (found) { // If we found a previous entry AND we don't want duplicates, then we are done.
102+
log_d("Ignoring %s, already seen it.", advertisedAddress.toString().c_str());
103+
vTaskDelay(1); // <--- allow to switch task in case we scan infinity and dont have new devices to report, or we are blocked here
104+
break;
105+
}
102106
}
103107

104108
// We now construct a model of the advertised device that we have just found for the first
@@ -109,19 +113,23 @@ void BLEScan::handleGAPEvent(
109113
advertisedDevice->setAddress(advertisedAddress);
110114
advertisedDevice->setRSSI(param->scan_rst.rssi);
111115
advertisedDevice->setAdFlag(param->scan_rst.flag);
112-
advertisedDevice->parseAdvertisement((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
116+
if (m_shouldParse) {
117+
advertisedDevice->parseAdvertisement((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
118+
} else {
119+
advertisedDevice->setPayload((uint8_t*)param->scan_rst.ble_adv, param->scan_rst.adv_data_len + param->scan_rst.scan_rsp_len);
120+
}
113121
advertisedDevice->setScan(this);
114122
advertisedDevice->setAddressType(param->scan_rst.ble_addr_type);
115123

116-
if (!found) { // If we have previously seen this device, don't record it again.
117-
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
118-
}
119-
120-
if (m_pAdvertisedDeviceCallbacks) {
124+
if (m_pAdvertisedDeviceCallbacks) { // if has callback, no need to record to vector
121125
m_pAdvertisedDeviceCallbacks->onResult(*advertisedDevice);
126+
} else if (!m_wantDuplicates && !found) { // if no callback and not want duplicate, and not already in vector, record it
127+
m_scanResults.m_vectorAdvertisedDevices.insert(std::pair<std::string, BLEAdvertisedDevice*>(advertisedAddress.toString(), advertisedDevice));
128+
shouldDelete = false;
122129
}
123-
if(found)
130+
if (shouldDelete) {
124131
delete advertisedDevice;
132+
}
125133

126134
break;
127135
} // ESP_GAP_SEARCH_INQ_RES_EVT
@@ -161,13 +169,14 @@ void BLEScan::setActiveScan(bool active) {
161169
* @brief Set the call backs to be invoked.
162170
* @param [in] pAdvertisedDeviceCallbacks Call backs to be invoked.
163171
* @param [in] wantDuplicates True if we wish to be called back with duplicates. Default is false.
172+
* @param [in] shouldParse True if we wish to parse advertised package or raw payload. Default is true.
164173
*/
165-
void BLEScan::setAdvertisedDeviceCallbacks(BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates) {
174+
void BLEScan::setAdvertisedDeviceCallbacks(BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks, bool wantDuplicates, bool shouldParse) {
166175
m_wantDuplicates = wantDuplicates;
167176
m_pAdvertisedDeviceCallbacks = pAdvertisedDeviceCallbacks;
177+
m_shouldParse = shouldParse;
168178
} // setAdvertisedDeviceCallbacks
169179

170-
171180
/**
172181
* @brief Set the interval to scan.
173182
* @param [in] The interval in msecs.

Diff for: libraries/BLE/src/BLEScan.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ class BLEScan {
5151
void setActiveScan(bool active);
5252
void setAdvertisedDeviceCallbacks(
5353
BLEAdvertisedDeviceCallbacks* pAdvertisedDeviceCallbacks,
54-
bool wantDuplicates = false);
54+
bool wantDuplicates = false,
55+
bool shouldParse = true);
5556
void setInterval(uint16_t intervalMSecs);
5657
void setWindow(uint16_t windowMSecs);
5758
bool start(uint32_t duration, void (*scanCompleteCB)(BLEScanResults), bool is_continue = false);
@@ -73,6 +74,7 @@ class BLEScan {
7374
esp_ble_scan_params_t m_scan_params;
7475
BLEAdvertisedDeviceCallbacks* m_pAdvertisedDeviceCallbacks = nullptr;
7576
bool m_stopped = true;
77+
bool m_shouldParse = true;
7678
FreeRTOS::Semaphore m_semaphoreScanEnd = FreeRTOS::Semaphore("ScanEnd");
7779
BLEScanResults m_scanResults;
7880
bool m_wantDuplicates;

0 commit comments

Comments
 (0)