From 202136648bdcbc21858f49d558df8a9585a4c6c2 Mon Sep 17 00:00:00 2001 From: clydebarrow <2366188+clydebarrow@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:07:05 +1100 Subject: [PATCH] [packet_interface] Warn when the HDLC link cannot come up A frame larger than max_packet_size, usually from a peer with a larger setting, is warned about once. A link reset that the peer does not answer is warned about after max_retries tries, and a full queue is logged at debug level while the link is down. Co-Authored-By: Claude Opus 5.5 --- .../packet_interface/hdlc_reliability.cpp | 21 +++++++++++++++++-- .../packet_interface/hdlc_reliability.h | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/esphome/components/packet_interface/hdlc_reliability.cpp b/esphome/components/packet_interface/hdlc_reliability.cpp index 8b5946ad979..2b0afc7d078 100644 --- a/esphome/components/packet_interface/hdlc_reliability.cpp +++ b/esphome/components/packet_interface/hdlc_reliability.cpp @@ -111,7 +111,11 @@ bool HdlcReliability::send_to_interface(const PacketBuffer &data, const PacketMe } uint8_t outstanding = this->outstanding_(); if (outstanding >= this->max_queue_length_) { - ESP_LOGV(TAG, "%s: Send queue full", this->name_); + if (this->state_ == LinkState::LINK_STATE_CONNECTED) { + ESP_LOGV(TAG, "%s: Send queue full", this->name_); + } else { + ESP_LOGD(TAG, "%s: Send queue full, waiting for the peer to answer the link reset", this->name_); + } return false; } uint8_t seq = this->vs_; @@ -181,6 +185,11 @@ void HdlcReliability::start_timer_() { void HdlcReliability::on_timeout_() { if (this->state_ != LinkState::LINK_STATE_CONNECTED) { + // Counted up to max_retries_ only, so the warning is logged once until the link comes up + if (this->retries_ < this->max_retries_ && ++this->retries_ == this->max_retries_) { + ESP_LOGW(TAG, "%s: No answer to the link reset after %u tries; check that the peer has a reliability layer", + this->name_, this->max_retries_); + } this->send_frame_(UNNUMBERED_SABM, nullptr, 0); this->start_timer_(); return; @@ -270,7 +279,15 @@ void HdlcReliability::receive_(const PacketBuffer &data, const PacketMetaData &m } // The peer's packets may only be larger if it has a larger max_packet_size, which the layers above cannot take if (length > this->max_packet_size_) { - ESP_LOGV(TAG, "%s: Frame of %zu bytes is larger than %zu, dropped", this->name_, length, this->max_packet_size_); + if (!this->oversize_warned_) { + this->oversize_warned_ = true; + ESP_LOGW(TAG, + "%s: Frame of %zu bytes is larger than %zu, dropped; check that both devices use the same " + "max_packet_size", + this->name_, length, this->max_packet_size_); + } else { + ESP_LOGV(TAG, "%s: Frame of %zu bytes is larger than %zu, dropped", this->name_, length, this->max_packet_size_); + } this->note_received_(false); return; } diff --git a/esphome/components/packet_interface/hdlc_reliability.h b/esphome/components/packet_interface/hdlc_reliability.h index fab9dd72405..21e97609dbe 100644 --- a/esphome/components/packet_interface/hdlc_reliability.h +++ b/esphome/components/packet_interface/hdlc_reliability.h @@ -91,6 +91,7 @@ class HdlcReliability : public PacketInterface { bool ack_due_{false}; // and should be sent now bool rej_sent_{false}; bool peer_frame_seen_{false}; // a numbered frame has arrived since the link came up + bool oversize_warned_{false}; }; } // namespace esphome::packet_interface