A default implementation to monitor the ongoing connection is provided in the
generic MMBroadbandModem, based on AT+CGACT? to check whether the PDP context
of the connection (identified by the cached cid) is active or not.
This commit also disables the connection monitoring logic in those plugins that
have custom connection methods.
Split into two different actions the actual COPS? response parsing and the
operator name normalization process.
Also, allow parsing not only the operator string, but also the format, mode
and the optional access technology value.
We need at least ID_USB_INTERFACE_NUM, as some plugins (Huawei, Telit, Option)
require this property when gathering port type hints.
We also add support for other properties (ID_VENDOR_ID, ID_MODEL_ID...) as we
already have those values preloaded.
Instead of relying on the udev daemon and GUDev to manage the devices reported
by the kernel, we can now run ModemManager relying solely on the kernel events
reported via the new ReportKernelEvent() API. Therefore, the '--no-auto-scan'
option is implicit for the ModemManager daemon when udev is disabled in the
build.
Additionally, a new custom implementation of the kernel device object is
provided, which uses sysfs to load the properties and attributes required in
each kernel device, instead of using a GUdevDevice.
The udev rule files are kept in place, and a simple custom parser is provided
which preloads all rules in memory once and then applies them to the different
kernel objects reported via ReportKernelEvent(), e.g. to set port type hints.
A simple unit test setup is prepared to validate the udev rules during the
`check' Makefile target.
The mm_base_modem_grab_port() now receives a MMKernelDevice directly from the
plugin, which is then stored in the MMPort corresponding to the port.
This means that we have direct access to e.g. all properties set by udev rules
everywhere, and we don't need additional GUdevClient objects (e.g. like the one
used in the Huawei plugin to detect NDISDUP support during runtime).
For virtual ports (e.g. generated during unit tests), we have a new 'generic'
kernel device object which just provides the values from the kernel device
properties given during its creation.
This commit enables a new core ModemManager daemon option, so that automatic
detection of available modems is totally disabled: '--no-auto-scan'. Note that
this option also replaces the previously used '--test-no-auto-scan' option,
which was only used during tests.
Along with the new ModemManager option, a new ReportKernelEvent() method in
the API is defined, which allows notifying the daemon of which interfaces it
should be accessing, as well as the main details of each interface. The only
mandatory parameters in the new method are 'action' (add/remove), 'name' (the
name of the interface) and 'subsystem' (the subsystem of the interface).
The mmcli tool has support for using the new api method via several new options:
* The '--report-kernel-event' option allows specifying device ports one by
one, and is a direct mapping of the ReportKernelEvent() method:
$ sudo mmcli --report-kernel-event="action=add,name=wwan0,subsystem=net"
$ sudo mmcli --report-kernel-event="action=add,name=cdc-wdm0,subsystem=usbmisc"
* The '--report-kernel-event-auto-scan' option uses udev monitoring to notify
events automatically to the daemon. This allows to operate in a way
equivalent to the default daemon operation (with implicit auto-scan).
Worth noting that the ReportKernelEvent() method is only usable when
'--no-auto-scan' is explicitly used in the daemon. An error will be reported if
the method is tried while standard udev monitoring is enabled (implicit if
auto scan isn't explicitly disabled in the daemon).
If mmcli is going to be used only to report 'real time' events, an optional
'--initial-kernel-events=[PATH]' may be given in the ModemManager call to
automatically process a set of port kernel events one by one on boot. The file
may e.g. contain:
action=add,name=wwan0,subsystem=net
action=add,name=cdc-wdm0,subsystem=usbmisc
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 adds another Infineon flashloader device 0x8087/0x0801
to the blacklist
Reference to the kernel commit:
github.com/torvalds/linux/commit/f190fd92458da3e869b4e2c6289e2c617490ae53
Implement the detailed signal info interface for some Huawei 3GPP modems
including those based on HiSilicon chipsets like the E3276. Known not to
work on many Qualcomm-based Huawei modems like E392, E397, and E367 as
they don't support the ^HCSQ command, but they do support QMI and so
have access to the extended signal interface via QMI.
BaseModem
added reprobe property.
MMDevice
added logic to recreate the modem if it is set invalid and "to reprobe"
MMBroadbandModem
* added initialization step for SIM hot swap:
1. keep dedicated ports open to listen to modem's unsolicited
2. dedicated error management in case of initialization failure due to SIM missing
* added function to be called in order to act upon SIM insertion/removal:
1. close dedicated ports
2. set the modem to be reprobed
3. disable modem
* added SIM HOT SWAP boolean property
MMIfaceModem
* added initialization step for SIM hot swap, if supported by the plugin
* dedicated error management in case of initialization failure due to SIM missing
When a CDMA-only modem is registered with the EVDO network, its not possible to
read signal strength in the following cases:
1) while a data connection is active on single-AT-port modems, because the AT
port is used for PPP and not available for AT+CSQ, AT+CIND or vendor-specific
signal strength commands
2) when the modem reports only CDMA 1x signal strength with AT+CSQ
Now that we have a reasonable interpretation of RSSI from the QCDM
EVDO Pilot Sets V2 log messgae, use that when other means of getting
signal strength aren't available.
Inverted steps UPDATE_LOCK_INFO_CONTEXT_STEP_RETRIES and
UPDATE_LOCK_INFO_CONTEXT_STEP_AFTER_UNLOCK.
Soon after the unlock, the SIM can be busy and
loading unlock retries might fail.
When implemented, let run "after unlock" logic before any other step in
update lock info, when SIM is not locked this change does not have any
effect since "after unlock" is not executed.
The mm_iface_modem_is_*_only() checks were validating that all the other
capabilities except for the ones being queried were unset, but the check wasn't
explicitly checking that the actual capabilities being queried were set.
This was making the check fail when capabilities == MM_MODEM_CAPABILITY_NONE.
Reported-by: Matthew Stanger <stangerm2@gmail.com>
Deciding the IP method to use based on the underlying QMI port LLP should not be
done when the bearer object is created, because the QMI port in use may not
actually be open or have been opened at that time. During the connection attempt
we do make sure the QMI port is open, so we should check the LLP to use just
after that step.
When the logic decided that we had to update the kernel data format to match the
one configured in the WWAN network interface, we were not flagging the port LLP
with the correct value, what resulted in NetworkManager trying to use dhclient
on the raw-ip interface:
dhclient[3257]: Unsupported device type 65534 for "wwan1"
dhclient[3257]:
dhclient[3257]: If you think you have received this message due to a bug rather
dhclient[3257]: than a configuration issue please read the section on submitting
dhclient[3257]: bugs on either our web page at www.isc.org or in the README file
dhclient[3257]: before submitting a bug. These pages explain the proper
dhclient[3257]: process and the information we find helpful for debugging..
dhclient[3257]:
dhclient[3257]: exiting.
Fix the internal LLP flag, so that Static IP addressing is requested for all raw-ip
based interfaces.
MM never passes MBIM_CONTEXT_IP_TYPE_DEFAULT which would require paying
attention to the ip_type in the reply to figure out what type the modem
activated. Instead, MM always specifies the ip_type it wants to activate,
and some modems (K5160) return a different type in the response. The modem
is required to activate the type MM asks for or return an error, so if
the activation was successful we can safely assume the modem activated
the ip_type we want, and we can ignore the ip_type in the response.
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.
v4: modems/providers may not return DNS servers and not all modems
support DHCP, so lack of DNS servers should not indicate a bearer
IP method of "DHCP". IP config daemon/scripts already have to handle
missing DNS anyway.
v6: IPv6 requires SLAAC or DHCPv6 as part of the specification, so for
now we assume modems will support it. Provide all the info the modem
sent, but if there is any missing information use an IP method of
"DHCP" to indicate that info should be obtained via SLAAC/DHCPv6. Only
use an IP method of "STATIC" when all basic properties are given by
the modem.
When we were completing tasks in idle, the logic was like this:
* Schedule task completion in idle
* self->priv->task = NULL
* (idle) Task completion callback called
This meant that the self->priv->task was always set to NULL before the
completion callback was called, which is what we wanted as a new task may be
scheduled in the callback itself.
Now, without completing in idle, we were wrongly doing:
* Task completion callback called
* self->priv->task = NULL
This commit fixes the logic by making sure self->priv->task = NULL before any
task completion.
The options that require an argument should explicitly specify so.
Before:
--log-level=INFO Log level: one of [ERR, WARN, INFO, DEBUG]
--log-file Path to log file
After:
--log-level=[LEVEL] Log level: one of ERR, WARN, INFO, DEBUG
--log-file=[PATH] Path to log file