libusbg/libusbg — pull request #8 by kopasiak (2014-07-08 12:36:30+00:00)
Title: Add import from/export to file functionality

Dear Matt,

This quite big series adds new part of libusbg API which allows to
import/export gadget/function/configuration from/to file.

Motivation:

Libusbg allows to create a binary file which set up custom
gadget. This is useful but if we have to create custom binary for
each gadget we wast a lot of work which kernel people put to separate
code from configuration. This leads us to main idea of gadget
schemes. Allow to create simple, human readable config file which
library will be able to translate into usb gadget.

Description:

Gadget schemes is idea of describing gadget/function/configuration in
config file. To not reinvent the wheel I have used existing library
libconfig [1]. This means that the syntax is similar to this described
in documentation of libconfig.

I have extended the library with set of usbg_export_*() functions
which allows to export selected gadget to given FILE. There is also
set of complementary usbg_import_*() functions which allows to read
scheme of gadget/function/config from file and create it using
configfs.

To avoid name conflict I have used the convention that
usbg_import_gadget() function takes name of new gadget as parameter
and usbg_export_gadget() doesn't export gadget name to scheme
file. Similar idea is used in configuration and functions.

Base convention of gadget schemes is simple: if something is not set
in scheme file, default values provided by kernel are used. Moreover
configfs has some attributes which are read only. To allow to store
them in scheme file they are ignored by import functions.

Usage of libconfig and whole design of gadget schemes allows us to use
include directive in gadget definition to import complicated
configurations or functions.

Syntax and detailed rules of using schemes has been described in
gadget_schemes.txt in commit:

libusbg: doc: Add document about gadget schemes

Example:

I have used the gadget-acm-ecm example to create a gadget and then exported it and imported.
Gadget exported using usbg_export_gadget():

$ gadget-export g1 g1.schema
$ cat g1.schema

attrs =
{
bcdUSB = 0x200
bDeviceClass = 0x0
bDeviceSubClass = 0x0
bDeviceProtocol = 0x0
bMaxPacketSize0 = 0x40
idVendor = 0x1D6B
idProduct = 0x104
bcdDevice = 0x1
}
strings = (
{
lang = 0x409
manufacturer = "Foo Inc."
product = "Bar Gadget"
serialnumber = "0123456789"
} )
functions =
{
acm_usb0 =
{
instance = "usb0"
type = "acm"
attrs =
{
port_num = 0
}
}
acm_usb1 =
{
instance = "usb1"
type = "acm"
attrs =
{
port_num = 1
}
}
ecm_usb0 =
{
instance = "usb0"
type = "ecm"
attrs =
{
dev_addr = "aa:bb:f9:ca:76:fb"
host_addr = "a2:ad:a2:3f:c8:6f"
qmult = 5
}
}
}
configs = (
{
id = 1
name = "The only one"
attrs =
{
bmAttributes = 0x80
bMaxPower = 0x2
}
strings = (
{
lang = 0x409
configuration = "CDC 2xACM+ECM"
} )
functions = (
{
name = "acm.GS0"
function = "acm_usb0"
},
{
name = "acm.GS1"
function = "acm_usb1"
},
{
name = "ecm.usb0"
function = "ecm_usb0"
} )
} )

This is quite verbose because it contains read only attributes and some default ones. This file can be shorten to:

attrs =
{
bcdUSB = 0x200
bMaxPacketSize0 = 0x40
idVendor = 0x1D6B
idProduct = 0x104
bcdDevice = 0x1
}
strings = (
{
lang = 0x409
manufacturer = "Foo Inc."
product = "Bar Gadget"
serialnumber = "0123456789"
} )
functions =
{
acm_usb0 =
{
instance = "usb0"
type = "acm"
}
acm_usb1 =
{
instance = "usb1"
type = "acm"
}
ecm_usb0 =
{
instance = "usb0"
type = "ecm"
attrs =
{
dev_addr = "aa:bb:f9:ca:76:fb"
host_addr = "a2:ad:a2:3f:c8:6f"
qmult = 5
}
}
}
configs = (
{
id = 1
name = "The only one"
strings = (
{
lang = 0x409
configuration = "CDC 2xACM+ECM"
} )
functions = (
{
name = "acm.GS0"
function = "acm_usb0"
},
{
name = "acm.GS1"
function = "acm_usb1"
},
{
name = "ecm.usb0"
function = "ecm_usb0"
} )
} )

Remarks:

Current version of libconfig has no possibility to select output
format details. I have created a patch and set up github pull request
and this patch is waiting for maintainer review[2], so results of
usbg_export_*() may be slightly different in format but both layouts
are acceptable by import functions.