Optimize bluetooth_proxy memory usage on ESP32 (#9114)

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
J. Nick Koston 2025-06-19 03:11:13 +02:00 committed by GitHub
parent eeb0710ad4
commit 2e11e66db4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 49 additions and 19 deletions

View File

@ -26,10 +26,17 @@ class BluetoothConnection : public esp32_ble_client::BLEClientBase {
protected:
friend class BluetoothProxy;
bool seen_mtu_or_services_{false};
int16_t send_service_{-2};
// Memory optimized layout for 32-bit systems
// Group 1: Pointers (4 bytes each, naturally aligned)
BluetoothProxy *proxy_;
// Group 2: 2-byte types
int16_t send_service_{-2}; // Needs to handle negative values and service count
// Group 3: 1-byte types
bool seen_mtu_or_services_{false};
// 1 byte used, 1 byte padding
};
} // namespace bluetooth_proxy

View File

@ -134,11 +134,17 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
BluetoothConnection *get_connection_(uint64_t address, bool reserve);
bool active_;
std::vector<BluetoothConnection *> connections_{};
// Memory optimized layout for 32-bit systems
// Group 1: Pointers (4 bytes each, naturally aligned)
api::APIConnection *api_connection_{nullptr};
// Group 2: Container types (typically 12 bytes on 32-bit)
std::vector<BluetoothConnection *> connections_{};
// Group 3: 1-byte types grouped together
bool active_;
bool raw_advertisements_{false};
// 2 bytes used, 2 bytes padding
};
extern BluetoothProxy *global_bluetooth_proxy; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)

View File

@ -96,21 +96,34 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
void set_state(espbt::ClientState st) override;
protected:
int gattc_if_;
esp_bd_addr_t remote_bda_;
esp_ble_addr_type_t remote_addr_type_{BLE_ADDR_TYPE_PUBLIC};
uint16_t conn_id_{UNSET_CONN_ID};
// Memory optimized layout for 32-bit systems
// Group 1: 8-byte types
uint64_t address_{0};
bool auto_connect_{false};
// Group 2: Container types (grouped for memory optimization)
std::string address_str_{};
uint8_t connection_index_;
int16_t service_count_{0};
uint16_t mtu_{23};
bool paired_{false};
espbt::ConnectionType connection_type_{espbt::ConnectionType::V1};
std::vector<BLEService *> services_;
// Group 3: 4-byte types
int gattc_if_;
esp_gatt_status_t status_{ESP_GATT_OK};
// Group 4: Arrays (6 bytes)
esp_bd_addr_t remote_bda_;
// Group 5: 2-byte types
uint16_t conn_id_{UNSET_CONN_ID};
uint16_t mtu_{23};
// Group 6: 1-byte types and small enums
esp_ble_addr_type_t remote_addr_type_{BLE_ADDR_TYPE_PUBLIC};
espbt::ConnectionType connection_type_{espbt::ConnectionType::V1};
uint8_t connection_index_;
uint8_t service_count_{0}; // ESP32 has max handles < 255, typical devices have < 50 services
bool auto_connect_{false};
bool paired_{false};
// 6 bytes used, 2 bytes padding
void log_event_(const char *name);
};

View File

@ -129,7 +129,7 @@ class ESPBTDeviceListener {
ESP32BLETracker *parent_{nullptr};
};
enum class ClientState {
enum class ClientState : uint8_t {
// Connection is allocated
INIT,
// Client is disconnecting
@ -165,7 +165,7 @@ enum class ScannerState {
STOPPED,
};
enum class ConnectionType {
enum class ConnectionType : uint8_t {
// The default connection type, we hold all the services in ram
// for the duration of the connection.
V1,
@ -193,15 +193,19 @@ class ESPBTClient : public ESPBTDeviceListener {
}
}
ClientState state() const { return state_; }
int app_id;
// Memory optimized layout
uint8_t app_id; // App IDs are small integers assigned sequentially
protected:
// Group 1: 1-byte types
ClientState state_{ClientState::INIT};
// want_disconnect_ is set to true when a disconnect is requested
// while the client is connecting. This is used to disconnect the
// client as soon as we get the connection id (conn_id_) from the
// ESP_GATTC_OPEN_EVT event.
bool want_disconnect_{false};
// 2 bytes used, 2 bytes padding
};
class ESP32BLETracker : public Component,
@ -262,7 +266,7 @@ class ESP32BLETracker : public Component,
/// Called to set the scanner state. Will also call callbacks to let listeners know when state is changed.
void set_scanner_state_(ScannerState state);
int app_id_{0};
uint8_t app_id_{0};
/// Vector of addresses that have already been printed in print_bt_device_info
std::vector<uint64_t> already_discovered_;