solokeys / solo1

Solo 1 firmware in C
https://solokeys.com/
Other
2.31k stars 273 forks source link

Linux ModemManager messes with the Solo CDC ACM serial port interface #62

Closed conorpp closed 5 years ago

conorpp commented 5 years ago

Since it looks like a modem, the linux daemon ModemManager will automatically start messing with it. I had to disable it:

systemctl stop ModemManager 

Need to find what to change in the USB descriptors to prevent things like this from happening.

https://github.com/solokeys/solo/blob/master/targets/stm32l432/lib/usbd/usbd_composite.c#L100

szszszsz commented 5 years ago

I will test today the idea from https://github.com/solokeys/solo/pull/60#issuecomment-452428432

szszszsz commented 5 years ago

The Udev rule, as mentioned in the commit, works for me. Fedora 29.

nickray commented 5 years ago

It seems this doesn't always work: ModemManager has different filter policies, and if you're running "strict", then ID_MM_DEVICE_IGNORE tag itself is ignored :/ Debian Buster for instance seems to use this strict filter mode by default. https://www.freedesktop.org/software/ModemManager/api/latest/ModemManager-Common-udev-tags.html

nickray commented 5 years ago

Let's try and get our VID/PID in http://cgit.freedesktop.org/ModemManager/ModemManager when they're up again.

nickray commented 5 years ago

I guess we should add our VID/PID to https://gitlab.freedesktop.org/mobile-broadband/ModemManager/blob/master/src/77-mm-usb-device-blacklist.rules?

nickray commented 5 years ago

https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/111

nickray commented 5 years ago

@conorpp the second line of the ModemManager log file i attached to the above issue on https://gitlab.freedesktop.org states:

ModemManager[17846]: <debug> [1552418922.832261] [filter] (tty/ttyACM0): port allowed: cdc-acm interface reported AT-capable

Is this perhaps an issue we can easily fix on our side?

conorpp commented 5 years ago

I found that the bInterfaceProtocol parameter in the interface descriptor is currently set to 1, which indicates it is AT command capable. I changed it to 0, and the ModemManager no longer seems to mess with it.

There's still an issue though, the ModemManager seems to keep the device opened for 10+ seconds after plugging it in or reset, so nothing can open it easily without first waiting a while.

nickray commented 5 years ago

This is the same behaviour as before then when I ran with filter policy "strict": udev inspected the device for ~20 seconds until it gave up and released it again. Thanks for locating the bInterfaceProtocol parameter, I will experiment.

matthijskooijman commented 5 years ago

We've also ran into essentially the same issue with Arduino devices. I've started some discussion at ModemManager upstream and Debian about this, see https://gitlab.freedesktop.org/mobile-broadband/ModemManager/issues/127 and https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930264.

nickray commented 5 years ago

@matthijskooijman the thing to do is not signal modem functionality to udev, see

Hope that helps! It seems somewhat obscure knowledge, but make sense.

EDIT: I see now you are aware of the "proper" solution.

nickray commented 5 years ago

Closing this as the issue is solved.

matthijskooijman commented 5 years ago

@nickray, Yeah, I already found the protocol value that indicates modem functionality. However, a lot of Arduino boards have this value hardcoded in a USB-to-serial firmware that is not typically updated by users, so I also raised the issue with MM so they can support the existing devices as well.

How is this for the Solo device? Aren't there already devices out there with older firmware? Or is this firmware routinely updated?

nickray commented 5 years ago

Yes! This is like our "unique value proposition" :D

See https://update.solokeys.com

The other thing is that non-Hacker builds don't have VCOM enabled in the first place.

matthijskooijman commented 5 years ago

Ah, nice, and even from the browser by posing the commands as key requests it seems. Clever :-)

nickray commented 5 years ago

Well, "clever", yes. But the deluge of popups is not really nice. We hope at some point to (entice the powers that be to) introduce a proper API for authenticator maintenance/general vendor-specific commands. Clearly our competitors with their closed-source/non-updatable products hadn't considered the need :) Using WebUSB is not a real solution either IMHO since Firefox doesn't want to support it.

aleksander0m commented 5 years ago

I found that the bInterfaceProtocol parameter in the interface descriptor is currently set to 1, which indicates it is AT command capable. I changed it to 0, and the ModemManager no longer seems to mess with it.

There's still an issue though, the ModemManager seems to keep the device opened for 10+ seconds after plugging it in or reset, so nothing can open it easily without first waiting a while.

MM should not touch the device at all if the ttyACM port isn't flagging itself as AT-command capable. If MM keeps the device open for those 10+ seconds even if the port is flagged as AT, please let us know in the MM gitlab issues please.

KVAnton-WEB commented 4 years ago

This is solution help me for ModemManager 1.10.0 with --filter-policy=strict (Ubuntu 18.04)
ModemManager -V

You can learn more: Common udev tags

Create a file /etc/udev/rules.d/49-stm32.rules and add this:

# 0483:5740 - STM32 in USB Serial Mode (CN5)
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_TTY_BLACKLIST}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{MTP_NO_PROBE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_PORT_IGNORE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_TTY_MANUAL_SCAN_ONLY}="1"

After save file and run:
sudo udevadm control --reload-rules

and (maybe it's not necessary):
sudo systemctl restart ModemManager.service

After reconnecting the USB device (physically pull out and pull in it into the USB port) and enjoy.

P.S. This is a solution for the STM32 CDC Virtual Com port - if necessary, you can change the PID / VID and udev tags.

aleksander0m commented 4 years ago

Create a file /etc/udev/rules.d/49-stm32.rules and add this:

# 0483:5740 - STM32 in USB Serial Mode (CN5)
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_DEVICE_IGNORE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_TTY_BLACKLIST}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{MTP_NO_PROBE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_PORT_IGNORE}="1"
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", ENV{ID_MM_TTY_MANUAL_SCAN_ONLY}="1"

Please do not do this :)

Just update to a new enough ModemManager (e.g. 1.12.x or even 1.10.8), and your problem should be solved. None of those tags are supposed to be user-usable tags in MM 1.10.0.

If you run 1.12.0 and don't want to rely on the automagic detection of modems and you want to always ignore that specific device, you could use ID_MM_DEVICE_IGNORE, but only on 1.12.0 or newer as that is supported for all filter types since that version. In your version 1.10.0, ID_MM_DEVICE_IGNORE would only work when using the "default" filter, not when using the "strict" filter.

All the other tags used above should not be used by the user, and some of them aren't even supported in your MM 1.10.0 ...

nickray commented 4 years ago

I'm not sure why this is being brought up again, as far as I know the issue was fixed in the PR linked above, and https://github.com/solokeys/solo/blob/master/targets/stm32l432/lib/usbd/usbd_composite.c#L138 is still there.