X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=arexxd.c;h=0358db145ba9d1d36953c9123f7f71c61918a486;hb=78a7acc0f53e3eadff75fd4f9452b5a974e40334;hp=ffd1b4ca2847ebc0bf63b59efb49b85ff2f52f69;hpb=9429fa22411636727d5609cb95ef4b05856348a5;p=arexx.git diff --git a/arexxd.c b/arexxd.c index ffd1b4c..0358db1 100644 --- a/arexxd.c +++ b/arexxd.c @@ -141,6 +141,7 @@ static void rrd_point(time_t t, const char *name, double val, char *unit) rrd_create(arg_cnt, arg_ptr); if (rrd_test_error()) { log_error("rrd_create on %s failed: %s", rr_name, rrd_get_error()); + rrd_clear_error(); return; } } @@ -149,8 +150,10 @@ static void rrd_point(time_t t, const char *name, double val, char *unit) arg_push(rr_name); arg_push("%d:%f", t, val); rrd_update(arg_cnt, arg_ptr); - if (rrd_test_error()) + if (rrd_test_error()) { log_error("rrd_update on %s failed: %s", rr_name, rrd_get_error()); + rrd_clear_error(); + } } /*** Transforms ***/ @@ -300,6 +303,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 +368,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 +423,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 +436,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;