From 810d33d0d75e8280f8db027dc1ae5d2d956cf407 Mon Sep 17 00:00:00 2001 From: Robert Middleton Date: Fri, 27 Mar 2026 09:34:48 -0400 Subject: [PATCH] Better calculate the transmit timeout for packets Some packets(such as firmware upgrade packets) can be so large that they will cause a timeout on libosdp, especially at slower baud rates. Add in a way to calculate how long the packet transmission should take in order to have an acceptable timeout. See: #282 --- src/osdp_common.h | 1 + src/osdp_cp.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/osdp_common.h b/src/osdp_common.h index b8420155..dc396b7e 100644 --- a/src/osdp_common.h +++ b/src/osdp_common.h @@ -417,6 +417,7 @@ struct osdp_pd { tick_t tstamp; /* Last POLL command issued time in ticks */ tick_t sc_tstamp; /* Last received secure reply time in ticks */ tick_t phy_tstamp; /* Time in ticks since command was sent */ + tick_t resp_expected; /* Time in ticks when the response is expected */ uint32_t request; /* Event loop requests */ uint16_t peer_rx_size; /* Receive buffer size of the peer PD/CP */ diff --git a/src/osdp_cp.c b/src/osdp_cp.c index e5883e57..5b9d807e 100644 --- a/src/osdp_cp.c +++ b/src/osdp_cp.c @@ -795,6 +795,10 @@ static void cp_phy_state_wait(struct osdp_pd *pd, uint32_t wait_ms) pd->phy_state = OSDP_CP_PHY_STATE_WAIT; } +static int cp_calculate_transmit_time(struct osdp_pd* pd){ + return (pd->packet_buf_len * 10000U + pd->baud_rate - 1) / pd->baud_rate; +} + static int cp_phy_state_update(struct osdp_pd *pd) { int rc, ret = OSDP_CP_ERR_DEFER; @@ -825,6 +829,7 @@ static int cp_phy_state_update(struct osdp_pd *pd) pd->reply_id = REPLY_INVALID; pd->phy_state = OSDP_CP_PHY_STATE_REPLY_WAIT; pd->phy_tstamp = osdp_millis_now(); + pd->resp_expected = pd->phy_tstamp + OSDP_RESP_TOUT_MS + cp_calculate_transmit_time(pd); break; case OSDP_CP_PHY_STATE_REPLY_WAIT: rc = cp_process_reply(pd); @@ -851,7 +856,7 @@ static int cp_phy_state_update(struct osdp_pd *pd) cp_phy_state_wait(pd, OSDP_CMD_RETRY_WAIT_MS); return OSDP_CP_ERR_DEFER; } - if (osdp_millis_since(pd->phy_tstamp) > OSDP_RESP_TOUT_MS) { + if (osdp_millis_since(pd->phy_tstamp) > pd->resp_expected) { if (pd->phy_retry_count < OSDP_CMD_MAX_RETRIES) { pd->phy_retry_count += 1; LOG_WRN("No response in 200ms; probing (%d)",