From: Martin Mares Date: Mon, 13 Feb 2012 16:03:38 +0000 (+0100) Subject: Replace hard-wired endpoint IDs by proper descriptor parsing X-Git-Tag: v1.3~1 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=4bad19fd8e55750f4e8ff1605bcef210b2394fa7;p=arexx.git Replace hard-wired endpoint IDs by proper descriptor parsing --- diff --git a/arexxd.c b/arexxd.c index ffd1b4c..8cbd567 100644 --- a/arexxd.c +++ b/arexxd.c @@ -300,6 +300,56 @@ static void raw_point(int t, int id, int raw, int q) /*** USB interface ***/ +static int rx_endpoint, tx_endpoint; + +static int parse_descriptors(libusb_device *dev) +{ + int err; + struct libusb_config_descriptor *desc; + + if (err = libusb_get_active_config_descriptor(dev, &desc)) { + log_error("libusb_get_config_descriptor failed: error %d", err); + return 0; + } + if (desc->bNumInterfaces != 1) { + log_error("Unexpected number of interfaces: %d", desc->bNumInterfaces); + goto failed; + } + + const struct libusb_interface *iface = &desc->interface[0]; + if (iface->num_altsetting != 1) { + log_error("Unexpected number of alternate interface settings: %d", iface->num_altsetting); + goto failed; + } + + const struct libusb_interface_descriptor *ifd = &iface->altsetting[0]; + if (ifd->bNumEndpoints != 2) { + log_error("Unexpected number of endpoints: %d", ifd->bNumEndpoints); + goto failed; + } + + rx_endpoint = tx_endpoint = -1; + for (int i=0; i<2; i++) { + const struct libusb_endpoint_descriptor *epd = &ifd->endpoint[i]; + if (epd->bEndpointAddress & 0x80) + rx_endpoint = epd->bEndpointAddress; + else + tx_endpoint = epd->bEndpointAddress; + } + if (rx_endpoint < 0 || tx_endpoint < 0) { + log_error("Failed to identify endpoints"); + goto failed; + } + + log_pkt("Found endpoints: rx==%02x tx=%02x\n", rx_endpoint, tx_endpoint); + libusb_free_config_descriptor(desc); + return 1; + +failed: + libusb_free_config_descriptor(desc); + return 0; +} + static int find_device(void) { libusb_device **devlist; @@ -315,6 +365,8 @@ static int find_device(void) if (!libusb_get_device_descriptor(dev, &desc)) { if (desc.idVendor == 0x0451 && desc.idProduct == 0x3211) { log_info("Arexx data logger found at usb%d.%d", libusb_get_bus_number(dev), libusb_get_device_address(dev)); + if (!parse_descriptors(dev)) + continue; int err; if (err = libusb_open(dev, &devh)) { log_error("libusb_open() failed: error %d", err); @@ -368,7 +420,7 @@ static int send_and_receive(byte *req, byte *reply) } int err, transferred; - if (err = libusb_bulk_transfer(devh, 0x01, req, 64, &transferred, 200)) { + if (err = libusb_bulk_transfer(devh, tx_endpoint, req, 64, &transferred, 200)) { if (err == LIBUSB_ERROR_TIMEOUT) { log_pkt(">> xmit timed out\n"); return 0; @@ -381,7 +433,7 @@ static int send_and_receive(byte *req, byte *reply) log_pkt(">> xmit %d bytes\n", transferred); dump_packet(req); } - if (err = libusb_bulk_transfer(devh, 0x81, reply, 64, &transferred, 200)) { + if (err = libusb_bulk_transfer(devh, rx_endpoint, reply, 64, &transferred, 200)) { if (err == LIBUSB_ERROR_TIMEOUT) { log_pkt("<< recv timed out\n"); return 0;