ESPHome 2026.8.0b4
Loading...
Searching...
No Matches
bluetooth_connection_bluedroid.h
Go to the documentation of this file.
1// Bluedroid (esp32) GATT client backend: the esp32 arm of the
2// ble_device_base::BLEGattConnection alias for the hub BluetoothConnection
3// wrapper. Not a BLEClientBase: the tracker's promote loop owns
4// scan-stop/coex/one-connect-at-a-time, so the contract's connect() only
5// parks the address in DISCOVERED; the real esp_ble_gattc_open happens in
6// the tracker-invoked connect() override.
7
8#pragma once
9
11
12#if defined(USE_ESP32_BLE) && defined(USE_BLE_GATT_CLIENT)
13
17
18#include <esp_gap_ble_api.h>
19#include <esp_gattc_api.h>
20
22
23#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
25#endif
26
27// One class carries both halves: the tracker's ESPBTClient surface (its
28// promote loop owns scan-stop/coex/one-connect-at-a-time and calls the
29// virtual connect()/disconnect()) and the neutral contract ops. The
30// contract's teardown op is named gatt_disconnect() because the tracker's
31// void disconnect() cannot overload with an int-returning twin.
33 public:
34 static constexpr uint16_t UNSET_CONN_ID = 0xFFFF;
35
36 // Lifecycle of one connection attempt's service search.
37 enum class SearchState : uint8_t {
38 NONE, // no search this attempt
39 PRESTARTED, // issued at OPEN_EVT, no claimant yet
40 PRESTART_DONE, // completed with search_status_ latched, no claimant yet
41 CLAIMED, // in flight with a claimant (pre-started or direct)
42 REPORT_PENDING // completed and claimed: deliver on the next flush
43 };
44
45 void setup() override;
46 void loop() override;
47 void dump_config() override;
48 float get_setup_priority() const override { return setup_priority::AFTER_BLUETOOTH; }
49
50 // Wired by codegen before setup and invariant for the device lifetime.
51 void set_listener(ble_device_base::GattClientListener *listener) { this->listener_ = listener; }
52
53 // ---- esp32_ble_tracker::ESPBTClient ----
54 bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
55 esp_ble_gattc_cb_param_t *param) override;
56 void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
57 void connect() override;
58 void disconnect() override;
59 bool wants_parsed_advertisements() override { return false; }
60 void on_scan_end() override {}
61 bool parse_device(const ble_device_base::ESPBTDevice &device) override { return false; }
62
63 // ---- ble_device_base::BLEGattConnection contract ----
64 int connect(uint64_t address, uint8_t addr_type);
65 int gatt_disconnect();
68 int read_characteristic(uint16_t handle);
69 int write_characteristic(uint16_t handle, const uint8_t *data, uint16_t len, bool response);
70 int read_descriptor(uint16_t handle);
71 int write_descriptor(uint16_t handle, const uint8_t *data, uint16_t len);
72 int notify_characteristic(uint16_t handle, bool enable);
73 int pair();
74 int update_connection_params(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout);
75 // Contract stub: the proxy streams in place; the on-demand materializer
76 // for direct consumers lands with #18205. NOTE: a direct consumer reaching
77 // this stub gets an empty table indistinguishable from a service-less
78 // peer - do not ship one against this backend before the materializer.
80 void release_services();
81
82#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
87#endif
88
90
91 protected:
92 bool check_addr_(const esp_bd_addr_t &addr) const;
93 void tracker_connect_();
94 void handle_open_evt_(esp_ble_gattc_cb_param_t *param);
95 void handle_disconnect_evt_(esp_ble_gattc_cb_param_t *param);
96 int handle_search_cmpl_(esp_gatt_status_t status);
99 void set_idle_();
100 void set_disconnecting_();
101 esp_err_t update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout,
102 const char *param_type);
103 int check_and_log_error_(const char *operation, esp_err_t err);
104 void log_gattc_warning_(const char *operation, int code);
105
106 // Group 1: pointers / composed objects
108 // Group 2: 4-byte types
110
111 // Group 3: arrays
112 esp_bd_addr_t remote_bda_{};
113
114 // Group 4: 2-byte types
116 uint16_t service_total_{0};
117
118 // Group 5: 1-byte types
119 esp_gatt_if_t gattc_if_{ESP_GATT_IF_NONE}; // uint8_t width keeps the object at 48 bytes
120 // Stored narrow (the enum is 4 bytes); widened at the esp_ble_gattc_open call.
122 esp32_ble_tracker::ConnectionType connection_type_{esp32_ble_tracker::ConnectionType::V3_WITHOUT_CACHE};
124 // Terminates an in-flight stream (never send a partial list as authoritative)
125 // and marks a cleaned cache unsafe to walk (Bluedroid asserts).
126 bool services_released_ : 1 {false};
127 // The connected report waits for the MTU exchange; OPEN_EVT alone would
128 // hand HA the default 23.
129 bool seen_mtu_ : 1 {false};
130 // The MTU request was refused at CONNECT_EVT; OPEN_EVT reports instead.
131 bool mtu_failed_ : 1 {false};
132 // Search issued at OPEN_EVT overlaps the MTU exchange; discover_services()
133 // completes from it. Reset by set_idle_().
134 static_assert(static_cast<uint8_t>(SearchState::REPORT_PENDING) < (1 << 4), "search_state_ bitfield too narrow");
136 // esp_gatt_status_t of the completed search, held until claimed.
137 uint8_t search_status_{0};
138};
139
140} // namespace esphome::bluetooth_connection
141
142#endif // USE_ESP32_BLE && USE_BLE_GATT_CLIENT
uint8_t address
Definition bl0906.h:4
The event surface a backend delivers completions through - the one place with genuine runtime polymor...
esp_err_t update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout, const char *param_type)
void set_listener(ble_device_base::GattClientListener *listener)
bool parse_device(const ble_device_base::ESPBTDevice &device) override
int write_descriptor(uint16_t handle, const uint8_t *data, uint16_t len)
int write_characteristic(uint16_t handle, const uint8_t *data, uint16_t len, bool response)
void set_connection_type(ble_device_base::ConnectionType ct)
int update_connection_params(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout)
void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override
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 stream_service_batch(BluetoothConnection &conn)
In-place service streamer (the proxy wrapper detects and prefers it): builds one api response batch d...
Base class for BLE GATT clients that connect to remote devices.
bluetooth_connection::BluetoothConnection BluetoothConnection
constexpr float AFTER_BLUETOOTH
Definition component.h:49
const void size_t len
Definition hal.h:64
static void uint32_t
Borrowed view of the backend-owned service table.
spi_device_handle_t handle