+ memcpy(packet + packet_len, buf + 2, len - 2);
+ packet_len += len - 2;
+ if (packet_len < 5)
+ /* Not even enough to check prefix yet. */
+ continue;
+
+ if (!testo_check_packet_prefix(packet, packet_len)) {
+ /* Tail end of some previous data, drop it. */
+ packet_len = 0;
+ continue;
+ }
+
+ if (packet_len >= 7 + packet[6] * 7 + 2)
+ /* Got a complete packet. */
+ break;
+ }
+ sdi->driver->dev_close(sdi);
+
+ if (packet[6] > MAX_CHANNELS) {
+ sr_err("Device says it has %d channels!", packet[6]);
+ return SR_ERR;
+ }
+
+ for (i = 0; i < packet[6]; i++) {
+ unit = packet[7 + i * 7 + 4];
+ devc->channel_units[i] = unit;
+ switch (unit) {
+ case 1:
+ probe_name = "Temperature";
+ break;
+ case 3:
+ probe_name = "Humidity";
+ break;
+ case 5:
+ probe_name = "Windspeed";
+ break;
+ case 24:
+ probe_name = "Pressure";
+ break;
+ default:
+ sr_dbg("Unsupported measurement unit %d", unit);
+ return SR_ERR;
+ }
+ ch = sr_channel_new(i, SR_CHANNEL_ANALOG, TRUE, probe_name);
+ sdi->channels = g_slist_append(sdi->channels, ch);
+ }
+ devc->num_channels = packet[6];
+ sr_dbg("Found %d channel%s.", devc->num_channels,
+ devc->num_channels > 1 ? "s" : "");
+
+ return SR_OK;
+}
+
+SR_PRIV int testo_request_packet(const struct sr_dev_inst *sdi)
+{
+ struct dev_context *devc;
+ struct sr_usb_dev_inst *usb;
+ int ret;
+
+ devc = sdi->priv;
+ usb = sdi->conn;
+
+ libusb_fill_bulk_transfer(devc->out_transfer, usb->devhdl, EP_OUT,
+ devc->model->request, devc->model->request_size,
+ receive_transfer, (void *)sdi, 100);
+ if ((ret = libusb_submit_transfer(devc->out_transfer) != 0)) {
+ sr_err("Failed to request packet: %s.", libusb_error_name(ret));
+ sdi->driver->dev_acquisition_stop((struct sr_dev_inst *)sdi,
+ devc->cb_data);
+ return SR_ERR;
+ }
+ sr_dbg("Requested new packet.");
+
+ return SR_OK;
+}
+
+/* Check if the packet is well-formed. This matches packets for the
+ * Testo 175/177/400/650/950/435/635/735/445/645/945/946/545. */
+SR_PRIV gboolean testo_check_packet_prefix(unsigned char *buf, int len)
+{
+ int i;
+ unsigned char check[] = { 0x21, 0, 0, 0, 1 };
+
+ if (len < 5)
+ return FALSE;
+
+ for (i = 0; i < 5; i++) {
+ if (buf[i] != check[i]) {
+ sr_dbg("Packet has invalid prefix.");
+ return FALSE;
+ }