ESPHome 2026.11.0-dev
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 // User provided, not "= default": `new(p) BluedroidGattClient()` would zero-fill .bss that is already zero.
36
37 static constexpr uint16_t UNSET_CONN_ID = 0xFFFF;
38
39 // Lifecycle of one connection attempt's service search.
40 enum class SearchState : uint8_t {
41 NONE, // no search this attempt
42 PRESTARTED, // issued at OPEN_EVT, no claimant yet
43 PRESTART_DONE, // completed with search_status_ latched, no claimant yet
44 CLAIMED, // in flight with a claimant (pre-started or direct)
45 REPORT_PENDING // completed and claimed: deliver on the next flush
46 };
47
48 void setup() override;
49 void loop() override;
50 void dump_config() override;
51 float get_setup_priority() const override { return setup_priority::AFTER_BLUETOOTH; }
52
53 // Wired by codegen before setup and invariant for the device lifetime.
54 void set_listener(ble_device_base::GattClientListener *listener) { this->listener_ = listener; }
55
56 // ---- esp32_ble_tracker::ESPBTClient ----
57 bool gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if,
58 esp_ble_gattc_cb_param_t *param) override;
59 void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param) override;
60 void connect() override;
61 void disconnect() override;
63 bool wants_parsed_advertisements() override { return false; }
64 void on_scan_end() override {}
65 bool parse_device(const ble_device_base::ESPBTDevice &device) override { return false; }
66
67 // ---- ble_device_base::BLEGattConnection contract ----
68 int connect(uint64_t address, uint8_t addr_type);
69 int gatt_disconnect();
72 int read_characteristic(uint16_t handle);
73 int write_characteristic(uint16_t handle, const uint8_t *data, uint16_t len, bool response);
74 int read_descriptor(uint16_t handle);
75 int write_descriptor(uint16_t handle, const uint8_t *data, uint16_t len);
76 int notify_characteristic(uint16_t handle, bool enable);
77 int pair();
78 int update_connection_params(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout);
79 // Contract stub: the proxy streams in place; the on-demand materializer
80 // for direct consumers lands with #18205. NOTE: a direct consumer reaching
81 // this stub gets an empty table indistinguishable from a service-less
82 // peer - do not ship one against this backend before the materializer.
84 void release_services();
85
86#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
91#endif
92
94
95 protected:
96 bool check_addr_(const esp_bd_addr_t &addr) const;
97 void tracker_connect_();
98 void handle_open_evt_(esp_ble_gattc_cb_param_t *param);
99 void handle_disconnect_evt_(esp_ble_gattc_cb_param_t *param);
100 int handle_search_cmpl_(esp_gatt_status_t status);
104 void set_idle_();
105 void set_disconnecting_();
106 esp_err_t update_conn_params_(uint16_t min_interval, uint16_t max_interval, uint16_t latency, uint16_t timeout,
107 const char *param_type);
108 int check_and_log_error_(const char *operation, esp_err_t err);
109 void log_gattc_warning_(const char *operation, int code);
110
111 // Group 1: pointers / composed objects
113 // Group 2: 4-byte types
115
116 // Group 3: arrays
117 esp_bd_addr_t remote_bda_{};
118
119 // Group 4: 2-byte types
121 uint16_t service_total_{0};
122
123 // Group 5: 1-byte types
124 esp_gatt_if_t gattc_if_{ESP_GATT_IF_NONE}; // uint8_t width keeps the object at 48 bytes
125 // Stored narrow (the enum is 4 bytes); widened at the esp_ble_gattc_open call.
127 esp32_ble_tracker::ConnectionType connection_type_{esp32_ble_tracker::ConnectionType::V3_WITHOUT_CACHE};
129 // Terminates an in-flight stream (never send a partial list as authoritative)
130 // and marks a cleaned cache unsafe to walk (Bluedroid asserts).
131 bool services_released_ : 1 {false};
132 // The connected report waits for the MTU exchange; OPEN_EVT alone would
133 // hand HA the default 23.
134 bool seen_mtu_ : 1 {false};
135 // The MTU request was refused at CONNECT_EVT; OPEN_EVT reports instead.
136 bool mtu_failed_ : 1 {false};
137 // esp_ble_gattc_cancel_open() was accepted; CANCEL_OPEN_EVT or OPEN_EVT ends
138 // the attempt, so the scheduled teardown can no longer be cancelled.
139 bool cancel_open_sent_ : 1 {false};
140 // Search issued at OPEN_EVT overlaps the MTU exchange; discover_services()
141 // completes from it. Reset by set_idle_().
142 static_assert(static_cast<uint8_t>(SearchState::REPORT_PENDING) < (1 << 4), "search_state_ bitfield too narrow");
144 // esp_gatt_status_t of the completed search, held until claimed.
145 uint8_t search_status_{0};
146};
147
148} // namespace esphome::bluetooth_connection
149
150#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:68
static void uint32_t
Borrowed view of the backend-owned service table.
spi_device_handle_t handle