mia-0 / cadmousectl

Configuration Tool for 3Dconnexion CadMouse
31 stars 9 forks source link

Doesn't work with (my) CadMouse Pro Wireless #7

Open danielthompson opened 4 years ago

danielthompson commented 4 years ago

Hello,

Thanks for putting together this project. This question is not really an issue about cadmousectl, since the failure it's experiencing is in the HID API, but I was hoping you might have some insight into what's going on.

Goal I want to turn off the annoying "smart scroll" feature that simulates scroll wheel inertia.

System I'm running Ubuntu 18.04.3 LTS with gnome-shell on xorg. I have a CadMouse Pro Wireless (apparently just released by 3Dconnexion). This mouse has two USB modes: it can be used wirelessly with a USB receiver, or it can be directly plugged in via a micro-USB cable (it can also be used via Bluetooth, but I haven't tried that, and I assume that wouldn't work with the HID API anyway).

The issue cadmousectl fails to open the mouse via the HID API in either wired or wireless mode. We'll take them one at a time...

Wired USB mode When plugged in to a USB port via a micro-USB cable, the mouse is correctly recognized by the kernel as shown by dmesg:

daniel@ubuntu:~$ dmesg -w
[10758.269137] usb 1-3: new full-speed USB device number 10 using xhci_hcd
[10758.608911] usb 1-3: New USB device found, idVendor=256f, idProduct=c654, bcdDevice= 1.06
[10758.608913] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[10758.608915] usb 1-3: Product: CadMouse Pro Wireless
[10758.608916] usb 1-3: Manufacturer: 3Dconnexion
[10758.635675] input: 3Dconnexion CadMouse Pro Wireless as /devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-3/1-3:1.0/0003:256F:C654.001C/input/input44
[10758.636070] hid-generic 0003:256F:C654.001C: input,hidraw0: USB HID v1.11 Mouse [3Dconnexion CadMouse Pro Wireless] on usb-0000:03:00.0-3/input0
[10758.648184] input: 3Dconnexion CadMouse Pro Wireless as /devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-3/1-3:1.1/0003:256F:C654.001D/input/input45
[10758.648408] hid-generic 0003:256F:C654.001D: input,hiddev0,hidraw1: USB HID v1.11 Multi-Axis Controller [3Dconnexion CadMouse Pro Wireless] on usb-0000:03:00.0-3/input1

Mouse input is reflected in X11 for about 2-3 seconds, then ceases. In other words, I can move the mouse cursor around and click buttons just fine, for 2-3 seconds, but then it just stops working. No further messages occur in dmesg. Are there any other places where I could look for why this stops working?

In any case, note the idProduct=c654 line in dmesg. I updated my local copy of cadmousectl.c to use that instead here: https://github.com/lachs0r/cadmousectl/blob/master/cadmousectl.c#L131

However, running cadmousectl with the update product ID still shows the dreaded Could not find/open a CadMouse.

I then modified cadmousectl to use hid_enumerate() to just tell me what HID sees, and got this:

/home/daniel/repos/cadmousectl/cmake-build-debug/cadmousectl
Successfully initialized the HID API
3Dconnection devices found:
Path: /dev/hidraw0
Manufacturer: 3Dconnexion
Product: CadMouse Pro Wireless
Vendor ID: 0x256f
Product ID: 0xc654
Serial number: 

Path: /dev/hidraw1
Manufacturer: 3Dconnexion
Product: CadMouse Pro Wireless
Vendor ID: 0x256f
Product ID: 0xc654
Serial number: 

Could not find/open a CadMouse

So.. the kernel sees it, HID sees it, but it doesn't respond in X and I can't open it HID for further examination. Any ideas?

Wireless mode with the provided USB receiver When using the provided wireless USB receiver, I see the following in dmesg:

daniel@ubuntu:~$ dmesg -w
[11280.935473] usb 1-4: new full-speed USB device number 11 using xhci_hcd
[11281.267843] usb 1-4: New USB device found, idVendor=256f, idProduct=c652, bcdDevice= 1.04
[11281.267845] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[11281.267847] usb 1-4: Product: 3Dconnexion Universal Receiver
[11281.267848] usb 1-4: Manufacturer: 3Dconnexion
[11281.309659] input: 3Dconnexion 3Dconnexion Universal Receiver Mouse as /devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-4/1-4:1.0/0003:256F:C652.001E/input/input47
[11281.309860] input: 3Dconnexion 3Dconnexion Universal Receiver as /devices/pci0000:00/0000:00:01.3/0000:03:00.0/usb1/1-4/1-4:1.0/0003:256F:C652.001E/input/input48
[11281.309949] hid-generic 0003:256F:C652.001E: input,hiddev0,hidraw0: USB HID v1.11 Mouse [3Dconnexion 3Dconnexion Universal Receiver] on usb-0000:03:00.0-4/input0
[11281.319706] hid-generic 0003:256F:C652.001F: hiddev3,hidraw1: USB HID v1.11 Device [3Dconnexion 3Dconnexion Universal Receiver] on usb-0000:03:00.0-4/input1
[11281.332369] hid-generic 0003:256F:C652.0020: hiddev4,hidraw7: USB HID v1.11 Device [3Dconnexion 3Dconnexion Universal Receiver] on usb-0000:03:00.0-4/input2
[11281.343344] hid-generic 0003:256F:C652.0021: hiddev5,hidraw8: USB HID v1.11 Device [3Dconnexion 3Dconnexion Universal Receiver] on usb-0000:03:00.0-4/input3
[11281.352179] hid-generic 0003:256F:C652.0022: hiddev6,hidraw9: USB HID v1.11 Device [3Dconnexion 3Dconnexion Universal Receiver] on usb-0000:03:00.0-4/input4

Note here that the kernel sees the receiver, not the mouse.

In wireless mode, the mouse works in X without issue (i.e. it doesn't stop responding after 2-3 sec the way it did in wired mode).

However, hid_open() still fails (with this productID 0xc652), and my modified, enumerated output is now:

/home/daniel/repos/cadmousectl/cmake-build-debug/cadmousectl
Successfully initialized the HID API
3Dconnection devices found:
Path: /dev/hidraw0
Manufacturer: 3Dconnexion
Product: 3Dconnexion Universal Receiver
Vendor ID: 0x256f
Product ID: 0xc652
Serial number: 

Path: /dev/hidraw1
Manufacturer: 3Dconnexion
Product: 3Dconnexion Universal Receiver
Vendor ID: 0x256f
Product ID: 0xc652
Serial number: 

Path: /dev/hidraw7
Manufacturer: 3Dconnexion
Product: 3Dconnexion Universal Receiver
Vendor ID: 0x256f
Product ID: 0xc652
Serial number: 

Path: /dev/hidraw8
Manufacturer: 3Dconnexion
Product: 3Dconnexion Universal Receiver
Vendor ID: 0x256f
Product ID: 0xc652
Serial number: 

Path: /dev/hidraw9
Manufacturer: 3Dconnexion
Product: 3Dconnexion Universal Receiver
Vendor ID: 0x256f
Product ID: 0xc652
Serial number: 

Could not find/open a CadMouse

Annoyingly, hid_open() returns NULL on failure, so I can't use hid_error() to get any further error information, in either the wired or wireless case.

Please let me know if you have any insight or ideas for further progress. Thanks.

mia-0 commented 4 years ago

Permissions, maybe? By default only root should be able to send raw HID messages, afaik.

danielthompson commented 4 years ago

OK, progress. Running as root in wireless mode, with 0xc652 as the product Id (for the receiver, since the mouse doesn't show up in HID in wireless mode) as follows:

$ sudo ./cadmousectl -S 0
$

...seems to work inasmuch as no error message is displayed, but doesn't change the mouse behavior. That leads to some questions:

mia-0 commented 4 years ago

On Thursday, January 9, 2020 8:23:04 PM CET Daniel A. Thompson wrote:

  • Are the HID commands different for the CadMouse Pro Wireless and/or its receiver than they were for the regular CadMouse?

Very likely.

  • Is there a way to determine this empirically?

Run the official software and capture the HID packets using e.g. Wireshark (yes, it can capture USB device traffic). Use a VM if necessary.

danielthompson commented 4 years ago

Run the official software and capture the HID packets using e.g. Wireshark

OK. Here's what I found when disabling smart scroll in the official Windows software: image

Data fragment from this HID message is 10 00 1c 00 01 ff 00 00 00 00 00 00 00 00 00 00 00 03 00 0a 0b 0c 0c 0e 0d 2f 00 1e 00 00 00 01

And here's what I found when enabling smart scroll in the windows software: image

Data fragment from this HID message is 10 00 1c 00 00 00 00 01 00 00 00 00 00 00 00 00 00 03 00 0a 0b 0c 0c 0e 0d 2f 00 1e 00 00 00 01

Do you know how to interpret these data fragments? They're 32 bytes long, but the existing implementation you've provided for the CadMouse only sends 8 bytes of payload, viz. https://github.com/lachs0r/cadmousectl/blob/master/cadmousectl.c#L25-L26. I don't have a regular CadMouse to compare with, otherwise this would be a little easier.

danielthompson commented 4 years ago

Update: I just sent the entire 32 byte fragment instead of the 8 byte fragment, and that worked! I can now turn "smart scroll" on and off at will in Linux. I'll post code in a little bit.

kd30 commented 4 years ago

@danielthompson I was able to follow your steps and replicate your results up to the sudo command not failing and also not changing mouse behaviour. I have the CadMouse Wireless mouse identified as:

New USB device found, idVendor=256f, idProduct=c652

Would your code work with my mouse? What all do I need to change?

JulianLelandBell commented 4 years ago

Just wanted to share my two cents as a n00b following @danielthompson's example. I'm running 18.04.4, and the only thing I care about is being able to turn off Stupid Scroll, so I'm not going to try to implement this properly.

  1. Install hidapi (not sure whether both of these are required to run - worked after second one) sudo apt-get install libhidapi-hidraw0 sudo apt-get install libhidapi-dev
  2. Run dmesg - look at messages to identify idProduct for my mouse (in my case, c652 with a Wireless CADMouse, like Daniel's) dmesg -w
  3. Edit cadmousectl.c with the following lines Lines 25-26: unsigned char cmd[32] = { 0x10, 0x00, 0x1c, 0x00, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x0b, 0x0c, 0x0c, 0x0e, 0x0d, 0x2f, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x01 }; return hid_send_feature_report(mouse, cmd, 32); Line 131: hid_device *mouse = hid_open(0x256f, 0xc652, NULL);
  4. Build per instructions cc cadmousectl.c -o cadmousectl $(pkg-config --cflags --libs hidapi-hidraw)
  5. Run any command as superuser sudo ./cadmousectl -S 0
danielthompson commented 4 years ago

I totally forgot about this. @JulianLelandBell, you are correct, just sending the whole payload should work to disable smart scroll. I do have to run it as root, and I do have to re-run it whenever I manually turn the mouse on or off.

After posting the results I got above, I remember now that I also did some further research to figure out what, if anything, the other bytes in the 32 byte payload are for. You'll note that if you run the Windows software, there are some more settings in addition to smart scroll on/off - polling rate, scroll speed, lift-off detection, etc.

I was able to determine that some of those settings are sent to the mouse in that 32-byte payload when the user changes them in the Windows software (notably, polling rate). I can't find those results at the moment, unfortunately.

So, the long-winded point I'm making is that that payload above, in addition to turning off smart scroll, may also set some of those other settings.

I really like this mouse; it's rock solid & precision-engineered... yet the customer support and documentation is basically "it is what it is, if you don't like it, we don't care". I grew up there so I say this with all the love in the world - how typically German 😀 🇩🇪