--- /dev/null
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <libusb-1.0/libusb.h>
+
+#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;
+}