From 052b5c29263df66ac238d2a9ac7e6c75c9e6b54f Mon Sep 17 00:00:00 2001 From: David Gwynne Date: Wed, 1 Feb 2023 20:48:07 +1000 Subject: [PATCH] reset recv parser if it takes too long for the message to arrive. (#17845) i have a tuyamcu based device that occasionally gets a flipped bit in messages it receives from the muc. those usually show up as checksum failures, but if the bit flips in the length field then we wait for bytes that just arent going to arrive, so we don't get to the cksum field for that test to fail. instead, add a timeout that the tick checks, and reset the recv state machine on a timeout. if the message that was corrupted was a dp update, we'll end up with an inconsistent view of the state of the DPs. maybe we should send a request for all datapoint values when this or a cksum failure happens? --- tasmota/tasmota_xdrv_driver/xdrv_65_tuyamcubr.ino | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tasmota/tasmota_xdrv_driver/xdrv_65_tuyamcubr.ino b/tasmota/tasmota_xdrv_driver/xdrv_65_tuyamcubr.ino index e6b471750..d5d4b0ac8 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_65_tuyamcubr.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_65_tuyamcubr.ino @@ -380,6 +380,7 @@ tuyamcubr_parse(struct tuyamcubr_softc *sc, uint8_t byte) if (byte != TUYAMCUBR_H_TWO) return (TUYAMCUBR_P_START); + p->p_deadline = sc->sc_clock + (10 * 1000); nstate = TUYAMCUBR_P_VERSION; break; case TUYAMCUBR_P_VERSION: @@ -889,6 +890,16 @@ tuyamcubr_tick(struct tuyamcubr_softc *sc, unsigned int ms) sc->sc_clock += ms; + if (sc->sc_parser.p_state >= TUYAMCUBR_P_VERSION) { + /* parser timeout only starts after the header */ + diff = sc->sc_clock - sc->sc_parser.p_deadline; + if (diff > 0) { + AddLog(LOG_LEVEL_ERROR, + TUYAMCUBR_FMT("recv timeout")); + sc->sc_parser.p_state = TUYAMCUBR_P_START; + } + } + diff = sc->sc_clock - sc->sc_deadline; if (diff < 0) { /* deadline hasn't been reached, nothing to do */