blob: df122001632f9490a76dbde8b3e057630842cb6f [file] [log] [blame] [view] [edit]
# mist: Modem Interface Switching Tool
## Overview
`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](https://www.freedesktop.org/wiki/Software/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.
## Device Detection
`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`](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.
## Configuration File
`mist` uses a protobuf-based configuration file,
[`/usr/share/mist/default.conf`](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.
## USB Communications
`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.