Apply review: honest teardown status and unresolved-write cause

This commit is contained in:
J. Nick Koston
2026-08-09 03:29:20 -05:00
parent 93f9d4a1ad
commit 444a217ee7
3 changed files with 18 additions and 10 deletions
@@ -97,10 +97,14 @@ template<typename... Ts> class BLEClientWriteAction final : public Action<Ts...>
// response-less path can complete synchronously inside the call, so the
// handle is armed before the backend is touched.
bool write(const uint8_t *data, size_t len) {
if (!this->resolved_ || !this->ble_client_->connected()) {
if (!this->ble_client_->connected()) {
esph_log_w(Automation::TAG, "Cannot write to BLE characteristic - not connected");
return false;
}
if (!this->resolved_) {
esph_log_w(Automation::TAG, "Cannot write to BLE characteristic - characteristic was not resolved");
return false;
}
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
char hex_buf[format_hex_pretty_size(BLE_WRITE_MAX_LOG_BYTES)];
esph_log_vv(Automation::TAG, "Will write %d bytes: %s", len, format_hex_pretty_to(hex_buf, data, len));
@@ -74,10 +74,12 @@ void BLEClient::disconnect() {
return;
// A deliberate teardown's failure report must not feed the backoff.
this->cancel_requested_ = true;
if (this->backend_->gatt_disconnect() != 0) {
// Refused synchronously: the backend is already down and no report will
// come; settle through the normal path so waiters resolve.
this->on_connection_state(false, 0, 0);
int err = this->backend_->gatt_disconnect();
if (err != 0) {
// Refused synchronously (states diverged; the backend is already down):
// settle through the normal path, carrying the real code so the log is
// distinguishable from a clean teardown.
this->on_connection_state(false, 0, err);
}
}
@@ -154,11 +154,13 @@ def _ledger() -> _SlotLedger:
return CORE.data[DOMAIN]
def consume_gatt_slot(consumer: str, count: int = 1):
"""Validator claiming GATT connection slots — the one spelling for every
claimant (the proxy per configured slot, dedicated backends once). The
neutral ledger feeds the platform cap check in FINAL_VALIDATE_SCHEMA;
esp32 additionally charges the controller's connection budget."""
def consume_gatt_slot(
consumer: str, count: int = 1
) -> Callable[[ConfigType], ConfigType]:
"""Validator claiming GATT connection slots for the neutral ledger (the
platform cap check in FINAL_VALIDATE_SCHEMA); esp32 additionally charges
the controller's connection budget. The proxy's esp32 arm still charges
the controller directly - route it through here when it migrates."""
def validator(config: ConfigType) -> ConfigType:
_ledger().consumers.extend([consumer] * count)