Device control object

Updated: April 19, 2023

The device control object allows applications to perform actions on USB hardware, modify the USB launcher service configuration, and request attached devices to run certain protocols.

Applications can write commands of the following types to the object:
Use this command type: To:
BUS::cmd,options Set the state of the USB bus
HUB::cmd,options Set the power state of a USB hub, or toggle a port's power on or off
LUA::cmd,options Modify the USB launcher service configuration
start_aoa::options Start Android Open Accessory (AOA) on an attached device

After processing a command, the USB launcher service publishes the command's outcome to the same object. For details about the attributes written, see the Command outcomes section.

Each instance of the launcher service (i.e., usblauncher_otg process) creates one device control object. By default, the object's path is /pps/qnx/device/usb_ctrl, but you can change the PPS directory (but not the filename) through the -m command option.

You want to run multiple launcher service instances if you're running multiple USB server (io-usb-otg) instances. You would do this if, say, you needed to manage different USB controllers independently. (The ports for each controller would be managed by a separate server instance.)

If you plan to use the same PPS directory for storing the device control objects of multiple USB launcher service instances, you need to start each instance with the -S server_number option, so the name of the object includes the server number. For instance, the command usblauncher_otg -S 1 creates a PPS object named /pps/qnx/device/usb_ctrl1.

BUS

The BUS command category supports these two commands:
  • start — Start a USB bus. You must specify the number of one bus, but not multiple buses.
  • stop — Stop a USB bus. You must specify the number of one bus, but not multiple buses.

HUB

The HUB command category supports these two commands:
  • port_power — Set a hub's power state. This command lets you repower a port if the upstream hub has disabled it (e.g., due to an overcurrent condition that may no longer apply). The syntax is:
    HUB::port_power,busno=n,devno=n,level=boolean[,portno=n]
  • toggle_port_power — Turn a hub's power off, wait for a fixed delay, then turn the power back on. The syntax is:
    HUB::toggle_port_power,busno=n,devno=n[,portno=n,delay=n]
The options in HUB commands are as follows:
Options Description Type
busno Bus number of the hub Integer
devno Device number of the hub Integer
level New power setting, either off (0) or on (1) Boolean
portno

Port number.

If you issue a port_power command and omit portno, the specified level applies to all ports on the hub.

Likewise, if you issue a toggle_port_power command and omit portno, the command toggles the power of all ports on the hub. You must include portno if you specify delay.

Integer
delay Delay, in milliseconds. The default is 500. Integer

You can specify the values for busno, devno, portno, and delay in decimal or hexadecimal. The values for busno and devno typically fall in the range of 0 to 64.

LUA

The LUA command category lets you modify the USB launcher service configuration. The command string begins with LUA:: and is followed by the command name and list of arguments:
LUA::lua_cmd,arg1[,arg2...]
The command name and arguments are separated by commas, and the arguments are key-value pairs with an equal sign (=) separating each key and value. You can issue the following commands:
Command Description
setvar,table_name[variable]=valuea

Override a table variable to change the behavior of a Lua callout function.

For example, this command enables the suspend_is_removal flag:
LUA::setvar,launcher_config[suspend_is_removal]
setvar,variable=valuea Override a global variable to change the behavior of a Lua callout function
getvar,table_name[variable]a Get the value of a table variable
getvar,variablea Get the value of a global variable
run,functiona Run a custom function defined in the main configuration file

Table variables and global variables are stored in the main configuration file, rules.lua. When you issue a setvar or getvar command, the command validates the existence of the variable and, if specified, the table. If one of these doesn't exist or if the value isn't of the expected type, an error is returned.

Currently, the LUA category supports only the LUA_STRING, LUA_BOOLEAN, and LUA_NUMBER types.

start_aoa

After learning that an attached device supports the Android Open Accessory (AOA) protocol, a process can issue the start_aoa command to make the device switch to its Android personality:
start_aoa::busno=bnum,devno=dnum,modes=AOAmodes[,option=value...]
The supported options are:
Option Description Type
busno (Required) Bus number of the device Integer
description (Optional) Description of the device String
devno (Required) Device number Integer
manufacturer (Sometimes required) Manufacturer name String
model (Sometimes required) Model number String
modes
(Required) AOA modes that the device is being asked to enable. The supported flags are:
  • AOA_MODE_ACCESSORY (0x0001)
  • AOA_MODE_AUDIO (0x0002)

For details, see “Specifying AOA modes” below.

Integer
serial (Optional) Serial number String
uri (Optional) Uniform resource identifier of the device String
version (Optional) Version of the device String

The values for busno and devno can be decimal, hexadecimal, or mixed. Typically, these values fall in the range of 0 to 64. The flags in modes can be decimal or hexadecimal.

For information on the identifiers manufacturer through serial, see the AOA section of the Android Open Source Project website.

Specifying AOA modes

If the device supports AOA version 1 (as indicated by an aoa value of 1 in the device information object), you can enable only AOA_MODE_ACCESSORY. If the device supports AOA version 2, you can enable one or both of AOA_MODE_ACCESSORY and AOA_MODE_AUDIO.

If you enable only the first mode, you must define the manufacturer and model options. If you enable the second mode, you should omit these two identifiers; otherwise, the device will ask the user to associate an Android application with the accessory (i.e., target system).

For either mode, the remaining identifiers are optional and allow you to launch an application on the device, based on matches with the identifier strings.

Command outcomes

When the USB launcher service executes commands, it publishes the following attributes to the device control object:
Attribute Description Type Examples
cmd_status

The processing status of the last command issued by any client. The USB launcher service broadcasts each update to this attribute to all clients of this object, not just to the one that issued the command.

When the service receives a new command, it publishes the processing status to cmd_status and to slogger2. The attribute value and log message say whether the command was successfully processed or not (e.g., if an illegal operation was requested).

Note: Even for unrecognized commands, the service writes an error message to this attribute and to slogger2.
An error string in the following format:
last_command,
completion_status 
=errno 
(str_error(errno)) 
If the command is processed successfully, this field contains:
0 (No error)
If the client specifies an improper bus number or device number (or both), this field contains:
19 (No such device)
last_cmd

The last command that was successfully processed, its completion status, and in some cases, its execution details. Only the client that issued the command receives notification; the update isn't broadcast.

The service updates this attribute when it finishes processing a command, whether the underlying request succeeded or not.

In some cases, the service reads USB server descriptors and includes their information in the new attribute value.

A string in this format:
last_command,
completion_status 
=errno
(str_error(errno)) 
[, details::
extra_details] 
If a LUA getvar command succeeds, this field contains a string like the following:
last_cmd::LUA,
completion_status=0 
(No error), 
lua_type::1, 
lua_value::false
where lua_type stores the type of variable and lua_value stores the value that getvar read from the variable.
a You can name only one variable per setvar or getvar command.