3#ifdef USE_BLE_SCAN_RESPONSE_MERGER
11void ScanResponseMerger::deliver_(
const uint8_t *mac, int8_t rssi, uint8_t addr_type,
const uint8_t *data,
12 uint8_t data_len,
bool raw_only) {
14 if (this->dispatcher_ ==
nullptr || this->scan_continuous_ ==
nullptr)
16 this->dispatcher_->
dispatch(mac, rssi, addr_type, data, data_len, raw_only,
17 *this->scan_continuous_ ?
nullptr : this->log_tag_);
24 PendingAdv *slot =
nullptr;
25 PendingAdv *free_slot =
nullptr;
26 for (
auto &p : this->pending_adv_) {
28 if (free_slot ==
nullptr)
32 if (p.addr_type == addr_type && memcmp(p.mac, mac, MAC_ADDRESS_SIZE) == 0) {
37 this->pending_count_--;
38 this->deliver_(p.mac, p.rssi, p.addr_type, p.data, p.data_len,
false);
45 if (slot ==
nullptr) {
47 this->deliver_(mac, rssi, addr_type, data, data_len,
false);
51 this->pending_count_++;
52 memcpy(slot->mac, mac, MAC_ADDRESS_SIZE);
53 slot->addr_type = addr_type;
55 slot->data_len = (data_len <=
sizeof(slot->data)) ? data_len :
sizeof(slot->data);
56 memcpy(slot->data, data, slot->data_len);
57 slot->stored_ms = now;
64 if (this->pending_count_ != 0) {
65 for (
auto &p : this->pending_adv_) {
66 if (p.used && p.addr_type == addr_type && memcmp(p.mac, mac, MAC_ADDRESS_SIZE) == 0) {
69 const uint8_t room =
sizeof(p.data) - p.data_len;
70 const uint8_t add = (data_len <= room) ? data_len : room;
71 memcpy(p.data + p.data_len, data, add);
73 this->pending_count_--;
75 this->deliver_(mac, p.rssi, addr_type, p.data, p.data_len + add,
false);
83 this->deliver_(mac, rssi, addr_type, data, data_len,
true);
87 if (this->pending_count_ == 0)
89 for (
auto &p : this->pending_adv_) {
90 if (p.used && now - p.stored_ms > PENDING_ADV_TIMEOUT_MS) {
92 this->pending_count_--;
93 this->deliver_(p.mac, p.rssi, p.addr_type, p.data, p.data_len,
false);
99 if (this->pending_count_ == 0)
101 for (
auto &p : this->pending_adv_) {
104 this->pending_count_--;
105 this->deliver_(p.mac, p.rssi, p.addr_type, p.data, p.data_len,
false);
111 bool raw_only,
const char *log_unclaimed_tag) {
117 .data_len = data_len,
119 .addr_type = addr_type};
123#ifdef ESPHOME_BLE_DEVICE_BASE_LISTENER_COUNT
134 if (listener->parse_device(device)) {
138 if (!found && log_unclaimed_tag !=
nullptr)
144#ifdef ESPHOME_BLE_DEVICE_BASE_LISTENER_COUNT
146 listener->on_scan_end();
StaticVector< ESPBTDeviceListener *, ESPHOME_BLE_DEVICE_BASE_LISTENER_COUNT > listeners_
RawAdvertisementCallback raw_callback_
DiscoveredDeviceLog discovered_log_
void on_scan_end()
Fire listeners' on_scan_end and reset the per-scan discovered-log dedup.
void dispatch(const uint8_t *mac, int8_t rssi, uint8_t addr_type, const uint8_t *data, uint8_t data_len, bool raw_only, const char *log_unclaimed_tag)
Dispatch one (possibly merged) advertisement: the raw callback, and — unless raw_only — parsing for l...
void clear()
Reset the per-period dedup list (call when a scan period ends).
void log_device(const char *tag, const ESPBTDevice &device)
Log the device at DEBUG the first time its MAC is seen this scan period.
void from_scan_result(const uint8_t *mac, int rssi, uint8_t addr_type, const uint8_t *data, uint16_t data_len)
Populate from a raw scan result delivered by a BLE tracker backend.
void stash_adv(const uint8_t *mac, int8_t rssi, uint8_t addr_type, const uint8_t *data, uint8_t data_len, uint32_t now)
Hold a scannable advertisement, waiting for its scan response.
void sweep(uint32_t now)
Timeout flush (call from loop() with the stash_adv() clock): deliver held advertisements whose scan r...
void flush()
Deliver every held advertisement now (scan period/scan is ending, before on_scan_end fires): unmerged...
void submit_scan_rsp(const uint8_t *mac, int8_t rssi, uint8_t addr_type, const uint8_t *data, uint8_t data_len)
A scan response arrived: append it to the held advertisement from the same device and deliver the pai...
uint64_t mac_lsb_first_to_uint64(const uint8_t *mac)
Pack a controller-order (LSB-first) MAC into the uint64 the API speaks.
bool is_set() const
A default-constructed slot is "no subscriber"; hubs must guard on this.
void invoke(const RawAdvertisement &adv) const
One raw advertisement as delivered by the controller — a borrowed view, valid only for the duration o...