1035 lines
46 KiB
XML
1035 lines
46 KiB
XML
<?xml version="1.0"?>
|
|
<!DOCTYPE part PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
|
|
]>
|
|
<part id="ref-overview">
|
|
<title>ModemManager Overview</title>
|
|
|
|
<chapter id="ref-overview-introduction">
|
|
<title>Introduction</title>
|
|
<para>
|
|
ModemManager provides a unified high level API for communicating with mobile
|
|
broadband modems, regardless of the protocol used to communicate with the
|
|
actual device (Generic AT, vendor-specific AT, QCDM, QMI, MBIM...).
|
|
</para>
|
|
<formalpara>
|
|
<title>Using</title>
|
|
<para>
|
|
ModemManager is a system daemon and is not meant to be used directly from
|
|
the command line. However, since it provides a DBus API, it is possible to use
|
|
'dbus-send' commands or the new 'mmcli' command line interface to control it
|
|
from the terminal. The devices are queried from udev and automatically updated
|
|
based on hardware events, although a manual re-scan can also be requested to
|
|
look for RS232 modems.
|
|
</para>
|
|
</formalpara>
|
|
<formalpara>
|
|
<title>Implementation</title>
|
|
<para>
|
|
ModemManager is a DBus system bus activated service (meaning it's started
|
|
automatically when a request arrives). It is written in C, using glib and gio.
|
|
Several GInterfaces specify different features that the modems support,
|
|
including the generic MMIfaceModem3gpp and MMIfaceModemCdma which provice basic
|
|
operations for 3GPP (GSM, UMTS, LTE) or CDMA (CDMA1x, EV-DO) modems. If a given
|
|
feature is not available in the modem, the specific interface will not be
|
|
exported in DBus.
|
|
</para>
|
|
</formalpara>
|
|
<formalpara>
|
|
<title>Plugins</title>
|
|
<para>
|
|
Plugins are loaded on startup, and must implement the MMPlugin interface. It
|
|
consists of a couple of methods which tell the daemon whether the plugin
|
|
supports a port and to create custom MMBroadbandModem implementations. It most
|
|
likely makes sense to derive custom modem implementations from one of the
|
|
generic classes and just add (or override) operations which are not standard.
|
|
There are multiple fully working plugins in the plugins/ directory that can be
|
|
used as an example for writing new plugins. Writing new plugins is highly
|
|
encouraged! The plugin API is open for changes, so if you're writing a plugin
|
|
and need to add or change some public method, feel free to suggest it!
|
|
</para>
|
|
</formalpara>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-modem-detection">
|
|
<title>Modem detection</title>
|
|
|
|
<section>
|
|
<title>Builds with udev support</title>
|
|
<para>
|
|
ModemManager requires <emphasis>udev</emphasis>-powered Linux kernels in order
|
|
to get notified of possible available Modems. udev will report each of the ports
|
|
found in the device, and ModemManager will consider for probing each of the ports
|
|
marked with the <emphasis>ID_MM_CANDIDATE</emphasis> tag in udev.
|
|
</para>
|
|
<para>
|
|
Aditionally, users of RS232-based devices may need to request additional manual
|
|
scans via DBus, in order to detect modems that may have been connected to
|
|
RS232 to USB adapters. In this case, udev just knows about the USB adapter being
|
|
connected, not about the RS232 modem connected to the adapter, if any.
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Builds without udev support</title>
|
|
<para>
|
|
When the udev daemon isn't available in the system, the
|
|
<link linkend="gdbus-method-org-freedesktop-ModemManager1.ReportKernelEvent">ReportKernelEvent</link>
|
|
method in the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1">Manager interface</link>
|
|
may be used to notify the ModemManager daemons of device addition and removals.
|
|
</para>
|
|
<para>
|
|
When udev support is disabled in the build, the <emphasis>ID_MM_CANDIDATE</emphasis>
|
|
tag and manual scan requests are still applicable. ModemManager has a built-in parser
|
|
of udev rule files that is enabled when udev itself isn't available.
|
|
</para>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-modem-filter">
|
|
<title>Modem filter</title>
|
|
|
|
<para>
|
|
ModemManager will not probe all TTYs, NET and cdc-wdm ports found in the system,
|
|
as this may end up interfering e.g. with TTYs that have nothing to do with modem
|
|
devices.
|
|
</para>
|
|
<para>
|
|
The daemon comes with several predefined <emphasis>filter policies</emphasis>, each
|
|
of them composed of one or more <emphasis>filter rules</emphasis>.
|
|
</para>
|
|
|
|
<section>
|
|
<title>Filter rules</title>
|
|
<para>
|
|
The device filter in ModemManager defines the following independent filter rules. The
|
|
predefined filter policies are based on one or more of these predefined filter rules.
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_EXPLICIT_WHITELIST</emphasis></para>
|
|
<para>
|
|
This filter allows users to manually tag devices and/or device ports with the
|
|
<emphasis>ID_MM_DEVICE_PROCESS</emphasis> udev tag. If the filter finds this tag,
|
|
the device and/or device ports will be automatically accepted and port probing
|
|
will be allowed.
|
|
</para>
|
|
<programlisting>
|
|
$ sudo vim /lib/udev/rules.d/78-mm-whitelist-internal-modem.rules
|
|
ACTION!="add|change|move", GOTO="mm_whitelist_internal_modem_end"
|
|
ATTRS{idVendor}=="1199", ATTRS{idProduct}=="a001", ENV{ID_MM_DEVICE_PROCESS}="1"
|
|
LABEL="mm_whitelist_internal_modem_end"
|
|
// Apply new rules without reboot
|
|
$ sudo udevadm control --reload
|
|
$ sudo udevadm trigger
|
|
</programlisting>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_EXPLICIT_BLACKLIST</emphasis></para>
|
|
<para>
|
|
This filter allows users to manually tag devices and/or device ports with the
|
|
<emphasis>ID_MM_DEVICE_IGNORE</emphasis> udev tag. If the filter finds this tag,
|
|
the device and/or device ports will be automatically ignored and port probing
|
|
will be never run on them.
|
|
</para>
|
|
<programlisting>
|
|
$ sudo vim /lib/udev/rules.d/78-mm-blacklist-internal-modem.rules
|
|
ACTION!="add|change|move", GOTO="mm_blacklist_internal_modem_end"
|
|
ATTRS{idVendor}=="1199", ATTRS{idProduct}=="a001", ENV{ID_MM_DEVICE_IGNORE}="1"
|
|
LABEL="mm_blacklist_internal_modem_end"
|
|
// Apply new rules without reboot
|
|
$ sudo udevadm control --reload
|
|
$ sudo udevadm trigger
|
|
</programlisting>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_PLUGIN_WHITELIST</emphasis></para>
|
|
<para>
|
|
This filter will automatically whitelist devices that are explicitly referenced
|
|
by plugins, either with plugin-specific whitelist tags, with exact
|
|
<emphasis>vid:pid</emphasis> matches, or just with <emphasis>vid</emphasis> matches.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_QRTR</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as allowed all QRTR nodes that have been
|
|
notified as being modem management capable.
|
|
</para>
|
|
<para>
|
|
This filter rule is available since 1.18.0.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_VIRTUAL</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as forbidden all ports exposed by virtual
|
|
devices, like the 'lo' network interface or the tty0, tty1... virtual terminals.
|
|
There is no reason to disable this filter, except for testing purposes.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_NET</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as allowed all network ports exposed by
|
|
devices. Unless there is a will to explicitly forbid network ports, this filter
|
|
should always be enabled.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_USBMISC</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as allowed all cdc-wdm ports exposed in the
|
|
usbmisc subsystem. Unless there is a will to explicitly forbid the cdc-wdm ports exposed
|
|
by qmi_wwan, cdc_mbim or huawei-cdc-ncm kernel drivers, this filter should always
|
|
be enabled.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_RPMSG</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as allowed all rpmsg ports exposed in the
|
|
rpmsg subsystem. Unless there is a will to explicitly forbid the rpmsg ports,
|
|
this filter should always be enabled.
|
|
</para>
|
|
<para>
|
|
This filter rule is available since 1.16.0.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_WWAN</emphasis></para>
|
|
<para>
|
|
This filter will automatically flag as allowed all wwan control ports exposed
|
|
in the wwan subsystem. Unless there is a will to explicitly forbid the wwan control
|
|
ports, this filter should always be enabled.
|
|
</para>
|
|
<para>
|
|
This filter rule is available since 1.18.0.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY</emphasis></para>
|
|
<para>
|
|
If the MM_FILTER_RULE_TTY filter is disabled, no TTY port will be allowed. If this
|
|
filter is enabled, TTY ports will only be allowed if the TTY-specific filters (defined
|
|
next) allow it.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_PLATFORM_DRIVER</emphasis></para>
|
|
<para>
|
|
If this filter is enabled, all platform TTY ports will be forbidden automatically.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_DRIVER</emphasis></para>
|
|
<para>
|
|
If this filter is enabled, all TTY ports managed by modem-specific kernel drivers will be
|
|
allowed automatically.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>FILTER_RULE_TTY_ACM_INTERFACE</emphasis></para>
|
|
<para>
|
|
If this filter is enabled, all TTY ports managed by the cdc-acm kernel driver with
|
|
class=2/subclass=2/protocol=1 (AT command capable ttyACM port) will be allowed
|
|
automatically.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_WITH_NET</emphasis></para>
|
|
<para>
|
|
If this filter is enabled, all TTY ports for devices that also expose a network
|
|
interface port will be allowed automatically.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN</emphasis></para>
|
|
<para>
|
|
This rule is the implicit one defining what happens when a TTY port isn't explicitly
|
|
accepted by any of the TTY-specific filters; i.e. the TTY port will be forbidden.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<para>
|
|
The following filter rules have been deprecated and are no longer used.
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_BLACKLIST</emphasis></para>
|
|
<para>
|
|
Deprecated in 1.18.0.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>MM_FILTER_RULE_TTY_MANUAL_SCAN_ONLY</emphasis></para>
|
|
<para>
|
|
Deprecated in 1.18.0.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Filter policies</title>
|
|
|
|
<para>
|
|
The predefined filter policies are:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Whitelist only</emphasis></para>
|
|
<para>
|
|
This is a policy where only the MM_FILTER_RULE_EXPLICIT_WHITELIST rule is enabled.
|
|
</para>
|
|
<programlisting># /usr/sbin/ModemManager --filter-policy=WHITELIST-ONLY</programlisting>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Strict</emphasis></para>
|
|
<para>
|
|
This is a policy where the following rules are enabled:
|
|
<itemizedlist>
|
|
<listitem>MM_FILTER_RULE_EXPLICIT_WHITELIST</listitem>
|
|
<listitem>MM_FILTER_RULE_EXPLICIT_BLACKLIST</listitem>
|
|
<listitem>MM_FILTER_RULE_PLUGIN_WHITELIST</listitem>
|
|
<listitem>MM_FILTER_RULE_QRTR</listitem>
|
|
<listitem>MM_FILTER_RULE_VIRTUAL</listitem>
|
|
<listitem>MM_FILTER_RULE_NET</listitem>
|
|
<listitem>MM_FILTER_RULE_USBMISC</listitem>
|
|
<listitem>MM_FILTER_RULE_RPMSG</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY_PLATFORM_DRIVER</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY_DRIVER</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY_ACM_INTERFACE</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY_WITH_NET</listitem>
|
|
<listitem>MM_FILTER_RULE_TTY_DEFAULT_FORBIDDEN</listitem>
|
|
<listitem>MM_FILTER_RULE_WWAN</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
<para>
|
|
This policy is the default one when a different one is not explicitly
|
|
selected. In this policy, all TTYs are forbidden except for the ones
|
|
explicitly allowed by one of the TTY-specific rules.
|
|
</para>
|
|
<programlisting># /usr/sbin/ModemManager --filter-policy=STRICT</programlisting>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Custom</emphasis></para>
|
|
<para>
|
|
Any of the previously defined predefined policies may be modified rule per rule
|
|
by explicitly enabling or disabling rules via environment variables.
|
|
</para>
|
|
<para>
|
|
E.g. this would launch ModemManager with the Strict filter policy but with all
|
|
net and cdc-wdm ports forbidden completely:
|
|
<programlisting>
|
|
# MM_FILTER_RULE_NET=0 \
|
|
MM_FILTER_RULE_USBMISC=0 \
|
|
/usr/sbin/ModemManager --filter-policy=STRICT</programlisting>
|
|
</para>
|
|
<para>
|
|
E.g. this would launch ModemManager with the Whitelist-only filter policy but also
|
|
explicitly allowing all net and cdc-wdm ports. Note that in this case, all virtual
|
|
net ports (e.g. 'lo') are also being allowed.
|
|
<programlisting>
|
|
# MM_FILTER_RULE_NET=1 \
|
|
MM_FILTER_RULE_USBMISC=1 \
|
|
/usr/sbin/ModemManager --filter-policy=WHITELIST-ONLY</programlisting>
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-modem-port-probing">
|
|
<title>Port probing</title>
|
|
<para>
|
|
Whenever a new device is detected by ModemManager, port probing process will
|
|
get started, so that we can determine which kind of ports we have, and also
|
|
which plugin we need to use for the specific device. Devices may expose one or
|
|
more ports, and all of them will follow the same probing logic.
|
|
</para>
|
|
<para>
|
|
The whole probing process, including pre-probing and post-probing filters, is
|
|
implemented in the core ModemManager daemon. Plugins will just configure their
|
|
own special needs in the probing process, so that only the steps required by the
|
|
given plugin are executed. For example, plugins which do not support RS232
|
|
devices will not need AT-based vendor or product filters.
|
|
</para>
|
|
|
|
<section>
|
|
<title>Pre-probing filters</title>
|
|
<para>
|
|
Pre-probing filters are those which control whether the probing, as
|
|
requested by the specific plugin, takes place.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Allowed vendor IDs</emphasis></para>
|
|
<para>
|
|
Plugins can provide a list of udev-reported vendor IDs to be used as
|
|
pre-probing filters. If the vendor ID reported by the device via udev
|
|
is found in the list provided by the plugin, port probing will be
|
|
launched as requested by the given plugin.
|
|
</para>
|
|
<para>
|
|
This filter is specified by the <type>MM_PLUGIN_ALLOWED_VENDOR_IDS</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Product IDs</emphasis></para>
|
|
<para>
|
|
Plugins can provide a list of udev-reported pairs of vendor and product
|
|
IDs to be used as pre-probing filters.
|
|
</para>
|
|
<para>
|
|
If the vendor ID and product ID pair reported by the device via udev is
|
|
found in the list of 'allowed' pairs provided by the plugin, port probing
|
|
will be launched as requested by the given plugin. This additional filter
|
|
should be used when the plugin is expected to work only with a given
|
|
specific product of a given vendor.
|
|
</para>
|
|
<para>
|
|
If the vendor ID and product ID pair reported by the device via udev is
|
|
found in the list of 'forbidden' pairs provided by the plugin, port probing
|
|
will not be launched by this plugin. This additional filter
|
|
should be used when the plugin supports all devices of a given vendor
|
|
except for some specific ones.
|
|
</para>
|
|
<para>
|
|
These filters are specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_IDS</type>
|
|
and <type>MM_PLUGIN_FORBIDDEN_PRODUCT_IDS</type> properties in the
|
|
<structname>MMPlugin</structname> object provided by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Subsystems</emphasis></para>
|
|
<para>
|
|
Plugins can specify which subsystems they expect, so that we filter out
|
|
any port detected with a subsystem not listed by the plugin.
|
|
</para>
|
|
<para>
|
|
This filter is specified by the <type>MM_PLUGIN_ALLOWED_SUBSYSTEMS</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Drivers</emphasis></para>
|
|
<para>
|
|
Plugins can specify which drivers they expect, so that we filter out
|
|
any port detected being managed by a driver not listed by the plugin.
|
|
</para>
|
|
<para>
|
|
Plugins can also specify which drivers they do not expect, so that we
|
|
filter out any port detected being managed by a driver listed by the plugin.
|
|
</para>
|
|
<para>
|
|
These filters are specified by the <type>MM_PLUGIN_ALLOWED_DRIVERS</type>
|
|
and <type>MM_PLUGIN_FORBIDDEN_DRIVERS</type> properties in the
|
|
<structname>MMPlugin</structname> object provided by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>udev tags</emphasis></para>
|
|
<para>
|
|
Plugins can provide a list of udev tags, so that we filter out
|
|
any port detected which doesn't expose any of the given tags.
|
|
</para>
|
|
<para>
|
|
This filter is specified by the <type>MM_PLUGIN_ALLOWED_UDEV_TAGS</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Probing sequence</title>
|
|
<para>
|
|
Whenever all pre-probing filters of a given plugin pass, ModemManager will run
|
|
the probing sequence as requested by the specific plugin. The main purpose of the
|
|
probing sequence step is to determine the type of port being probed, and also
|
|
prepare the information required in any expected post-probing filter.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Custom initialization</emphasis></para>
|
|
<para>
|
|
This property allows plugins to provide an asynchronous method which will get
|
|
executed as soon as the AT port gets opened. This method may be used for any
|
|
purpose, like running an early command in the ports as soon as possible, or
|
|
querying the modem for info about the port layout.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_CUSTOM_INIT</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>AT allowed</emphasis></para>
|
|
<para>
|
|
This boolean property allows plugins to specify that they expect and support
|
|
AT serial ports.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_ALLOWED_AT</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Single AT expected</emphasis></para>
|
|
<para>
|
|
This boolean property allows plugins to specify that they only expect and support
|
|
one AT serial port. Whenever the first AT port is grabbed, any remaining AT probing
|
|
in ports of the same device will get cancelled.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_ALLOWED_SINGLE_AT</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Custom AT probing</emphasis></para>
|
|
<para>
|
|
This property allows plugins to specify custom commands to check whether a port
|
|
is AT or not. By default, the 'AT' command will be used if no custom one specified.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_CUSTOM_AT_PROBE</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>QCDM allowed</emphasis></para>
|
|
<para>
|
|
This boolean property allows plugins to specify that they expect and support
|
|
QCDM serial ports.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_ALLOWED_QCDM</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Check Icera support</emphasis></para>
|
|
<para>
|
|
This boolean property allows plugins to specify that they want to have the Icera
|
|
support checks included in the probing sequence. They can afterwards get the result
|
|
of the support check to decide whether they want to create a Icera-based modem
|
|
object or not.
|
|
</para>
|
|
<para>
|
|
This configuration is specified by the <type>MM_PLUGIN_ICERA_PROBE</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Post-probing filters</title>
|
|
<para>
|
|
Post-probing filters are required to identify whether a plugin can handle a given
|
|
modem, in special cases where the information retrieved from udev is either not
|
|
enough or wrong. This covers, for example, RS232 modems connected through a RS232
|
|
to USB converter, where udev-reported vendor ID is that of the converter, not the
|
|
one of the modem.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Allowed vendor strings</emphasis></para>
|
|
<para>
|
|
Plugins can provide a list of vendor strings to be used as post-probing
|
|
filters. If the vendor string reported by the device via AT commands
|
|
is found in the list provided by the plugin, the plugin will report that
|
|
it can handle this modem.
|
|
</para>
|
|
<para>
|
|
This filter is specified by the <type>MM_PLUGIN_ALLOWED_VENDOR_STRINGS</type>
|
|
property in the <structname>MMPlugin</structname> object provided
|
|
by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Product strings</emphasis></para>
|
|
<para>
|
|
Plugins can provide a list of pairs of vendor and product
|
|
strings to be used as post-probing filters.
|
|
</para>
|
|
<para>
|
|
If the vendor and product string pair reported by the device via AT
|
|
commands is found in the 'allowed' list provided by the plugin, the
|
|
plugin will report that it can handle this modem. This additional filter
|
|
should be used when the plugin is expected to work only with a given
|
|
specific product of a given vendor.
|
|
</para>
|
|
<para>
|
|
If the vendor and product string pair reported by the device via AT
|
|
commands is found in the 'forbidden list provided by the plugin, the
|
|
plugin will report that it cannot handle this modem. This additional filter
|
|
should be used when the plugin supports all devices of a given vendor, except for some specific ones.
|
|
</para>
|
|
<para>
|
|
These filters are specified by the <type>MM_PLUGIN_ALLOWED_PRODUCT_STRINGS</type>
|
|
and <type>MM_PLUGIN_FORBIDDEN_PRODUCT_STRINGS</type> properties in the
|
|
<structname>MMPlugin</structname> object provided by the plugin.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Icera support</emphasis></para>
|
|
<para>
|
|
Plugins can specify that they only support Icera-based modems, or that they
|
|
do not support any Icera-based modem. When either of this configurations is
|
|
enabled, the Icera support checks will be included in the
|
|
probing sequence, and the result of the check will help to determine whether
|
|
the plugin supports the modem or not.
|
|
</para>
|
|
<para>
|
|
This filter is specified by the <type>MM_PLUGIN_ALLOWED_ICERA</type> and
|
|
<type>MM_PLUGIN_FORBIDDEN_ICERA</type> properties in the
|
|
<structname>MMPlugin</structname> object provided by the plugin.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<note>
|
|
<para>
|
|
Plugins which require post-probing filters will always be sorted last, and
|
|
therefore they will be the last ones being checked for pre-probing filters. This
|
|
is due to the fact that we need to assume that these plugins aren't able to
|
|
determine port support just with pre-probing filters, as we want to avoid
|
|
unnecessary probing sequences launched. Also note that the Generic plugin is
|
|
anyway always the last one in the list.
|
|
</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Probing setup examples</title>
|
|
<example>
|
|
<title>Probing setup for a plugin requiring udev-based vendor/product checks</title>
|
|
<programlisting>
|
|
G_MODULE_EXPORT MMPlugin *
|
|
mm_plugin_create (void)
|
|
{
|
|
static const gchar *subsystems[] = { "tty", NULL };
|
|
static const guint16 vendor_ids[] = { 0xabcd, 0 };
|
|
static const mm_uint16_pair product_ids[] = {
|
|
{ 0x1234, 0xffff }
|
|
};
|
|
static const gchar *vendor_strings[] = { "vendor", NULL };
|
|
|
|
return MM_PLUGIN (
|
|
g_object_new (MM_TYPE_PLUGIN_IRIDIUM,
|
|
MM_PLUGIN_NAME, "Example",
|
|
|
|
/* Next items are pre-probing filters */
|
|
MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
|
|
MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
|
|
MM_PLUGIN_ALLOWED_PRODUCT_IDS, product_ids,
|
|
|
|
/* Next items are probing sequence setup */
|
|
MM_PLUGIN_ALLOWED_AT, TRUE,
|
|
|
|
/* No post-probing filters */
|
|
NULL));
|
|
}
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Probing setup for a plugin requiring AT-probed vendor/product checks</title>
|
|
<programlisting>
|
|
G_MODULE_EXPORT MMPlugin *
|
|
mm_plugin_create (void)
|
|
{
|
|
static const gchar *subsystems[] = { "tty", NULL };
|
|
static const gchar *vendor_strings[] = { "vendor", NULL };
|
|
static const mm_str_pair product_strings[] = { "another-vendor", "product xyz" };
|
|
|
|
return MM_PLUGIN (
|
|
g_object_new (MM_TYPE_PLUGIN_IRIDIUM,
|
|
MM_PLUGIN_NAME, "Example",
|
|
|
|
/* Next items are pre-probing filters */
|
|
MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
|
|
|
|
/* Next items are probing sequence setup */
|
|
MM_PLUGIN_ALLOWED_AT, TRUE,
|
|
|
|
/* Next items are post-probing filters */
|
|
MM_PLUGIN_VENDOR_STRINGS, vendor_strings,
|
|
MM_PLUGIN_PRODUCT_STRINGS, product_strings,
|
|
NULL));
|
|
}
|
|
</programlisting>
|
|
</example>
|
|
|
|
<example>
|
|
<title>Probing setup for a plugin with custom initialization requirements</title>
|
|
<programlisting>
|
|
static gboolean
|
|
parse_custom_at (const gchar *response,
|
|
const GError *error,
|
|
GValue *result,
|
|
GError **result_error)
|
|
{
|
|
if (error) {
|
|
*result_error = g_error_copy (error);
|
|
return FALSE;
|
|
}
|
|
|
|
/* Otherwise, done. And also report that it's an AT port. */
|
|
g_value_init (result, G_TYPE_BOOLEAN);
|
|
g_value_set_boolean (result, TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
static const MMPortProbeAtCommand custom_at_probe[] = {
|
|
{ "AT+SOMETHING", parse_custom_at },
|
|
{ NULL }
|
|
};
|
|
|
|
G_MODULE_EXPORT MMPlugin *
|
|
mm_plugin_create (void)
|
|
{
|
|
static const gchar *subsystems[] = { "tty", NULL };
|
|
static const guint16 vendor_ids[] = { 0xabcd, 0 };
|
|
|
|
return MM_PLUGIN (
|
|
g_object_new (MM_TYPE_PLUGIN_EXAMPLE,
|
|
MM_PLUGIN_NAME, "Example",
|
|
|
|
/* Next items are pre-probing filters */
|
|
MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems,
|
|
MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids,
|
|
|
|
/* Next items are probing sequence setup */
|
|
MM_PLUGIN_CUSTOM_AT_PROBE, custom_at_probe,
|
|
MM_PLUGIN_ALLOWED_AT, TRUE,
|
|
|
|
/* No post-probing filters */
|
|
NULL));
|
|
}
|
|
</programlisting>
|
|
</example>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-modem-object-creation">
|
|
<title>Modem object creation</title>
|
|
<para>
|
|
Once a port passes all probing filters of a given plugin, the plugin will grab
|
|
the port. When the first port of a given device is grabbed, the plugin will create
|
|
the required Modem object.
|
|
</para>
|
|
<para>
|
|
While preparing to get the Modem object grab the specific port probed, udev-based
|
|
port type hints can be used to specify AT port flags (e.g. if a port is to be
|
|
considered primary, secondary or for PPP).
|
|
</para>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-modem-state-machine">
|
|
<title>Modem state machine</title>
|
|
<para>
|
|
Once all ports of a given modem have been probed and grabbed by a newly created
|
|
Modem object, ModemManager will start the global state machine for the modem, as
|
|
defined in the picture below.
|
|
</para>
|
|
<figure id="mm-modemmanager-states">
|
|
<title>ModemManager states</title>
|
|
<graphic fileref="ModemManager-states.png" format="PNG"></graphic>
|
|
</figure>
|
|
<para>
|
|
The state machine of a modem can be summarized in 5 main sequences:
|
|
initialization, enabling, connection, disconnection and disabling.
|
|
</para>
|
|
|
|
<section>
|
|
<title>Initialization</title>
|
|
<para>
|
|
The modem initialization sequence starts only when all ports
|
|
have been probed and grabbed by a given plugin. This is done so that the proper
|
|
AT port (that suggested to be Primary) is used as control port.
|
|
</para>
|
|
<para>
|
|
The global initialization sequence is itself splitted into N per-interface
|
|
initialization steps (being N the number of interfaces implemented by the
|
|
modem object). The following list provides the steps required in the
|
|
initialization sequence of a Broadband modem object.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Modem interface initialization</emphasis></para>
|
|
<para>
|
|
The <link linkend="gdbus-org.freedesktop.ModemManager1.Modem">Modem interface</link>
|
|
provides common actions and information available in the majority of the modems
|
|
(including Broadband-specific items which won't be implemented by POTS modems).
|
|
</para>
|
|
<para>
|
|
One of the key things done during the initialization of this interface is the
|
|
<emphasis>checking of supported capabilities</emphasis>. Broadband modem objects
|
|
are able to handle 3GPP-only, CDMA-only and mixed 3GPP+CDMA modems, but in order
|
|
to properly handle the distinctions required in these, ModemManager first needs
|
|
to know exactly which is the current set of capabilities.
|
|
</para>
|
|
<para>
|
|
The other key step in this sequence involves <emphasis>checking the lock status
|
|
of the modem and/or SIM </emphasis>. If the modem/SIM is found to be locked, the
|
|
whole initialization sequence is halted and the modem is left in a locked state
|
|
until unlocked by the user. Note, therefore, that modems that are locked will not
|
|
expose additional feature-specific DBus interfaces until they get unlocked.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
It may be the case that some of the steps in the initialization of the Modem
|
|
interface require the modem itself to be unlocked. If the modem is found locked
|
|
during the first initialization attempt, as soon as it gets unlocked the
|
|
initialization sequence will be re-executed.
|
|
</para>
|
|
</note>
|
|
</listitem>
|
|
<listitem>
|
|
<emphasis>3GPP interface initialization</emphasis>
|
|
<para>
|
|
The <link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Modem3gpp">3GPP interface</link>
|
|
provides common actions and setup for modems which provide 3GPP capabilities. Therefore,
|
|
this interface initialization sequence will only be run in 3GPP-enabled modems.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<emphasis>CDMA interface initialization</emphasis>
|
|
<para>
|
|
The <link linkend="gdbus-org.freedesktop.ModemManager1.Modem.ModemCdma">CDMA interface</link>
|
|
provides common actions and setup for modems which provide CDMA capabilities. Therefore,
|
|
this interface initialization sequence will only be run in CDMA-enabled modems.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Additional feature-specific interface initializations</emphasis></para>
|
|
<para>
|
|
Modems with additional features will export feature-specific interfaces, such as
|
|
the <link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Location">Location</link> or
|
|
the <link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Messaging">Messaging</link>
|
|
ones.
|
|
</para>
|
|
<para>
|
|
These interfaces also have their own initialization sequences, where the first step
|
|
in the sequence is always the check of whether the given modem supports the given feature.
|
|
In other words, modems will only end up exporting the interfaces for the features they
|
|
support.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Enabling</title>
|
|
<para>
|
|
Modem enabling is the user-requested sequence with the sole purpose of bringing
|
|
the modem to a state where it can get connected.
|
|
</para>
|
|
<para>
|
|
As with the initialization sequence, the global enabling sequence is itself
|
|
splitted into N per-interface enabling steps (being N the number of interfaces
|
|
exported by the modem). Those interfaces implemented by the object but not
|
|
supported by the modem will not be enabled.
|
|
</para>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Modem interface enabling</emphasis></para>
|
|
<para>
|
|
The sequence to enable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem">Modem interface</link>
|
|
takes care of different important steps, such as <emphasis>powering up the
|
|
radio interface</emphasis> or <emphasis>configuring</emphasis> the best charset
|
|
to use.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>3GPP interface enabling</emphasis></para>
|
|
<para>
|
|
Modems with 3GPP capabilities will enable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Modem3gpp">3GPP interface</link>
|
|
as part of the global enabling sequence. This sequence involves setting up the
|
|
<emphasis>automatic registration</emphasis> of the device in the network, as well
|
|
as configuring 3GPP specific <emphasis>indicators and unsolicited message
|
|
handlers</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>CDMA interface enabling</emphasis></para>
|
|
<para>
|
|
Modems with CDMA capabilities will enable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.ModemCdma">CDMA interface</link>
|
|
as part of the global enabling sequence. This sequence involves setting up the
|
|
<emphasis>periodic checks of registration</emphasis> in the CDMA network.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Additional feature-specific interface enablings</emphasis></para>
|
|
<para>
|
|
Each feature-specific interface will have its own enabling sequence, with operations
|
|
which are directly related to the purpose of the interface. For example, enabling the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Location">Location</link>
|
|
interface will involve setting up the initial location information; and enabling the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Messaging">Messaging</link>
|
|
interface will involve loading the initial list of SMS available in the SIM or Modem.
|
|
</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Connection & disconnection</title>
|
|
<para>
|
|
Connecting the Modem is done through the <emphasis>Bearer</emphasis> objects. Once such an
|
|
object is created, the user can request to get the given bearer connected.
|
|
</para>
|
|
<para>
|
|
Broadband Modems will usually create Broadband Bearers. This kind of bearers can run either
|
|
the CDMA connection sequence (if the modem has CDMA capabilities) or the 3GPP connection
|
|
sequence (if the modem has 3GPP capabilities). For the special case of mixed 3GPP+CDMA
|
|
modems, it is assumed that the plugin implementation needs to decide how the connection gets
|
|
done. By default, anyway, the 3GPP sequence is used in this case.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Modems which are both LTE (3GPP) and CDMA can hand over from LTE to CDMA transparently and
|
|
automatically when no LTE network is available, even keeping the same IP address. When this
|
|
happens, the modem will get notified about the access technology change, and ModemManager
|
|
will update that information.
|
|
</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Disabling</title>
|
|
<para>
|
|
Users can disable the modems, which will bring them to a state where they are in low power
|
|
mode (e.g. RF switched off) and not registered in any network.
|
|
</para>
|
|
<para>
|
|
As with the initialization or enabling sequences, the global disabling sequence is itself
|
|
splitted into N per-interface disabling steps (being N the number of interfaces
|
|
exported by the modem). Those interfaces implemented by the object but not
|
|
supported by the modem will not be disabled.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
The global disabling sequence will go on disabling the interfaces one by one, but
|
|
starting with the interface which was last enabled during the enabling sequence, and
|
|
backwards. This ensures that the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem">Modem interface</link>
|
|
gets disabled last.
|
|
</para>
|
|
</note>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para><emphasis>Additional feature-specific interface disablings</emphasis></para>
|
|
<para>
|
|
Each feature-specific interface will have its own disabling sequence, with operations
|
|
which are directly related to the purpose of the interface. For example, disabling the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Location">Location</link>
|
|
interface will involve shutting down the location gathering; and disabling the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Messaging">Messaging</link>
|
|
interface will involve unexporting all SMS objects from DBus.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>CDMA interface disabling</emphasis></para>
|
|
<para>
|
|
Modems with CDMA capabilities will disable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.ModemCdma">CDMA interface</link>
|
|
as part of the global disabling sequence. This sequence involves cancelling the
|
|
<emphasis>periodic checks of registration</emphasis> in the CDMA network.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>3GPP interface disabling</emphasis></para>
|
|
<para>
|
|
Modems with 3GPP capabilities will disable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem.Modem3gpp">3GPP interface</link>
|
|
as part of the global disabling sequence. This sequence involves, among other things,
|
|
cleaning up 3GPP specific <emphasis>indicators and unsolicited message handlers</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para><emphasis>Modem interface disabling</emphasis></para>
|
|
<para>
|
|
The sequence to disable the
|
|
<link linkend="gdbus-org.freedesktop.ModemManager1.Modem">Modem interface</link>
|
|
takes care of different important steps, such as <emphasis>powering down the
|
|
radio interface</emphasis>.
|
|
</para>
|
|
</listitem>
|
|
|
|
</itemizedlist>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="ref-overview-plugin-specific-modems">
|
|
<title>Plugin-specific Modems</title>
|
|
<para>
|
|
ModemManager plugins exist in order to handle all non-standard vendor-specific behaviour
|
|
that needs to get supported.
|
|
</para>
|
|
<para>
|
|
Plugins will provide their own Modem object implementations, usually subclassing the
|
|
generic <structname>MMBroadbandModem</structname> object. As previously explained, this
|
|
object implements every interface that may be exported by the Modem object in DBus; and
|
|
then, depending on the per-interface support checks, the interface will end up being
|
|
really exported or not.
|
|
</para>
|
|
<para>
|
|
Each interface defines every step to be run during the initialization, enabling or
|
|
disabling sequences. Then, the object implementing the interface may or may not provide
|
|
the implementation of such step. By default, the generic
|
|
<structname>MMBroadbandModem</structname> object implements already most of the steps
|
|
in the interfaces providing common features:
|
|
</para>
|
|
<figure id="mm-modemmanager-interface-initialization-sequence">
|
|
<title>Modem interface initialization sequence</title>
|
|
<graphic fileref="ModemManager-interface-initialization-sequence.png" format="PNG"></graphic>
|
|
</figure>
|
|
<para>
|
|
Vendor-specific subclasses of <structname>MMBroadbandModem</structname> are then able to
|
|
either provide their own implementation of a given step (in the image below, a custom
|
|
implementation for capabilities checking); or even completely disable the step if they
|
|
know that there is no way to run it (in the image below, revision string loading is
|
|
removed).
|
|
</para>
|
|
<figure id="mm-modemmanager-interface-initialization-sequence-subclassed">
|
|
<title>Modem interface initialization sequence subclassed</title>
|
|
<graphic fileref="ModemManager-interface-initialization-sequence-subclassed.png" format="PNG"></graphic>
|
|
</figure>
|
|
<para>
|
|
These subclass-able steps are all implemented as standard GIO asynchronous functions,
|
|
so subclassing a step involves implementing both the async method which receives the
|
|
input arguments to the action and the corresponding <literal>_finish()</literal> method
|
|
which provides the results of the action once the operation is ready.
|
|
</para>
|
|
<para>
|
|
It is worth noting that these steps and the asynchronous methods implementing them
|
|
don't assume that an AT port will be used to implement the real action. This means
|
|
that any other kind of port may be really used (e.g. QCDM or QMI) in the implementation,
|
|
or even that a static reply can be returned (e.g. Iridium modems will always report
|
|
"Iridium" as current OperatorName).
|
|
</para>
|
|
</chapter>
|
|
</part>
|