]> sigrok.org Git - libsigrok.git/commitdiff
rdtech-tc: avoid too eager request retransmission
authorGerhard Sittig <redacted>
Sun, 19 Mar 2023 18:21:04 +0000 (19:21 +0100)
committerGerhard Sittig <redacted>
Sun, 19 Mar 2023 21:40:08 +0000 (22:40 +0100)
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

src/hardware/rdtech-tc/protocol.c
src/hardware/rdtech-tc/protocol.h

index bef28a932a4418a368c7f7fa21f73da28c7ed50d..3dff0d6a8271e358b411d66220432386d44f27c2 100644 (file)
@@ -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;
        }
 
        /*
index 789b18c2a96efdeb2db28012c7a265ebaad15104..e495375ca673dc7b46bef478fbec0c964e237be4 100644 (file)
@@ -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);