mist
is a Chromium OS utility for switching USB cellular dongles into the
modem mode. A cellular dongle may implement multiple functions and the function
exposed by its initial USB configuration may not be a modem. We need to switch
the device into a modem before it can be detected and managed by
ModemManager to
provide cellular connectivity.
mist
is activated by udev events. When udev detects a supported dongle, it
invokes mist
to switch the dongle into the modem mode. The mode switching
operation invokes the following:
- Open the USB device associated with the dongle. If the device has a USB configuration that exposes a MBIM interface, select that configuration and complete the switch operation. Otherwise, find and claim the mass storage interface of the device.
- Initiate a bulk output transfer of a (or multiple) special USB message(s) to the mass storage endpoint of the device.
- On some devices, a bulk input transfer from the mass storage endpoint of the device is expected after completing each bulk output transfer.
- Once the transfer of the last message completes, the device is expected to disconnect from the USB bus and then reconnect to the bus after it has been switched to the modem mode. The device may change its USB vendor ID and product ID (mostly the latter) after the switch operation.
mist
relies on udev to detect when a dongle is plugged into the system. A
udev rules file, /lib/udev/rules.d/51-mist.rules
, is used to
identify a supported dongle based on its USB vendor ID and product ID before
and after mode switching. Upon detecting a supported dongle in the non-modem
mode, udev launches a mist process to switch the dongle into modem, and also
tags the dongle as MIST_SUPPORTED_DEVICE=1
, which allows cros-disks to
filter out the mass storage exposed by the dongle.
After udev launches the mist
process, mist
daemonizes itself so that it can
use libudev to monitor the status of the mode switching via udev events. After
the special USB messages are sent to the mass storage interface of the dongle,
the dongle detaches itself from USB, which results in a udev remove event.
After the dongle switches into the modem mode, it reattaches to USB, which
results in a udev add event.
mist
uses a protobuf-based configuration file,
/usr/share/mist/default.conf
, to specify information about
the supported dongles. The configuration file specifies a list of supported
dongles and the following information associated with each dongle:
- Initial USB vendor and product ID of the modem when it is in the mass storage mode.
- A list of possible final USB vendor and product IDs of the modem after it has switched to the modem mode.
- A list of USB messages, in form of hexadecimal strings, to send to the mass storage interface of the modem in order to switch the modem to the modem mode.
- An optional flag to indicate whether a response is expected from the mass storage interface after sending each USB message to the interface.
- An optional initial delay, in milliseconds, that mist should wait before starting the modem switch operation.
mist
uses libusb 1.x API to retrieve the USB descriptors of the dongle and
initiate bulk transfers to the mass storage interface of the dongle. It thus
needs to have read and write access to the USB device associated with the
dongle.