Package: gadgetconfig
Gadget ConfigStuart LynneThu Apr 09 23:46:27 PDT 2020This package contains tools for configuring Gadget USB Devices and integrating withsystemd.It relies on the Gadget ConfigFS module libcomposite to create and manage Gadget USB Devices.InstallationTo install:pip3 install gadgetconfigTo uninstall:pip3 uninstall gadgetconfigIf you have trouble getting it installed you can try:pip3 install --no-binary :all: gadgetconfigN.B. --no-binary is needed with recent versions of pip to cope with a bug.
C.f.https://stackoverflow.com/questions/40588634/how-to-install-data-files-to-absolute-pathGadget USB Device OverviewThe Gadget USB Device implementation has three layers when using the new libcomposite
driver:Function Drivers, e.g. usb_f_acm, usb_f_ecm, usb_f_\eemLibComposite, for selecting and configuring the device to use the Function DriversUDC, to connect the Function Drivers to the underlying USB Device Controller hardwareThe libcomposite implementation allows the USB Device configuration to be specified ad hoc
and changed as needed.A USB Device definition contains:idVendor, idProduct, bcdDevice and other attributesone of more configurationsa list of functions that configurations may usestrings describing the deviceEach configuration contains:attributeslist of functions to be usedstrings describing the configurationSystemd IntegrationAgadget.servicefile is installed which will use the following to start and stop
the gadget service:/usr/lib/gadgetservice/gadget.start
/usr/lib/gadgetservice/gadget.stopThese rely on a default Gadget Device Definition file being present in:/etc/gadgetservice/default.jsonThe service should auto-start when the system is rebooted. Thesystemctlcommand can also be used;systemctl start gadget
systemctl stop gadgetSee below for more information on Gadget Device Definition files.Gadget USB Device LifecycleThegadgetconfigprogram uses USB Device definitions stored inJSONfiles.When using the Gadget Libcomposite module:Create:gadgetconfig --create gadget-definition.jsonEnable:gadgetconfig --enable configuration_nameDisable:gadgetconfig --disableDestroy:gadgetconfig --destroyGadget UDC:Disconnect:gadgetconfig --soft_connect disconnectConnect:gadgetconfig --soft_connect connect+-------------------+
            |     No Gadget     |
            +-------------------+
                  |       ^             
                  |       |
               Create   Destroy
                  |       |
                  v       |
            +-------------------+
            | Distabled Gadget  |<---
            +-------------------+   |
                  |                 | 
                  |                 |
                Enable           Disable
                  |                 |
                  v                 |
            +-------------------+   |
            | Configured Gadget |---|
   Gadget   +-------------------+                                    
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   UDC      +-------------------+  Disconnect   +-------------------+ 
            | Attached Gadget   |-------------->| Detached Gadget   |
            |                   |<------------- |                   |
            +-------------------+   Connect     +-------------------+
     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   HardwareN.B.Multiple Gadget USB Device Definitions can be created and co-exist.Only a single Gadget USB Device can beenabledat one time.Attempting to enable a Gadget USB Device will fail another Gadget Device is enabled.Whenenableda device defaults toattached.An enabled Gadget Device cannot beremoved.Each of multiple Gadget Devices must be separatelyremoved.Gadget USB Device Definition FileGadget USB Device Definition FilesareJSONfiles that contain all of the information to define
one or more USB Device's along with their attributes, strings, os descriptors, functions and configurations.There is a close correspondence between the JSON definition file and the resulting Gadget ConfigFS information.N.B.multipleUSB Device Definitionscan be present and can be configured into the GadgetFSmultipleUSB Device Functionscan be specified (from the list of Gadget Functions available)multipleUSB Device Configurationscan be specified, each with a different set of the availableUSB Device Functionswithin a configuration the array ofconfiguration function definitionsare used to create the symlinks pointing to the defined functions by the creation process.some entries in ConfigFS functions display Gadget generated data, notably acm port_num and ecm ifname are automatically created and not set from the definition filethe os_desc entry rules are specific and designed to support Windows, see the RNDIS example for more informationmultiple languages can have strings by specifying separate LANG identifiers for each, for both theUSB Device Definitionand eachUSB Device ConfigurationExampleThis defines a composite USB Device calledbelcarracontaining two ACM and one ECM functions. There
is one configuration called "Belcarra Composite CDC 2xACM+ECM.1" which will be the default configuration
presented to the host during enumeration.This is sample file:# Gadget Device Definition File
# 2020-03-17
{
    "belcarra-acm-ecm": {
        # USB Device Descriptor Fields
        "idVendor": "0x15ec",
        "idProduct": "0xf102",
        "bcdDevice": "0x0001",
        "bDeviceClass": "0x00",
        "bDeviceSubClass": "0x00",
        "bDeviceProtocol": "0x00",
        "bcdUSB": "0x0200",
        "bMaxPacketSize0": "0x40",
        # USB Device Strings
        "strings": {
            "0x409": {
                "serialnumber": "0123456789",
                "product": "ACMx2-ECM Gadget",
                "manufacturer": "Belcarra Technologies Corp"
            }
        },
        # Gadget Functions list: see /sys/module/usb_f*,
        # E.g.: usb_f_acm, usb_f_ecm, usb_f_eem, usb_f_hid, usb_f_mass_storage
        #       usb_f_midi, usb_f_ncm, usb_f_obex, usb_f_rndis, usb_f_serial
        # Use: The function name (without prefix) is used with instantion name, e.g. eem.usb0 or acm.GS0
        "functions": {
            "acm.GS0": {},
            "acm.GS1": {},
            "ecm.usb0": {
                "qmult": "5",
                "host_addr": "c6:34:7c:45:a6:c5",
                "dev_addr": "0e:6a:8a:85:db:76"
            }
        },
        # Gadget Configurations list
        "configs": {
            "config.1": {
                # Configuration Descriptor
                # bmAttributes: bit 5 support remote wakeup
                # bmAttributes: bit 6 self-powered
                # bmAttributes: bit 7 bus-powered
                # MaxPower: Power requirements in two-milliampere units, only valid of bit 7 is set
                "bmAttributes": "0x80",
                "MaxPower": "2",
                "strings": {
                    # USB Device Configuration Strings
                    "0x409": {
                        "configuration": "CDC 2xACM+ECM"
                    }
                },
                # This determines the order in the Configuration descriptor
                "functions": [
                    {
                        # Host Match USB\VID_15EC&PID_F102&MI_00
                        "name": "acm.GS0",
                        "function": "acm.GS0"
                    },
                    {
                        # Host Match USB\VID_15EC&PID_F102&MI_02
                        "name": "ecm.usb0",
                        "function": "ecm.usb0"
                    },
                    {
                        # Host Match USB\VID_15EC&PID_F102&MI_04
                        "name": "acm.GS1",
                        "function": "acm.GS1"
                    }
                ]
            }
        },
        # Microsoft OS Descriptors Support
        # C.f. https://docs.microsoft.com/en-us/previous-versions/gg463179(v=msdn.10)
        "os_desc": {
            "qw_sign": "",
            "b_vendor_code": "0x00",
            "use": "0"
        }
    }
}We can view the generated Gadget ConfigFS usingsysfstree:# gadgetconfig --add belcarra-2acm+ecm.json
# sysfstree_raspbian --gadget
[/sys/kernel/config/usb_gadget]
└──[belcarra]
    ├──bcdDevice: 0x0001
    ├──bcdUSB: 0x0200
    ├──bDeviceClass: 0x00
    ├──bDeviceProtocol: 0x00
    ├──bDeviceSubClass: 0x00
    ├──bMaxPacketSize0: 0x40
    ├──[configs]
    │   └──[Belcarra Composite CDC 2xACM+ECM.1]
    │       ├──acm.GS0 -> /sys/kernel/config/usb_gadget/belcarra/functions/acm.usb0
    │       ├──acm.GS1 -> /sys/kernel/config/usb_gadget/belcarra/functions/acm.usb1
    │       ├──bmAttributes: 0x80
    │       ├──ecm.usb0 -> /sys/kernel/config/usb_gadget/belcarra/functions/ecm.usb0
    │       ├──MaxPower: 2
    │       └──[strings]
    │           └──[0x409]
    │               ├──configuration: CDC 2xACM+ECM
    ├──[functions]
    │   ├──[acm.usb0]
    │   │   ├──port_num: 0
    │   ├──[acm.usb1]
    │   │   ├──port_num: 1
    │   └──[ecm.usb0]
    │       ├──dev_addr: 4e:28:20:f0:35:ab
    │       ├──host_addr: b6:fe:ea:86:2a:50
    │       ├──ifname: usb0
    │       ├──qmult: 5
    ├──idProduct: 0xd031
    ├──idVendor: 0x15ec
    ├──[os_desc]
    │   ├──b_vendor_code: 0x00
    │   ├──qw_sign:
    │   ├──use: 0
    ├──[strings]
    │   └──[0x409]
    │       ├──manufacturer: Belcarra Technologies
    │       ├──product: Composite CDC 2xACM+ECM
    │       ├──serialnumber: 0123456789
    ├──UDC: fe980000.usbShell scriptTo facilitate installing Gadget definitions in an early boot environment a Gadget Definition file
can be converted to a simple shell script:gadgetconfig --sh-auto definitions/hid-example.json > hid-example.shWould produce:#!/bin/sh
    # Created from definitions/hid-example.json

    mkdir -p "/sys/kernel/config/usb_gadget/g2"
    echo "0x1d6b" > "/sys/kernel/config/usb_gadget/g2/idVendor"
    echo "0x0104" > "/sys/kernel/config/usb_gadget/g2/idProduct"
    echo "0x0001" > "/sys/kernel/config/usb_gadget/g2/bcdDevice"
    echo "0x00" > "/sys/kernel/config/usb_gadget/g2/bDeviceClass"
    echo "0x00" > "/sys/kernel/config/usb_gadget/g2/bDeviceSubClass"
    echo "0x00" > "/sys/kernel/config/usb_gadget/g2/bDeviceProtocol"
    echo "0x0200" > "/sys/kernel/config/usb_gadget/g2/bcdUSB"
    echo "0x40" > "/sys/kernel/config/usb_gadget/g2/bMaxPacketSize0"
    mkdir -p "/sys/kernel/config/usb_gadget/g2/strings/0x409"
    echo "0123456789" > "/sys/kernel/config/usb_gadget/g2/strings/0x409/serialnumber"
    echo "Bar Gadget" > "/sys/kernel/config/usb_gadget/g2/strings/0x409/product"
    echo "Foo Inc." > "/sys/kernel/config/usb_gadget/g2/strings/0x409/manufacturer"
    mkdir -p "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0"
    echo "235:0" > "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0/dev"
    echo "8" > "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0/report_length"
    echo "1" > "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0/protocol"
    echo "0" > "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0/subclass"
    echo -ne "\\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0" > "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0/report_desc"
    mkdir -p "/sys/kernel/config/usb_gadget/g2/configs/The only one.1"
    echo "0x80" > "/sys/kernel/config/usb_gadget/g2/configs/The only one.1/bmAttributes"
    echo "2" > "/sys/kernel/config/usb_gadget/g2/configs/The only one.1/MaxPower"
    mkdir -p "/sys/kernel/config/usb_gadget/g2/configs/The only one.1/strings/0x409"
    echo "1xHID" > "/sys/kernel/config/usb_gadget/g2/configs/The only one.1/strings/0x409/configuration"
    ln -s "/sys/kernel/config/usb_gadget/g2/functions/hid.usb0" "/sys/kernel/config/usb_gadget/g2/configs/The only one.1/some_name"

    basename /sys/class/udc/* > /sys/kernel/config/usb_gadget/g2/UDCRunning Testsgadgetconfig currently only has doctests.Run tests with nose::nosetests --with-doctest src/gadgetconfigRun tests with doctest::python -m doctest -v src/gadgetconfig/__init__.pyAuthorStuart.Lynne@belcarra.comCopyright (c) 2020 Belcarra Technologies (2005) Corp.