ccMSC / ckb

RGB Driver for Linux and OS X
http://forum.corsair.com/v3/showthread.php?t=133929
GNU General Public License v2.0
1.34k stars 170 forks source link

Keyboard not recognized #8

Closed teto closed 9 years ago

teto commented 9 years ago

Hi, I've succesfully compiled latest trunk. My keyboard was not recognized, Here is the output of command lsusb -vd 1b1c: (verbose output for corsair products):


Bus 003 Device 005: ID 1b1c:1b09 Corsair 
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x1b1c Corsair
  idProduct          0x1b09 
  bcdDevice            1.09
  iManufacturer           1 
  iProduct                2 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           84
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      65
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      25
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0004  1x 4 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.11
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      37
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x000f  1x 15 bytes
        bInterval               1

This is the output for my k70 vengeance I just bought. I found that ckb did not take into account because the idProduct differs from the one set in ckb #define P_K70_STR "1b13" while mine is 0x1b09 . So I started working on a patch until ckb crashed. While running the debugger (it would be nice to add some doc on how to build debug binaries, I do "make sub-src-ckb-daemon-debug" is that good ? "make debug" does not work because some subprojects don't have CONFIG += release_and_debug), I realized that ckb crashed in, openusb around strncpy(kb->profile.serial, udev_device_get_sysattr_value(dev, "serial"), SERIAL_LEN); because it's NULL. ckb seems to rely on the serial for operations I haven't peeked into yet. Any idea as how I (we?) could change that so that my keyboard works as well ?

Thanks for your software.

ccMSC commented 9 years ago

Surprised the Vengeance model has a different product ID...it's exactly the same aside from the logo, isn't it? Anyway, I went ahead and added 1b09 to the daemon code.

The serial parameter is supposed to be a unique identifier to track the keyboard in case you use more than one of them (mind you, I don't actually have multiple keyboards, so I'm not 100% sure they're unique). I've added some code to insert a placeholder string instead if it's null, so try it out now and see if it works. I also added debug_and_release to the rest of the project files, so make debug should work properly now.

teto commented 9 years ago

Wow that was quite reactive ! Thanks for your help !

My keyboard is this one: https://delightlylinux.wordpress.com/2014/07/01/the-corsair-vengeance-k70-and-linux/

I still have problems though. First the ioctl calls in usbclaim fail for i = 3 as can be seen here:

ckb Corsair Keyboard RGB driver v0.0.20
Setting FPS to 30
Setting default layout: fr
Root controller ready at /dev/input/ckb0
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Failed ioctl 3
Error: Failed to claim interface: Argument invalide
Trying again...
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Failed ioctl 3
Error: Failed to claim interface: Argument invalide
Trying again...
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Failed ioctl 3
Error: Failed to claim interface: Argument invalide
Trying again...
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Failed ioctl 3
Error: Failed to claim interface: Argument invalide
Trying again...
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Failed ioctl 3
Error: Failed to claim interface: Argument invalide

So I updated the code to not call ioctl for i=3 and then I get this (it may be a sideeffect ?)

ckb Corsair Keyboard RGB driver v0.0.20
Setting FPS to 30
Setting default layout: fr
Root controller ready at /dev/input/ckb0
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Error: usbdequeue (firmware.c:23): Opération non permise
Error: usbdequeue (usb.c:71): Opération non permise
Error: usbdequeue (usb.c:79): Opération non permise
Error: usbdequeue (profile.c:286): Opération non permise
USB failure. Attempting reset (1 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (2 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (3 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (4 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (5 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (6 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (7 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (8 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (9 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (10 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (11 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (12 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (13 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (14 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (15 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (16 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (17 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (18 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (19 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (20 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (21 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (22 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (23 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (24 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Attempting reset (25 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise
Reset failed. Disconnecting.
Trying again...
Connecting Corsair K70R Gaming Keyboard (S/N: K70-NoID)
Error: usbdequeue (firmware.c:17): Opération non permise
Error: usbdequeue (usb.c:71): Opération non permise
Error: usbdequeue (usb.c:79): Opération non permise
Error: usbdequeue (profile.c:286): Opération non permise
USB failure. Attempting reset (1 of 25)...
Error: usbdequeue (firmware.c:23): Opération non permise

"Opération non permise" translates into "Operation not allowed" though I launched the command with sudo bin/ckb-daemon. Of course I have to replug my keyboard after every failure since otherwise it does not operate anymore. I would like to add more debug info to the daemon. I could do so via a PR; any advice on what I should use ? qDebug or a custom solution ?

ccMSC commented 9 years ago

Ah, I didn't realize you had a non-RGB model. It looks like it doesn't have an interface 3 and doesn't respond to any of the RGB command messages.

I'm not sure how difficult it will be to get the keyboard working without the RGB features, but there's a good chance I'll need USB captures from the Windows software. Would it be possible for you to get a Windows install running in a virtual machine?

teto commented 9 years ago

I am in the process of installing a windows in a VM. I've never used their driver, can the driver export USBN captures or should I go with another tool (I believe wireshark can do it too). Any advice ? Is there any specific input sequence you would have me do ?

Wouldn't it be possible to add a flag in the driver to enable/disable the RGB feature. It may be automatically triggered for the productId 1b09.

ccMSC commented 9 years ago

That's my thought, yeah - disable RGB commands for non-RGB keyboards. The other problem is that the daemon handles key input through a proprietary Corsair protocol, instead of the standard keyboard input. It would be possible to disable this as well, but at that point you might as well not be using the driver. What I'm not sure about is whether the proprietary input exists on the non-RGB keyboards at all, or whether the software can process special keys e.g. Win Lock. I'm also aware that there's a firmware update for these keyboards, but since the protocol is completely different I'm not sure how it's handled.

Here's how I do my USB captures:

So, here's what I'd like you to do once you have the VM up and running, and got Corsair's software installed:

After you've done that, stop the capture, then use File > Export Specified Packets in Wireshark to save the data. Send that file to me and hopefully it should contain everything I need to know. Let me know if you have any questions.

teto commented 9 years ago

I had installed a VM with Win10 technical preview as it's free but I couldn't make CUE recognize the keyboard. I first thought it was due to a VM/Win10 bug so I used a friend's laptop with native Windows (and my own keyboard) but CUE didn't recognize my k70 vengeance NON-RGB either. I searched the Corsair forums and it is apparently normal which surprised me quite a bit ! I mean I bought this keyboard to program the lights so if after looking at the traces you tell me it's not possible I may as well return it and get an RGB version. I used usbcap with wireshark: http://desowin.org/usbpcap/tour.html You can download the captures from http://downloads.tuxfamily.org/bluecosmos/pcap/ "Simple-commands" corresponds to:

•Press the following keys in order: Left Ctrl, Left Shift, A. (if your keyboard is a non-English layout, press whichever key is next to Caps Lock)
•Turn Num Lock on and then turn it back off. Do the same for Caps Lock and Scroll Lock

Firmware update to:

•Perform a firmware update on the keyboard.

"Complex.pcapng" refers to:

•Press in order: LCtrl, Program (the one above F12), LCtrl, Brightness, LCtrl, Win Lock, LCtrl, Mute, LCtrl, Volume Up (just try to move the wheel by one notch), LCtrl, Volume Down, LCtrl. (Edit: Actually, I think you'll have to press Program and Win Lock twice - once to enable, once to disable. Make sure they're turned off before hitting Ctrl again).

While the first 2 should match perfectly the inputs you asked without any extra key, there might be an "Escape key" at the end of "complex".

Tell me if you need other inputs or to test a branch etc... Thanks for your help !

ccMSC commented 9 years ago

Hmm, the URB_CONTROL messages from the captures are all missing their data. Odd. It doesn't matter except for the firmware update, though. I can guess what the other ones are.

So, interestingly enough it seems that the keyboard actually DOES provide USB reports for some of the special keys, although the Windows driver doesn't seem to respond to them in any way. Under Windows, is it possible to remap them, or to change the function of the Win Lock key? It seems odd that they would provide any USB input if there's no integration with CUE or any other software controls for them...

I'll try to get the daemon working with this keyboard in the next day or two and I can get some more info from you then. For now I have a pretty good idea of what's going on, thanks :)

ccMSC commented 9 years ago

Hey, sorry this took me so long, but as of commit fb4686228ea646058066c5722c2a1a812eaf6c94, the daemon should support the keyboard properly now. I can't test the key input since the RGB keyboards are totally different, but hopefully the code that I took from the Linux keyboard driver will do the trick. :) Let me know whether or not it's working when you get a chance.

Assuming the keyboard DOES work, could you try pressing all of the keys (including volume wheel, win lock, etc) and tell me if you get any "unknown key" messages from the daemon? If so, copy the output, and tell me which key caused it. If it's not working at all then just tell me what messages you see (if any) and we'll try to go from there.

teto commented 9 years ago

Thanks for your work. I am abroad for the next month so I will not beable to test the code before then but I am really looking forward to testing this. Maybe some people on the corsair forums would also be interested in testing it ?

ccMSC commented 9 years ago

Ok, I'll ask around. Hope you enjoy your travels.

teto commented 9 years ago

I am back for the week end (will be definitely back next month) so I pulled changes, recompiled via "make debug" and then start the daemon:

 INSERT  sudo bin/ckb-daemon                                                      19:00:45   master 
[sudo] password for teto: 
ckb Corsair Keyboard RGB driver alpha-v0.0.34
Setting FPS to 30
Setting default layout: fr
Root controller ready at /dev/input/ckb0
Connecting Corsair K70R Gaming Keyboard (S/N: 1b1c:1b0904-NoID)
Device ready at /dev/input/ckb1

and then I ran the ckb binary in gdb because it crashes at startup. Here is the output:

 (gdb) directory src
Source directories searched: /home/teto/ckb/src:$cdir:$cwd
(gdb) r
Starting program: /home/teto/ckb/bin/ckb 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7fffec311700 (LWP 6766)]
[New Thread 0x7fffdeaed700 (LWP 6768)]
[New Thread 0x7fffde2ec700 (LWP 6769)]
[New Thread 0x7fffddaeb700 (LWP 6770)]
[New Thread 0x7fffdd2ea700 (LWP 6771)]
[New Thread 0x7fffceccd700 (LWP 6772)]
[New Thread 0x7fffce2ca700 (LWP 6773)]
[New Thread 0x7fffcdac9700 (LWP 6774)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffceccd700 (LWP 6772)]
0x00007ffff6919fa4 in QIODevice::isOpen() const () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
(gdb) 
(gdb) bt
#0  0x00007ffff6919fa4 in QIODevice::isOpen() const () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#1  0x00007ffff690bb09 in QFile::open(QFlags<QIODevice::OpenModeFlag>) ()
   from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#2  0x000000000045d5b8 in Kb::_readNotify (this=0xb16330) at kb.cpp:269
#3  0x00000000004607be in QtConcurrent::VoidStoredMemberFunctionPointerCall0<void, Kb>::runFunctor (
    this=0x8ee270)
    at /usr/include/x86_64-linux-gnu/qt5/QtConcurrent/qtconcurrentstoredfunctioncall.h:207
#4  0x000000000045fb47 in QtConcurrent::RunFunctionTask<void>::run (this=0x8ee270)
    at /usr/include/x86_64-linux-gnu/qt5/QtConcurrent/qtconcurrentrunbase.h:132
#5  0x00007ffff67bc2ce in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#6  0x00007ffff67bf2ee in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#7  0x00007ffff650c0a5 in start_thread (arg=0x7fffceccd700) at pthread_create.c:309
#8  0x00007ffff5a0d88d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111

EDIT: when killing the daemon, I have to replug the keyboard. I really don't care but I thought I would let you know in case it is a wrong behavior.

teto commented 9 years ago

I just noticed the daemon also displayed messages:

Got unknown key press 233 on EP 2  # when pressing Volume up
Got unknown key press 234 on EP 2 # when pressing Volume down
# the following 3 messages appear when pressing the same button changing light intensity
Got unknown key press 251 on EP 1
Got unknown key press 252 on EP 1
Got unknown key press 253 on EP 1

# this one for the lightning mode button (all buttons Z/Q/S/D for the French layout, equivalent to WASD)
Got unknown key press 204 on EP 1

Got unknown key press 226 on EP 2 # mute button
# media keys from left to right
Got unknown key press 183 on EP 2
Got unknown key press 182 on EP 2
Got unknown key press 205 on EP 2
Got unknown key press 181 on EP 2

No message appears when pressing the "windows lock" button.

ccMSC commented 9 years ago

Check out the k70test branch here: https://github.com/ccMSC/ckb/tree/k70test I synced it with the latest version of the master branch and added support for the media keys, so those should work now. This is a test build that prints output for all keypresses, even the ones that the driver recognizes. Can you tell me whether this version prints anything when you press Win Lock or not?

Regarding the keyboard not working after the driver exits, it's due to problems with the RGB keyboards, which usually refuse to reconnect the kernel driver correctly. I'm not sure if the problem applies to non-RGB keyboards or not. I added some code in the k70test branch to reconnect everything, so test that out and see whether the keyboard works after exit now.

Not sure about ckb crashing, I'll look in to that some more. You're not really missing anything at the moment, as ckb just does lighting and I haven't added rebinding support yet.

teto commented 9 years ago

I checkout this new branch and:

Thanks again :)

ccMSC commented 9 years ago

The RGB commands won't do anything on the non-RGB models, since there isn't any way (as far as I can tell) for the software to control the lighting. It's a bit disappointing that Win Lock doesn't report anything, but oh well. Sounds like the driver is working fine for the input itself, though, so I'll merge the fixes into the master branch and close this for now. Thanks for your help :)