+ /*
+ * Synchronize to the packetized input stream. Check the model
+ * ID at the start of receive data. Which is a weak condition,
+ * but going out of sync should be rare, and repeated attempts
+ * to synchronize should eventually succeed. Try to rate limit
+ * the emission of diagnostics messages. (Re-)run this logic
+ * at the first reception which makes enough data available,
+ * but not during subsequent accumulation of more data.
+ *
+ * Reducing redundancy in the implementation at the same time as
+ * increasing robustness would involve the creation of a checker
+ * routine, which just gets called for every byte position until
+ * it succeeds. Similar to what a previous implementation of the
+ * read loop did, which was expensive on the serial transport.
+ */
+ sync_idx = 0;
+ if (do_sync_check && read_u16be(&devc->buf[sync_idx]) != p->model_id)
+ sr_warn("Unexpected response data, trying to synchronize.");
+ while (do_sync_check) {
+ if (sync_idx + sync_len >= devc->buflen)
+ break;
+ if (read_u16be(&devc->buf[sync_idx]) == p->model_id)
+ break;
+ sync_idx++;
+ }
+ if (do_sync_check && sync_idx) {
+ sr_dbg("Skipping %zu bytes in attempt to sync.", sync_idx);
+ sync_len = devc->buflen - sync_idx;
+ if (sync_len)
+ memmove(&devc->buf[0], &devc->buf[sync_idx], sync_len);
+ devc->buflen -= sync_idx;
+ }
+
+ /*
+ * Process packets as their reception completes. Periodically
+ * re-transmit poll requests. Discard consumed data after all
+ * processing has completed.
+ */
+ rdptr = devc->buf;
+ rdlen = devc->buflen;
+ ret = SR_OK;
+ while (ret == SR_OK && rdlen >= POLL_RECV_LEN) {
+ ret = process_data(sdi, rdptr, rdlen);
+ if (ret != SR_OK) {
+ sr_err("Processing response packet failed.");
+ break;
+ }
+ rdptr += POLL_RECV_LEN;
+ rdlen -= POLL_RECV_LEN;