[bluetooth_proxy] Replace loop() with set_interval for advertisement flushing (#15347)

This commit is contained in:
J. Nick Koston
2026-04-01 16:11:50 -10:00
committed by GitHub
parent eefbb42be4
commit 27c662e73f
2 changed files with 27 additions and 38 deletions
@@ -30,6 +30,19 @@ void BluetoothProxy::setup() {
this->configured_scan_active_ = this->parent_->get_scan_active();
this->parent_->add_scanner_state_listener(this);
this->set_interval(100, [this]() {
if (api::global_api_server->is_connected() && this->api_connection_ != nullptr) {
this->flush_pending_advertisements_();
return;
}
for (uint8_t i = 0; i < this->connection_count_; i++) {
auto *connection = this->connections_[i];
if (connection->get_address() != 0 && !connection->disconnect_pending()) {
connection->disconnect();
}
}
});
}
void BluetoothProxy::on_scanner_state(esp32_ble_tracker::ScannerState state) {
@@ -101,25 +114,15 @@ bool BluetoothProxy::parse_devices(const esp32_ble::BLEScanResult *scan_results,
// Flush if we have reached BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE
if (this->response_.advertisements_len >= BLUETOOTH_PROXY_ADVERTISEMENT_BATCH_SIZE) {
this->flush_pending_advertisements();
this->flush_pending_advertisements_();
}
}
return true;
}
void BluetoothProxy::flush_pending_advertisements() {
if (this->response_.advertisements_len == 0 || !api::global_api_server->is_connected() ||
this->api_connection_ == nullptr)
return;
// Send the message
this->api_connection_->send_message(this->response_);
void BluetoothProxy::log_advertisement_flush_() {
ESP_LOGV(TAG, "Sent batch of %u BLE advertisements", this->response_.advertisements_len);
// Reset the length for the next batch
this->response_.advertisements_len = 0;
}
void BluetoothProxy::dump_config() {
@@ -130,27 +133,6 @@ void BluetoothProxy::dump_config() {
YESNO(this->active_), this->connection_count_);
}
void BluetoothProxy::loop() {
if (!api::global_api_server->is_connected() || this->api_connection_ == nullptr) {
for (uint8_t i = 0; i < this->connection_count_; i++) {
auto *connection = this->connections_[i];
if (connection->get_address() != 0 && !connection->disconnect_pending()) {
connection->disconnect();
}
}
return;
}
// Flush any pending BLE advertisements that have been accumulated but not yet sent
uint32_t now = App.get_loop_component_start_time();
// Flush accumulated advertisements every 100ms
if (now - this->last_advertisement_flush_time_ >= 100) {
this->flush_pending_advertisements();
this->last_advertisement_flush_time_ = now;
}
}
esp32_ble_tracker::AdvertisementParserType BluetoothProxy::get_advertisement_parser_type() {
return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
}
@@ -65,8 +65,6 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener,
bool parse_devices(const esp32_ble::BLEScanResult *scan_results, size_t count) override;
void dump_config() override;
void setup() override;
void loop() override;
void flush_pending_advertisements();
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
void register_connection(BluetoothConnection *connection) {
@@ -150,6 +148,18 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener,
protected:
void send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerState state);
/// Caller must ensure api_connection_ is non-null and API server is connected.
void flush_pending_advertisements_() {
if (this->response_.advertisements_len == 0)
return;
this->api_connection_->send_message(this->response_);
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
this->log_advertisement_flush_();
#endif
this->response_.advertisements_len = 0;
}
void log_advertisement_flush_();
BluetoothConnection *get_connection_(uint64_t address, bool reserve);
void log_connection_request_ignored_(BluetoothConnection *connection, espbt::ClientState state);
void log_connection_info_(BluetoothConnection *connection, const char *message);
@@ -166,9 +176,6 @@ class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener,
// BLE advertisement batching
api::BluetoothLERawAdvertisementsResponse response_;
// Group 3: 4-byte types
uint32_t last_advertisement_flush_time_{0};
// Pre-allocated response message - always ready to send
api::BluetoothConnectionsFreeResponse connections_free_response_;