71 struct usbdevfs_bulktransfer transfer = {0};
74 transfer.timeout = 5000;
75 transfer.data = (
void*)out_msg;
76 res = ioctl(kb->
handle - 1, USBDEVFS_BULK, &transfer);
78 struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, kb->
epcount - 1,
MSG_SIZE, 5000, (
void*)out_msg };
79 res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
83 ckb_err_fn(
" %s, res = 0x%x\n", file, line, res ? strerror(errno) :
"No data written", res);
84 if(res == -1 && errno == ETIMEDOUT)
93 sprintf(&converted[i*3],
"%02x ", out_msg[i]);
140 struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, kb->
epcount - 1,
MSG_SIZE, 5000, in_msg };
141 res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
144 ckb_err_fn(
"%s\n", file, line, res ? strerror(errno) :
"No data read");
145 if(res == -1 && errno == ETIMEDOUT)
151 #ifdef DEBUG_USB_RECV
154 sprintf(&converted[i*3],
"%02x ", in_msg[i]);
191 struct usbdevfs_ctrltransfer transfer = { 0x40, bRequest, wValue, 0, 0, 5000, 0 };
192 int res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
194 ckb_err_fn(
"%s\n", file, line, res ? strerror(errno) :
"No data written");
214 static int countForReset = 0;
215 struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, 1, 500, &kb->
ileds };
216 int res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
218 ckb_err(
"%s\n", res ? strerror(errno) :
"No data written");
251 ckb_err(
"urbcount = 0, so there is nothing to claim in os_inputmain()\n");
256 struct usbdevfs_urb urbs[urbcount + 1];
257 memset(urbs, 0,
sizeof(urbs));
272 urbs[0].buffer_length = 8;
273 if(urbcount > 1 &&
IS_RGB(vendor, product)) {
275 urbs[1].buffer_length = 10;
277 urbs[1].buffer_length = 21;
280 urbs[urbcount - 1].buffer_length =
MSG_SIZE;
282 urbs[1].buffer_length = 4;
283 urbs[2].buffer_length = 15;
288 for(
int i = 0; i < urbcount; i++){
289 urbs[i].type = USBDEVFS_URB_TYPE_INTERRUPT;
290 urbs[i].endpoint = 0x80 | (i + 1);
291 urbs[i].buffer = malloc(urbs[i].buffer_length);
292 ioctl(fd, USBDEVFS_SUBMITURB, urbs + i);
297 struct usbdevfs_urb* urb = 0;
301 if (ioctl(fd, USBDEVFS_REAPURB, &urb)) {
302 if (errno == ENODEV || errno == ENOENT || errno == ESHUTDOWN)
305 else if(errno == EPIPE && urb){
307 ioctl(fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
310 ioctl(fd, USBDEVFS_SUBMITURB, urb);
332 pthread_mutex_lock(
imutex(kb));
334 switch(urb->actual_length){
346 }
else if(
IS_RGB(vendor, product)){
347 switch(urb->actual_length){
370 pthread_mutex_unlock(
imutex(kb));
373 ioctl(fd, USBDEVFS_SUBMITURB, urb);
382 for(
int i = 0; i < urbcount; i++){
383 ioctl(fd, USBDEVFS_DISCARDURB, urbs + i);
384 free(urbs[i].buffer);
407 int handle = kb->
handle - 1;
409 for (
int i = 0; i < count; i++) {
410 ioctl(handle, USBDEVFS_RELEASEINTERFACE, &i);
415 struct usbdevfs_ioctl ctl = { 0, USBDEVFS_CONNECT, 0 };
416 ioctl(handle, USBDEVFS_IOCTL, &ctl);
418 ioctl(handle, USBDEVFS_IOCTL, &ctl);
422 ioctl(handle, USBDEVFS_IOCTL, &ctl);
441 udev_device_unref(kb->
udev);
462 ckb_info(
"claiming %d endpoints\n", count);
465 for(
int i = 0; i < count; i++){
466 struct usbdevfs_ioctl ctl = { i, USBDEVFS_DISCONNECT, 0 };
467 ioctl(kb->
handle - 1, USBDEVFS_IOCTL, &ctl);
468 if(ioctl(kb->
handle - 1, USBDEVFS_CLAIMINTERFACE, &i)) {
469 ckb_err(
"Failed to claim interface %d: %s\n", i, strerror(errno));
479 #define TEST_RESET(op) \
481 ckb_err_fn("resetusb failed: %s\n", file, line, strerror(errno)); \
482 if(errno == EINTR || errno == EAGAIN) \
513 for(
char* c =
string; *c != 0; c++){
519 char* first = string;
520 for(; *first != 0; first++){
525 memmove(
string, first, last - first);
538 struct udev_device* dev = kb->
udev;
539 const char* name = udev_device_get_sysattr_value(dev,
"product");
543 const char* serial = udev_device_get_sysattr_value(dev,
"serial");
549 const char* firmware = udev_device_get_sysattr_value(dev,
"bcdDevice");
564 const char* ep_str = udev_device_get_sysattr_value(dev,
"bNumInterfaces");
566 ckb_info(
"claiming interfaces. name=%s, firmware=%s; Got >>%s<< as ep_str\n", name, firmware, ep_str);
570 sscanf(ep_str,
"%d", &kb->
epcount);
573 ckb_err(
"Unable to read endpoint count from udev, assuming %d and reading >>%s<< or device is in BIOS mode\n", kb->
epcount, ep_str);
575 static int retryCount = 0;
576 if (retryCount++ < 5) {
587 ckb_err(
"Failed to claim interfaces: %s\n", strerror(errno));
593 int usbadd(
struct udev_device* dev,
short vendor,
short product) {
594 const char* path = udev_device_get_devnode(dev);
595 const char* syspath = udev_device_get_syspath(dev);
596 if(!path || !syspath || path[0] == 0 || syspath[0] == 0){
597 ckb_err(
"Failed to get device path\n");
601 ckb_info(
">>>vendor = 0x%x, product = 0x%x, path = %s, syspath = %s\n", vendor, product, path, syspath);
604 for(
int index = 1; index <
DEV_MAX; index++){
606 if(pthread_mutex_trylock(
dmutex(kb))){
616 kb->
handle = open(path, O_RDWR) + 1;
618 ckb_err(
"Failed to open USB device: %s\n", strerror(errno));
620 pthread_mutex_unlock(
dmutex(kb));
627 strncpy(
kbsyspath[index], syspath, FILENAME_MAX);
633 pthread_mutex_unlock(
dmutex(kb));
682 #define N_MODELS (sizeof(models) / sizeof(_model))
696 const char* vendor = udev_device_get_sysattr_value(dev,
"idVendor");
698 const char* product = udev_device_get_sysattr_value(dev,
"idProduct");
701 if(!strcmp(product, model->name)){
722 const char* syspath = udev_device_get_syspath(dev);
723 if(!syspath || syspath[0] == 0)
725 for(
int i = 1; i <
DEV_MAX; i++){
748 struct udev_enumerate* enumerator = udev_enumerate_new(udev);
749 udev_enumerate_add_match_subsystem(enumerator,
"usb");
750 udev_enumerate_add_match_sysattr(enumerator,
"idVendor",
V_CORSAIR_STR);
751 udev_enumerate_scan_devices(enumerator);
752 struct udev_list_entry* devices, *dev_list_entry;
753 devices = udev_enumerate_get_list_entry(enumerator);
755 udev_list_entry_foreach(dev_list_entry, devices){
756 const char* path = udev_list_entry_get_name(dev_list_entry);
759 struct udev_device* dev = udev_device_new_from_syspath(udev, path);
765 udev_device_unref(dev);
767 udev_enumerate_unref(enumerator);
781 if(system(
"modprobe uinput") != 0)
782 ckb_warn(
"Failed to load uinput module\n");
787 if(!(udev = udev_new())) {
788 ckb_fatal(
"Failed to initialize udev in usbmain(), usb_linux.c\n");
799 struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev,
"udev");
800 udev_monitor_filter_add_match_subsystem_devtype(monitor,
"usb", 0);
801 udev_monitor_enable_receiving(monitor);
803 int fd = udev_monitor_get_fd(monitor);
809 if(select(fd + 1, &fds, 0, 0, 0) > 0 && FD_ISSET(fd, &fds)){
810 struct udev_device* dev = udev_monitor_receive_device(monitor);
813 const char* action = udev_device_get_action(dev);
815 udev_device_unref(dev);
819 if(!strcmp(action,
"add")){
826 }
else if(!strcmp(action,
"remove"))
828 udev_device_unref(dev);
831 udev_monitor_unref(monitor);
static char kbsyspath[9][FILENAME_MAX]
#define P_STRAFE_NRGB_STR
void setupusb(usbdevice *kb)
int usb_tryreset(usbdevice *kb)
#define TEST_RESET(op)
TEST_RESET doesa "try / catch" for resetting the usb interface.
#define ckb_err(fmt, args...)
#define IS_RGB(vendor, product)
RGB vs non-RGB test (note: non-RGB Strafe is still considered "RGB" in that it shares the same protoc...
usbdevice keyboard[9]
remember all usb devices. Needed for closeusb().
uchar keys[((((152+3+12)+25)+7)/8)]
void os_sendindicators(usbdevice *kb)
static int usbunclaim(usbdevice *kb, int resetting)
struct udev_device * udev
static int usbclaim(usbdevice *kb)
int usbadd(struct udev_device *dev, short vendor, short product)
pthread_mutex_t devmutex[9]
Mutex for handling the usbdevice structure.
void * os_inputmain(void *context)
os_inputmain This function is run in a separate thread and will be detached from the main thread...
int os_usbsend(usbdevice *kb, const uchar *out_msg, int is_recv, const char *file, int line)
os_usbsend sends a data packet (MSG_SIZE = 64) Bytes long
#define P_K95_PLATINUM_STR
int os_resetusb(usbdevice *kb, const char *file, int line)
void usbkill()
Stop the USB system.
#define ckb_fatal(fmt, args...)
#define IS_MOUSE(vendor, product)
Mouse vs keyboard test.
static void usb_rm_device(struct udev_device *dev)
usb_rm_device find the usb port to remove and close it via closeusb().
#define ckb_warn_fn(fmt, file, line, args...)
void hid_mouse_translate(unsigned char *kbinput, short *xaxis, short *yaxis, int endpoint, int length, const unsigned char *urbinput)
#define ckb_warn(fmt, args...)
void corsair_mousecopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
void os_closeusb(usbdevice *kb)
const char *const devpath
#define ckb_info(fmt, args...)
#define INDEX_OF(entry, array)
#define P_K70_RFIRE_NRGB_STR
int os_usbrecv(usbdevice *kb, uchar *in_msg, const char *file, int line)
os_usbrecv receives a max MSGSIZE long buffer from usb device
void strtrim(char *string)
int closeusb(usbdevice *kb)
void hid_kb_translate(unsigned char *kbinput, int endpoint, int length, const unsigned char *urbinput)
#define HAS_FEATURES(kb, feat)
static void udev_enum()
udev_enum use the udev_enumerate_add_match_subsystem() to get all you need but only that...
static int usb_add_device(struct udev_device *dev)
Add a udev device. Returns 0 if device was recognized/added.
Definitions for using USB interface.
static struct udev * udev
struct udef is defined in /usr/include/libudev.h
int os_setupusb(usbdevice *kb)
void corsair_kbcopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
#define V_CORSAIR
For the following Defines please see "Detailed Description".
#define ckb_err_fn(fmt, file, line, args...)
#define P_SCIMITAR_PRO_STR
int _nk95cmd(usbdevice *kb, uchar bRequest, ushort wValue, const char *file, int line)
_nk95cmd If we control a non RGB keyboard, set the keyboard via ioctl with usbdevfs_ctrltransfer ...
#define P_K70_LUX_NRGB_STR