From: Gerhard Sittig Date: Sun, 19 Mar 2023 18:21:04 +0000 (+0100) Subject: rdtech-tc: avoid too eager request retransmission X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=66d58fcb9fdd3a167b8fc6ca19f7f0a007c2ee8f;p=libsigrok.git rdtech-tc: avoid too eager request retransmission The sequence of a scan/probe (which exchanges exactly one request and response pair) before an acquisition (which requests another response, then keeps re-requesting periodically) resulted in the transmission of more requests shortly after a request was sent and before any response started receiving at all. Which then resulted in unexpected lengths and failed consistency checks for the receive data. This condition stuck because rdtech-tc does not support the re-synchronization to the input stream as rdtech-um does. Defer transmission of requests until after receive data was seen (or an acquisition start forces their transmission). Tested by repeatedly running: $ sigrok-cli -d rdtech-tc:conn=bt/dialog/$MAC --continuous --- diff --git a/src/hardware/rdtech-tc/protocol.c b/src/hardware/rdtech-tc/protocol.c index bef28a93..3dff0d6a 100644 --- a/src/hardware/rdtech-tc/protocol.c +++ b/src/hardware/rdtech-tc/protocol.c @@ -202,10 +202,17 @@ SR_PRIV int rdtech_tc_poll(const struct sr_dev_inst *sdi, gboolean force) /* * Don't send the request while receive data is being accumulated. + * Defer request transmission when a previous request has not yet + * seen any response data at all (more probable to happen shortly + * after connecting to the peripheral). */ devc = sdi->priv; - if (!force && devc->rdlen) - return SR_OK; + if (!force) { + if (devc->rdlen) + return SR_OK; + if (!devc->rx_after_tx) + return SR_OK; + } /* * Send the request when the transmit interval was reached. Or @@ -228,6 +235,7 @@ SR_PRIV int rdtech_tc_poll(const struct sr_dev_inst *sdi, gboolean force) return SR_ERR; } devc->cmd_sent_at = now; + devc->rx_after_tx = 0; return SR_OK; } @@ -291,6 +299,7 @@ static int recv_poll_data(struct sr_dev_inst *sdi, struct sr_serial_dev_inst *se if (len == 0) return SR_OK; devc->rdlen += len; + devc->rx_after_tx += len; } /* diff --git a/src/hardware/rdtech-tc/protocol.h b/src/hardware/rdtech-tc/protocol.h index 789b18c2..e495375c 100644 --- a/src/hardware/rdtech-tc/protocol.h +++ b/src/hardware/rdtech-tc/protocol.h @@ -62,6 +62,7 @@ struct dev_context { uint8_t buf[RDTECH_TC_RSPBUFSIZE]; size_t rdlen; int64_t cmd_sent_at; + size_t rx_after_tx; }; SR_PRIV int rdtech_tc_probe(struct sr_serial_dev_inst *serial, struct dev_context *devc);