5#ifdef USE_BLUETOOTH_PROXY
25using bluetooth_connection::CONN_OK;
27using bluetooth_connection::GATT_NOT_CONNECTED;
28using bluetooth_connection::DONE_SENDING_SERVICES;
29using bluetooth_connection::INIT_SENDING_SERVICES;
30using bluetooth_connection::SERVICES_DONE_PENDING;
32#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
43static constexpr uint32_t LEGACY_ACTIVE_CONNECTIONS_VERSION = 5;
44static constexpr uint32_t LEGACY_ACTIVE_NO_CACHE_CLEAR_VERSION = 4;
45static constexpr uint32_t LEGACY_ACTIVE_NO_PAIRING_VERSION = 3;
46static constexpr uint32_t LEGACY_PASSIVE_ONLY_VERSION = 1;
63#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
71 this->word_ = (
address & ADDRESS_MASK) | (
static_cast<uint64_t
>(
static_cast<uint16_t
>(
error)) << 48);
73 constexpr void clear() { this->word_ = 0; }
77 constexpr bool empty()
const {
return this->word_ == 0; }
80 constexpr uint64_t
address()
const {
return this->word_ & ADDRESS_MASK; }
81 constexpr conn_err_t error()
const {
return static_cast<int16_t
>(this->word_ >> 48); }
84 static constexpr uint64_t ADDRESS_MASK = 0x0000FFFFFFFFFFFFULL;
97static_assert(PendingReply{}.empty());
101#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
109 void setup()
override;
110 void loop()
override;
112#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
123#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
142#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
167 return LEGACY_PASSIVE_ONLY_VERSION;
172 if (bluetooth_connection::SUPPORTS_CACHE_CLEARING) {
173 return LEGACY_ACTIVE_CONNECTIONS_VERSION;
175 return bluetooth_connection::SUPPORTS_PAIRING ? LEGACY_ACTIVE_NO_CACHE_CLEAR_VERSION
176 : LEGACY_ACTIVE_NO_PAIRING_VERSION;
190 if (ble_device_base::BLEHub::get_capabilities().scan_mode_switch) {
201 if (bluetooth_connection::SUPPORTS_PAIRING) {
204 if (bluetooth_connection::SUPPORTS_CACHE_CLEARING) {
213 uint8_t mac[MAC_ADDRESS_SIZE] = {};
214 this->
hub_->get_adapter_mac(mac);
226#ifdef USE_BLE_SCANNER_STATE_CALLBACK
240#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
247#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
259 if (new_address == 0 && old_address != 0) {
260 if (resp.free < BLUETOOTH_PROXY_MAX_CONNECTIONS) {
266 }
else if (new_address != 0 && old_address == 0) {
303#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
316#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
318 std::array<BluetoothConnection *, BLUETOOTH_PROXY_MAX_CONNECTIONS>
connections_{};
336#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
343#ifdef USE_BLUETOOTH_PROXY_CONNECTIONS
357#ifdef USE_BLE_SCANNER_STATE_CALLBACK
bool send_message(const T &msg)
Returns false as soon as the TCP buffer is full.
bool client_supports_api_version(uint16_t major, uint16_t minor) const
uint16_t advertisements_len
void bluetooth_gatt_read(const api::BluetoothGATTReadRequest &msg)
void bluetooth_gatt_send_services(const api::BluetoothGATTGetServicesRequest &msg)
void handle_gatt_not_connected_(uint64_t address, uint16_t handle, const char *action, const char *type)
void log_reply_deferred_(const char *what, uint64_t address)
A latched reply's leading edge; the drain's re-refusals stay quiet.
bool configured_scan_active_
void get_bluetooth_mac_address_pretty(std::span< char, MAC_ADDRESS_PRETTY_BUFFER_SIZE > output)
void on_raw_advertisement_(const ble_device_base::RawAdvertisement &raw)
bool adv_flush_toggle_
Wi-Fi only: flush on every other non-empty tick (~200 ms) so partial batches fill; an idle tick re-ar...
void log_not_connected_gatt_(const char *action, const char *type)
api::APIConnection * get_api_connection()
void send_scanner_state_(ble_device_base::ScannerState state)
void answer_device_disconnected_(uint64_t address)
Answer a request with connected=false.
void bluetooth_device_request(const api::BluetoothDeviceRequest &msg)
void send_device_unpairing(uint64_t address, bool success, conn_err_t error)
No default error: the drain rebuilds success as (error == CONN_OK), so a caller that omitted it would...
void replace_allocated_slot_(uint64_t find_value, uint64_t set_value)
PendingReply pending_unpairing_
bool send_gatt_services_done(uint64_t address)
Same convention as send_device_connection: false only on a refused frame.
void bluetooth_gatt_write_descriptor(const api::BluetoothGATTWriteDescriptorRequest &msg)
std::array< PendingReply, BLUETOOTH_PROXY_MAX_CONNECTIONS > pending_disconnections_
void bluetooth_scanner_set_mode(bool active)
void log_advertisement_flush_(bool sent)
void subscribe_api_connection(api::APIConnection *api_connection, uint32_t flags)
uint32_t get_legacy_version() const
float get_setup_priority() const override
void send_device_clear_cache(uint64_t address, bool success, conn_err_t error=CONN_OK)
void reset_connection_slot_(BluetoothConnection *connection, conn_err_t reason)
Free a connection slot after teardown: notify the API client and reset the streaming cursor.
void dump_config() override
uint32_t get_feature_flags() const
void send_connections_free()
void update_address_slot_(uint64_t old_address, uint64_t new_address)
Keep the pre-allocated connections-free message in step when a connection slot changes address (0 = f...
void set_active(bool active)
void unsubscribe_api_connection(api::APIConnection *api_connection)
void register_connection(BluetoothConnection *connection)
void send_device_pairing(uint64_t address, bool paired, conn_err_t error=CONN_OK)
bool scanner_state_pending_
ble_device_base::BLEHub * hub_
bool send_gatt_error(uint64_t address, uint16_t handle, conn_err_t error)
False only when the API refused the frame, so the reply is still owed.
api::BluetoothLERawAdvertisementsResponse response_
void send_device_disconnected_(uint64_t address, conn_err_t error=CONN_OK)
Send connected=false and pool it for the paced drain if refused.
void log_connection_info_(BluetoothConnection *connection, const char *message)
void reset_owed_replies_()
Drop everything the ending session was owed.
bool send_device_connection(uint64_t address, bool connected, uint16_t mtu=0, conn_err_t error=CONN_OK)
False only when a subscriber refused the frame; true = delivered or nobody subscribed.
void log_reply_displaced_(const char *what, uint64_t owed, uint64_t address)
A latched reply lost to a newer one for a different address.
BluetoothConnection * get_connection_(uint64_t address, bool reserve)
void bluetooth_set_connection_params(const api::BluetoothSetConnectionParamsRequest &msg)
bool send_bluetooth_scanner_state_(ble_device_base::ScannerState state)
void bluetooth_gatt_read_descriptor(const api::BluetoothGATTReadDescriptorRequest &msg)
bool connections_free_pending_
void bluetooth_gatt_write(const api::BluetoothGATTWriteRequest &msg)
void bluetooth_gatt_notify(const api::BluetoothGATTNotifyRequest &msg)
void log_reply_dropped_(const char *what, uint64_t address)
Report a reply we deliberately do not latch, so no drop is silent.
void set_ble_hub(ble_device_base::BLEHub *hub)
void send_polled_scanner_state_()
uint32_t last_advertisement_flush_time_
void flush_pending_advertisements_()
Caller must ensure api_connection_ is non-null and API server is connected.
bool client_supports_efficient_uuids() const
Whether the subscribed API client understands 16/32-bit UUID fields.
api::APIConnection * api_connection_
std::array< BluetoothConnection *, BLUETOOTH_PROXY_MAX_CONNECTIONS > connections_
void latch_pending_disconnection_(uint64_t address, conn_err_t error)
Pool a refused freed-slot notification for the paced drain.
api::BluetoothConnectionsFreeResponse connections_free_response_
void log_connection_request_ignored_(BluetoothConnection *connection, ClientState state)
uint8_t connection_count_
void log_slot_accounting_mismatch_()
void clear_pending_disconnection_(uint64_t address)
Drop any owed freed-slot notification for this address (client reconnected).
One owed address-keyed reply in a single word: 48-bit address low, 16-bit error on top.
constexpr uint64_t address() const
constexpr bool empty() const
constexpr bool matches(uint64_t address) const
constexpr void set(uint64_t address, conn_err_t error)
constexpr conn_err_t error() const
const LogString * message
ScannerState
Scanner lifecycle, wire-value aligned with the api enum so consumers cast directly (pinned by static_...
ESPHOME_BLE_HUB_TYPE BLEHub
constexpr bool pending_reply_round_trips(uint64_t address, uint64_t expected_address, conn_err_t error)
@ FEATURE_ACTIVE_CONNECTIONS
@ FEATURE_CONNECTION_PARAMS_SETTING
@ FEATURE_RAW_ADVERTISEMENTS
BluetoothProxy * global_bluetooth_proxy
BluetoothProxySubscriptionFlag
@ SUBSCRIPTION_RAW_ADVERTISEMENTS
constexpr float AFTER_WIFI
For components that should be initialized after WiFi is connected.
bool mac_address_is_valid(const uint8_t *mac)
Check if the MAC address is not all zeros or all ones.
char * format_mac_addr_upper(const uint8_t *mac, char *output)
Format MAC address as XX:XX:XX:XX:XX:XX (uppercase, colon separators)
One raw advertisement as delivered by the controller — a borrowed view, valid only for the duration o...
spi_device_handle_t handle