Android USB Gadget » History » Revision 2
Revision 1 (laforge, 12/17/2016 11:27 AM) → Revision 2/7 (laforge, 12/17/2016 06:12 PM)
h1. Android USB Gadget
The Android Linux kernel has an incredibly versatile USB gadget that is not present in mainline linux.
Using sysfs, you can configure a USB device that has a large number of interfaces, each exposing one particular function.
Each function (class) is implemented by a _gadget_ driver. In the source code they are prefixed with "f_", so the serial function is called @f_serial@
h2. Using sysfs to configure
Each USB device is exposed as a @/sys/devices/virtual/android_usb/androidX@ interface where @X@ corresponds to the logical number. Most devices these days have only one or two USB ports, so it is mostly @android0@ or @android1@ that you will see.
Below this sysfs directory ad a number of different files. They can only be modified/written to if the USB port is disabled by means of
<pre>
echo 0 > sys/devices/virtual/android_usb/android0/enable
</pre>
It will disconnect from the USB host at this point.
After modifying what you want to modify, you can use
<pre>
echo 1 > sys/devices/virtual/android_usb/android0/enable
</pre>
to re-enable the USB port. It will re-enumerate to the host at this point.
h3. /sys/devices/virtual/android_usb/androidX/functions
h3. /sys/devices/virtual/android_usb/androidX/idVendor
Allows you to set the USB Vendor ID
h3. /sys/devices/virtual/android_usb/androidX/idProduct
Allows you to set the USB Device ID
h3.
'struct android_usb_function' implements a given function
h2. Gadgets
h3. ffs (function FS)
* userspace process can implement USB functions
* used e.g. by adbd
h3. acm (CDC "astract control model")
* USB-IF standardized version of serial-type ports
* exposed via /dev/ttyGS* device
h3. rmnet
usb gadget driver to implement a rmnet gadget, f_rmnet.c
Documentation/usb/gadget_rmnet.txt
* drivers/net/ethernet/msm/msm_rmnet_mhi.c
* interface descriptor: class/subclass/proto = 0xff, numEP=3
** stringdescriptor en-us, string 0 == "RmNet"
** full speed descriptors (notify/in/out)
** high speed descriptors (notify/in/out)
** super speed descriptors (notify/in/out + comp)
* rmnet has ports
* control ports can map to SMD, QTY, HSIC,HSUART
* data ports can map to BAM2BAM, BAM_DMUX, BAM2BAM_IPA, HSIC, HSUART, ETHER
** BAM2BAM is normal case?
** ETHER exposes the data pipe as usb_rmnet%d device on Linux (EC25 only)
* frmnet_init_port() establishes connections
h3. gps
* IF class/sub/proto = 0xff
* only one endpoint (notify)
* string[0] (en-us) is "GPS"
h3. ncm (CDC Netowrk (NCM) link function)
h3. ecm_qc (CDC Ethernet)
h3. usb_mbim (Mobile Broadband Interface Model)
h3. audio (uac1?)
h3. diag
* class/sub/proto = 0xff
* num-ep 2
* max-packet 512
* some special assumption only if bInterfaceNumber==0
h3. qdss (Qualcomm Debug Sub-System)
* has QDSS DATA / QDSS CTRL string descriptor
* somehow connects to BAM
h3. serial
* class=0xff, sub/proto = 0
* num_endpoints = 3
* string descroptor "Generic Serial"
* transports
** tty (-> gserial)
** smd (shared memory)
** char_bridge (?)
** hsic
h3. ccid (chipcard reader)
* /dev/ccid_ctrl
* /dev/ccid_bulk
* probably intended to be used with userspace progam translating USB CCID requests into QMI requests to access SIM card(s)
h3. charging
* usb charger support
h3. mtp
h3. ptp
h3. rndis
h3. rndis_qc
h3. ecm
h3. mass_storage
h3. accessory
h3. audio_source
h3. midi
h3. rndis_gsi
h3. rmnet_gsi
h3. ecm_gsi
h3. mbim_gsi
h3. dpl_gsi
h2. modem detection / EC20 re-using same usb device id / interface numbers
The idea here is to dynamically detect which interface number exposes a certain interface,
regardless what order / qty / interface number
* ADB: 255/66/1, 2 EP
* Diag: 255/255/255, 2 EP
* TTY: 255/0/0, 3 EP, unrecognized descriptors
* RMNET: 255/255/255, 3EP