Apply the dial delay the same way at boot and after a disconnect, tell socket create and setblocking failures apart, and cap the delay so the wait always elapses

This commit is contained in:
J. Nick Koston
2026-09-04 12:42:07 +02:00
parent 9c4a08aaad
commit 0a74cb4e89
3 changed files with 7 additions and 7 deletions
+3 -2
View File
@@ -317,10 +317,11 @@ _OUTGOING_CONNECTION_SCHEMA = cv.Schema(
{
cv.Optional(CONF_HOST): cv.ipaddress,
cv.Optional(CONF_PORT, default=6054): cv.port,
# Bounded so the value cannot wrap the device's uint32 milliseconds
# Bounded to half the device's uint32 millisecond range so the wait
# always elapses under a wrapping clock
cv.Optional(CONF_DELAY, default="60s"): cv.All(
cv.positive_time_period_milliseconds,
cv.Range(max=cv.TimePeriod(milliseconds=4294967295)),
cv.Range(max=cv.TimePeriod(milliseconds=2147483647)),
),
}
)
@@ -43,9 +43,8 @@ void OutgoingConnectionManager::loop(APIServer *server) {
const uint32_t now = App.get_loop_component_start_time();
switch (this->state_) {
case DialState::DIAL_STATE_IDLE:
#if defined(API_OUTGOING_CONNECTION_HOST) || defined(USE_DEEP_SLEEP)
// A fixed host has no inbound path worth waiting for, and a deep
// sleep wake window is too short to spend on the delay
#ifdef USE_DEEP_SLEEP
// A deep sleep wake window is too short to spend on the delay
this->schedule_wait_(now, BACKOFF_MIN_MS);
#else
// Target went away; give it the configured delay to reconnect first
@@ -102,7 +101,7 @@ void OutgoingConnectionManager::try_dial_(APIServer *server, uint32_t now) {
}
this->dial_socket_ = socket::socket_loop_monitored(((struct sockaddr *) &addr)->sa_family, SOCK_STREAM, IPPROTO_TCP);
if (!this->dial_socket_ || this->dial_socket_->setblocking(false) != 0) {
ESP_LOGW(TAG, "Socket create failed: errno %d", errno);
ESP_LOGW(TAG, "Socket %s failed: errno %d", this->dial_socket_ ? "setblocking" : "create", errno);
this->schedule_retry_(now);
return;
}
@@ -66,7 +66,7 @@ def test_outgoing_connection_bare_block(
def test_outgoing_connection_delay_bounded(
set_core_config: SetCoreConfigCallable,
) -> None:
"""A delay past the device's uint32 milliseconds is rejected, not wrapped."""
"""A delay past half the uint32 millisecond range is rejected, not wrapped."""
set_core_config(PlatformFramework.ESP32_IDF, platform_data=ESP32_PLATFORM_DATA)
with pytest.raises(cv.Invalid, match="value must be at most"):
CONFIG_SCHEMA(_api_config({"delay": "60d"}))