/* * ===================================================================================== * * Filename: hanvon-libusb.c * * Description: Libusb GP0504 handler prototype * * Version: 0.1 * Created: 08/17/2020 04:05:14 PM * Revision: none * Compiler: gcc * * Author: surkeh@protonmail.com * * ===================================================================================== */ #include #include #include #include "hidapi/hidapi.h" #include #include #define STATE_SUCCESS 0 #define STATE_NOT_FOUND 1 #define UNREF_DEVICE 1 #define KEEP_DEVICE_REF 0 #define VENDOR_ID_HANVON 0x0b57 #define PRODUCT_ID_AM3M 0x8528 #define PRODUCT_ID_AM0806 0x8502 #define PRODUCT_ID_AM0605 0x8503 #define PRODUCT_ID_AM1107 0x8505 #define PRODUCT_ID_AM1209 0x8501 #define PRODUCT_ID_RL0604 0x851f #define PRODUCT_ID_RL0504 0x851d #define PRODUCT_ID_GP0806 0x8039 #define PRODUCT_ID_GP0806B 0x8511 #define PRODUCT_ID_GP0605 0x8512 #define PRODUCT_ID_GP0605A 0x803a #define PRODUCT_ID_GP0504 0x8037 #define PRODUCT_ID_NXS1513 0x8030 #define PRODUCT_ID_GP0906 0x8521 #define PRODUCT_ID_APPIV0906 0x8532 #define AM_PACKET_LEN 10 //static int lbuttons[]={BTN_0,BTN_1,BTN_2,BTN_3}; /* reported on all AMs */ //static int rbuttons[]={BTN_4,BTN_5,BTN_6,BTN_7}; /* reported on AM1107+ */ #define AM_WHEEL_THRESHOLD 4 #define AM_MAX_TILT_X 0x3f #define AM_MAX_TILT_Y 0x7f #define AM_MAX_PRESSURE 0x400 struct hanvon { unsigned char *data; //dma_addr_t data_dma; struct input_dev *dev; struct usb_device *usbdev; struct urb *irq; int old_wheel_pos; char phys[32]; }; int find_device(libusb_device **list, unsigned int count) { if (count < 0) { return -1; } int found = -1; struct libusb_device_descriptor desc; for (unsigned int i = 0; i < count; i++) { libusb_device *t = list[i]; libusb_get_device_descriptor(list[i], &desc); // printf( "Dev%u ID %04x:%04x\n", (i), desc.idVendor, desc.idProduct ); if (desc.idVendor == VENDOR_ID_HANVON) { switch(desc.idProduct) { default: break; case PRODUCT_ID_AM0806: case PRODUCT_ID_AM0605: case PRODUCT_ID_AM1107: case PRODUCT_ID_AM1209: case PRODUCT_ID_RL0604: case PRODUCT_ID_RL0504: case PRODUCT_ID_GP0806: case PRODUCT_ID_GP0806B: case PRODUCT_ID_GP0605: case PRODUCT_ID_GP0605A: case PRODUCT_ID_GP0504: case PRODUCT_ID_NXS1513: case PRODUCT_ID_GP0906: case PRODUCT_ID_APPIV0906: return i; } // end switch } // end if } // end for return found; } void callback(struct libusb_transfer *transfer) { unsigned char *data = transfer -> buffer; for(int i = 0; i < 10; i++) { printf("0x%x, ", data[i]); } printf("placeholder\n"); } int handle_device_lusb(libusb_device *d) { libusb_device_handle *h; int status = libusb_open(d, &h); if (status < 0 || h == NULL) { printf("Error opening device, %i.\n", status); libusb_exit(NULL); return 0; } // Wait and handle interrupts? struct libusb_transfer *tx; const int ENDPOINT_ADDR = 0x81; // bEndpointAddress from lsusb -v const unsigned int LEN = 10; // wMaxPacketSize from lsusb -v unsigned char buffer[LEN]; // Allocate memory for transfer, configure, then submit tx = libusb_alloc_transfer(0); libusb_fill_interrupt_transfer( tx, h, ENDPOINT_ADDR, buffer, LEN, callback, NULL, 130); // timeout in milliseconds do { status = libusb_submit_transfer(tx); if (status < 0 ) { return status; } libusb_handle_events(NULL); } while (1); return 0; } libusb_device *FindHanvon( libusb_context **context); int HandleData( void ); int main() { #define UNREF_DEVICE 1 #define KEEP_DEVICE_REF 0 libusb_device ** devs; int r = libusb_init(NULL); if (r < 0) { return r; } int count = libusb_get_device_list(NULL, &devs); if (count < 0) { libusb_exit(NULL); return count; } int index = find_device(devs, count); if (index < 0) { printf("Device not plugged in\n"); libusb_exit(NULL); return 0; } libusb_device *device = devs[index]; libusb_free_device_list (devs, UNREF_DEVICE); int res = hid_init(); hid_device *handle = hid_open(VENDOR_ID_HANVON, PRODUCT_ID_GP0504, NULL); if (handle != NULL) { // wchar_t wstr[80]; // setlocale(LC_CTYPE, ""); unsigned char buf[10]; res = hid_read(handle, buf, 10); for (unsigned int i = 0; i < 10; i++) { printf("0x%x, ", buf[i]); } } else { printf("hidapi: Could not open device\n"); } hid_close(handle); res = hid_exit(); int s = handle_device_lusb(device); libusb_exit(NULL); return 0; } libusb_device *FindHanvon( libusb_context **context) { libusb_device **deviceList; libusb_device *found = NULL; ssize_t nDevices = libusb_get_device_list( context[0], &deviceList); if( nDevices > 0 ) { struct libusb_device_descriptor description; for( ssize_t i = 0; i < nDevices; i++ ) { libusb_device *device = deviceList[i]; libusb_get_device_descriptor(device, &description); //printf( "Dev%u ID %04x:%04x\n", (i + 1), description.idVendor, description.idProduct ); if( description.idVendor == VENDOR_ID_HANVON ) { switch( description.idProduct ) case PRODUCT_ID_AM0806: case PRODUCT_ID_AM0605: case PRODUCT_ID_AM1107: case PRODUCT_ID_AM1209: case PRODUCT_ID_RL0604: case PRODUCT_ID_RL0504: case PRODUCT_ID_GP0806: case PRODUCT_ID_GP0806B: case PRODUCT_ID_GP0605: case PRODUCT_ID_GP0605A: case PRODUCT_ID_GP0504: case PRODUCT_ID_NXS1513: case PRODUCT_ID_GP0906: case PRODUCT_ID_APPIV0906: found = device; break; } } printf( "\n\n" ); } libusb_free_device_list( deviceList, UNREF_DEVICE ); return found; }