diff --git a/esphome/components/esp32_ble/ble.cpp b/esphome/components/esp32_ble/ble.cpp index 917467d1ad..24bb8cc642 100644 --- a/esphome/components/esp32_ble/ble.cpp +++ b/esphome/components/esp32_ble/ble.cpp @@ -23,6 +23,9 @@ namespace esp32_ble { static const char *const TAG = "esp32_ble"; +// Maximum size of the BLE event queue +static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2; + static RAMAllocator EVENT_ALLOCATOR( // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) RAMAllocator::ALLOW_FAILURE | RAMAllocator::ALLOC_INTERNAL); @@ -333,8 +336,8 @@ void ESP32BLE::loop() { // Cast is safe because all three event structures start with status this->real_gap_event_handler_(gap_event, (esp_ble_gap_cb_param_t *) &scan_complete_param); } else { - // Unexpected GAP event - log and drop - ESP_LOGW(TAG, "Unexpected GAP event type: %d", gap_event); + // Unexpected GAP event - drop it + ESP_LOGV(TAG, "Unexpected GAP event type: %d", gap_event); } break; } @@ -352,17 +355,14 @@ void ESP32BLE::loop() { } void ESP32BLE::gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) { - static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2; - // Only queue the 4 GAP events we actually handle if (event != ESP_GAP_BLE_SCAN_RESULT_EVT && event != ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT && event != ESP_GAP_BLE_SCAN_START_COMPLETE_EVT && event != ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT) { - ESP_LOGW(TAG, "Ignoring unexpected GAP event type: %d", event); return; } if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) { - ESP_LOGW(TAG, "BLE event queue full (%d), dropping GAP event %d", MAX_BLE_QUEUE_SIZE, event); + ESP_LOGV(TAG, "BLE event queue full (%d), dropping event", MAX_BLE_QUEUE_SIZE); return; } @@ -384,10 +384,8 @@ void ESP32BLE::real_gap_event_handler_(esp_gap_ble_cb_event_t event, esp_ble_gap void ESP32BLE::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { - static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2; - if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) { - ESP_LOGW(TAG, "BLE event queue full (%d), dropping GATTS event %d", MAX_BLE_QUEUE_SIZE, event); + ESP_LOGV(TAG, "BLE event queue full (%d), dropping event", MAX_BLE_QUEUE_SIZE); return; } @@ -410,10 +408,8 @@ void ESP32BLE::real_gatts_event_handler_(esp_gatts_cb_event_t event, esp_gatt_if void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param) { - static constexpr size_t MAX_BLE_QUEUE_SIZE = SCAN_RESULT_BUFFER_SIZE * 2; - if (global_ble->ble_events_.size() >= MAX_BLE_QUEUE_SIZE) { - ESP_LOGW(TAG, "BLE event queue full (%d), dropping GATTC event %d", MAX_BLE_QUEUE_SIZE, event); + ESP_LOGV(TAG, "BLE event queue full (%d), dropping event", MAX_BLE_QUEUE_SIZE); return; } diff --git a/esphome/components/esp32_ble/ble.h b/esphome/components/esp32_ble/ble.h index 4d4fbe4de9..ef006ef73c 100644 --- a/esphome/components/esp32_ble/ble.h +++ b/esphome/components/esp32_ble/ble.h @@ -139,6 +139,7 @@ class ESP32BLE : public Component { bool ble_pre_setup_(); void advertising_init_(); + private: std::vector gap_event_handlers_; std::vector gap_scan_event_handlers_; std::vector gattc_event_handlers_; diff --git a/esphome/components/esp32_ble/ble_event.h b/esphome/components/esp32_ble/ble_event.h index 932d0fef5e..c7574be6cc 100644 --- a/esphome/components/esp32_ble/ble_event.h +++ b/esphome/components/esp32_ble/ble_event.h @@ -36,7 +36,7 @@ class BLEEvent { // Only copy the data we actually use for each GAP event type switch (e) { case ESP_GAP_BLE_SCAN_RESULT_EVT: - // Copy only the fields we use from scan results (~72 bytes) + // Copy only the fields we use from scan results memcpy(this->event_.gap.scan_result.bda, p->scan_rst.bda, sizeof(esp_bd_addr_t)); this->event_.gap.scan_result.ble_addr_type = p->scan_rst.ble_addr_type; this->event_.gap.scan_result.rssi = p->scan_rst.rssi; @@ -142,24 +142,24 @@ class BLEEvent { esp_bt_status_t status; } scan_complete; // 1 byte }; - } gap; // 77 bytes (4 + 73) + } gap; // 80 bytes total // NOLINTNEXTLINE(readability-identifier-naming) struct gattc_event { esp_gattc_cb_event_t gattc_event; esp_gatt_if_t gattc_if; - esp_ble_gattc_cb_param_t *gattc_param; // External allocation - std::vector *data; // External allocation - } gattc; // 16 bytes (4 + 4 + 4 + 4) + esp_ble_gattc_cb_param_t *gattc_param; + std::vector *data; + } gattc; // 16 bytes (pointers only) // NOLINTNEXTLINE(readability-identifier-naming) struct gatts_event { esp_gatts_cb_event_t gatts_event; esp_gatt_if_t gatts_if; - esp_ble_gatts_cb_param_t *gatts_param; // External allocation - std::vector *data; // External allocation - } gatts; // 16 bytes (4 + 4 + 4 + 4) - } event_; // Union size is 80 bytes with padding + esp_ble_gatts_cb_param_t *gatts_param; + std::vector *data; + } gatts; // 16 bytes (pointers only) + } event_; // 80 bytes ble_event_t type_; @@ -169,9 +169,8 @@ class BLEEvent { const BLEScanResult &scan_result() const { return event_.gap.scan_result; } esp_bt_status_t scan_complete_status() const { return event_.gap.scan_complete.status; } }; -// Total size: 84 bytes (80 byte union + 1 byte type + 3 bytes padding) -// Was 296 bytes - 71.6% reduction! -// GATTC/GATTS events use external storage, keeping the queue size minimal + +// BLEEvent total size: 84 bytes (80 byte union + 1 byte type + 3 bytes padding) } // namespace esp32_ble } // namespace esphome