tree: 491022521f3497d2fbc8afc352a58ed4f1dc501c [path history] [tgz]
  1. 51-mist.rules
  2. BUILD.gn
  3. OWNERS
  4. README.md
  5. config_loader.cc
  6. config_loader.h
  7. config_loader_test.cc
  8. context.cc
  9. context.h
  10. default.conf
  11. event_dispatcher.cc
  12. event_dispatcher.h
  13. event_dispatcher_test.cc
  14. main.cc
  15. metrics.cc
  16. metrics.h
  17. mist.cc
  18. mist.h
  19. mock_config_loader.h
  20. mock_context.cc
  21. mock_context.h
  22. mock_udev.h
  23. mock_udev_device.h
  24. mock_udev_enumerate.h
  25. mock_udev_list_entry.h
  26. mock_udev_monitor.h
  27. mock_usb_device_event_observer.h
  28. proto/
  29. udev.cc
  30. udev.h
  31. udev_device.cc
  32. udev_device.h
  33. udev_enumerate.cc
  34. udev_enumerate.h
  35. udev_list_entry.cc
  36. udev_list_entry.h
  37. udev_monitor.cc
  38. udev_monitor.h
  39. usb_bulk_transfer.cc
  40. usb_bulk_transfer.h
  41. usb_config_descriptor.cc
  42. usb_config_descriptor.h
  43. usb_config_descriptor_test.cc
  44. usb_constants.cc
  45. usb_constants.h
  46. usb_constants_test.cc
  47. usb_device.cc
  48. usb_device.h
  49. usb_device_descriptor.cc
  50. usb_device_descriptor.h
  51. usb_device_descriptor_test.cc
  52. usb_device_event_notifier.cc
  53. usb_device_event_notifier.h
  54. usb_device_event_notifier_test.cc
  55. usb_device_event_observer.h
  56. usb_endpoint_descriptor.cc
  57. usb_endpoint_descriptor.h
  58. usb_endpoint_descriptor_test.cc
  59. usb_error.cc
  60. usb_error.h
  61. usb_error_test.cc
  62. usb_interface.cc
  63. usb_interface.h
  64. usb_interface_descriptor.cc
  65. usb_interface_descriptor.h
  66. usb_interface_descriptor_test.cc
  67. usb_manager.cc
  68. usb_manager.h
  69. usb_modem_one_shot_switcher.cc
  70. usb_modem_one_shot_switcher.h
  71. usb_modem_switch_context.cc
  72. usb_modem_switch_context.h
  73. usb_modem_switch_context_test.cc
  74. usb_modem_switch_operation.cc
  75. usb_modem_switch_operation.h
  76. usb_modem_switcher.cc
  77. usb_modem_switcher.h
  78. usb_transfer.cc
  79. usb_transfer.h
  80. usb_transfer_test.cc
mist/README.md

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 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, 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, 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.