From 059abd8d8b234963f5784464f69d1b362836f8fd Mon Sep 17 00:00:00 2001 From: Siddharth Chandrasekaran Date: Thu, 26 May 2022 14:35:58 +0200 Subject: [PATCH] mgmt/osdp: Flush RX buffer before sending data Partial packets in the RX buffers cause the subsequent packet to be treated as malformed. The RX buffer can have partial data if the sender is too slow in sending the packet of if there is an interruption in transmission mid-way. To avoid any issues due to such partials, flush the uart channel before sending the command/response. Signed-off-by: Siddharth Chandrasekaran --- subsys/mgmt/osdp/src/osdp_cp.c | 18 ++++++++---------- subsys/mgmt/osdp/src/osdp_pd.c | 5 +++++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/subsys/mgmt/osdp/src/osdp_cp.c b/subsys/mgmt/osdp/src/osdp_cp.c index 1e1716e0b7a..ccb2b957847 100644 --- a/subsys/mgmt/osdp/src/osdp_cp.c +++ b/subsys/mgmt/osdp/src/osdp_cp.c @@ -519,6 +519,11 @@ static int cp_send_command(struct osdp_pd *pd) return OSDP_CP_ERR_GENERIC; } + /* flush rx to remove any invalid data. */ + if (pd->channel.flush) { + pd->channel.flush(pd->channel.data); + } + ret = pd->channel.send(pd->channel.data, pd->rx_buf, len); if (ret != len) { LOG_ERR("Channel send for %d bytes failed! ret: %d", len, ret); @@ -604,14 +609,9 @@ static inline void cp_set_state(struct osdp_pd *pd, enum osdp_cp_state_e state) CLEAR_FLAG(pd, PD_FLAG_AWAIT_RESP); } -static void cp_reset_channel(struct osdp_pd *pd) -{ - pd->rx_buf_len = 0; - if (pd->channel.flush) { - pd->channel.flush(pd->channel.data); - } -} - +/** + * Note: This method must not dequeue cmd unless it reaches an invalid state. + */ static int cp_phy_state_update(struct osdp_pd *pd) { int rc, ret = OSDP_CP_ERR_CAN_YIELD; @@ -629,7 +629,6 @@ static int cp_phy_state_update(struct osdp_pd *pd) pd->cmd_id = cmd->id; memcpy(pd->cmd_data, cmd, sizeof(struct osdp_cmd)); osdp_cmd_free(pd, cmd); - cp_reset_channel(pd); /* fall-thru */ case OSDP_CP_PHY_STATE_SEND_CMD: if ((cp_send_command(pd)) < 0) { @@ -672,7 +671,6 @@ static int cp_phy_state_update(struct osdp_pd *pd) pd->phy_state = OSDP_CP_PHY_STATE_IDLE; break; case OSDP_CP_PHY_STATE_ERR: - cp_reset_channel(pd); cp_flush_command_queue(pd); pd->phy_state = OSDP_CP_PHY_STATE_ERR_WAIT; ret = OSDP_CP_ERR_GENERIC; diff --git a/subsys/mgmt/osdp/src/osdp_pd.c b/subsys/mgmt/osdp/src/osdp_pd.c index 874e5df6427..0e09057c481 100644 --- a/subsys/mgmt/osdp/src/osdp_pd.c +++ b/subsys/mgmt/osdp/src/osdp_pd.c @@ -630,6 +630,11 @@ static int pd_send_reply(struct osdp_pd *pd) return OSDP_PD_ERR_GENERIC; } + /* flush rx to remove any invalid data. */ + if (pd->channel.flush) { + pd->channel.flush(pd->channel.data); + } + ret = pd->channel.send(pd->channel.data, pd->rx_buf, len); if (ret != len) { LOG_ERR("Channel send for %d bytes failed! ret: %d", len, ret);