From a06d3b72215465ead33c376e663f2931fd70da62 Mon Sep 17 00:00:00 2001 From: Michael Gernoth Date: Sat, 20 Apr 2013 22:34:27 +0200 Subject: [PATCH] fs20pcs utility using libusb to send FS20 commands from the command line --- .gitignore | 2 + Makefile | 10 ++++ fs20pcs.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 fs20pcs.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e607cf0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +fs20pcs.o +fs20pcs diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..14f37d5 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +CFLAGS=-O2 -Wall -I/opt/local/include -g +LDFLAGS=-L/opt/local/lib -lusb-1.0 +CC=gcc + +all: fs20pcs + +fs20pcs: fs20pcs.o + +clean: + rm -f fs20pcs.o fs20pcs diff --git a/fs20pcs.c b/fs20pcs.c new file mode 100644 index 0000000..8bc28c7 --- /dev/null +++ b/fs20pcs.c @@ -0,0 +1,165 @@ +#include +#include +#include +#include +#include +#include + +#define USB_TIMEOUT 10000 + +#define ID_VENDOR 0x18ef +#define ID_PRODUCT 0xe015 + +/* Not in all libusb-1.0 versions, so we have to roll our own :-( */ +static char * usb_strerror(int e) +{ + static char unknerr[256]; + + switch (e) { + case LIBUSB_SUCCESS: + return "Success"; + case LIBUSB_ERROR_IO: + return "Input/output error"; + case LIBUSB_ERROR_INVALID_PARAM: + return "Invalid parameter"; + case LIBUSB_ERROR_ACCESS: + return "Access denied (insufficient permissions)"; + case LIBUSB_ERROR_NO_DEVICE: + return "No such device (it may have been disconnected)"; + case LIBUSB_ERROR_NOT_FOUND: + return "Entity not found"; + case LIBUSB_ERROR_BUSY: + return "Resource busy"; + case LIBUSB_ERROR_TIMEOUT: + return "Operation timed out"; + case LIBUSB_ERROR_OVERFLOW: + return "Overflow"; + case LIBUSB_ERROR_PIPE: + return "Pipe error"; + case LIBUSB_ERROR_INTERRUPTED: + return "System call interrupted (perhaps due to signal)"; + case LIBUSB_ERROR_NO_MEM: + return "Insufficient memory"; + case LIBUSB_ERROR_NOT_SUPPORTED: + return "Operation not supported or unimplemented on this platform"; + case LIBUSB_ERROR_OTHER: + return "Other error"; + }; + snprintf(unknerr, sizeof(unknerr), "Unknown error code %d / 0x%02x", e, e); + return unknerr; +} + +libusb_device_handle *fs20pcs_find() { + libusb_device_handle *devh = NULL; + libusb_device **list; + ssize_t cnt; + ssize_t i; + int err; + + cnt = libusb_get_device_list(NULL, &list); + if (cnt < 0) { + fprintf(stderr, "Can't get USB device list: %d\n", (int)cnt); + return NULL; + } + + for (i = 0; i < cnt; i++){ + struct libusb_device_descriptor desc; + + err = libusb_get_device_descriptor(list[i], &desc); + if (err) + continue; + + if ((desc.idVendor == ID_VENDOR) && (desc.idProduct == ID_PRODUCT)) { + libusb_device *dev = list[i]; + + err = libusb_open(dev, &devh); + if (err) { + fprintf(stderr, "Can't open device: %s\n", usb_strerror(err)); + return NULL; + } + + err = libusb_detach_kernel_driver(devh, 0); + 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); + if ((err != 0)) { + fprintf(stderr, "Can't claim interface: %s\n", usb_strerror(err)); + return NULL; + } + + return devh; + } + + } + + return NULL; +} + +int fs20pcs_send(libusb_device_handle *devh, unsigned char* send_data) +{ + unsigned char recv_data[5] = {0x00, 0x00, 0x00, 0x00, 0x00}; + int err; + int cnt; + int i; + + err = libusb_interrupt_transfer(devh, 0x01, send_data, 11, &cnt, 5000); + if (err) { + fprintf(stderr, "Can't send data: %s\n", usb_strerror(err)); + return 0; + } + + err = libusb_interrupt_transfer(devh, 0x81, recv_data, sizeof(recv_data), &cnt, 5000); + if (err) { + fprintf(stderr, "Can't receive data: %s\n", usb_strerror(err)); + return 0; + } + + for (i = 0; i < cnt; i++) { + printf("0x%02x ", recv_data[i]); + } + printf("\n"); + + return 1; +} + +int main(int argc, char **argv) +{ + unsigned char send_data[11]; + libusb_device_handle *devh = NULL; + int err; + int i; + + if ((argc < 2) || (argc > 12)) { + fprintf(stderr, "Invalid number of parameters!\n"); + return EXIT_FAILURE; + } + + memset(send_data, 0, sizeof(send_data)); + for (i = 0; i < argc - 1; i++) { + send_data[i] = strtoul(argv[i+1], NULL, 16); + } + + err = libusb_init(NULL); + if (err != 0) { + fprintf(stderr, "Can't initialize libusb: %s\n", usb_strerror(err)); + return EXIT_FAILURE; + } + + devh = fs20pcs_find(); + if (!devh) { + fprintf(stderr, "Can't find/open fs20pcs!\n"); + return EXIT_FAILURE; + } + + if (fs20pcs_send(devh, send_data) == 0) { + fprintf(stderr, "Can't communicate with fs20pcs!\n"); + return EXIT_FAILURE; + } + + libusb_close(NULL); + + return EXIT_SUCCESS; +} -- 2.39.2