2020-08-18 06:36:07 +05:30
|
|
|
/*
|
|
|
|
* =====================================================================================
|
|
|
|
*
|
|
|
|
* 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 <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <libusb-1.0/libusb.h>
|
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
#include "hidapi/hidapi.h"
|
|
|
|
#include <wchar.h>
|
|
|
|
#include <locale.h>
|
|
|
|
|
2020-08-18 06:36:07 +05:30
|
|
|
#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];
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-09-03 11:39:12 +05:30
|
|
|
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);
|
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
// printf( "Dev%u ID %04x:%04x\n", (i), desc.idVendor, desc.idProduct );
|
2020-09-03 11:39:12 +05:30
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
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;
|
2020-09-03 11:39:12 +05:30
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
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;
|
|
|
|
}
|
2020-09-03 11:39:12 +05:30
|
|
|
|
2020-08-18 06:36:07 +05:30
|
|
|
libusb_device *FindHanvon( libusb_context **context);
|
|
|
|
int HandleData( void );
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2020-09-03 11:39:12 +05:30
|
|
|
#define UNREF_DEVICE 1
|
|
|
|
#define KEEP_DEVICE_REF 0
|
2020-08-18 06:36:07 +05:30
|
|
|
|
2020-09-03 11:39:12 +05:30
|
|
|
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");
|
2020-09-30 14:37:24 +05:30
|
|
|
libusb_exit(NULL);
|
2020-09-03 11:39:12 +05:30
|
|
|
return 0;
|
|
|
|
}
|
2020-09-30 14:37:24 +05:30
|
|
|
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();
|
2020-09-03 11:39:12 +05:30
|
|
|
|
|
|
|
|
2020-09-16 04:57:29 +05:30
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
int s = handle_device_lusb(device);
|
2020-09-03 11:39:12 +05:30
|
|
|
|
2020-09-30 14:37:24 +05:30
|
|
|
libusb_exit(NULL);
|
|
|
|
return 0;
|
2020-08-18 06:36:07 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2020-09-30 14:37:24 +05:30
|
|
|
//printf( "Dev%u ID %04x:%04x\n", (i + 1), description.idVendor, description.idProduct );
|
2020-08-18 06:36:07 +05:30
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|