diff --git a/esphome/components/esp32_ble/ble.h b/esphome/components/esp32_ble/ble.h index c43ec8c7ed..4d4fbe4de9 100644 --- a/esphome/components/esp32_ble/ble.h +++ b/esphome/components/esp32_ble/ble.h @@ -2,6 +2,7 @@ #include "ble_advertising.h" #include "ble_uuid.h" +#include "ble_scan_result.h" #include @@ -64,17 +65,6 @@ class GAPEventHandler { virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0; }; -// Structure for BLE scan results - only fields we actually use -struct BLEScanResult { - esp_bd_addr_t bda; - uint8_t ble_addr_type; - int8_t rssi; - uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX]; - uint8_t adv_data_len; - uint8_t scan_rsp_len; - uint8_t search_evt; -}; // ~73 bytes vs ~400 bytes for full esp_ble_gap_cb_param_t - class GAPScanEventHandler { public: // Receives scan results directly without memcpy diff --git a/esphome/components/esp32_ble/ble_event.h b/esphome/components/esp32_ble/ble_event.h index 451c52b114..7b1af08d54 100644 --- a/esphome/components/esp32_ble/ble_event.h +++ b/esphome/components/esp32_ble/ble_event.h @@ -8,6 +8,8 @@ #include #include +#include "ble_scan_result.h" + namespace esphome { namespace esp32_ble { diff --git a/esphome/components/esp32_ble/ble_scan_result.h b/esphome/components/esp32_ble/ble_scan_result.h new file mode 100644 index 0000000000..b46e9ea896 --- /dev/null +++ b/esphome/components/esp32_ble/ble_scan_result.h @@ -0,0 +1,24 @@ +#pragma once + +#ifdef USE_ESP32 + +#include + +namespace esphome { +namespace esp32_ble { + +// Structure for BLE scan results - only fields we actually use +struct BLEScanResult { + esp_bd_addr_t bda; + uint8_t ble_addr_type; + int8_t rssi; + uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX]; + uint8_t adv_data_len; + uint8_t scan_rsp_len; + uint8_t search_evt; +}; // ~73 bytes vs ~400 bytes for full esp_ble_gap_cb_param_t + +} // namespace esp32_ble +} // namespace esphome + +#endif \ No newline at end of file diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp index 09fe451a3c..7168be0825 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp @@ -123,7 +123,7 @@ void ESP32BLETracker::loop() { this->scan_result_index_ && // if it looks like we have a scan result we will take the lock xSemaphoreTake(this->scan_result_lock_, 0)) { uint32_t index = this->scan_result_index_; - if (index >= ESP32BLETracker::SCAN_RESULT_BUFFER_SIZE) { + if (index >= SCAN_RESULT_BUFFER_SIZE) { ESP_LOGW(TAG, "Too many BLE events to process. Some devices may not show up."); } @@ -139,24 +139,7 @@ void ESP32BLETracker::loop() { if (this->parse_advertisements_) { for (size_t i = 0; i < index; i++) { ESPBTDevice device; - // Convert BLEScanResult to ESP-IDF format for parse_scan_rst - esp_ble_gap_cb_param_t::ble_scan_result_evt_param param; - memcpy(param.bda, this->scan_result_buffer_[i].bda, sizeof(esp_bd_addr_t)); - param.ble_addr_type = this->scan_result_buffer_[i].ble_addr_type; - param.rssi = this->scan_result_buffer_[i].rssi; - param.adv_data_len = this->scan_result_buffer_[i].adv_data_len; - param.scan_rsp_len = this->scan_result_buffer_[i].scan_rsp_len; - param.search_evt = this->scan_result_buffer_[i].search_evt; - memcpy(param.ble_adv, this->scan_result_buffer_[i].ble_adv, - ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX); - // Fill in fields we don't store - param.dev_type = 0; - param.ble_evt_type = 0; - param.flag = 0; - param.num_resps = 1; - param.num_dis = 0; - - device.parse_scan_rst(param); + device.parse_scan_rst(this->scan_result_buffer_[i]); bool found = false; for (auto *listener : this->listeners_) { @@ -443,14 +426,14 @@ void ESP32BLETracker::gap_scan_event_handler(const BLEScanResult &scan_result) { esp_ble_gap_cb_param_t param; memset(¶m, 0, sizeof(param)); memcpy(param.scan_rst.bda, scan_result.bda, sizeof(esp_bd_addr_t)); - param.scan_rst.ble_addr_type = scan_result.ble_addr_type; + param.scan_rst.ble_addr_type = static_cast(scan_result.ble_addr_type); param.scan_rst.rssi = scan_result.rssi; param.scan_rst.adv_data_len = scan_result.adv_data_len; param.scan_rst.scan_rsp_len = scan_result.scan_rsp_len; - param.scan_rst.search_evt = scan_result.search_evt; + param.scan_rst.search_evt = static_cast(scan_result.search_evt); memcpy(param.scan_rst.ble_adv, scan_result.ble_adv, ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX); - param.scan_rst.dev_type = 0; - param.scan_rst.ble_evt_type = 0; + param.scan_rst.dev_type = static_cast(0); + param.scan_rst.ble_evt_type = static_cast(0); param.scan_rst.flag = 0; param.scan_rst.num_resps = 1; param.scan_rst.num_dis = 0; @@ -539,13 +522,15 @@ optional ESPBLEiBeacon::from_manufacturer_data(const ServiceData return ESPBLEiBeacon(data.data.data()); } -void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) { - this->scan_result_ = param; +void ESPBTDevice::parse_scan_rst(const BLEScanResult &scan_result) { for (uint8_t i = 0; i < ESP_BD_ADDR_LEN; i++) - this->address_[i] = param.bda[i]; - this->address_type_ = param.ble_addr_type; - this->rssi_ = param.rssi; - this->parse_adv_(param); + this->address_[i] = scan_result.bda[i]; + this->address_type_ = static_cast(scan_result.ble_addr_type); + this->rssi_ = scan_result.rssi; + + // Parse advertisement data directly + uint8_t total_len = scan_result.adv_data_len + scan_result.scan_rsp_len; + this->parse_adv_(scan_result.ble_adv, total_len); #ifdef ESPHOME_LOG_HAS_VERY_VERBOSE ESP_LOGVV(TAG, "Parse Result:"); @@ -603,13 +588,13 @@ void ESPBTDevice::parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_e ESP_LOGVV(TAG, " Data: %s", format_hex_pretty(data.data).c_str()); } - ESP_LOGVV(TAG, " Adv data: %s", format_hex_pretty(param.ble_adv, param.adv_data_len + param.scan_rsp_len).c_str()); + ESP_LOGVV(TAG, " Adv data: %s", + format_hex_pretty(scan_result.ble_adv, scan_result.adv_data_len + scan_result.scan_rsp_len).c_str()); #endif } -void ESPBTDevice::parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m) { + +void ESPBTDevice::parse_adv_(const uint8_t *payload, uint8_t len) { size_t offset = 0; - const uint8_t *payload = param.ble_adv; - uint8_t len = param.adv_data_len + param.scan_rsp_len; while (offset + 2 < len) { const uint8_t field_length = payload[offset++]; // First byte is length of adv record diff --git a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h index 75f164c137..50a1a14740 100644 --- a/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +++ b/esphome/components/esp32_ble_tracker/esp32_ble_tracker.h @@ -62,7 +62,7 @@ class ESPBLEiBeacon { class ESPBTDevice { public: - void parse_scan_rst(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m); + void parse_scan_rst(const BLEScanResult &scan_result); std::string address_str() const; @@ -84,8 +84,6 @@ class ESPBTDevice { const std::vector &get_service_datas() const { return service_datas_; } - const esp_ble_gap_cb_param_t::ble_scan_result_evt_param &get_scan_result() const { return scan_result_; } - bool resolve_irk(const uint8_t *irk) const; optional get_ibeacon() const { @@ -98,7 +96,7 @@ class ESPBTDevice { } protected: - void parse_adv_(const esp_ble_gap_cb_param_t::ble_scan_result_evt_param ¶m); + void parse_adv_(const uint8_t *payload, uint8_t len); esp_bd_addr_t address_{ 0, @@ -112,7 +110,6 @@ class ESPBTDevice { std::vector service_uuids_{}; std::vector manufacturer_datas_{}; std::vector service_datas_{}; - esp_ble_gap_cb_param_t::ble_scan_result_evt_param scan_result_{}; }; class ESP32BLETracker;