[esp32_ble_tracker] Retire the raw listener path and parser-type enum (#18177)

This commit is contained in:
J. Nick Koston
2026-08-08 19:13:07 -05:00
committed by GitHub
parent 8c74e3d5ef
commit c7d6b4aaa4
7 changed files with 30 additions and 94 deletions
@@ -479,12 +479,6 @@ esp_err_t BluetoothConnection::notify_characteristic(uint16_t handle, bool enabl
return this->check_and_log_error_("esp_ble_gattc_unregister_for_notify", err);
}
esp32_ble_tracker::AdvertisementParserType BluetoothConnection::get_advertisement_parser_type() {
// RAW keeps the tracker from building parsed ESPBTDevice objects for the
// proxy's connections (the proxy itself consumes the hub raw callback).
return esp32_ble_tracker::AdvertisementParserType::RAW_ADVERTISEMENTS;
}
} // namespace esphome::bluetooth_connection
#endif // USE_ESP32
@@ -21,7 +21,8 @@ class BluetoothConnection final : public esp32_ble_client::BLEClientBase {
bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) override;
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
esp32_ble_tracker::AdvertisementParserType get_advertisement_parser_type() override;
// The proxy's connections never consume parsed ESPBTDevice objects.
bool wants_parsed_advertisements() override { return false; }
esp_err_t read_characteristic(uint16_t handle);
esp_err_t write_characteristic(uint16_t handle, const uint8_t *data, size_t length, bool response);
@@ -20,10 +20,6 @@
#include "esphome/components/bluetooth_connection/bluetooth_connection_esp32.h"
#ifndef CONFIG_ESP_HOSTED_ENABLE_BT_BLUEDROID
#include <esp_bt.h>
#endif
#include <esp_bt_device.h>
#else
#include "esphome/components/ble_device_base/ble_hub.h"
#ifdef USE_BLE_GATT_CLIENT
@@ -179,28 +175,15 @@ class BluetoothProxy final : public Component {
}
void get_bluetooth_mac_address_pretty(std::span<char, 18> output) {
#ifdef USE_ESP32
const uint8_t *mac = esp_bt_dev_get_address();
if (mac != nullptr) {
format_mac_addr_upper(mac, output.data());
} else {
output[0] = '\0';
}
#else
uint8_t mac[6] = {};
this->hub_->get_adapter_mac(mac);
// Mirror the esp32 arm's unavailable -> empty-string fallback: some hubs
// (rp2040's BTstack) only learn the address once the link layer is up, and
// report all-zero until then.
bool nonzero = false;
for (uint8_t b : mac)
nonzero |= b != 0;
if (nonzero) {
// Unavailable -> empty string: some hubs (rp2040's BTstack) only learn
// the address once the link layer is up, and report all-zero until then.
if (mac_address_is_valid(mac)) {
format_mac_addr_upper(mac, output.data());
} else {
output[0] = '\0';
}
#endif
}
protected:
+14 -2
View File
@@ -674,11 +674,23 @@ void ESP32BLE::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gat
}
#endif
void ESP32BLE::get_mac_msb_first(uint8_t out[6]) const {
// The running stack owns the address (on hosted controllers it lives in
// the remote chip's efuse); null before init becomes all-zero.
const uint8_t *mac = esp_bt_dev_get_address();
if (mac != nullptr) {
memcpy(out, mac, 6);
} else {
memset(out, 0, 6);
}
}
float ESP32BLE::get_setup_priority() const { return setup_priority::BLUETOOTH; }
void ESP32BLE::dump_config() {
const uint8_t *mac_address = esp_bt_dev_get_address();
if (mac_address) {
uint8_t mac_address[6];
this->get_mac_msb_first(mac_address);
if (mac_address_is_valid(mac_address)) {
const char *io_capability_s;
switch (this->io_cap_) {
case ESP_IO_CAP_OUT:
+2
View File
@@ -108,6 +108,8 @@ class ESP32BLE final : public Component {
void setup() override;
void loop() override;
void dump_config() override;
/// Adapter MAC in printable (MSB-first) order; all-zero until the stack is up.
void get_mac_msb_first(uint8_t out[6]) const;
float get_setup_priority() const override;
void set_name(const char *name) { this->name_ = name; }
@@ -271,7 +271,9 @@ void ESP32BLETracker::register_client(ESPBTClient *client) {
// Safe because ESP32BLETracker (singleton) outlives all registered clients.
client->set_tracker_state_version(&this->state_version_);
this->clients_.push_back(client);
this->recalculate_advertisement_parser_types();
// Registration is add-only, so the flag is a monotonic OR.
if (client->wants_parsed_advertisements())
this->parse_advertisements_ = true;
#endif
}
@@ -283,48 +285,11 @@ void ESP32BLETracker::register_listener(ble_device_base::ESPBTDeviceListener *li
#endif
}
void ESP32BLETracker::get_adapter_mac(uint8_t out[6]) {
get_mac_address_raw(out); // WiFi base MAC, MSB-first
// BT MAC = base MAC + 2 on the last octet only, wrapping without carry —
// exactly ESP-IDF's esp_read_mac(ESP_MAC_BT): mac[5] += MAC_ADDR_UNIVERSE_BT_OFFSET.
out[5] += 2;
}
void ESP32BLETracker::register_listener(ESPBTDeviceListener *listener) {
#ifdef ESPHOME_ESP32_BLE_TRACKER_LISTENER_COUNT
listener->set_parent(this);
this->listeners_.push_back(listener);
this->recalculate_advertisement_parser_types();
#endif
}
void ESP32BLETracker::recalculate_advertisement_parser_types() {
this->raw_advertisements_ = false;
this->parse_advertisements_ = false;
#ifdef ESPHOME_BLE_DEVICE_BASE_LISTENER_COUNT
// Neutral (BLEHub) listeners are parsed-advertisement consumers and are not in
// listeners_; without this, any later esp32-path registration (e.g. the proxy's
// GATT clients) would recompute the flags and silently drop parsed dispatch.
if (!this->neutral_listeners_.empty())
this->parse_advertisements_ = true;
#endif
#ifdef ESPHOME_ESP32_BLE_TRACKER_LISTENER_COUNT
for (auto *listener : this->listeners_) {
if (listener->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
this->parse_advertisements_ = true;
} else {
this->raw_advertisements_ = true;
}
}
#endif
#ifdef ESPHOME_ESP32_BLE_TRACKER_CLIENT_COUNT
for (auto *client : this->clients_) {
if (client->get_advertisement_parser_type() == AdvertisementParserType::PARSED_ADVERTISEMENTS) {
this->parse_advertisements_ = true;
} else {
this->raw_advertisements_ = true;
}
}
this->parse_advertisements_ = true;
#endif
}
@@ -478,20 +443,6 @@ void ESP32BLETracker::process_scan_result_(const BLEScanResult &scan_result) {
this->raw_advertisement_callback_.invoke(adv);
}
// Process raw advertisements
if (this->raw_advertisements_) {
#ifdef ESPHOME_ESP32_BLE_TRACKER_LISTENER_COUNT
for (auto *listener : this->listeners_) {
listener->parse_devices(&scan_result, 1);
}
#endif
#ifdef ESPHOME_ESP32_BLE_TRACKER_CLIENT_COUNT
for (auto *client : this->clients_) {
client->parse_devices(&scan_result, 1);
}
#endif
}
// Process parsed advertisements
if (this->parse_advertisements_) {
#ifdef USE_ESP32_BLE_DEVICE
@@ -35,11 +35,6 @@ using namespace esp32_ble;
using adv_data_t = ble_device_base::adv_data_t;
enum AdvertisementParserType {
PARSED_ADVERTISEMENTS,
RAW_ADVERTISEMENTS,
};
#ifdef USE_ESP32_BLE_UUID
using ServiceData = ble_device_base::ServiceData;
#endif
@@ -63,10 +58,6 @@ class ESPBTDeviceListener : public ble_device_base::ESPBTDeviceListener {
// Raw-only build: no parsed-device support is compiled in.
bool parse_device(const ble_device_base::ESPBTDevice &device) override { return false; }
#endif
virtual bool parse_devices(const BLEScanResult *scan_results, size_t count) { return false; };
virtual AdvertisementParserType get_advertisement_parser_type() {
return AdvertisementParserType::PARSED_ADVERTISEMENTS;
};
void set_parent(ESP32BLETracker *parent) { parent_ = parent; }
protected:
@@ -123,6 +114,10 @@ class BLEScannerStateListener {
/// The pointer may be null if the client is not registered with a tracker.
class ESPBTClient : public ESPBTDeviceListener {
public:
/// False keeps the tracker from building parsed ESPBTDevice objects on
/// this client's account (raw consumers use the hub callback).
virtual bool wants_parsed_advertisements() { return true; }
virtual bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
esp_ble_gattc_cb_param_t *param) = 0;
virtual void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) = 0;
@@ -199,7 +194,6 @@ class ESP32BLETracker final : public Component,
// esp32-flavored path (unmigrated esp32 sensors; sets the tracker back-pointer).
void register_listener(ESPBTDeviceListener *listener);
void register_client(ESPBTClient *client);
void recalculate_advertisement_parser_types();
// ---- ble_device_base::BLEHub (the platform-neutral tracker contract) ----
void register_listener(ble_device_base::ESPBTDeviceListener *listener) override;
@@ -212,7 +206,7 @@ class ESP32BLETracker final : public Component,
return {/* active_scan = */ true, /* merges_scan_response = */ true, /* gatt = */ true,
/* scan_mode_switch = */ false};
}
void get_adapter_mac(uint8_t out[6]) override;
void get_adapter_mac(uint8_t out[6]) override { this->parent_->get_mac_msb_first(out); }
bool scan_running() override { return this->scanner_state_ == ScannerState::RUNNING; }
bool scan_active() override { return this->scan_active_; }
@@ -355,7 +349,6 @@ class ESP32BLETracker final : public Component,
bool scan_continuous_before_ota_{false};
#endif
bool ble_was_disabled_{true};
bool raw_advertisements_{false};
bool parse_advertisements_{false};
#ifdef USE_ESP32_BLE_SOFTWARE_COEXISTENCE
bool coex_prefer_ble_{false};