Open randalla0622 opened 9 years ago
It looks like we've both been burned by the same Massdrop >< The "Unsupported Devices" instructions for building this kext also failed me by not producing a yaml file (I'm assuming that's what it was supposed to do) to be mapped into the Info.plist. Coming loaded with absolutely no experience with the inner workings of USB devices or this particular driver, I created my own called va87m.yaml (is there magic to the numbers before the names of the other .yaml files?) with the following contents:
---
- idVendor: 65535
idProduct: 4174
bcdDevice: 258
bConfigurationValue: 1
bInterfaceNumber: 0
hidReportDescriptor: !binary |-
BQEJBqEBBQgZASkDFQAlAXUBlQORApUFkQEFBxngKeeVCIECGQQpJwktCS4JLwkwCTEJMwk0CTYJ
Nwk4CTUJLAk5CSgJK5UzgQIZSilOlQWBAsA=
- idVendor: 65535
idProduct: 4174
bcdDevice: 258
bConfigurationValue: 1
bInterfaceNumber: 1
hidReportDescriptor: !binary |-
BQwJAaEBhQEZACo8AhUAJjwClQF1EIEAwAUBCQahAYUDBQcZ4CnnFQAlAXUBlQiBAhk5KWUJKQkq
CUkVACUBlTCBAsA=
So far, this has not produced good results (the character spam from pressing keys on the va87m has changed to different character spam) after repeating the "build" portion of the installation instructions. In particular, only one IOUSBHIDDriverDescriptorOverride is present when I expected two:
$ ioreg -b -f | grep IOUSBHIDDriverDescriptorOverride
| | | | | +-o IOUSBHIDDriverDescriptorOverride <class IOUSBHIDDriverDescriptorOverride, id 0x100000ac5, registered, matched, active, busy 0 (3 ms), retain 10>
Any advice would be appreciated.
The HID report descriptors were mapped into YAML binary via the following Python script:
import yaml
descriptor0 = bytes([
0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x03, 0x15, 0x00, 0x25, 0x01,
0x75, 0x01, 0x95, 0x03, 0x91, 0x02, 0x95, 0x05, 0x91, 0x01, 0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7,
0x95, 0x08, 0x81, 0x02, 0x19, 0x04, 0x29, 0x27, 0x09, 0x2D, 0x09, 0x2E, 0x09, 0x2F, 0x09, 0x30,
0x09, 0x31, 0x09, 0x33, 0x09, 0x34, 0x09, 0x36, 0x09, 0x37, 0x09, 0x38, 0x09, 0x35, 0x09, 0x2C,
0x09, 0x39, 0x09, 0x28, 0x09, 0x2B, 0x95, 0x33, 0x81, 0x02, 0x19, 0x4A, 0x29, 0x4E, 0x95, 0x05,
0x81, 0x02, 0xC0])
print(yaml.dump(descriptor0))
descriptor1 = bytes([
0x05, 0x0C, 0x09, 0x01, 0xA1, 0x01, 0x85, 0x01, 0x19, 0x00, 0x2A, 0x3C, 0x02, 0x15, 0x00, 0x26,
0x3C, 0x02, 0x95, 0x01, 0x75, 0x10, 0x81, 0x00, 0xC0, 0x05, 0x01, 0x09, 0x06, 0xA1, 0x01, 0x85,
0x03, 0x05, 0x07, 0x19, 0xE0, 0x29, 0xE7, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x08, 0x81,
0x02, 0x19, 0x39, 0x29, 0x65, 0x09, 0x29, 0x09, 0x2A, 0x09, 0x49, 0x15, 0x00, 0x25, 0x01, 0x95,
0x30, 0x81, 0x02, 0xC0])
print(yaml.dump(descriptor1))
The following is all the device information I could dig up given the USB Prober tool in the mac hardware dev kit (it includes the HID request descriptors used above in hex):
Full Speed device @ 1 (0x14100000): ............................................. Composite device: "zhihaihe keyboard"
Port Information: 0x101a
Not Captive
Attached to Root Hub
External Device
Connected
Enabled
Connected to External Port
Number Of Endpoints (includes EP0):
Total Endpoints for Configuration 1 (current): 3
Device Descriptor
Descriptor Version Number: 0x0200
Device Class: 0 (Composite)
Device Subclass: 0
Device Protocol: 0
Device MaxPacketSize: 64
Device VendorID/ProductID: 0xFFFF/0x104E (unknown vendor)
Device Version Number: 0x0102
Number of Configurations: 1
Manufacturer String: 1 "zhihaihe elec c0"
Product String: 2 "zhihaihe keyboard"
Serial Number String: 3 "Ver1.0 N001"
Configuration Descriptor (current config)
Length (and contents): 59
Raw Descriptor (hex) 0000: 09 02 3B 00 02 01 00 A0 F4 09 04 00 00 01 03 01
Raw Descriptor (hex) 0010: 01 00 09 21 11 01 00 01 22 53 00 07 05 81 03 08
Raw Descriptor (hex) 0020: 00 0A 09 04 01 00 01 03 00 00 00 09 21 11 01 00
Raw Descriptor (hex) 0030: 01 22 44 00 07 05 82 03 08 00 0A
Number of Interfaces: 2
Configuration Value: 1
Attributes: 0xA0 (bus-powered, remote wakeup)
MaxPower: 488 mA
Interface #0 - HID/Boot Interface
Alternate Setting 0
Number of Endpoints 1
Interface Class: 3 (HID)
Interface Subclass; 1 (Boot Interface)
Interface Protocol: 1
HID Descriptor
Descriptor Version Number: 0x0111
Country Code: 0
Descriptor Count: 1
Descriptor 1
Type: 0x22 (Report Descriptor)
Length (and contents): 83
Raw Descriptor (hex) 0000: 05 01 09 06 A1 01 05 08 19 01 29 03 15 00 25 01
Raw Descriptor (hex) 0010: 75 01 95 03 91 02 95 05 91 01 05 07 19 E0 29 E7
Raw Descriptor (hex) 0020: 95 08 81 02 19 04 29 27 09 2D 09 2E 09 2F 09 30
Raw Descriptor (hex) 0030: 09 31 09 33 09 34 09 36 09 37 09 38 09 35 09 2C
Raw Descriptor (hex) 0040: 09 39 09 28 09 2B 95 33 81 02 19 4A 29 4E 95 05
Raw Descriptor (hex) 0050: 81 02 C0
Parsed Report Descriptor:
Usage Page (Generic Desktop)
Usage (Keyboard)
Collection (Application)
Usage Page (LED)
Usage Minimum........... (1)
Usage Maximum........... (3)
Logical Minimum......... (0)
Logical Maximum......... (1)
Report Size............. (1)
Report Count............ (3)
Output.................. (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Report Count............ (5)
Output.................. (Constant, Array, Absolute, No Wrap, Linear, Preferred State, No Null Position, Nonvolatile, Bitfield)
Usage Page (Keyboard/Keypad)
Usage Minimum........... (224)
Usage Maximum........... (231)
Report Count............ (8)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
Usage Minimum........... (4)
Usage Maximum........... (39)
Usage 45 (0x2d)
Usage 46 (0x2e)
Usage 47 (0x2f)
Usage 48 (0x30)
Usage 49 (0x31)
Usage 51 (0x33)
Usage 52 (0x34)
Usage 54 (0x36)
Usage 55 (0x37)
Usage 56 (0x38)
Usage 53 (0x35)
Usage 44 (0x2c)
Usage 57 (0x39)
Usage 40 (0x28)
Usage 43 (0x2b)
Report Count............ (51)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
Usage Minimum........... (74)
Usage Maximum........... (78)
Report Count............ (5)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
End Collection
Endpoint 0x81 - Interrupt Input
Address: 0x81 (IN)
Attributes: 0x03 (Interrupt)
Max Packet Size: 8
Polling Interval: 10 ms
Interface #1 - HID
Alternate Setting 0
Number of Endpoints 1
Interface Class: 3 (HID)
Interface Subclass; 0
Interface Protocol: 0
HID Descriptor
Descriptor Version Number: 0x0111
Country Code: 0
Descriptor Count: 1
Descriptor 1
Type: 0x22 (Report Descriptor)
Length (and contents): 68
Raw Descriptor (hex) 0000: 05 0C 09 01 A1 01 85 01 19 00 2A 3C 02 15 00 26
Raw Descriptor (hex) 0010: 3C 02 95 01 75 10 81 00 C0 05 01 09 06 A1 01 85
Raw Descriptor (hex) 0020: 03 05 07 19 E0 29 E7 15 00 25 01 75 01 95 08 81
Raw Descriptor (hex) 0030: 02 19 39 29 65 09 29 09 2A 09 49 15 00 25 01 95
Raw Descriptor (hex) 0040: 30 81 02 C0
Parsed Report Descriptor:
Usage Page (Consumer)
Usage 1 (0x1)
Collection (Application)
ReportID................ (1)
Usage Minimum........... (0)
Usage Maximum........... (572)
Logical Minimum......... (0)
Logical Maximum......... (572)
Report Count............ (1)
Report Size............. (16)
Input................... (Data, Array, Absolute)
End Collection
Usage Page (Generic Desktop)
Usage (Keyboard)
Collection (Application)
ReportID................ (3)
Usage Page (Keyboard/Keypad)
Usage Minimum........... (224)
Usage Maximum........... (231)
Logical Minimum......... (0)
Logical Maximum......... (1)
Report Size............. (1)
Report Count............ (8)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
Usage Minimum........... (57)
Usage Maximum........... (101)
Usage 41 (0x29)
Usage 42 (0x2a)
Usage 73 (0x49)
Logical Minimum......... (0)
Logical Maximum......... (1)
Report Count............ (48)
Input................... (Data, Variable, Absolute, No Wrap, Linear, Preferred State, No Null Position, Bitfield)
End Collection
Endpoint 0x82 - Interrupt Input
Address: 0x82 (IN)
Attributes: 0x03 (Interrupt)
Max Packet Size: 8
Polling Interval: 10 ms
Hi,
In the case of @randalla0622, where nothing from the keyboard works at all, that's hard to work with. If you're motivated, I've pushed a utility (in hid_report_dumper
) that will show raw hid reports and might help with debugging. It's quite rough around the edges.
Looking at the descriptor in @dr-jam's post, it looks like the exact thing this project sets out to solve. I'm a little surprised it didn't JustWork™. There's no magic in the name for the .yaml files, it's just the PID/VID to keep the files separate. Using the file you pasted, the modified descriptor looks sensible. Can you give an example of the key spam you're seeing? You might also find the hid_report_dumper
useful for debugging.
Cheers, Andrew
I have a second one that is working as intended. I don't know why the one that I had to evaluate is not typing anything where my second one is sending out a flurry of keys. I'll post some keys from my personal board tomorrow (as it's not hooked up at the moment).
A: k/
B: ik,/
C: jk./
D: ijk,./
E: l`
F: il,`
G: jl.`
H: ijl,.`
I: kl/`
J: ikl,/`
K: jkl./`
L: ijkl,./`
M: m<space>
N: im,<space>
O: jm.<space>
P: ijm,.<space>
Q: km/<space>
R: ikm,/<space>
S: jkm./<space>
T: ijkm,./<space>
U: lm`<space>
V: ilm,`<space>
W: jlm.`<space>
X: ijlm,.`<space>
Y: klm/`<space>
Z: iklm,/`<space>
`: ikmn,/<space><capslock>
1: jklm./`<space>
2: ijklm,./`<space>
3: n<capslock>
4: in,<capslock>
5: jn.<capslock>
6: ijn,.<capslock>
7: kn/<capslock>
8: ikn,/<capslock>
9: jkn./<capslock>
0: ijkn,./<space>caps
-: ikln,/`<capslock>
=: jkln./`<capslock>
[: mn<space><capslock>
]: imn,<space><capslock>
\: jmn.<space><capslock>
;: ijmn,.<space><capslock>
': kmn/<space>caps
,: jkmn./<space><capslock>
.: ijkmn,./<space><capslock>
/: lmn`<space><capslock>
ESCAPE: iln,`<capslock>
BS: jln.`<capslock>
TAB: ijln,.`<capslock>
CAPS: ilmn,`<space><capslock>
LSHIFT: nothing
RSHIFT: nothing
LCTRL: nothing
LWIN: nothing
LALT: nothing
SPACE: kln/`<capslock>
RALT: nothing
RWIN: nothing
FN: mnop<space><enter><tab>
RCTRL: nothing
PRINTSCREEN: jko./<enter>
SCROLLLOCK: ijko,./<enter>
PAUSE: lo`<enter>
INSERT: ilo,`<enter>
HOME: jlo.`<enter>
PAGEUP: ijlo,.`<enter>
DELETE: klo/`<enter>
END: iklo,/`<enter>
PAGEDOWN: jklo./`<enter>
UP: jmo.<space><enter>
DOWN: imo,<space><enter>
LEFT: mo<space><enter>
RIGHT: ijklo,./`<enter>
Unfortunately I am going to say the following in a vague, cryptic way: while playing with the hid_report_dumper, I reached a mode where nearly all of the keyboard's functionality worked. This included media keys and changing the led light level (fn+up and down arrows). However, I cannot reliably reproduce this state.
This seems to happen in at least two steps: 1) Through simultaneous pressing many keys around the enter key (approximately the area starting at f9 and extending to right control -- perhaps print screen through delete as well), the report id from 0 to 3 and the report size went from 8 to 3 on the second interface. 2) This allowed fn+f6 and fn+f7 to toggle between the original report size and report id. After experimenting, these fn+f{6,7} combos moved the location of where the keys a-Z were reported: from byte 3 to byte 2 as shown by the hid_report_dumper.
This holds true both when the IOUSBH driver descriptor is or is not overridden (the kernel extension was removed by using kextunload and deleting System/Library/Extensions/IOUSBHIDDriverDescriptorOverride.kext).
Speculation leads me to believe that there are key combinations for changing how the board orders its output. I'm new to both mechanical keyboards and the inner workings of USB -- is this common or reasonable?
The commands used to remove the kernel extension:
sudo kextunload \
/System/Library/Extensions/IOUSBHIDDriverDescriptorOverride.kext
sudo rm -rf \
/System/Library/Extensions/IOUSBHIDDriverDescriptorOverride.kext
For reference, here is the keyboard spam for the yaml files I posted earlier: [a-z] k ik jk ijk l il jl ijl kl ikl jkl ijkl m im jm ijm km ikm jkm ijkm lm ilm jlm ijlm klm iklm [A-Z] K QS QRTU IJK L IL JL IJL ST IKL RST QRST U QU RU QRU KM IKM JKM IJKM LM QTU JLM KM KLM QSTU [1-0] jklm ijklm n in jn ijn kn ikn jkn ijkn
I tried similar steps as dr-jam which produced the same multi-character output. In addition, I noticed pressing Fn+up arrow outputs: “JUVWX.NO PROBLEM” Perhaps there is some device initialization message that’s not being sent by OS X?
I also tried connecting the board to the Arduino Yun running OpenWrt Linux. Everything seems to function except for the LED indicators for Caps Lock & Scroll Lock. I can see the board mounts as two separate interfaces recorded as event1 & event2 event2 handles: backspace, arrow keys, insert, escape, F1 -> F12, print screen, scroll lock, pause all other keys come in on event1
HID keyboards have a simple mode (boot protocol) for environments where doing full HID isn't an option, it's a simple well-known descriptor that sends key state through as an array of up to 6 bytes. When the operating system takes over from the low level, it's meant to issue SET_PROTOCOL
and then use the descriptor supplied by the device.
The output above looks like the keyboard is sending boot-protocol style reports, but they're being interpreted by the OS as the bitfield. Pressing two keys at once should take you further through the alphabet.
I don't know why these keyboards aren't running in the normal high level mode, but it's worth sending the SET_REPORT
request to see if they respond to it. I've pushed a script in scripts/set-protocol.rb
, which works on my Noppoo.
Hey Andrew, do you happen to be in the Seattle area?
Adam Randall http://www.xaren.net AIM: blitz574 Twitter: @randalla0622
"To err is human... to really foul up requires the root password." On Dec 15, 2014 11:13 PM, "Andrew Childs" notifications@github.com wrote:
HID keyboards have a simple mode (boot protocol) for environments where doing full HID isn't an option, it's a simple well-known descriptor that sends key state through as an array of up to 6 bytes. When the operating system takes over from the low level, it's meant to issue SET_PROTOCOL and then use the descriptor supplied by the device.
The output above looks like the keyboard is sending boot-protocol style reports, but they're being interpreted by the OS as the bitfield. Pressing two keys at once should take you further through the alphabet.
I don't know why these keyboards aren't running in the normal high level mode, but it's worth sending the SET_REPORT request to see if they respond to it. I've pushed a script in scripts/set-protocol.rb, which works on my Noppoo.
— Reply to this email directly or view it on GitHub https://github.com/thefloweringash/iousbhiddriver-descriptor-override/issues/17#issuecomment-67121099 .
Not even close sorry, I'm in New Zealand.
thnx - should we test the script by running it specifically or would it be utilized in the compiled kext?
The script is standalone. By default it will send SET_PROTCOL
with REQUEST_PROTOCOL
to every hid device. You can restrict the devices with -v vendor-id
and -p product-id
. The protocol can be specified with -P
, where -P 1
is request protocol (high level mode, bitset) and -P 0
is boot protocol (low level mode, literal bytes).
Example usage:
./scripts/set-protocol.rb -v 0xFFFF -p 0x104E -P 1
Thanks for clarifying. Sadly, there's no change in behavior after running the script.
$ ./scripts/set-protocol.rb -v 0xFFFF -p 0x104E -P 1
{:bClass=>3, :idVendor=>65535, :idProduct=>4174}
Setting report on device: #<LIBUSB::Device 250/8 ffff:104e zhihaihe elec c0 zhihaihe keyboard Ver1.0 N001 (HID (01,01), HID (00,00))>
interface: #<LIBUSB::Interface 0>
interface: #<LIBUSB::Interface 1>
and -P 0
yielded the same results.
I hope you guys can pull this off, since you're our best hope at this point. I'd try to throw in something useful, but you've already far surpassed my knowledge. Let me know if I can help test anything (2008 Late MBP 2.53 + Mid 2014 MBP 2.8 i7.) or provide add'l datas.
Thanks for the map, randall, I was working on that myself, but you've already done it! Awesome.
Hopefully it's a use to someone :)
I'm with Proletariat99, I'm rooting for you guys and I wish I could be of more help! God Speed.
Any update on this? Am thinking about buying one of these myself, but if it's broken on OSX...
I've heard nothing, unfortunately.
@randalla0622 I am thinking about pulling the trigger on one of these boards, as my leopold FC660M's are starting to test my patients when writing markdown documents and such.
If you havent got very far yet, are you still on the mission to get it working? and if so, do you want help finishing it?
I love this keyboard and have actually scheduled a return because it seemed prohibitively hard for me, a MK neophyte, to figure out what in the hell these bastards did with this keyboard and why they're unwilling to help us.
That being said, if you're a linux guy and want to buy for a few bucks off of MD, lemme know :)
On Tue, Feb 17, 2015 at 2:36 PM, Charles Peach notifications@github.com wrote:
@thefloweringash https://github.com/thefloweringash I also live in NZ, Wellington to be precise. I am thinking about pulling the trigger on one of these boards, as my leopold FC660M's are starting to test my patients when writing markdown documents and such.
If you havent got very far yet, are you still on the mission to get it working? and if so, do you want help finishing it?
— Reply to this email directly or view it on GitHub https://github.com/thefloweringash/iousbhiddriver-descriptor-override/issues/17#issuecomment-74759136 .
@Proletariat99 where in the world are you? Also what switches? I am keen to replace my home keyboard also. My email address is on my github profile
Edit: I see you are Colorado, I am in New Zealand so would need to know total cost incl cheapest shipping
@Proletariat99
I had to make an account just to post this. If the sales with charlespeach falls through, let me know, I am looking for mx clears :)
@charlespeach I haven't made any progress on this bug yet, mostly because I don't have the hardware to poke. If you do get one I would like to spend some time with to see what I can do. Can't make any promises though.
What a sad end of discussion :/
I would definitely lend the hardware if I were geographically closer to you @thefloweringash. But thanks for the initiative.
So if there's any interested one around brazilian region, I got a VA87MD w/ black case, mint key caps, white cherry mx.
I was hoping that I might find a solution to allow this stubborn keyboard to work on OS X. It is from Varmilo, which seems to be a sister company to Leopold, and the board itself may be somewhat related to the FC750R, though it's pure speculation on my part.
I followed the instructions to build the kernel extension here, and had no issues with that. I tried the rake scan process, but it did not appear to output anything accept to the terminal itself, and just to make sure I make sure no existing descriptors folder existed before I ran it. It identified my mouse and apple keyboard to the screen, created a descriptors folder, but did not actually create any descriptor files. Seems like this board does not appear in it's list.
Using USB Overdrive I see that the board does show as two completely different USB interfaces, one with 49 programmable keys and the other with 48. Nothing on the board functions at all when plugged into either of my Macs, which are a mid-2012 mini and Macbook Pro). This also includes the controls for non-host things like the back-light.
One thing I did notice that was interesting is that on my Macbook Pro I have the full disk encryption enabled (FileVault). During boot where it asks me for my password, the keyboard does work there, which I believe is in the land of EFI.
I have also been told that the keyboard works in Linux, not that that's much help I'm sure.
Your thoughts, and suggestions are most welcome.
Adam.