1
0
mirror of https://github.com/esphome/esphome.git synced 2025-10-30 14:43:51 +00:00

[esp32_ble_server][esp32_improv] Eliminate unnecessary heap allocations (#11569)

This commit is contained in:
J. Nick Koston
2025-10-28 14:05:12 -05:00
committed by GitHub
parent da19673f51
commit 7dd829cfca
7 changed files with 27 additions and 16 deletions

View File

@@ -461,7 +461,9 @@ async def parse_value(value_config, args):
if isinstance(value, str):
value = list(value.encode(value_config[CONF_STRING_ENCODING]))
if isinstance(value, list):
return cg.std_vector.template(cg.uint8)(value)
# Generate initializer list {1, 2, 3} instead of std::vector<uint8_t>({1, 2, 3})
# This calls the set_value(std::initializer_list<uint8_t>) overload
return cg.ArrayInitializer(*value)
val = cg.RawExpression(f"{value_config[CONF_TYPE]}({cg.safe_exp(value)})")
return ByteBuffer_ns.wrap(val, value_config[CONF_ENDIANNESS])

View File

@@ -35,13 +35,18 @@ BLECharacteristic::BLECharacteristic(const ESPBTUUID uuid, uint32_t properties)
void BLECharacteristic::set_value(ByteBuffer buffer) { this->set_value(buffer.get_data()); }
void BLECharacteristic::set_value(const std::vector<uint8_t> &buffer) {
void BLECharacteristic::set_value(std::vector<uint8_t> &&buffer) {
xSemaphoreTake(this->set_value_lock_, 0L);
this->value_ = buffer;
this->value_ = std::move(buffer);
xSemaphoreGive(this->set_value_lock_);
}
void BLECharacteristic::set_value(std::initializer_list<uint8_t> data) {
this->set_value(std::vector<uint8_t>(data)); // Delegate to move overload
}
void BLECharacteristic::set_value(const std::string &buffer) {
this->set_value(std::vector<uint8_t>(buffer.begin(), buffer.end()));
this->set_value(std::vector<uint8_t>(buffer.begin(), buffer.end())); // Delegate to move overload
}
void BLECharacteristic::notify() {

View File

@@ -33,7 +33,8 @@ class BLECharacteristic {
~BLECharacteristic();
void set_value(ByteBuffer buffer);
void set_value(const std::vector<uint8_t> &buffer);
void set_value(std::vector<uint8_t> &&buffer);
void set_value(std::initializer_list<uint8_t> data);
void set_value(const std::string &buffer);
void set_broadcast_property(bool value);

View File

@@ -46,15 +46,17 @@ void BLEDescriptor::do_create(BLECharacteristic *characteristic) {
this->state_ = CREATING;
}
void BLEDescriptor::set_value(std::vector<uint8_t> buffer) {
size_t length = buffer.size();
void BLEDescriptor::set_value(std::vector<uint8_t> &&buffer) { this->set_value_impl_(buffer.data(), buffer.size()); }
void BLEDescriptor::set_value(std::initializer_list<uint8_t> data) { this->set_value_impl_(data.begin(), data.size()); }
void BLEDescriptor::set_value_impl_(const uint8_t *data, size_t length) {
if (length > this->value_.attr_max_len) {
ESP_LOGE(TAG, "Size %d too large, must be no bigger than %d", length, this->value_.attr_max_len);
return;
}
this->value_.attr_len = length;
memcpy(this->value_.attr_value, buffer.data(), length);
memcpy(this->value_.attr_value, data, length);
}
void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,

View File

@@ -27,7 +27,8 @@ class BLEDescriptor {
void do_create(BLECharacteristic *characteristic);
ESPBTUUID get_uuid() const { return this->uuid_; }
void set_value(std::vector<uint8_t> buffer);
void set_value(std::vector<uint8_t> &&buffer);
void set_value(std::initializer_list<uint8_t> data);
void set_value(ByteBuffer buffer) { this->set_value(buffer.get_data()); }
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
@@ -42,6 +43,8 @@ class BLEDescriptor {
}
protected:
void set_value_impl_(const uint8_t *data, size_t length);
BLECharacteristic *characteristic_{nullptr};
ESPBTUUID uuid_;
uint16_t handle_{0xFFFF};

View File

@@ -270,8 +270,8 @@ void ESP32ImprovComponent::set_error_(improv::Error error) {
}
}
void ESP32ImprovComponent::send_response_(std::vector<uint8_t> &response) {
this->rpc_response_->set_value(ByteBuffer::wrap(response));
void ESP32ImprovComponent::send_response_(std::vector<uint8_t> &&response) {
this->rpc_response_->set_value(std::move(response));
if (this->state_ != improv::STATE_STOPPED)
this->rpc_response_->notify();
}
@@ -409,10 +409,8 @@ void ESP32ImprovComponent::check_wifi_connection_() {
}
}
#endif
// Pass to build_rpc_response using vector constructor from iterators to avoid extra copies
std::vector<uint8_t> data = improv::build_rpc_response(
improv::WIFI_SETTINGS, std::vector<std::string>(url_strings, url_strings + url_count));
this->send_response_(data);
this->send_response_(improv::build_rpc_response(improv::WIFI_SETTINGS,
std::vector<std::string>(url_strings, url_strings + url_count)));
} else if (this->is_active() && this->state_ != improv::STATE_PROVISIONED) {
ESP_LOGD(TAG, "WiFi provisioned externally");
}

View File

@@ -109,7 +109,7 @@ class ESP32ImprovComponent : public Component, public improv_base::ImprovBase {
void set_state_(improv::State state, bool update_advertising = true);
void set_error_(improv::Error error);
improv::State get_initial_state_() const;
void send_response_(std::vector<uint8_t> &response);
void send_response_(std::vector<uint8_t> &&response);
void process_incoming_data_();
void on_wifi_connect_timeout_();
void check_wifi_connection_();