]> mj.ucw.cz Git - arexx.git/commitdiff
Replace hard-wired endpoint IDs by proper descriptor parsing
authorMartin Mares <mj@ucw.cz>
Mon, 13 Feb 2012 16:03:38 +0000 (17:03 +0100)
committerMartin Mares <mj@ucw.cz>
Mon, 13 Feb 2012 16:03:38 +0000 (17:03 +0100)
arexxd.c

index ffd1b4ca2847ebc0bf63b59efb49b85ff2f52f69..8cbd56752ab35367780840e1a9cf1f0ebd6f54f9 100644 (file)
--- 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;