Skip to content

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

Closed

Description

@dhalbert

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).

Activity

  1. added this to the Long term milestone on Jul 11, 2018
  2. modified the milestones: Long term, 3.x on Jul 11, 2018
  3. self-assigned this
    on Jul 11, 2018
  4. modified the milestones: 3.x, Long term on Aug 24, 2018
  5. ATMakersBill commented on Sep 11, 2018

    @ATMakersBill
    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

  6. tannewt commented on Sep 11, 2018

    @tannewt
    Member

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

  7. ATMakersBill commented on Sep 11, 2018

    @ATMakersBill
    Collaborator

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

  8. tannewt commented on Sep 12, 2018

    @tannewt
    Member

    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).

  9. ATMakersBill commented on Sep 12, 2018

    @ATMakersBill
    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?

  10. tannewt commented on Sep 13, 2018

    @tannewt
    Member

    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.

  11. removed their assignment
    on Feb 14, 2019
  12. changed the title [-]Dynamic USB device enabling/disabling[/-] [+]Dynamic USB descriptors: enable/disable, change HID descriptors, etc.[/+] on Apr 28, 2019
  13. RichardFoo commented on May 9, 2020

    @RichardFoo

    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?

  14. dhalbert commented on May 9, 2020

    @dhalbert
    CollaboratorAuthor

    @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.

  15. mytechnotalent commented on Sep 24, 2020

    @mytechnotalent

    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.

  16. mytechnotalent commented on Sep 24, 2020

    @mytechnotalent

    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.

  17. tannewt commented on Sep 24, 2020

    @tannewt
    Member

    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.

  18. npendlington commented on Apr 15, 2021

    @npendlington

    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.

  19. deshipu commented on Apr 15, 2021

    @deshipu

    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.

  20. dhalbert commented on Apr 15, 2021

    @dhalbert
    CollaboratorAuthor

    @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.

  21. modified the milestones: Long term, 7.0.0 on Apr 26, 2021
  22. unicorn79 commented on Mar 9, 2022

    @unicorn79

    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!

  23. bitboy85 commented on Mar 9, 2022

    @bitboy85

    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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions