Skip to content

Dynamic USB descriptors: enable/disable, change HID descriptors, etc. #1015

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dhalbert opened this issue Jul 11, 2018 · 16 comments · Fixed by #4689
Closed

Dynamic USB descriptors: enable/disable, change HID descriptors, etc. #1015

dhalbert opened this issue Jul 11, 2018 · 16 comments · Fixed by #4689
Assignees
Milestone

Comments

@dhalbert
Copy link
Collaborator

dhalbert commented Jul 11, 2018

A couple of forum posts recently have asked if HID or MSC could be disabled for security or device interference reasons. We need some kind of dynamic USB descriptors to do this.

https://forums.adafruit.com/viewtopic.php?f=8&t=136248#p683158
https://forums.adafruit.com/viewtopic.php?f=60&t=137940#p682494

Other uses for dynamic USB descriptors include adding new HID devices, disabling selected HID devices, and varying an HID device (e.g., changing the joystick coordinate ranges).

@dhalbert dhalbert added this to the Long term milestone Jul 11, 2018
@tannewt tannewt modified the milestones: Long term, 3.x Jul 11, 2018
@tannewt tannewt self-assigned this Jul 11, 2018
@tannewt tannewt mentioned this issue Jul 24, 2018
@dhalbert dhalbert modified the milestones: 3.x, Long term Aug 24, 2018
@ATMakersBill
Copy link
Collaborator

This would be helpful in some of our projects as well. One way I could see this working is to check for the presence (or absence) of a file or config option in the BOOT filesystem. So, when CP's UF2 is loaded, it checks for that file (maybe a config file?) and checked which USB descriptors to present.

This would make it possible to enter the bootloader mode, tell it to not share the mass storage device or the HID (or the Serial port?) and restart. If you ever wanted to change that, just double click to get into the boot loader.

Just a thought

@tannewt
Copy link
Member

tannewt commented Sep 11, 2018

The idea I had was to control the descriptors from boot.py which runs before usb enumeration.

@ATMakersBill
Copy link
Collaborator

Where does that live? On the BOOT drive or on the CIRCUITPY drive? How does a user edit it?

@tannewt
Copy link
Member

tannewt commented Sep 12, 2018

CIRCUITPY just like code.py. You can edit it the same way but it won't be rerun automatically. Instead, one needs to eject the drive and then reset the board (using the button or unplugging).

@ATMakersBill
Copy link
Collaborator

I understand how that would be helpful for the HID descriptors, etc. But shouldn't the Mass Storage descriptor be controllable by something not on that drive?

@tannewt
Copy link
Member

tannewt commented Sep 13, 2018

I think its ok. You can change files through the REPL or use the REPL to reboot to safe mode which skips all user code.

A common technique for the similar problem of flipping read-only for the file system is to read an external line connected to a switch to determine whether to do it or not on boot.

@RichardFoo
Copy link

Just an observer here, but is this bootloader command what might be needed here?
pyb.usb_mode

It seems that it'd make sense to control this behavior in boot.py, which is accessible by double-clicking the reset button to mount the bootloader's partition. Presumably, if boot.py changes this mode, it could intercept the CircuitPy partition / MSC device from being presented?

@dhalbert
Copy link
Collaborator Author

dhalbert commented May 9, 2020

@RichardFoo Yes, that's the part of the kind of capability we have in mind, but we'd also like for user-supplied descriptors both for the different USB devices, and for different HID devices in the HID desccriptor. The actual API would be different. It would be invoked from boot.py, which runs before the USB enumeration happens.

@mytechnotalent
Copy link

mytechnotalent commented Sep 24, 2020

How would one accomplish the three following tasks very specifically?
1)disable REPL (like going into a given ports main.c in MP)
2)disable USB (for instances where you want both a REPL and USB no access)
3)have full serial input and output available

The potential use case will NOT be default or standard it would be an option for advanced uses in the event CP were to be used in more advanced IoT devices where security is of primary concern. This can create significant potential for CP however would not change CP just add options.

@mytechnotalent
Copy link

It looks like https://github.com/adafruit/circuitpython/blob/main/main.c#L436 has a run_repl function that might be what I am looking for.

@tannewt
Copy link
Member

tannewt commented Sep 24, 2020

As you've seen, CircuitPython unifies main.c outside of ports. It is the equivalent of MicroPython's port/*/main.c but applies to all ports.

Take a look in supervisor for the serial APIs. It should be possible to disable USB and interface with a UART there.

Please continue to ask about this on Discord or a separate issue. This issue isn't a great place because it's specifically about changing the USB descriptor, not disabling it.

@npendlington
Copy link

npendlington commented Apr 15, 2021

Just adding my +1 to this. @dhalbert - Since you've already suggested the likely solution similar to the pyb.usb_mode API, I'm really excited to get my hands on the feature. Dynamically (via an I/O pin) allowing the storage to be turned off, but continue to operate the USB as a HID device is my goal.

@deshipu
Copy link

deshipu commented Apr 15, 2021

Same here. I would love to be able to re-enable the CIRCUITPY drive in my keyboards when, for example, a certain key is pressed while connecting it. That would make it much easier to tweak the layouts and other settings.

@dhalbert
Copy link
Collaborator Author

@npendlington @deshipu Yes, this will be possible. MSC, REPL CDC and data CDC, and MIDI will all be togglable individually from boot.py. You will also be able to specify a list of included HID devices, and include your own descriptors if needed, or drop HID entirely. It might also be possible initially to have extra non-composite HID devices so that a boot keyboard is possible, though I may not do that for the first pass.

@unicorn79
Copy link

unicorn79 commented Mar 9, 2022

Hello! I am currently working with Arduino. Can you please tell me if it is possible to implement a Dynamic USB HID descriptor? The most convenient would be, for example, changing the USB HID descriptor when a certain pin is shorted to ground. I saw the following code on the Internet – and I understand that this is possible.
—————code———————-
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
#ifdef ABSOLUTE_MOUSE_MODE
0x15, 0x01, // LOGICAL_MINIMUM (1) <<<< This allows us to talk to any display resolution
0x25, 0x64, // LOGICAL_MAXIMUM (100) <<<< as though it was 100×100 pixels
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x02, // INPUT (Data,Var,Abs) <<<< This allows us to moveTo absolute positions
#else
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
#endif
————-end code —————–
However, I'm not entirely sure that in the .cpp code (not in the sketch), where USB HID DISCRIPTOR located, it is possible to read the level of the pin and, depending on the result, and then change the descriptor with a new boot of device. Thanks!

@bitboy85
Copy link

bitboy85 commented Mar 9, 2022

Are you trying to switch between a normal and an absolute mouse?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants