better input parsing/output formatting
[hmcfgusb] / hmcfgusb.c
index 9b00c84eecb43dbd51b88ce33f59dc81140bd213..b8c1546708802beba99b3f0b00f1eb21ad1ccee2 100644 (file)
@@ -34,7 +34,7 @@
 #include "hexdump.h"
 #include "hmcfgusb.h"
 
 #include "hexdump.h"
 #include "hmcfgusb.h"
 
-#define USB_TIMEOUT            10000
+#define USB_TIMEOUT    10000
 
 #define ID_VENDOR      0x1b1f
 #define ID_PRODUCT     0xc00f
 
 #define ID_VENDOR      0x1b1f
 #define ID_PRODUCT     0xc00f
 #define EP_OUT         0x02
 #define EP_IN          0x83
 
 #define EP_OUT         0x02
 #define EP_IN          0x83
 
+#define INTERFACE      0
+
 static int quit = 0;
 static int quit = 0;
+static int debug = 0;
 
 /* Not in all libusb-1.0 versions, so we have to roll our own :-( */
 static char * usb_strerror(int e)
 
 /* Not in all libusb-1.0 versions, so we have to roll our own :-( */
 static char * usb_strerror(int e)
@@ -116,13 +119,13 @@ static libusb_device_handle *hmcfgusb_find() {
                                return NULL;
                        }
 
                                return NULL;
                        }
 
-                       err = libusb_detach_kernel_driver(devh, 0);
+                       err = libusb_detach_kernel_driver(devh, INTERFACE);
                        if ((err != 0) && (err != LIBUSB_ERROR_NOT_FOUND)) {
                                fprintf(stderr, "Can't detach kernel driver: %s\n", usb_strerror(err));
                                return NULL;
                        }
 
                        if ((err != 0) && (err != LIBUSB_ERROR_NOT_FOUND)) {
                                fprintf(stderr, "Can't detach kernel driver: %s\n", usb_strerror(err));
                                return NULL;
                        }
 
-                       err = libusb_claim_interface(devh, 0);
+                       err = libusb_claim_interface(devh, INTERFACE);
                        if ((err != 0)) {
                                fprintf(stderr, "Can't claim interface: %s\n", usb_strerror(err));
                                return NULL;
                        if ((err != 0)) {
                                fprintf(stderr, "Can't claim interface: %s\n", usb_strerror(err));
                                return NULL;
@@ -140,13 +143,12 @@ int hmcfgusb_send(struct hmcfgusb_dev *usbdev, unsigned char* send_data, int len
 {
        int err;
        int cnt;
 {
        int err;
        int cnt;
-       int ret;
 
 
+       if (debug)
+               hexdump(send_data, len, "< ");
        err = libusb_interrupt_transfer(usbdev->usb_devh, EP_OUT, send_data, len, &cnt, USB_TIMEOUT);
        if (err) {
                fprintf(stderr, "Can't send data: %s\n", usb_strerror(err));
        err = libusb_interrupt_transfer(usbdev->usb_devh, EP_OUT, send_data, len, &cnt, USB_TIMEOUT);
        if (err) {
                fprintf(stderr, "Can't send data: %s\n", usb_strerror(err));
-               if (err == LIBUSB_ERROR_NO_DEVICE)
-                       exit(EXIT_FAILURE);
                return 0;
        }
 
                return 0;
        }
 
@@ -154,13 +156,11 @@ int hmcfgusb_send(struct hmcfgusb_dev *usbdev, unsigned char* send_data, int len
                err = libusb_interrupt_transfer(usbdev->usb_devh, EP_OUT, send_data, 0, &cnt, USB_TIMEOUT);
                if (err) {
                        fprintf(stderr, "Can't send data: %s\n", usb_strerror(err));
                err = libusb_interrupt_transfer(usbdev->usb_devh, EP_OUT, send_data, 0, &cnt, USB_TIMEOUT);
                if (err) {
                        fprintf(stderr, "Can't send data: %s\n", usb_strerror(err));
-                       if (err == LIBUSB_ERROR_NO_DEVICE)
-                               exit(EXIT_FAILURE);
                        return 0;
                }
        }
 
                        return 0;
                }
        }
 
-       return ret;
+       return 1;
 }
 
 static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh, libusb_transfer_cb_fn cb, void *data)
 }
 
 static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh, libusb_transfer_cb_fn cb, void *data)
@@ -185,7 +185,7 @@ static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh,
        libusb_fill_interrupt_transfer(transfer, devh, EP_IN,
                        data_buf, ASYNC_SIZE, cb, data, USB_TIMEOUT);
 
        libusb_fill_interrupt_transfer(transfer, devh, EP_IN,
                        data_buf, ASYNC_SIZE, cb, data, USB_TIMEOUT);
 
-       transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK;
+       transfer->flags = LIBUSB_TRANSFER_SHORT_NOT_OK | LIBUSB_TRANSFER_FREE_BUFFER;
 
        err = libusb_submit_transfer(transfer);
        if (err != 0) {
 
        err = libusb_submit_transfer(transfer);
        if (err != 0) {
@@ -199,6 +199,7 @@ static struct libusb_transfer *hmcfgusb_prepare_int(libusb_device_handle *devh,
 }
 
 struct hmcfgusb_cb_data {
 }
 
 struct hmcfgusb_cb_data {
+       struct hmcfgusb_dev *dev;
        hmcfgusb_cb_fn cb;
        void *data;
 };
        hmcfgusb_cb_fn cb;
        void *data;
 };
@@ -208,18 +209,26 @@ static void LIBUSB_CALL hmcfgusb_interrupt(struct libusb_transfer *transfer)
        int err;
        struct hmcfgusb_cb_data *cb_data;
 
        int err;
        struct hmcfgusb_cb_data *cb_data;
 
+       cb_data = transfer->user_data;
+
        if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
                if (transfer->status != LIBUSB_TRANSFER_TIMED_OUT) {
                        fprintf(stderr, "Interrupt transfer not completed: %d!\n", transfer->status);
                        quit = EIO;
        if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {
                if (transfer->status != LIBUSB_TRANSFER_TIMED_OUT) {
                        fprintf(stderr, "Interrupt transfer not completed: %d!\n", transfer->status);
                        quit = EIO;
+
+                       if (cb_data && cb_data->dev && cb_data->dev->transfer) {
+                               libusb_free_transfer(cb_data->dev->transfer);
+                               cb_data->dev->transfer = NULL;
+                       }
                        return;
                }
        } else {
                        return;
                }
        } else {
-               cb_data = transfer->user_data;
                if (cb_data && cb_data->cb) {
                if (cb_data && cb_data->cb) {
+                       if (debug)
+                               hexdump(transfer->buffer, transfer->actual_length, "> ");
                        cb_data->cb(transfer->buffer, transfer->actual_length, cb_data->data);
                } else {
                        cb_data->cb(transfer->buffer, transfer->actual_length, cb_data->data);
                } else {
-                       hexdump(transfer->buffer, transfer->actual_length, "RECV> ");
+                       hexdump(transfer->buffer, transfer->actual_length, "> ");
                }
        }
 
                }
        }
 
@@ -269,6 +278,7 @@ struct hmcfgusb_dev *hmcfgusb_init(hmcfgusb_cb_fn cb, void *data)
 
        memset(cb_data, 0, sizeof(struct hmcfgusb_cb_data));
 
 
        memset(cb_data, 0, sizeof(struct hmcfgusb_cb_data));
 
+       cb_data->dev = dev;
        cb_data->cb = cb;
        cb_data->data = data;
 
        cb_data->cb = cb;
        cb_data->data = data;
 
@@ -392,3 +402,28 @@ int hmcfgusb_poll(struct hmcfgusb_dev *dev, int timeout)
 
        return -1;
 }
 
        return -1;
 }
+
+void hmcfgusb_close(struct hmcfgusb_dev *dev)
+{
+       int err;
+
+       if (dev->transfer) {
+               libusb_cancel_transfer(dev->transfer);
+       }
+
+       err = libusb_release_interface(dev->usb_devh, INTERFACE);
+       if ((err != 0)) {
+               fprintf(stderr, "Can't release interface: %s\n", usb_strerror(err));
+       }
+
+       libusb_close(dev->usb_devh);
+       free(dev->pfd);
+       free(dev);
+
+       libusb_exit(NULL);
+}
+
+void hmcfgusb_set_debug(int d)
+{
+       debug = d;
+}
Impressum, Datenschutz