|
@@ -29,6 +29,7 @@ static int use_syslog;
|
|
|
static int debug_mode;
|
|
|
static int debug_packets;
|
|
|
static int debug_raw_data;
|
|
|
+static int debug_usb;
|
|
|
static char *log_dir = DEFAULT_LOG_DIR;
|
|
|
|
|
|
static void die(char *fmt, ...)
|
|
@@ -299,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;
|
|
@@ -314,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);
|
|
@@ -337,6 +390,8 @@ failed:
|
|
|
|
|
|
static void release_device(void)
|
|
|
{
|
|
|
+ libusb_release_interface(devh, 0);
|
|
|
+ libusb_reset_device(devh);
|
|
|
libusb_close(devh);
|
|
|
devh = NULL;
|
|
|
}
|
|
@@ -365,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;
|
|
@@ -378,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;
|
|
@@ -520,6 +575,7 @@ Options:\n\
|
|
|
-l, --log-dir=<dir> Directory where all received data should be stored\n\
|
|
|
-p, --debug-packets Log all packets sent and received\n\
|
|
|
-r, --debug-raw Log conversion from raw values\n\
|
|
|
+-u, --debug-usb Enable libusb debug messages (to stdout/stderr)\n\
|
|
|
");
|
|
|
exit(1);
|
|
|
}
|
|
@@ -527,7 +583,7 @@ Options:\n\
|
|
|
int main(int argc, char **argv)
|
|
|
{
|
|
|
int opt;
|
|
|
- while ((opt = getopt_long(argc, argv, "dl:pr", long_options, NULL)) >= 0)
|
|
|
+ while ((opt = getopt_long(argc, argv, "dl:pru", long_options, NULL)) >= 0)
|
|
|
switch (opt) {
|
|
|
case 'd':
|
|
|
debug_mode++;
|
|
@@ -541,6 +597,9 @@ int main(int argc, char **argv)
|
|
|
case 'r':
|
|
|
debug_raw_data++;
|
|
|
break;
|
|
|
+ case 'u':
|
|
|
+ debug_usb++;
|
|
|
+ break;
|
|
|
default:
|
|
|
usage();
|
|
|
}
|
|
@@ -550,7 +609,8 @@ int main(int argc, char **argv)
|
|
|
int err;
|
|
|
if (err = libusb_init(&usb_ctxt))
|
|
|
die("Cannot initialize libusb: error %d", err);
|
|
|
- // libusb_set_debug(usb_ctxt, 3);
|
|
|
+ if (debug_usb)
|
|
|
+ libusb_set_debug(usb_ctxt, 3);
|
|
|
|
|
|
if (!debug_mode) {
|
|
|
if (chdir(log_dir) < 0)
|