usb_moded-doc.txt 16.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
USB_MODED use and API description/overview.

Usb_moded is a relatively simple daemon which tracks the
usb cable connection status and activates a certain USB
profile based on that.
To do this it has a number of built in common profiles, 
an optional application launcher (app_sync) and configurable
dynamic modes.

All the system wide communication goes over the DBus system bus,
while application launching is handled on the session bus.
Thus if you need this functionality, usb_moded needs to be started 
with the session. 
(functionality not verified yet on multi-user setups. See TODO)

17 18 19 20 21
Usb cable detection is handled with udev, it even tries to guess
which is the correct power_supply entry to use. 

A Qt lib to interact with usb-moded is available here:
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40

Starting usb_moded

Simply start with usb_moded.
usb_moded --help will give you more details

Status and configuration query/setting

The current status can be queried any time over DBus. From a program
using a method call or using dbus-send.

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.mode_request

Similary a mode can be set.

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.set_mode string:'<mode_name>'

Even the configuration can be set over DBus
42 43 44

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.set_config string:'<mode_name>'

45 46 47 48
To get the currently stored default mode from the config:

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.get_config

49 50 51 52
The supported modes can be queried over dbus as follows:

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.get_modes

53 54 55 56 57 58 59 60
Usb_moded will also broadcast changes and errors over the system bus.
This will happen on the com.meego.usb_moded interface

For regular signals: sig_usb_state_ind
And errors: sig_usb_state_error_ind

More info and details in usb_moded-dbus.h

61 62 63
Main configuration file

There is also a configuration file and some configuration directories under /etc/usb-moded
65 66 67 68 69 70 71 72 73 74 75 76
The main config file is /etc/usb-moded/usb-moded.ini . This file will be auto-generated if 
it is not there (default profile will be developer_mode). Also it will be regenerated if some
extra config file gets dropped into the /etc/usb-moded/ directory. This way you can easily 
add extra hw/configuration dependent information in there.

Most common use case would be passing the udev information for the power supply tracking entry,
as in some cases it is not /sys/class/power_supply/usb

This is also known as config file merging (see further)

The most imporant entry is the power_supply, or iow the place in sysfs where usb_moded can
read the cable connection status and type. For example on the N900 

78 79 80 81 82
path = /sys/class/power_supply/isp1704

Without this information usb_moded will not run and exit.

83 84 85 86 87
In case nothing is specified and it is not the typical path it will try to guess.
This might not always work. There is the source of a utility in the tree udev-search.c
under utils, that will give you an idea of what paths usb-moded might be choosing. It always
takes the one with the highest score.

There are the mountpoints, this defines which device/filesystem entry should be 
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
exported over mass-storage (this ideally also has an entry in /etc/fstab). You can add more 
filesystems to the mount option, by making it a comma-seperated list in case there are 
several exports (like internal mmc and sd card for example)

mount = /dev/mmcblk0p1

The following option plays with certain sync options that exist and have to be set per
fs and thus cannot be handled by setting them in /etc/modprobe.d/....conf

nofua = 1

This mount is the alternative mountpoint for in case something goes wrong. Usb_moded
will mount a 512 RO tmpfs on that location to mitigate potential disasters on the system,
and make clear to programs on the device that something is wrong with the fs they want to use.

mount = /home/user/MyDocs

phdeswer's avatar
phdeswer committed
109 110 111 112 113
Also the default usb mode can be configured there. For example:

mode = ask

114 115 116
The other settings and config dirs will be handled later in the appsync and dynamic modes part.
(This is optional and can be compiled out)

117 118 119 120 121
There is also an optional network configuration. 

Certain parts of this config will override the settingsset in the dynamic mode configuration, like for example interface! 
The default ip set for usb networking is (for Meego/Nemo/SailfishOS). However this can be configured by 
hand in the ini file also (optionally in a separate ini file which is possible due to config file merging).

123 124 125 126 127 128 129 130 131
For example:

ip =
interface = usb1
gateway =

By default usb0 will be used, so no need to fill it in if not needed. The gateway setting is also optional
and will not be set if there is no value filled in.
If the ip is set to dhcp, usb_moded will try to use dhcp to configure the network (requires dhclient or udhcpc atm)

134 135 136 137 138 139 140
The network configuration can also be set with dbus method calls via the net_config method.
This requires two strings as arguments. Supported are: ip, interface and gateway

for exmaple:

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.net_config string:'ip' string:''

141 142 143 144 145
Usb_moded will generate a random mac address for the g_ether driver. Thus when plugging in the device repeatedly the mac address will not
change and udev rules / network manager etc will not think it is a new device each time.
This mac is stored using the default modprobe configuration and thus will be in /etc/modprobe.d/g_ether.conf
If this file exits usb_moded will assume there is a default mac set and will not do anything.

It is possible to set the configuration on the kernel command line also. For this the format of regular ip setting from the kernel is
being re-used. 

The format followed is:
151 152 153

For more info see the kernel source: Documentation/filesystems/nfs/nfsroot.txt

for example : usb_moded_ip=
155 156

NOTE: The device must be usb0! The autoconf value is ignored.

158 159
Ip forwarding or nat can also be set up by usb_moded. This is in case you want to use an interface
on the device to route traffic coming from your pc/laptop. The best use case example would be connecting
to the internet over USB using the data connection of your smartphone. This does not work the other way round!
161 162

To enable this you need to add the following lines to your network config (the example expects rmnet0 to be
your internet facing interface on the device). 
164 165 166

nat_interface = rmnet0

167 168 169 170
When nat=1 is given in the mode configuration this will be used to enable nat on that interface.
This is a bit complicated but related to the fact that the nat interface is usually the same on a device, 
but not all usb network related profiles might want it enabled.

If you want the device to load a dhcp server you need to configure this in the mode config, just like nat. (see lower)

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
Functional overview

When a usb cable is insertion is detected usb_moded will start to act.
First it will warn on the system bus that a cable is connected. 
Then it will check what the configuration setting is. Thus it knows how to act.
If it is a known configured mode it will load the correct modules (after checking 
what is loaded and clean up if needed), perform other needed operations and
make sure the chosen mode works. At this point it will broadcast which mode 
is set to warn other programs.
If things fail it will go to undefined state (and also broadcast this).

There is the special case where the config option is called "ask". In this
case usb_moded will enable a fake mass_storage profile to enable enumeration 
so charging can be done, and wait until it is instructed which mode needs
to be selected. Thus this state can be used for an UI that will set the right
mode on user interaction. For this purpose usb_moded broadcasts it goes in ask
mode, and also stays in ask mode until a chosen mode is requested or the cable
is disconnected. This also avoids race conditions in case the  UI starts
after a cable is inserted and usb_moded has also been started. The UI can then 
query the state to know if it needs to show a selection dialog or not.

Philippe De Swert's avatar
Philippe De Swert committed
On cable disconnect usb_moded will broadcast a disconnect signal, so that all programs
196 197 198 199
that use the usb interface/mode know that a cable is disconnected and then can act
(if needed) on the changed situation. It will then do all the necessary to reset
the system to a clean state.

Philippe De Swert's avatar
Philippe De Swert committed
200 201 202 203 204
Another special feature is the dedicated charger tracking. When a charger is connected
usb_moded will broadcast a charger_connected signal and go to "dedicated charger" mode.
This is just a place-holder mode. On charger disconnect then there will be a 
charger_disconnected signal.

205 206 207 208 209 210 211 212 213
Appsync feature

In case you need some program to be started along some mode the appsync option 
provides this option.
Only condition is that it can be activated by dbus and that (preferably) it will
notify usb_moded that it is ready by ready_method call on the session bus.
This ready method call is just calling the regular usb_moded interface, but now
on the session bus, with as argument the program name as defined in the config file.
Systemd is also supported.
215 216 217 218 219 220 221

To achieve this you need to have a config file in /etc/usb-moded/run.
Best practice would be giving it a descriptive name followed by .ini

For example:

Where foo.ini would be for dbus:
223 224 225 226 227
name = foo
mode = foo_mode
launch =

228 229 230 231 232 233 234 235
For systemd it would be as follows:
name = foo.service
mode = foo_mode
systemd = 1

The name here is the service name used when launching it for example with systemctl

236 237 238 239
Those files will be read on start and usb_moded will keep a list of apps to launch 
for a certain mode. This also means that if you change the files or add/remove some
you need to restart usb_moded. Later when the mode is activated, usb_moded will start 
each of them after the module has been loaded and keep track if they have been started.
It will warn you if that failed.

242 243 244 245
These services will start before the whole setup for the usb is done. In case the application
only works after everything has been set up, you can start the application at the end by adding
post = 1 to configuration.

246 247 248
Dynamic modes

249 250
Apart from ask and charging_only modes, all modes for usb_moded are defined
within configuration files. These are to be defined with an ini file alsoi, but this time in 
251 252 253 254 255 256

The format would be for example for : /etc/usb-moded/dyn-modes/dyn-mode-1.ini

name = dyn-mode-1
module = dyn-mode-module
258 259 260 261
appsync = 1
network = 1
network_interface = usb0

262 263 264 265
sysfs_path = /* in case you need to echo parameters somewhere in a sysfs path */
sysfs_value = /* the values */
sysfs_reset_value = /* in case a reset value needs to be written */

267 268 269 270
Only the mode name and module are mandatory. In case you do not use modules, use none as the value 
for module (as for the android gadget for example. See the android section for more info)

If appsync or network is not defined, or explicitly set to 0, it will not be used.
271 272 273
To use the mass_storage functions you need to define mass_storage = 1. The needed info for
mass_storage data need to be defined in the config file. (other approaches are possible so this is not
mandatory for all kinds of mass_storage support)

275 276
To enable nat, you need to set nat = 1 and configure the nat_interface in the network settings.

277 278 279 280 281 282
To have dhcp server functionality on the device, set dhcp_server = 1. This will use udhcpd.
It also uses the default network address or whatever has been configured and sets up a corresponding dhcp
configuration. This way the device is always available on the same address.

Both NAT and dhcp server need a corresponding service that can be started by usb_moded. (see Appsyn feature)

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
Trigger support

This will only work if udev is configured as it is a udev trigger.
Atm only one trigger is supported.
This is to support special equipment that will send a trigger event.
Usually this will be in combination with a dynamic mode.

You need to add the following to usb-moded.ini to get a trigger activated

For example

path = /sys/devices/platform/musb_hdrc
udev_subsystem = platform
mode = mass_storage
property = TRIGGER_CMD

301 302
Android gadget driver support

304 305
A number of configurations are already supported out of the box for android. They
just need to be installed in the right spot to work.

In the main configuration file a few extras can be configured for all modes.

An android extra section in the main configuration file would look like this:

311 312 313 314 315
iManufacturer = foo-factory
idVendor = 0666 /* this is the vendor id code in hex */
iProduct = awesome-device
idProduct = 0001 /* If you decide to use one Product id for all the supported modes. Not recommended if you will connect it to Windows machines */

A mode configuration would look like this: 

319 320 321 322 323
name = developer_mode
module = none
network = 1
network_interface = rndis0

# sysfs_value = comma separated list of functions to enable in this mode
327 328
sysfs_value = rndis
idProduct = 0002

330 331 332 333 334 335 336 337 338 339 340 341 342 343 344

Android portability

On some android kernels cable detection/charging etc is broken unless the gadget is active.
Often this is weirdly done on purpose by checking if the gadget is active before doing anything.
This is not recommend and is actually wrong. Not to mention all the potential issues this could cause.
(extra power drain, suspend issues, accidental exposure of data over USB, ...)

For this purpose there is the -a switch that activates by default the charging mode, and will set it
on disconnect. So technically unless you connect and set some mode, the gadget will always be active
in the fake mass-storage charging mode.

WARNING: This could potentially expose data over mass-storage (TODO, make sure this does not happen)

345 346 347 348
rescue mode

When started with -r usb_moded will always enable developer mode (networking)
if it can. This is a debug feature and should not be used in production software.
350 351 352 353

Turning it off when the device is booted completely can easily be done over dbus.

dbus-send --system --type=method_call --print-reply --dest=com.meego.usb_moded /com/meego/usb_moded com.meego.usb_moded.rescue_off
354 355 356 357 358 359 360 361 362

config files and config file merging

The main config file for usb_moded is /etc/usb-moded/usb-moded.ini

If this does not exist usb_moded will create one for you, which will default
to setting up a default network with ip and uses the g_ether module.

363 364 365 366
The different sections of the config file can be split out in different ini files 
(they thus need to end in .ini or they will not be considered as valid). However take into 
account usb_moded will need to be restarted to merge these in a new usb-moded.ini file. 
As usb_moded will only then check if new files were added to the /etc/usb-moded
directory and refresh the main ini file as needed on start-up.
368 369 370 371 372 373 374 375

diagnostic mode

Usb-moded supports a diagnostic mode. This requires a special command line parameter (-d).
One mode should be configured in /etc/usb-moded/diag and this will be automatically used.
This is a feature to allow for "hidden" or non-standard modes that are only of use for 
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394

USB tethering

Usb_moded can set up USB tethering. In the sense that it can share the connection of your device to a second one.
Most common use case would be using USB tethering from a phone to a laptop.

When compiled with ofono and connman support you can make the most of this. ofono can be used to detect roaming status.
Connman for getting dns settings and interface from the modem connection.
However it works also without it. It can be configured so that it knows what the interfaces are and get the dns info 
from /etc/resolv.conf.

For this are the 

#define NETWORK_NAT_INTERFACE_KEY       "nat_interface"
#define NO_ROAMING_KEY                  "noroaming"

Network options. nat_interface documents which interfaces the internet facing modem. noroaming when set to 1
will prohibit enabling the modem interface in case you are roaming (this requires ofono). 
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409

hidden modes

Sometimes it is useful to hide modes from the ui (the mode can be queried through dbus).
To hide modes this can be done by adding a hide= key to the
[usbmode] section. If you want to hide more modes this needs
to be a comma separated list.

For example

Modes can also be set and removed through dbus (one mode at a time)
See usb_moded_util (-v, -i and -u)