We used ttyACM0 as secondary port until now, just because we had an
extra AT capable TTY around in addition to the main control ttyACM2
port.
Turns out, using this ttyACM0 may actually break the connection setup
in the wwan interface in a bad way (e.g. not allowing DHCP setup).
The suggestion from u-blox and Intel is to fully ignore ttyACM0; and
given that we no longer need any primary/secondary port logic, we just
remove all the associated udev tags.
Releasing the port on the device looks benign but because it emits
a signal, it could call device_context_port_released and unref the
MMDevice in port_context_unref. This means the MMDevice might be
disposed before we get to the g_object_ref and the subsequent call
to g_hash_table_remove will try to hash a null string, which makes
MM crash.
The hashtable is keyed on the UID of the MMDevice, and its hash
function is g_str_hash. We shouldn't be passing a GObject into
g_hash_table_remove because calling g_str_hash on an MMDevice is
wrong.
MM was not updating the EPS registration status for qmi modems. This
led to LTE-only modems never having 'registered' status. This was
happening for Quectel EC21-V modem.
In mm_iface_modem_3gpp_register_in_network() when deciding whether to
force automatic registration or not, check whether the modem is already
registered in a network. Just checking whether we have a valid operator
code is not sufficient, as some modems (ublox Toby R2xx) don't always
return an operator name/code even when registered.
We should not cache the AT command response otherwise we will never
re-run the same command again. The cache is needed only for AT test
commands (e.g. AT+CESQ=?).
We don't want them to get in the way of our initialization phase:
/org/freedesktop/ModemManager1/Modem/0 (device id 'c49ed59c4a411e923307330d3e1d82582cbfac37')
-------------------------
Hardware | manufacturer: 'u-blox'
| model: 'unknown'
| revision: 'TOBY-L4906
| +PBREADY
| 40.19_ENG0003'
| H/W revision: 'unknown'
| supported: 'gsm-umts, lte'
| current: 'gsm-umts, lte'
We should only depend on GLib on the libmm-glib headers. Otherwise,
packages using just the core headers (e.g. ModemManagerQt) would also
need to build-depend on GLib and we don't want to enforce that.
cd ~/buildroot/output/build/kde-modemmanager-qt-v5.36.0/src && ~/buildroot/output/host/usr/bin/arm-cortexa9_neon-linux-gnueabihf-g++ .... -fPIC -o CMakeFiles/KF5ModemManagerQt_static.dir/bearer.cpp.o -c ~/buildroot/output/build/kde-modemmanager-qt-v5.36.0/src/bearer.cpp
In file included from ~/buildroot/output/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/include/ModemManager/ModemManager.h:41:0,
from ~/buildroot/output/build/kde-modemmanager-qt-v5.36.0/src/generictypes.h:27,
from ~/buildroot/output/build/kde-modemmanager-qt-v5.36.0/src/generictypes.cpp:23:
~/buildroot/output/host/usr/arm-buildroot-linux-gnueabihf/sysroot/usr/include/ModemManager/ModemManager-compat.h:23:18: fatal error: glib.h: No such file or directory
compilation terminated.
It may be undesirable to issue a MBIM_CID_CONNECT
(MBIMActivationCommandDeactivate) command to deactivate an IP session
when the session isn't activated. For instance, it's been observed on
Huawei ME936 that it takes more than 30s for the modem to deactivate a
not-yet-activated session. This patch modifies MMBearerMbim to query if
a session is activated before trying to deactivate the session during a
connection attempt.
Since commit 0c7f3380a ("bearer-mbim: ensure session is disconnected
before trying to connect"), MMBearerMbim always issues a
MBIM_CID_CONNECT (MBIMActivationCommandDeactivate) command before a
MBIM_CID_CONNECT (MBIMActivationCommandActivate) command during a
connection attempt. That is to ensure that an IP session is actually
deactivated before we try to activate a new IP session.
Unfortunately, it's been observed on Huawei ME936 that it takes more
than 30s for the modem to respond to a MBIM_CID_CONNECT
(MBIMActivationCommandDeactivate) command when trying to deactivate a
session that hasn't been activated.
When the signal is weak, it's also possible that a modem takes more than
30s to deactivate an IP session during a disconnection attempt.
This patch increases the timeout for deactivating an IP session from 30s
to 60s in both connection and disconnection attempt.
On Huawei ME936, the hex numbers in the response to AT^DHCP contain the 0x prefix, e.g.
AT^DHCP?
^DHCP: 0xda7d0e0a,0xff000000,0xdb7d0e0a,0xdb7d0e0a,0x01261aac,0x00000000,100000000,50000000
This patch updates mm_huawei_parse_dhcp_response() to handle the
optional 0x prefix.
The +CEMODE command is defined in 3GPP TS 27.007 (e.g. in section
10.1.28 in v11.0.0). This command allows querying or updating the
current UE mode, as well as checking the supported modes.
We implement support for loading the current mode and updating it. It
is assumed that the device does any additional operation needed by the
setting update, e.g. un-registering from CS when selecting an EPS-only
mode.
The UE modes of operation for LTE are defined in 3GPP TS 24.301 (e.g.
section 4.3 in v10.3.0):
* PS mode 1: EPS only, 'voice centric'
* PS mode 2: EPS only, 'data centric'
* CS/PS mode 1: EPS and non-EPS, 'voice centric'
* CS/PS mode 2: EPS and non-EPS, 'data centric'
The mode specifies, among other things, how the UE should behave w.r.t
CS fallback depending on the capabilities reported by the network.
When a modem is being enabled, an initial registration check is
scheduled to determine the current registration state and access
technology. The initial registration check is performed asynchronously
and may not complete before the modem state is transitioned to
'enabled'. When the modem is disabled shortly afterwards, the
registration state is transitioned to 'unknown' and the modem state is
transitioned to 'disabled'. But the completion of the initial
registration check after that can transition the registration state and
modem state to a wrong state. This patch addresses the issue by ignoring
a registration state update if the modem isn't already enabled or being
enabled.
The generic broadband modem provides a common method to load unlock
retries based on CSIM queries. We modify the Telit plugin to use the
generic method but keeping the CSIM locking/unlocking logic in place.
The AT control TTYs in the u-blox modems may take some time to be
usable. In order to handle this issue, we configured some longer
timeouts during AT probing, but that may not be always enough.
The u-blox TTYs will report readiness via a "+AT: READY" URC, which
we can use during custom initialization to decide right away that the
port is AT. We use up to 20s as that is close to the worst case seen
during experimentation, happening after the module undergoes a full
NVM reset. If the timeout is reached without receiving the URC, we
still run standard AT probing afterwards. This new logic just tries
to make it sure we don't do any probing before the module is ready to
accept it.
If the module hasn't been hotplugged (i.e. it was already there when
ModemManager started) we do a quick first AT probing and if that fails
we run the "+AT: READY" URC wait as if it was hotplugged.
If we get an error when setting up the WDS event report indications,
make sure we run connect_context_step() after having set the next step
as CONNECT_STEP_LAST.
Depsite 3GPP TS 23.038 specifies that Unicode SMS messages are encoded in
UCS-2, UTF-16 encoding is commonly used instead on many modern platforms to
allow encoding code points that fall outside the Basic Multilingual Plane
(BMP), such as Emoji. Most of the UCS-2 code points are identical to their
equivalent UTF-16 code points. In UTF-16, non-BMP code points are encoded in a
pair of surrogate code points (i.e. a high surrogate in 0xD800..0xDBFF,
followed by a low surrogate in 0xDC00..0xDFFF). An isolated surrogate code
point has no general interpretation in UTF-16, but could be a valid (though
unmapped) code point in UCS-2.
This patch modifies the 3GPP SMS decoding to first try UTF-16BE and then fall
back to UCS-2BE on failure. If both fail, an empty string is returned
instead of a NULL pointer.
When in low-power mode, some modems will not dispatch unsolicited
notifications, such as for SIM hot swapping. There is code in
MMBroadbandModemTelit to handle this by checking the SIM identifier
during modem power up against the identifier cached in the SIM
D-Bus object. If they're different, the SIM has likely been
swapped while we were powered down.
We can move this code out to MMBroadbandModem because it doesn't
actually rely on any Telit-specific details, and invoke it from
MMIfaceModem via a new method.
When using CPIN? to detect capabilities, use several possible +CME
errors as indication that the modem is at least GSM/UMTS.
E.g. to avoid situations like this one where the modem doesn't even
get into Failed state as we cannot gather capabilities:
debug_log(): (ttyMux1): --> 'AT+GCAP<CR>'
debug_log(): (ttyMux1): <-- '<CR><LF>+CME ERROR: 100<CR><LF>'
mm_serial_parser_v1_parse(): Got failure code 100: Unknown error
debug_log(): (ttyMux1): --> 'ATI<CR>'
debug_log(): (ttyMux1): <-- '<CR><LF>Cinterion<CR><LF>EHS5-E<CR><LF>REVISION 03.001<CR><LF><CR><LF>OK<CR><LF>'
debug_log(): (ttyMux1): --> 'AT+CPIN?<CR>'
debug_log(): (ttyMux1): <-- '<CR><LF>+CME ERROR: 10<CR><LF>'
mm_serial_parser_v1_parse(): Got failure code 10: SIM not inserted
debug_log(): (ttyMux1): --> 'AT+CGMM<CR>'
debug_log(): (ttyMux1): <-- '<CR><LF>EHS5-E<CR><LF>'
debug_log(): (ttyMux1): <-- '<CR><LF>OK<CR><LF>'
iface_modem_initialize_ready(): Modem couldn't be initialized: couldn't load current capabilities: Failed to determine modem capabilities.
All the previous filter rules were applicable per-port independently.
But, we also want to apply rules on a port based on the existence of
other ports on the same device (e.g. allow TTY if the device also has
a NET port). In this case, we need to wait for all ports to appear and
then apply the additional rules.
We re-use the "min wait time" timeout in the plugin-manager for this
same purpose. This timeout is setup to wait for ports to appear before
starting the probing process (e.g. so that plugin filters like the
forbidden-drivers one work). The very same timeout can therefore be
used to check whether we start the probing or not based on additional
filter rules.
The 'default' filter policy was based on blacklisting as much as
possible and otherwise allow.
The new 'strict' filter policy will be based on whitelisting as much
as much as possible, using custom defined rules, and otherwise forbid
the ports.
The new 'paranoid' filter policy is equivalent to the 'strict' filter
after having applied the blacklist rules from the 'default' filter.
Added a new '--filter-policy=[POLICY]' option in the daemon, which
allows selecting between the supported filter policies. For now, only
two policies are defined:
* default: the default policy used by ModemManager, where it tries
to probe and detect as many modem ports as possible.
* whitelist-only: only devices explicitly tagged via udev (with the
ID_MM_DEVICE_PROCESS tag) will be probed and used.
The user can tag modems (either full devices or ports independently)
to be explicitly probed by ModemManager, using the new
"ID_MM_DEVICE_PROCESS" udev tag, e.g.:
$ 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"
$ sudo udevadm control --reload
$ sudo udevadm trigger
This rule runs before any other filter rule.
This tag may be used e.g. by manufacturers building systems with
built-in modems that will always be available.
Distributions targeting support for multiple modem devices shouldn't
use this udev tag.
E.g. forcing a MBIM modem to run in AT-only mode:
# MM_FILTER_RULE_NET=0 \
MM_FILTER_RULE_CDC_WDM=0 \
/usr/sbin/ModemManager --debug
This is just for quick testing for now.
This new object allows configuring the filter rules applied to the
device ports. By default, for now, it implements the same rules as the
MMKernelDevice is_candidate() method, which is obsoleted.
This patch implicitly enables in the generic device backend the
manual-only greylist (ID_MM_DEVICE_MANUAL_SCAN_ONLY tag) and the
platform TTY whitelist (ID_MM_PLATFORM_DRIVER_PROBE), which were not
being applied.