X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Ftesto%2Fapi.c;h=9c22893b23084a8da72331d312c01d7350dbcbbb;hb=b5bbc3f1b00d5f3096c6800af4069fb07704d3a9;hp=8d6c4fc5d606a137cbddd6c29a96c47f73160396;hpb=6dcb97230eac000a4033aef0d5ec1099e5f8143d;p=libsigrok.git diff --git a/hardware/testo/api.c b/hardware/testo/api.c index 8d6c4fc5..9c22893b 100644 --- a/hardware/testo/api.c +++ b/hardware/testo/api.c @@ -18,7 +18,6 @@ */ #include -#include #include "protocol.h" #define SERIALCOMM "115200/8n1" @@ -186,6 +185,16 @@ static int dev_open(struct sr_dev_inst *sdi) return SR_ERR; } + if (libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) { + if (libusb_kernel_driver_active(usb->devhdl, 0) == 1) { + if ((ret = libusb_detach_kernel_driver(usb->devhdl, 0)) < 0) { + sr_err("Failed to detach kernel driver: %s.", + libusb_error_name(ret)); + return SR_ERR; + } + } + } + if ((ret = libusb_claim_interface(usb->devhdl, 0))) { sr_err("Failed to claim interface: %s.", libusb_error_name(ret)); return SR_ERR; @@ -320,6 +329,7 @@ static void receive_data(struct sr_dev_inst *sdi, unsigned char *data, int len) { struct dev_context *devc; int packet_size; + uint16_t crc; devc = sdi->priv; @@ -333,19 +343,30 @@ static void receive_data(struct sr_dev_inst *sdi, unsigned char *data, int len) memcpy(devc->reply + devc->reply_size, data, len); devc->reply_size += len; /* Sixth byte contains the length of the packet. */ - if (devc->reply_size >= 7) { - packet_size = 7 + devc->reply[6] * 7 + 2; - if (devc->reply_size >= packet_size) { - testo_receive_packet(sdi); - devc->num_samples++; - devc->reply_size = 0; - if (devc->limit_samples && devc->num_samples >= devc->limit_samples) - dev_acquisition_stop(sdi, devc->cb_data); - else - testo_request_packet(sdi); - } + if (devc->reply_size < 7) + return; + + packet_size = 7 + devc->reply[6] * 7 + 2; + if (devc->reply_size < packet_size) + return; + + if (!testo_check_packet_prefix(devc->reply, devc->reply_size)) + return; + + crc = crc16_mcrf4xx(0xffff, devc->reply, devc->reply_size - 2); + if (crc == RL16(&devc->reply[devc->reply_size - 2])) { + testo_receive_packet(sdi); + devc->num_samples++; + } else { + sr_dbg("Packet has invalid CRC."); } + devc->reply_size = 0; + if (devc->limit_samples && devc->num_samples >= devc->limit_samples) + dev_acquisition_stop(sdi, devc->cb_data); + else + testo_request_packet(sdi); + } SR_PRIV void receive_transfer(struct libusb_transfer *transfer)