We have a report of a modem that switches access technologies frequently,
in this case almost every 10 seconds. While that's unusual, it's not
unexpected depending on the RF environment. We shouldn't spam syslog
with that info; if we need it we can get it with mmcli.
There are systems in which the modem power source can be controlled externally,
e.g. to switch it on or off. In these cases, it is sometimes advisable to be
able to tell the modem to cleanly shut off completely before the power is cut.
So, allow transitioning to the OFF power state if the modem supports it, even if
afterwards the modem could be completely unreachable.
When wait_for_final_state_context_complete_and_free is invoked, if the callback
associated with the GSimpleAsyncResult object of the WaitForFinalStateContext
object updates the modem state via mm_iface_modem_update_state, state_changed
is invoked, which causes wait_for_final_state_context_complete_and_free to be
invoked again on the same WaitForFinalStateContext object. That leads to the
following crash, which is observed sometimes when a modem is being disabled.
Thread 0 *CRASHED* ( SIGSEGV @ 0x00000000 )
0x7fcb7728f202 [libgobject-2.0.so.0.3400.3] - gobject.c:2916 g_object_unref
0x7fcb7743205c [ModemManager] - mm-broadband-modem.c:8034 disabling_context_complete_and_free
0x7fcb77434d64 [ModemManager] - mm-broadband-modem.c:8130 disabling_wait_for_final_state_ready
0x7fcb770c0b86 [libgio-2.0.so.0.3400.3] - gsimpleasyncresult.c:775 g_simple_async_result_complete
0x7fcb7740cdbc [ModemManager] - mm-iface-modem.c:101] wait_for_final_state_context_complete_and_free
0x7fcb7740ce19 [ModemManager] - mm-iface-modem.c:128] state_changed_wait_expired
0x7fcb76f78c33 [libglib-2.0.so.0.3400.3] - gmain.c:4026] g_timeout_dispatch
0x7fcb76f78087 [libglib-2.0.so.0.3400.3] - gmain.c:2715] g_main_context_dispatch
0x7fcb76f78437 [libglib-2.0.so.0.3400.3] - gmain.c:3290] g_main_context_iterate
0x7fcb76f78891 [libglib-2.0.so.0.3400.3] - gmain.c:3484] g_main_loop_run
0x7fcb773f4d55 [ModemManager] - main.c:142] main
0x7fcb7698a9c6 [libc-2.15.so] - libc-start.c:234] __libc_start_main
0x7fcb773f48b8 [ModemManager] + 0x000218b8]
This patch removes an unnecessary G_SIMPLE_ASYNC_RESULT() cast of the
'result' field, which is already of type GSimpleAsyncResult, of
InternalLoadUnlockRequiredContext.
The new internal_load_unlock_required() method will take care of running the
subclassed load_unlock_required(), if available, and also retry the check up
to 6 times.
This method will be used both by the standard unlock required check and by the
check within the current capabilities loading for multimode devices.
This patch fixes an assertion failure 'ctx->fatal_error == NULL' in
initialization_context_complete_and_free(), which happens if
'fatal_error' of the initialization context is set during the modem
interface initialization and the initialization is later cancelled.
We will expose a new 'Ports' property listing all ports currently known by a
given modem. Ports which are not used but are detected as being part of the
modem will be listed with an 'unknown' port type.
This change uses the new 'MMModemPortType' enum and the new 'MMModemPortInfo'
helper struct to handle these values in libmm-glib. The already available
'MMPortType' enum hasn't been re-used for the interface because it contains
values that we don't need (e.g. IGNORED).
The port list is now also included in the modem information command of mmcli:
$ sudo mmcli -m 0
/org/freedesktop/ModemManager1/Modem/0 (device id '97b7b99e3e2bea103880545b619fb05a3cc81b26')
-------------------------
System | device: '/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.4'
| drivers: 'qcserial, qmi_wwan'
| plugin: 'Gobi'
| primary port: 'cdc-wdm0'
| ports: 'ttyUSB0 (qcdm), ttyUSB1 (at), cdc-wdm0 (qmi), wwp0s29u1u4 (net)'
https://bugzilla.gnome.org/show_bug.cgi?id=702678
The real power state value of the modem may be changed by other means, e.g.
rfkill. So when changing power state of the modem in MM, we better recheck
which the current power status is.
A better full approach would be to follow rfkill changes, but this fix should
help until that is done.
https://bugzilla.gnome.org/show_bug.cgi?id=702838
And also make it a list of masks, specifying which are the specific combinations
supported, not just one mask with all.
E.g.:
-------------------------
Hardware | manufacturer: 'Sierra Wireless, Incorporated'
| model: 'MC7710'
| revision: 'SWI9200X_03.05.19.04ap r5475 carmd-en-10527 2012/09/17 17:57:14'
| supported: 'gsm-umts
| gsm-umts, lte'
| current: 'gsm-umts, lte'
| equipment id: '358178040668164'
We now have a single 'CurrentModes' property which contains both values in a
tuple with signature "(uu)".
Also, rename 'SetAllowedModes()' to 'SetCurrentModes()', and update the list of
arguments expected to have a single "(uu)" tuple.
You can't g_array_insert_val() to an index that's beyond the end
of the array, which was happening if the user tried to set the
band list to "any":
mmcli -m 0 --set-bands=any
Just use g_array_append_val() instead.
==5618== Invalid read of size 2
==5618== at 0x4A0A158: memcpy@GLIBC_2.2.5 (mc_replace_strmem.c:881)
==5618== by 0x326201D8FB: g_array_insert_vals (string3.h:57)
==5618== by 0x442EFB: mm_iface_modem_set_bands (mm-iface-modem.c:1982)
==5618== by 0x44307E: handle_set_bands_auth_ready (mm-iface-modem.c:2100)
==5618== by 0x326386DFF6: g_simple_async_result_complete (gsimpleasyncresult.c:775)
==5618== by 0x4358E3: authorize_ready (mm-base-modem.c:1300)
==5618== by 0x326386DFF6: g_simple_async_result_complete (gsimpleasyncresult.c:775)
==5618== by 0x326386E0F8: complete_in_idle_cb (gsimpleasyncresult.c:787)
==5618== by 0x3262047A54: g_main_context_dispatch (gmain.c:2715)
==5618== by 0x3262047D87: g_main_context_iterate.isra.24 (gmain.c:3290)
==5618== by 0x3262048181: g_main_loop_run (gmain.c:3484)
==5618== by 0x426235: main (main.c:142)
==5618== Address 0x10a7ea74e is not stack'd, malloc'd or (recently) free'd
==5618==
==5618==
==5618== Process terminating with default action of signal 11 (SIGSEGV)
==5618== Access not within mapped region at address 0x10A7EA74E
==5618== at 0x4A0A158: memcpy@GLIBC_2.2.5 (mc_replace_strmem.c:881)
==5618== by 0x326201D8FB: g_array_insert_vals (string3.h:57)
==5618== by 0x442EFB: mm_iface_modem_set_bands (mm-iface-modem.c:1982)
==5618== by 0x44307E: handle_set_bands_auth_ready (mm-iface-modem.c:2100)
==5618== by 0x326386DFF6: g_simple_async_result_complete (gsimpleasyncresult.c:775)
==5618== by 0x4358E3: authorize_ready (mm-base-modem.c:1300)
==5618== by 0x326386DFF6: g_simple_async_result_complete (gsimpleasyncresult.c:775)
==5618== by 0x326386E0F8: complete_in_idle_cb (gsimpleasyncresult.c:787)
==5618== by 0x3262047A54: g_main_context_dispatch (gmain.c:2715)
==5618== by 0x3262047D87: g_main_context_iterate.isra.24 (gmain.c:3290)
==5618== by 0x3262048181: g_main_loop_run (gmain.c:3484)
==5618== by 0x426235: main (main.c:142)
We don't support SIM/RUIM on CDMA devices (yet), so for now it makes
no sense to run the after-sim-unlock step on CDMA-only devices where
a SIM won't be present.
Unfortunately we don't know at this point whether there is a SIM
or not, so if the modem is a multi-mode device (implying it has a SIM
slot) and its plugin implements the modem_after_sim_unlock() hook,
the hook will still be executed and might cause an unecessary delay
when a SIM is not inserted.
Allow mm_iface_modem_update_state() receive 'MM_MODEM_STATE_FAILED', and treat
it as any other change to failed state, but with
'MM_MODEM_STATE_FAILED_REASON_UNKNOWN'.
Patch "iface-modem: fix invalid modem state consolidation" (commit
69aff6183a) incorrectly consolidates the
modem state upon the disconnection of a bearer. The modem state remains
'connected' after the last bearer is disconnected. This patch fixes
that.
Instead of a custom modem_init() step in the 'Modem' interface, just add a
sequence of port initialization commands in each port.
While enabling for the first time a non-hotplugged modem, we will issue the
port initialization commands only after having run the enabling_modem_init()
step (i.e. after ATZ usually).
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.
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.