71 struct usbdevfs_bulktransfer transfer = {0};
75 transfer.timeout = 5000;
76 transfer.data = (
void*)out_msg;
77 res = ioctl(kb->
handle - 1, USBDEVFS_BULK, &transfer);
79 struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, kb->
epcount - 1,
MSG_SIZE, 5000, (
void*)out_msg };
80 res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
84 ckb_err_fn(
" %s, res = 0x%x\n", file, line, res ? strerror(errno) :
"No data written", res);
85 if(res == -1 && errno == ETIMEDOUT)
94 sprintf(&converted[i*3],
"%02x ", out_msg[i]);
141 struct usbdevfs_ctrltransfer transfer = { 0xa1, 0x01, 0x0300, kb->
epcount - 1,
MSG_SIZE, 5000, in_msg };
142 res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
145 ckb_err_fn(
"%s\n", file, line, res ? strerror(errno) :
"No data read");
146 if(res == -1 && errno == ETIMEDOUT)
152 #ifdef DEBUG_USB_RECV
155 sprintf(&converted[i*3],
"%02x ", in_msg[i]);
192 struct usbdevfs_ctrltransfer transfer = { 0x40, bRequest, wValue, 0, 0, 5000, 0 };
193 int res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
195 ckb_err_fn(
"%s\n", file, line, res ? strerror(errno) :
"No data written");
215 static int countForReset = 0;
219 leds = (kb->
ileds << 8) | 0x0001;
225 struct usbdevfs_ctrltransfer transfer = { 0x21, 0x09, 0x0200, 0x00, (kb->
fwversion >= 0x300 ? 2 : 1), 500, ileds };
226 int res = ioctl(kb->
handle - 1, USBDEVFS_CONTROL, &transfer);
228 ckb_err(
"%s\n", res ? strerror(errno) :
"No data written");
261 ckb_err(
"urbcount = 0, so there is nothing to claim in os_inputmain()\n");
266 struct usbdevfs_urb urbs[urbcount + 1];
267 memset(urbs, 0,
sizeof(urbs));
283 if(urbcount > 1 &&
IS_RGB(vendor, product)) {
285 urbs[1].buffer_length = 10;
287 urbs[1].buffer_length = 21;
290 urbs[urbcount - 1].buffer_length =
MSG_SIZE;
292 urbs[1].buffer_length = 4;
293 urbs[2].buffer_length = 15;
298 for(
int i = 0; i < urbcount; i++){
299 urbs[i].type = USBDEVFS_URB_TYPE_INTERRUPT;
300 urbs[i].endpoint = 0x80 | (i + 1);
301 urbs[i].buffer = malloc(urbs[i].buffer_length);
302 ioctl(fd, USBDEVFS_SUBMITURB, urbs + i);
307 struct usbdevfs_urb* urb = 0;
311 if (ioctl(fd, USBDEVFS_REAPURB, &urb)) {
312 if (errno == ENODEV || errno == ENOENT || errno == ESHUTDOWN)
315 else if(errno == EPIPE && urb){
317 ioctl(fd, USBDEVFS_CLEAR_HALT, &urb->endpoint);
320 ioctl(fd, USBDEVFS_SUBMITURB, urb);
342 pthread_mutex_lock(
imutex(kb));
345 uchar urbendpoint = (kb->
fwversion >= 0x300 ? 2 : (urb->endpoint & 0xF));
347 switch(urb->actual_length){
359 }
else if(
IS_RGB(vendor, product)){
360 switch(urb->actual_length){
383 pthread_mutex_unlock(
imutex(kb));
386 ioctl(fd, USBDEVFS_SUBMITURB, urb);
395 for(
int i = 0; i < urbcount; i++){
396 ioctl(fd, USBDEVFS_DISCARDURB, urbs + i);
397 free(urbs[i].buffer);
420 int handle = kb->
handle - 1;
422 for (
int i = 0; i < count; i++) {
423 ioctl(handle, USBDEVFS_RELEASEINTERFACE, &i);
428 struct usbdevfs_ioctl ctl = { 0, USBDEVFS_CONNECT, 0 };
429 ioctl(handle, USBDEVFS_IOCTL, &ctl);
431 ioctl(handle, USBDEVFS_IOCTL, &ctl);
435 ioctl(handle, USBDEVFS_IOCTL, &ctl);
454 udev_device_unref(kb->
udev);
475 ckb_info(
"claiming %d endpoints\n", count);
478 for(
int i = 0; i < count; i++){
479 struct usbdevfs_ioctl ctl = { i, USBDEVFS_DISCONNECT, 0 };
480 ioctl(kb->
handle - 1, USBDEVFS_IOCTL, &ctl);
481 if(ioctl(kb->
handle - 1, USBDEVFS_CLAIMINTERFACE, &i)) {
482 ckb_err(
"Failed to claim interface %d: %s\n", i, strerror(errno));
492 #define TEST_RESET(op) \
494 ckb_err_fn("resetusb failed: %s\n", file, line, strerror(errno)); \
495 if(errno == EINTR || errno == EAGAIN) \
526 for(
char* c =
string; *c != 0; c++){
532 char* first = string;
533 for(; *first != 0; first++){
538 memmove(
string, first, last - first);
551 struct udev_device* dev = kb->
udev;
552 const char* name = udev_device_get_sysattr_value(dev,
"product");
556 const char* serial = udev_device_get_sysattr_value(dev,
"serial");
562 const char* firmware = udev_device_get_sysattr_value(dev,
"bcdDevice");
577 const char* ep_str = udev_device_get_sysattr_value(dev,
"bNumInterfaces");
579 ckb_info(
"claiming interfaces. name=%s, firmware=%s; ep_str=%s\n", name, firmware, ep_str);
583 sscanf(ep_str,
"%d", &kb->
epcount);
586 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);
588 static int retryCount = 0;
589 if (retryCount++ < 5) {
600 ckb_err(
"Failed to claim interfaces: %s\n", strerror(errno));
606 int usbadd(
struct udev_device* dev,
short vendor,
short product) {
607 const char* path = udev_device_get_devnode(dev);
608 const char* syspath = udev_device_get_syspath(dev);
609 if(!path || !syspath || path[0] == 0 || syspath[0] == 0){
610 ckb_err(
"Failed to get device path\n");
614 ckb_info(
">>>vendor = 0x%x, product = 0x%x, path = %s, syspath = %s\n", vendor, product, path, syspath);
617 for(
int index = 1; index <
DEV_MAX; index++){
619 if(pthread_mutex_trylock(
dmutex(kb))){
629 kb->
handle = open(path, O_RDWR) + 1;
631 ckb_err(
"Failed to open USB device: %s\n", strerror(errno));
633 pthread_mutex_unlock(
dmutex(kb));
640 strncpy(
kbsyspath[index], syspath, FILENAME_MAX);
646 pthread_mutex_unlock(
dmutex(kb));
700 #define N_MODELS (sizeof(models) / sizeof(_model))
714 const char* vendor = udev_device_get_sysattr_value(dev,
"idVendor");
716 const char* product = udev_device_get_sysattr_value(dev,
"idProduct");
719 if(!strcmp(product, model->name)){
740 const char* syspath = udev_device_get_syspath(dev);
741 if(!syspath || syspath[0] == 0)
743 for(
int i = 1; i <
DEV_MAX; i++){
766 struct udev_enumerate* enumerator = udev_enumerate_new(udev);
767 udev_enumerate_add_match_subsystem(enumerator,
"usb");
768 udev_enumerate_add_match_sysattr(enumerator,
"idVendor",
V_CORSAIR_STR);
769 udev_enumerate_scan_devices(enumerator);
770 struct udev_list_entry* devices, *dev_list_entry;
771 devices = udev_enumerate_get_list_entry(enumerator);
773 udev_list_entry_foreach(dev_list_entry, devices){
774 const char* path = udev_list_entry_get_name(dev_list_entry);
777 struct udev_device* dev = udev_device_new_from_syspath(udev, path);
783 udev_device_unref(dev);
785 udev_enumerate_unref(enumerator);
799 if(system(
"modprobe uinput") != 0)
800 ckb_warn(
"Failed to load uinput module\n");
805 if(!(udev = udev_new())) {
806 ckb_fatal(
"Failed to initialize udev in usbmain(), usb_linux.c\n");
817 struct udev_monitor* monitor = udev_monitor_new_from_netlink(udev,
"udev");
818 udev_monitor_filter_add_match_subsystem_devtype(monitor,
"usb", 0);
819 udev_monitor_enable_receiving(monitor);
821 int fd = udev_monitor_get_fd(monitor);
827 if(select(fd + 1, &fds, 0, 0, 0) > 0 && FD_ISSET(fd, &fds)){
828 struct udev_device* dev = udev_monitor_receive_device(monitor);
831 const char* action = udev_device_get_action(dev);
833 udev_device_unref(dev);
837 if(!strcmp(action,
"add")){
844 }
else if(!strcmp(action,
"remove"))
846 udev_device_unref(dev);
849 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().
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...)
#define ckb_warn(fmt, args...)
void corsair_mousecopy(unsigned char *kbinput, int endpoint, const unsigned char *urbinput)
void os_closeusb(usbdevice *kb)
void hid_mouse_translate(unsigned char *kbinput, short *xaxis, short *yaxis, int endpoint, int length, const unsigned char *urbinput, ushort fwversion)
#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)
#define P_STRAFE_NRGB_2_STR
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".
uchar keys[((((152+22+12)+25)+7)/8)]
#define ckb_err_fn(fmt, file, line, args...)
#define IS_V2_OVERRIDE(kb)
Used when a device has a firmware with a low version number that uses the new protocol.
#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