1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-03 11:52:20 +01:00

[esp32_ble_client] Adjust connection parameters to improve device compatibility

This commit is contained in:
J. Nick Koston
2025-08-21 08:11:17 -05:00
parent 94accd5abe
commit 2f101c0a20
2 changed files with 32 additions and 40 deletions

View File

@@ -111,36 +111,8 @@ void BLEClientBase::connect() {
this->remote_addr_type_); this->remote_addr_type_);
this->paired_ = false; this->paired_ = false;
// Set preferred connection parameters before connecting // Open the connection without setting connection parameters
// Use FAST for all V3 connections (better latency and reliability) // Parameters will be set after connection is established if needed
// Use MEDIUM for V1/legacy connections (balanced performance)
uint16_t min_interval, max_interval, timeout;
const char *param_type;
if (this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE ||
this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
min_interval = FAST_MIN_CONN_INTERVAL;
max_interval = FAST_MAX_CONN_INTERVAL;
timeout = FAST_CONN_TIMEOUT;
param_type = "fast";
} else {
min_interval = MEDIUM_MIN_CONN_INTERVAL;
max_interval = MEDIUM_MAX_CONN_INTERVAL;
timeout = MEDIUM_CONN_TIMEOUT;
param_type = "medium";
}
auto param_ret = esp_ble_gap_set_prefer_conn_params(this->remote_bda_, min_interval, max_interval,
0, // latency: 0
timeout);
if (param_ret != ESP_OK) {
ESP_LOGW(TAG, "[%d] [%s] esp_ble_gap_set_prefer_conn_params failed: %d", this->connection_index_,
this->address_str_.c_str(), param_ret);
} else {
this->log_connection_params_(param_type);
}
// Now open the connection
auto ret = esp_ble_gattc_open(this->gattc_if_, this->remote_bda_, this->remote_addr_type_, true); auto ret = esp_ble_gattc_open(this->gattc_if_, this->remote_bda_, this->remote_addr_type_, true);
if (ret) { if (ret) {
this->log_gattc_warning_("esp_ble_gattc_open", ret); this->log_gattc_warning_("esp_ble_gattc_open", ret);
@@ -243,8 +215,21 @@ void BLEClientBase::log_warning_(const char *message) {
ESP_LOGW(TAG, "[%d] [%s] %s", this->connection_index_, this->address_str_.c_str(), message); ESP_LOGW(TAG, "[%d] [%s] %s", this->connection_index_, this->address_str_.c_str(), message);
} }
void BLEClientBase::restore_medium_conn_params_() { void BLEClientBase::set_fast_conn_params_() {
// Restore to medium connection parameters after initial connection phase // Switch to fast connection parameters for service discovery
// This improves discovery speed for devices with short timeouts
esp_ble_conn_update_params_t conn_params = {{0}};
memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t));
conn_params.min_int = FAST_MIN_CONN_INTERVAL;
conn_params.max_int = FAST_MAX_CONN_INTERVAL;
conn_params.latency = 0;
conn_params.timeout = FAST_CONN_TIMEOUT;
this->log_connection_params_("fast");
esp_ble_gap_update_conn_params(&conn_params);
}
void BLEClientBase::set_medium_conn_params_() {
// Set medium connection parameters for balanced performance
// This balances performance with bandwidth usage for normal operation // This balances performance with bandwidth usage for normal operation
esp_ble_conn_update_params_t conn_params = {{0}}; esp_ble_conn_update_params_t conn_params = {{0}};
memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t)); memcpy(conn_params.bda, this->remote_bda_, sizeof(esp_bd_addr_t));
@@ -308,12 +293,19 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
this->set_state(espbt::ClientState::CONNECTED); this->set_state(espbt::ClientState::CONNECTED);
ESP_LOGI(TAG, "[%d] [%s] Connection open", this->connection_index_, this->address_str_.c_str()); ESP_LOGI(TAG, "[%d] [%s] Connection open", this->connection_index_, this->address_str_.c_str());
if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) { if (this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) {
// Restore to medium connection parameters for cached connections too // Cached connections use medium connection parameters
this->restore_medium_conn_params_(); this->set_medium_conn_params_();
// only set our state, subclients might have more stuff to do yet. // only set our state, subclients might have more stuff to do yet.
this->state_ = espbt::ClientState::ESTABLISHED; this->state_ = espbt::ClientState::ESTABLISHED;
break; break;
} }
// For V3_WITHOUT_CACHE, switch to fast params for service discovery
// Service discovery period is critical - we typically have only 10s to complete
// discovery before the device disconnects us. Fast connection parameters are
// essential to finish service resolution in time and avoid retry loops.
if (this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
this->set_fast_conn_params_();
}
this->log_event_("Searching for services"); this->log_event_("Searching for services");
esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr); esp_ble_gattc_search_service(esp_gattc_if, param->cfg_mtu.conn_id, nullptr);
break; break;
@@ -395,12 +387,11 @@ bool BLEClientBase::gattc_event_handler(esp_gattc_cb_event_t event, esp_gatt_if_
if (this->conn_id_ != param->search_cmpl.conn_id) if (this->conn_id_ != param->search_cmpl.conn_id)
return false; return false;
this->log_gattc_event_("SEARCH_CMPL"); this->log_gattc_event_("SEARCH_CMPL");
// For V3 connections, restore to medium connection parameters after service discovery // For V3_WITHOUT_CACHE, switch back to medium connection parameters after service discovery
// This balances performance with bandwidth usage after the critical discovery phase // This balances performance with bandwidth usage after the critical discovery phase
if (this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE || if (this->connection_type_ == espbt::ConnectionType::V3_WITHOUT_CACHE) {
this->connection_type_ == espbt::ConnectionType::V3_WITH_CACHE) { this->set_medium_conn_params_();
this->restore_medium_conn_params_(); } else if (this->connection_type_ != espbt::ConnectionType::V3_WITH_CACHE) {
} else {
#ifdef USE_ESP32_BLE_DEVICE #ifdef USE_ESP32_BLE_DEVICE
for (auto &svc : this->services_) { for (auto &svc : this->services_) {
ESP_LOGV(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_.c_str(), ESP_LOGV(TAG, "[%d] [%s] Service UUID: %s", this->connection_index_, this->address_str_.c_str(),

View File

@@ -133,7 +133,8 @@ class BLEClientBase : public espbt::ESPBTClient, public Component {
void log_event_(const char *name); void log_event_(const char *name);
void log_gattc_event_(const char *name); void log_gattc_event_(const char *name);
void restore_medium_conn_params_(); void set_fast_conn_params_();
void set_medium_conn_params_();
void log_gattc_warning_(const char *operation, esp_gatt_status_t status); void log_gattc_warning_(const char *operation, esp_gatt_status_t status);
void log_gattc_warning_(const char *operation, esp_err_t err); void log_gattc_warning_(const char *operation, esp_err_t err);
void log_connection_params_(const char *param_type); void log_connection_params_(const char *param_type);