ruundii/bthidhub

How to write a filter for a Kensington Orbit trackball

Wheels00 opened this issue · 10 comments

This is a great project . I have been looking for something like this for ages.

But it looks like my mouse sends data in a funny format which doesn't fit the standard mouse filter. The output from hid-tools says:

# MOSART Semi. Orbit Wireless Mobile Trackball
# 0x05, 0x01,                    // Usage Page (Generic Desktop)        0
# 0x09, 0x02,                    // Usage (Mouse)                       2
# 0xa1, 0x01,                    // Collection (Application)            4
# 0x85, 0x01,                    //  Report ID (1)                      6
# 0x09, 0x01,                    //  Usage (Pointer)                    8
# 0xa1, 0x00,                    //  Collection (Physical)              10
# 0x05, 0x09,                    //   Usage Page (Button)               12
# 0x19, 0x01,                    //   Usage Minimum (1)                 14
# 0x29, 0x05,                    //   Usage Maximum (5)                 16
# 0x15, 0x00,                    //   Logical Minimum (0)               18
# 0x25, 0x01,                    //   Logical Maximum (1)               20
# 0x75, 0x01,                    //   Report Size (1)                   22
# 0x95, 0x05,                    //   Report Count (5)                  24
# 0x81, 0x02,                    //   Input (Data,Var,Abs)              26
# 0x75, 0x03,                    //   Report Size (3)                   28
# 0x95, 0x01,                    //   Report Count (1)                  30
# 0x81, 0x01,                    //   Input (Cnst,Arr,Abs)              32
# 0x05, 0x01,                    //   Usage Page (Generic Desktop)      34
# 0x09, 0x30,                    //   Usage (X)                         36
# 0x09, 0x31,                    //   Usage (Y)                         38
# 0x16, 0x01, 0xf8,              //   Logical Minimum (-2047)           40
# 0x26, 0xff, 0x07,              //   Logical Maximum (2047)            43
# 0x75, 0x0c,                    //   Report Size (12)                  46
# 0x95, 0x02,                    //   Report Count (2)                  48
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              50
# 0xc0,                          //  End Collection                     52
# 0xa1, 0x00,                    //  Collection (Physical)              53
# 0x95, 0x01,                    //   Report Count (1)                  55
# 0x75, 0x08,                    //   Report Size (8)                   57
# 0x05, 0x01,                    //   Usage Page (Generic Desktop)      59
# 0x09, 0x38,                    //   Usage (Wheel)                     61
# 0x15, 0x81,                    //   Logical Minimum (-127)            63
# 0x25, 0x7f,                    //   Logical Maximum (127)             65
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              67
# 0x05, 0x0c,                    //   Usage Page (Consumer Devices)     69
# 0x0a, 0x38, 0x02,              //   Usage (AC Pan)                    71
# 0x15, 0x81,                    //   Logical Minimum (-127)            74
# 0x25, 0x7f,                    //   Logical Maximum (127)             76
# 0x75, 0x08,                    //   Report Size (8)                   78
# 0x95, 0x01,                    //   Report Count (1)                  80
# 0x81, 0x06,                    //   Input (Data,Var,Rel)              82
# 0x05, 0x01,                    //   Usage Page (Generic Desktop)      84
# 0x0a, 0x68, 0x01,              //   Usage (Vendor Usage 0x168)        86
# 0x15, 0x81,                    //   Logical Minimum (-127)            89
# 0x25, 0x7f,                    //   Logical Maximum (127)             91
# 0x75, 0x08,                    //   Report Size (8)                   93
# 0x95, 0x01,                    //   Report Count (1)                  95
# 0x81, 0x02,                    //   Input (Data,Var,Abs)              97
# 0xc0,                          //  End Collection                     99
# 0xc0,                          // End Collection                      100
#
R: 101 05 01 09 02 a1 01 85 01 09 01 a1 00 05 09 19 01 29 05 15 00 25 01 75 01 95 05 81 02 75 03 95 01 81 01 05 01 09 30 09 31 16 01 f8 26 ff 07 75 0c 95 02 81 06 c0 a1 00 95 01 75 08 05 01 09 38 15 81 25 7f 81 06 05 0c 0a 38 02 15 81 25 7f 75 08 95 01 81 06 05 01 0a 68 01 15 81 25 7f 75 08 95 01 81 02 c0 c0
N: MOSART Semi. Orbit Wireless Mobile Trackball

I thought i could maybe make an appropriate filter by adjusting the mx510 filter.

My interpretation of the hid-tools output is that we have

5bits for buttons + 3 bits padding
12 bits for x (-+2047)
12 bits for y (-+2047)
8 bits for wheel (-+127)
8 bits for ac pan (-+127)
8 bits for Vendor Usage 0x168 (-+127)

am I right?

if so, how do I turn that into a filter?

any help would be appreciated

You don't need to figure out those details, actually. And the existing mouse filter is not actually a general filter, it fails with most devices I've personally used.

Can you try out the process of updating the sdp_record.xml as described at: #31 (comment)

Thanks @Dreamsorcerer ! So per your suggestion , I swapped the big long hex number in sdp_record.xml to the one in the report description for my trackball. I think I only have one report id and so I assume there's nothing else to change? (btw, i only want to use a mouse; no keyboard necessary).

The result feels somewhat like progress in that x/y movement is sort of coming through to the host if I use "default" filter, but the moment jumps around all over the place. It's definitely not usable .

So next I will try to get hid-tools running on the host (Windows) as well and if I succeed i'll post the two outputs here. But, if the SDP record is the same and bthidhub is just forwarding the data through to the host, i don't understand where the problem could be.

ok, i'm struggling to work out how to run hid-tools or similar on Windows. Any tips?

I've just realised that @ruundii changed the mouse filter code. So my other comment about the mouse filter should be to change the filter code to just:

    def filter_message_to_host(self, msg):
        return b'\xa1\x03' + msg

But, sdp_record.xml was also changed, so not sure if there are other changes needed. I still don't have anything running to retest with the new code.

ok, i'm struggling to work out how to run hid-tools or similar on Windows. Any tips?

No. I don't use Windows and am only familiar with hid-tools in so far as I have run it to see the output from my own devices. Sorry.

Download an Ubuntu disk and just boot Ubuntu off a USB drive? You can just test it from there without installing anything on your machine.

Good idea re: usb drive ubuntu.

Per @Dreamsorcerer 's excellent suggestion i ran hid-tools from an Ubuntu USB drive.

The difference between the HID events from the mouse directly versus via bthidhub is somewhat illuminating.

Direct:

# ReportID: 1 / Button: 0  0  0  0  0 | # | X:     0 | Y:     0 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.000000 8 01 00 00 00 00 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:     0 | Y:    -3 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.159625 8 01 00 00 d0 ff 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:     0 | Y:    -1 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.163695 8 01 00 00 f0 ff 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:     0 | Y:    -2 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.175529 8 01 00 00 e0 ff 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:     0 | Y:    -4 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.179489 8 01 00 00 c0 ff 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:    -2 | Y:    -9 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.191567 8 01 00 fe 7f ff 00 00 00
# ReportID: 1 / Button: 0  0  0  0  0 | # | X:    -6 | Y:   -12 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.195507 8 01 00 fa 4f ff 00 00 00

Via bthidhub:

# ReportID: 1 / Button: 1  0  0  0  0 | # | X:   256 | Y:   256 
#             | Wheel:    0 | AC Pan:    0 | 0x10168:    0 
E: 000000.000000 9 01 01 00 01 10 00 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:     0 | Y:  -256 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.028618 9 01 01 00 00 f0 ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X: -1536 | Y:  2047 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.079712 9 01 01 00 fa 7f ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:  -256 | Y:  -257 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.109602 9 01 01 00 ff ef ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:  -512 | Y:  -769 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.149613 9 01 01 00 fe cf ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:  -256 | Y:  -257 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.201166 9 01 01 00 ff ef ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:  -256 | Y:  -257 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.231032 9 01 01 00 ff ef ff 00 00 00
# ReportID: 1 / Button: 1  0  0  0  0 | # | X:     0 | Y:  -256 
#             | Wheel:   -1 | AC Pan:    0 | 0x10168:    0 
E: 000001.268584 9 01 01 00 00 f0 ff 00 00 00

Now i'm no computer scientist, but via bthidhub the x and y coordinates seem to be multiples of 256, which I think must mean that the x and y bytes are 8-bits out of alignment .

So how do I fix that?

So, I see in the first one:
E: 000000.163695 8 01 00 00 f0 ff 00 00 00
And, in the second one:
E: 000001.028618 9 01 01 00 00 f0 ff 00 00 00

Appears there is an extra 0x01 being added. Have you updated the mouse filter code as I mentioned? Maybe try printing out the msg going through that function to confirm exactly what is happening.