Instead of relying constantly on GUdevDevice objects reported by GUdev, we now
use a new generic object (MMKernelDevice) for which we provide an initial GUdev
based backend.
All ports of the same modem reported by the kernel will all be associated with
a common 'uid' (unique id), which uniquely identifies the physical device. This
logic was already in place, what we do now is avoid calling it the 'sysfs
path' of the physical device, because we may not want to use that to identify
a device.
This logic now also enables the possibility of "naming" the modems in a unique
way by setting the "ID_MM_PHYSDEV_UID" property in the "usb_device" that owns
all the ports.
E.g. a custom device has 4 modems in 4 different USB ports. The device path of
each USB device will always be the same, so the naming rules could go like this:
$ vim /usr/lib/udev/rules.d/78-mm-naming.rules
ACTION!="add|change|move", GOTO="mm_naming_rules_end"
DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.1", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-1"
DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.2", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-2"
DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.3", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-3"
DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.4", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-4"
LABEL="mm_naming_rules_end"
Each of the modems found will have a unique UID retrieved from the previous list
of rules. Then, "mmcli" has also been updated to allow using the UID instead of
the modem DBus path or index, e.g.:
$ sudo mmcli -m USB-MODEM-1
/org/freedesktop/ModemManager1/Modem/0 (device id '988d83252c0598f670c2d69d5f41e077204a92fd')
-------------------------
Hardware | manufacturer: 'ZTE CORPORATION'
| model: 'MF637'
| revision: 'BD_W7P673A3F3V1.0.0B04'
| supported: 'gsm-umts'
| current: 'gsm-umts'
| equipment id: '356516027657837'
-------------------------
System | device: 'USB-MODEM-1'
| drivers: 'option'
| plugin: 'ZTE'
| primary port: 'ttyUSB5'
| ports: 'ttyUSB5 (at)'
...
$ sudo mmcli -m USB-MODEM-1 --enable
...
This patch makes declarations bind to definitions within the same module
to prevent the potential ambiguity if referenced directly.
AddressSanitizer think they violated one definition rule, although
those symbols are accessed by address through their modules and do
not depend on the order of the libararies loaded.
Plugins which may support QMI ports need to explicitly request QMI probing
in cdc-wdm devices. This should also avoid probing cdc-wdm ports when we know
that the plugin doesn't support them (e.g. with Ericsson MBM devices).
https://bugzilla.gnome.org/show_bug.cgi?id=696701
For each port, we will construct the list of plugins to test with. In that list
we will include those plugins which are likely to handle a given port, so we
will skip all those which aren't.
To see if a plugin is likely or not, we will run the pre-probing filters before
adding them to the list, with the new `mm_plugin_discard_port_early()'. This
method will return one of these hints:
* UNSUPPORTED: The plugin will not be able to handle this port.
* MAYBE: The plugin may handle this port.
* LIKELY: The plugin may (very likely) handle this port.
* SUPPORTED: If any plugin should support the port, this is it.
Plugins reported to be 'likely' supporting the port will be probed before the
ones reported just as 'maybe'.
If a plugin reports 'supported' only that one and the fallback generic ones will
be tried.
This is the port to git master of the following patch:
commit 21e66dfa1774ac2ee037ac8b6e8bb4d71a6f7931
Author: Dan Williams <dcbw@redhat.com>
Date: Thu Aug 23 21:13:35 2012 -0500
core: add function to open probe ports without removing echo
Some devices (Sierra GSM ones) return stuff we need but don't
bother to prefix it with <CR><LF>, so we need to optionally turn
off the echo removal at probe time.
Different ports of the same modem may get handled by different drivers. We
therefore need to provide a list of drivers (new `Modem.Drivers' property with
signature 'as') instead of just one (removed `Modem.Driver' property with
signature 's').
$ sudo mmcli -m 0 | grep drivers
| drivers: 'qcserial, qmi_wwan'
Plugins may specify that specific vendor & product IDs or strings are not
supported. This is useful when plugins need to specify that they support
all devices of a given vendor except for some specific ones.
Instead of providing a method to get if a plugin is requesting to get sorted
last, we provide a way to comparing two plugins, compatible with the
GCompareFunc required in g_list_sort().
There's no real point in maintaining a separate `MMPlugin' interface, as all the
plugins will inherit from `MMPluginBase', so just merge them and simplify
everything.
Before this, we only exported the modem to DBus when all ports were organized,
in order to make sure that we select as primary port the one we really want and
not the first AT port grabbed. Given that to get all the ports organized we also
needed to wait to get all the ports grabbed, we can now also defer the creation
of the modem object until all the ports get grabbed. This allows us to create
different types of objects based on the ports available (e.g. we can now create
QMI-supported modem objects if we see a QMI port around).
The PluginBase object got modified during the new codebase development, and
therefore we need to ensure that the current codebase doesn't try to load old
plugins.
We chain up the Generic plugin created MMBroadbandModem objects within the
GDBusObjectManagerServer in MMManager, so that they get properly exported in
DBus.
Support checks are fully asynchronous and result is always reported when the
check is considered ready, so in-progress replies to
`mm_plugin_supports_port_finish()' don't make any sense.
There is no single case where more than one plugin may end up wanting to support
a given port, and therefore there is no need to report the numeric support level
when reporting SUPPORTED.
We now have 'supports_port' (async method) and 'supports_port_finish' (to get
the result of the async method), so it makes sense to rename the method to
'supports_port_cancel'.
Before this change, supports check was either synchronous (e.g. in some
UNSUPPORTED cases) or asynchronous (when IN_PROGRESS was returned).
With this fix, the supports check requested to the plugin will always be
completed asynchronously; either directly in an idle before launching any real
probing operation, or once the probing operation is finished.
Therefore, it is not expected to get a IN_PROGRESS reply in
mm_plugin_supports_port_finish(), only UNSUPPORTED|SUPPORTED|DEFERRED.
Note that even if a plugin says it wants to be sorted last, the generic plugin
will always be the last one. Also, there is no order guaranteed between two
plugins that request to be sorted last.
Allow plugins to perform asynchronous port detection, and to defer port detection
until later. This moves the prober bits into MMPluginBase so that all plugins
can take adavantage of it only when needed; the probing is not done at udev time.
Furthermore, plugins like Novatel can flip the secondary ports over the AT mode
through deferred detection, by deferring the secondary ports until the main port
has been detected and AT$NWDMAT has been sent.
This commit also finishes the port of the rest of the plugins (except mbm) over
to the new port detection methods and plugin API.
Get rid of dependency on HAL, using libgudev instead. Fix up the plugin API
to no longer use either HAL or udev defines, but let plugins use whatever
mechanism they want for getting more information out of the device given the
subsystem and device node name.
Modems are now defined as "master" devices which "own" a one or more ports.
A port could be a serial tty device or a network device or whatever. The
plugin figures out whether it supports a given port or not and then assigns
it to a new or existing modem. Modems now have a 'valid' property that
should be set to TRUE when the modem has enough ports to operate correctly.
For devices (ex. 'hso') that use a network device for data transfer, the
modem would need to grab at least one TTY and the network device associated
with that physical device to be 'valid'.
Also move the generic modem support code to a plugin like other modem plugins,
and change the I-support-this-device mechanism to return a number indicating
the level of support. For example, the generic plugin would return a quite
low number if the device indicates via probing that it can do GSM or CDMA, but
a more specific plugin can indicate better support for the device, and thus
the more specific plugin would win control.