From 32ea82060d5e134577bbfaf26531b885dc096c75 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 1 Nov 2025 15:02:26 -0500 Subject: [PATCH] fix ble latency --- esphome/components/esp32_ble/ble.cpp | 13 +++++++++++++ esphome/components/esp32_ble/ble.h | 12 +++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/esphome/components/esp32_ble/ble.cpp b/esphome/components/esp32_ble/ble.cpp index 7298dc9621..797dbcc2bf 100644 --- a/esphome/components/esp32_ble/ble.cpp +++ b/esphome/components/esp32_ble/ble.cpp @@ -723,6 +723,19 @@ void ESP32BLE::cleanup_event_notification_() { } } +void ESP32BLE::drain_event_notifications_() { + // Called from main loop to drain any pending notifications + // Must check is_socket_ready() to avoid blocking on empty socket + if (this->notify_fd_ >= 0 && App.is_socket_ready(this->notify_fd_)) { + char buffer[BLE_EVENT_NOTIFY_DRAIN_BUFFER_SIZE]; + // Drain all pending notifications with non-blocking reads + // Multiple BLE events may have triggered multiple writes, so drain until EWOULDBLOCK + while (lwip_recvfrom(this->notify_fd_, buffer, sizeof(buffer), 0, nullptr, nullptr) > 0) { + // Just draining, no action needed + } + } +} + #endif // USE_SOCKET_SELECT_SUPPORT uint64_t ble_addr_to_uint64(const esp_bd_addr_t address) { diff --git a/esphome/components/esp32_ble/ble.h b/esphome/components/esp32_ble/ble.h index 93c03063c6..a91d8756a8 100644 --- a/esphome/components/esp32_ble/ble.h +++ b/esphome/components/esp32_ble/ble.h @@ -167,10 +167,10 @@ class ESP32BLE : public Component { #endif #ifdef USE_SOCKET_SELECT_SUPPORT - void setup_event_notification_(); // Create notification socket - void cleanup_event_notification_(); // Close and unregister socket - inline void notify_main_loop_(); // Wake up select() from BLE thread (hot path - inlined) - inline void drain_event_notifications_(); // Read pending notifications in main loop (hot path - inlined) + void setup_event_notification_(); // Create notification socket + void cleanup_event_notification_(); // Close and unregister socket + inline void notify_main_loop_(); // Wake up select() from BLE thread (hot path - inlined) + void drain_event_notifications_(); // Read pending notifications in main loop #endif private: @@ -248,9 +248,7 @@ inline void ESP32BLE::notify_main_loop_() { inline void ESP32BLE::drain_event_notifications_() { // Called from main loop to drain any pending notifications // Must check is_socket_ready() to avoid blocking on empty socket - // Requires App to be defined - include esphome/core/application.h in .cpp files that use this - extern esphome::Application App; - if (this->notify_fd_ >= 0 && App.is_socket_ready(this->notify_fd_)) { + if (this->notify_fd_ >= 0 && esphome::App.is_socket_ready(this->notify_fd_)) { char buffer[BLE_EVENT_NOTIFY_DRAIN_BUFFER_SIZE]; // Drain all pending notifications with non-blocking reads // Multiple BLE events may have triggered multiple writes, so drain until EWOULDBLOCK