Yeah, GObject is pretty obscure here. But to get the implementation's
override function, we want GET_INTERFACE, otherwise we're looking at
some random memory location that's sometimes NULL. And then we crash.
This patch rearranges the initialization steps in MMIfaceModem such that
the following SIM related operations happen at the end of the
initialization:
- INITIALIZATION_STEP_UNLOCK_REQUIRED
- INITIALIZATION_STEP_SIM
- INITIALIZATION_STEP_OWN_NUMBERS
The rationale of this change is that the SIM interface of some modems
may require some time to initialize before it responds to SIM related
AT commands. By rearranging the initialization steps to execute non-SIM
related AT commands first, some of the latency for the SIM
initialization can be absorbed.
ModemManager has a bogus modem state transition from 'enabling' to 'disabled':
ModemManager[26214]: <info> Modem fully enabled...
ModemManager[26214]: <info> Modem /org/freedesktop/ModemManager1/Modem/2: state changed (enabling -> disabled)
The root cause seems to be the following:
get_current_consolidated_state() in MMIfaceModem returns
MM_MODEM_STATE_DISABLED as the default fallback value. When
mm_iface_modem_update_state() is invoked to transition the modem state from
MM_MODEM_STATE_ENABLING to MM_MODEM_STATE_ENABLED, the following code can
potentially cause the final state to be MM_MODEM_STATE_DISABLED instead.
/* Enabled may really be searching or registered */
if (new_state == MM_MODEM_STATE_ENABLED)
new_state = get_current_consolidated_state (self);
https://code.google.com/p/chromium-os/issues/detail?id=38173
This patch modifies MMIfaceModem to schedule the periodic signal quality
check with a period of 3s instead of 30s (up to 5 periods) initially
until a non-zero signal quality value is obtained and then switch back
to the 30s period.
This patch adds a 'hotplugged' flag to MMBaseModem to indicate if a
modem is newly plugged in. A plugin can use this information to
determine if, for example, the modem needs to be soft reset using the
ATZ command.
Dan Williams <dcbw@redhat.com> contributed the idea of implementation.
Setting access technologies from registration state as part of the
registration checking in the CDMA Interface code fights with
custom implementations in each modem subclass, which causes the
access technologies to ping-pong between more specific (custom
implementation) and less specific (generated from registration state
during registration checking). If the modem class has more
specific access technology knowledge, we should use that and not
override it on the next registration state poll.
So instead, implement the generic access technology update from
registration state in the broadband modem base class'
load_access_technologies() hook. Thus, modem classes with more
specific checking (which override MMBroadbandModem's implementation)
will never fight with generic checking, while modems that don't
(and thus actually need the generic checking) still get some basic
access technology handling.
We want the SID/NID even when AT Serving System checks are disabled,
otherwise the SID/NID don't get filled at all. QCDM doesn't need the
SID/NID to determine registration, so the values are informational
only and don't affect registration state. But we still want to
export them via the API.
Some devices (usually CDMA modems like the Sierra MC5725 and others)
don't prefix their +CSQ replies with +CSQ. So don't require that.
The scanf() should ensure the reply is valid even without the +CSQ.
Not many CDMA/EVDO-only modems support CNUM since it's not a
standard IS707/856 AT command, so for those that don't
support it and have a QCDM port, try grabbing the number from
NV memory.
The logic to handle the lock information (current lock and unlock retry count)
wasn't handling all possible cases properly, e.g.:
* When PIN is incorrectly entered too many times, a SIM-PUK error may happen.
In this case we need to directly assume SIM-PUK is the current lock (some
modems, like Option HSO ones, would incorrectly reply SIM-PIN if CPIN? asked
just after the SIM-PUK error).
* After every operation acting in SIM locks, we need to update the current
unlock retry count.
This change tries to cover those cases, by:
* The logic to check current lock is extended to also load the unlock retry
count when needed.
* Whenever a SIM-PUK error happens in the SIM operations, we directly assume
that SIM-PUK is required, without re-asking CPIN?.
* The overall logic of lock checking is now handled by a state machine, which
is much easier to understand.
Every port probing will have the Generic plugin as fallback, and due to some
other issues in other plugins (see ee099fcd), we need to allow overwriting the
suggested plugin from the Generic to a more specific one.
One of the drawbacks of this is that we're actually allowing the Generic plugin
to probe and accept the port, which means that the generic plugin may accept a
specific port type (e.g. QMI) while the specific plugin wouldn't. So, we will
now also run the subsystems filter before grabbing the specific port, in order
to really filter out those cases. We still keep the subsystems filter in
pre-probing, so that we build a better initial plugin list to probe.
If an error occurs early during the initialization (e.g. during port setup), we
would be aborting without even having exported the modem interface. So detect
that case and skip setting the modem as valid.
When the 3GPP location is enabled, we need to reload the operator code
information, but only if the modem is registered in a 3GPP network.
Now, instead of looking at the global modem state value, look at the specific
3GPP registration state. This will avoid issues like:
* updating 3GPP operator info and the modem registered in a CDMA network.
* not updating the 3GPP operator info when the modem is registered in a 3GPP
network but not yet fully enabled (i.e. 'enabling').
The Bus Pirate v4 presents itself as a CDC ACM device which
ModemManager attempts to configure. This results in a range
of confusing issues because it injects a bunch of AT commands
over whatever is going on at the time.
Firmware updates were failing at random points and avrdude
failed to work at all. Blacklisting it fixed my issues.
If the primary port is gone (e.g. when going to sleep) and we are just in the
middle of a connection attempt, we won't be able to receive any unsolicited
message regarding the status of the attempt. So, if we detect that the port is
forced to get closed, we'll just treat it as a connection failure.
http://code.google.com/p/chromium-os/issues/detail?id=35391
We need the kernel driver to give a proper value for the 'closing_wait'
variable, but don't assume it will.
This should solve the following kind of issues reported by valgrind:
==8985== Conditional jump or move depends on uninitialised value(s)
==8985== at 0x4409A6: mm_serial_port_close (mm-serial-port.c:932)
==8985== by 0x41A420: disable_all_done (mm-generic-cdma.c:753)
==8985== by 0x4125A4: mm_manager_shutdown (mm-manager.c:1130)
==8985== by 0x40DE35: main (main.c:203)
If we read a response that indicates the port is definitely not an
AT capable port, stop AT probing. Certain ports that use proprietary
protocols or other non-AT protocols tend to spew data at us, so when
this happens we can cut probing short.
If a response processor closed the port, don't try to read any
more data from it. Move the priv->watch_id check to the
while condition so the loop terminates before calling
g_io_channel_read_chars() again, which caused a warning since
the underlying file descriptor was already closed.
Also, bytes_read will never be less than zero (it's unsigned),
so skip the bytes_read > 0 check and just assert that this
condition is true.
Sierra devices often have limited AT parsers on their APP ports
which reply with OK to any command they don't understand, and
thus we need to actually check for a valid IPSYS reply instead of
just checking whether the IPSYS request completed without error.
Previously MM would detect Icera capability on devices that
didn't actually have it.