[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 <noreply@anthropic.com>
This commit is contained in:
clydebarrow
2026-10-19 14:40:33 +11:00
co-authored by Claude Opus 5.5
parent 7f2cd1fe0d
commit 202136648b
2 changed files with 20 additions and 2 deletions
@@ -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;
}
@@ -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