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
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>
When passing known_lock=UNKNOWN to mm_iface_modem_update_lock_info()
we actually do want to ask the modem itself for locks instead of
checking the cache. For example, when an unknown error is returned
after performing PIN/PUK operations, the cache value may well be
NONE if that was the prior lock state, and that bypasses the modem
which might now be locked. Thus the state gets messed up.
Reproducer is to send 'ChangePin' with the wrong "old" PIN 3 times,
then send a wrong PUK. No error was returned from mmcli and
the modem's lock state was shown as 'none'.
If for any reason the modem is in OFF state and still can talk to the modem,
allow running the remaining transition requests to LOW or ON. This can happen
for example for modems that use CFUN:0, i.e. which can still go online with
CFUN=1.
https://bugs.freedesktop.org/show_bug.cgi?id=89368
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).