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, ...)
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;
}
}
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 ***/
/*** 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;
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);
static void release_device(void)
{
+ libusb_release_interface(devh, 0);
+ libusb_reset_device(devh);
libusb_close(devh);
devh = NULL;
}
}
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;
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;
want_shutdown = 1;
}
-static void interruptible_sleep(int seconds)
+static void interruptible_msleep(int ms)
{
sigprocmask(SIG_UNBLOCK, &term_sigs, NULL);
- sleep(seconds);
+ struct timespec ts = { .tv_sec = ms/1000, .tv_nsec = (ms%1000) * 1000000 };
+ nanosleep(&ts, NULL);
sigprocmask(SIG_BLOCK, &term_sigs, NULL);
}
-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);
}
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++;
case 'r':
debug_raw_data++;
break;
+ case 'u':
+ debug_usb++;
+ break;
default:
usage();
}
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)
inited = 1;
log_error("Data logger not connected, waiting until it appears");
}
- interruptible_sleep(30);
+ interruptible_msleep(30000);
continue;
}
log_info("Listening");
if (err > 0 && parse_packet(reply))
want_sleep = 0;
if (want_sleep) {
- interruptible_sleep(4);
+ interruptible_msleep(4000);
want_stats = 1;
- }
+ } else
+ interruptible_msleep(5);
}
log_info("Disconnecting data logger");
release_device();
inited = 0;
- interruptible_sleep(10);
+ interruptible_msleep(10000);
}
log_info("Terminated");