It is not the Modem interface the one notifying about the 'enabling->enabled'
transition, it's the BroadbandModem directly doing it, covering all the enabling
sequences of all the interfaces.
It is not the Modem interface the one notifying about the 'disabling->disabled'
transition, it's the BroadbandModem directly doing it, covering all the
disabling sequences of all the interfaces.
Before the change, the client application loses all new property change
notifications in the interface object:
$ sudo mmcli -m 0 -w
/org/freedesktop/ModemManager1/Modem/0: Initial state, 'locked'
/org/freedesktop/ModemManager1/Modem/0: State changed, 'locked' --> 'initializing' (Reason: None or unknown)
After the change, it doesn't:
$ sudo mmcli -m 0 -w
/org/freedesktop/ModemManager1/Modem/0: Initial state, 'locked'
/org/freedesktop/ModemManager1/Modem/0: State changed, 'locked' --> 'initializing' (Reason: None or unknown)
/org/freedesktop/ModemManager1/Modem/0: State changed, 'initializing' --> 'disabled' (Reason: None or unknown)
/org/freedesktop/ModemManager1/Modem/0: State changed, 'disabled' --> 'enabling' (Reason: User request)
/org/freedesktop/ModemManager1/Modem/0: State changed, 'enabling' --> 'registered' (Reason: User request)
/org/freedesktop/ModemManager1/Modem/0: State changed, 'registered' --> 'disabling' (Reason: User request)
/org/freedesktop/ModemManager1/Modem/0: State changed, 'disabling' --> 'disabled' (Reason: User request)
In QMI modems the logic behind supported and current bands is completely
separated in different services (DMS vs NAS). Actually, the list reported by NAS
as current band preferences seems to include more values than the ones reported
by DMS as supported bands (e.g. CDMA bands are reported even if the firmware
image is GSM/HSPA only).
So, just clean up the list of current preferred bands so that no more than those
given as supported is used.
We do need to specify which is the primary port being used for controlling the
modem. This allows us to match the device with an already existing bluetooth
device in NetworkManager.
The interfaces usually retrieve objects (e.g. skeletons) from the Modem object
using g_object_get(), but we didn't make sure that these objects were actually
valid before using them.
This should clean up errors happening when the modem gets unplugged and still
some actions are ongoing.
Should fix https://bugzilla.gnome.org/show_bug.cgi?id=685933
Both the ModemManager daemon and the mmcli will now include `libmm-glib.h' only.
We also handle two new special `_LIBMM_INSIDE_MM' and `LIBMM_INSIDE_MMCLI'
symbols, which if included before the `libmm-glib.h' library allow us to:
* Don't include the libmm-glib high level API in the ModemManager daemon, as
the object names would clash with those in the core.
* Define some of the methods of helper objects to be included only if compiling
ModemManager daemon or the mmcli.
The power-down command defined by the plugin will be run *only* after having
checked for current and modem capabilities, as plugins (e.g. Sierra) may have
different commands for that depending on whether they are 3GPP or 3GPP2.
We do not reuse the 'modem_power_down' callback from the disabling sequence, as
some plugins really behave pretty badly with this (e.g. Samsung CFUN=4 may take
up to 30s to complete). So, we let plugins use the power-down command when
disabling but avoid launching it during init.
In order to ease the life for clients listening to the 'state-changed' signal,
the change in the 'state' property in the DBus interface skeleton is flushed
right away, before emitting 'state-changed'. By doing this we make sure that
the 'state-changed' callbacks in the clients are able to see exactly the same
current state in the modem proxy.
When the modem gets unplugged, or system gone into suspend, we start losing the
modem ports one by one. When the last is lost, we trigger the disposal of the
modem (we call g_object_run_dispose() and then we call the main-reference
unref()). So, if we end up losing all ports while the connection sequence was
being run, we would end up in this situation, where we try to disconnect the
bearers (the bearer and modem objects are still valid, as we have references
around, but the list of bearers won't be available any more in the modem object
as it was cleared in the modem dispose().
Thread 0 *CRASHED* ( SIGSEGV @ 0x00000000 )
0x7f5cdbd5cda0 [ModemManager] - mm-bearer-list.c:163] mm_bearer_list_foreach
0x7f5cdbd6a4bd [ModemManager] - mm-iface-modem.c:110] bearer_status_changed
0x7f5cdbad0903 [libgobject-2.0.so.0.3000.2] - gclosure.c:774] g_closure_invoke
0x7f5cdbae1dbb [libgobject-2.0.so.0.3000.2] - gsignal.c:3272] signal_emit_unlocked_R
0x7f5cdbaeac82 [libgobject-2.0.so.0.3000.2] - gsignal.c:3003] g_signal_emit_valist
0x7f5cdbaeae5e [libgobject-2.0.so.0.3000.2] - gsignal.c:3060] g_signal_emit
0x7f5cdbad3876 [libgobject-2.0.so.0.3000.2] - gobject.c:925] g_object_dispatch_properties_changed
0x7f5cdbad5ceb [libgobject-2.0.so.0.3000.2] - gobjectnotifyqueue.c:132] g_object_notify_by_pspec
0x7f5cdbd56b08 [ModemManager] - mm-bearer.c:112] bearer_update_status
0x7f5cdbd56ffd [ModemManager] - mm-bearer.c:393] disconnect_ready
0x7f5cdbbcc676 [libgio-2.0.so.0.3000.2] - gsimpleasyncresult.c:749] g_simple_async_result_complete
0x7f5cdbbcc788 [libgio-2.0.so.0.3000.2] - gsimpleasyncresult.c:761] complete_in_idle_cb
0x7f5cdb7cff44 [libglib-2.0.so.0.3000.2] - gmain.c:2441] g_main_context_dispatch
0x7f5cdb7d0597 [libglib-2.0.so.0.3000.2] - gmain.c:3089] g_main_context_iterate
0x7f5cdb7d0b51 [libglib-2.0.so.0.3000.2] - gmain.c:3297] g_main_loop_run
0x7f5cdbd4e331 [ModemManager] - main.c:150] main
0x7f5cdb1ea41c [libc-2.15.so] - libc-start.c:234] __libc_start_main
0x7f5cdbd4de48 [ModemManager] + 0x00019e48]
Reported by Ben Chan <benchan@google.com>
Whenever we query current unlock required status and we get that we're unlocked,
we'll launch the after-sim-unlock step so that we try to ensure that the SIM is
ready.
Different ports of the same modem may get handled by different drivers. We
therefore need to provide a list of drivers (new `Modem.Drivers' property with
signature 'as') instead of just one (removed `Modem.Driver' property with
signature 's').
$ sudo mmcli -m 0 | grep drivers
| drivers: 'qcserial, qmi_wwan'
In practice, it may take longer time for a SIM to become ready when the
modem interface tries to use AT+CPIN? to determine if the SIM is
PIN-locked. This patch increases the number of trials for PIN check to
address the issue.
Instead of hardcoding the logic to decide which ports are open or closed in the
different steps, we now let the subclasses of MMBroadbandModem to do that
themselves.
We now provide:
* initialization_started() and initialization_stopped(): the generic
implementation does the serial port open/close in these steps.
* enabling_started(): the generic implementation does the serial port opening
here. The serial ports are kept open as long the modem is in enabled state.
* disabling_stopped(): the generic implementation does the serial port closing
here.
When the interface is shut down the skeleton object no longer exists. Given that
we're allowing this actions from outside the interface, we should be safe and
don't assume that the caller knows exactly the state of the interface.
expire_signal_quality() / mm_iface_modem_update_access_technologies()
may be called after the DBus object skeleton is removed in
mm_iface_modem_shutdown() and before their associated timeout source is
removed (in *_context_free) due to destruction of the modem object.
This patch fixes the issue by removing context objects before removing
the DBus skeleton in mm_iface_modem_shutdown().
Modems which end up being found unusable (e.g. no SIM, fatal SIM error, no
capabilities) will be exposed in DBus, but just with the Modem interface and
in a FAILED state which allows no actions.
We need to define a state to be used while the modem is being initialized, so
that we forbid any operation on the modem on already exported interfaces, while
there are interfaces pending to get exported.
This Initializing state will also cover the state between having the SIM
unlocked (which launches re-initialization) and being completely initialized.
* mm_base_modem_peek_port_* () will return either a port object (no new
reference), or NULL if none available.
You would usually peek() a port if you're going to use it just in the current
method, as there is no way to that reference to get invalid (we're single
threaded).
* mm_base_modem_get_port_* () will return either NEW references to valid
port objects, or NULL if none available.
And, you would usually get() a port, whenever you want the port object to be
valid even out of the current method, for example when keeping it in the
context of an async operation.
Also, we need to consider that the primary AT port MAY BE NULL when you
peek() or get() it. This is due to the fact that we may be releasing ports
(due to device disconnection) in the middle of async operations.
Renamed `MMCommonSimpleProperties' to `MMSimpleStatus', and removed the
`MMSimpleStatusProperties' provided in libmm-glib. We'll just use the original
one from libmm-common always.
Renamed `MMCommonBearerProperties' to `MMBearerProperties', and removed the
`MMBearerProperties' provided in libmm-glib. We'll just use the original one
from libmm-common always.
Equivalent to `PinRetryCount' in the previous API. We don't have an additional
property for the retry count of the current lock, as it really is duplicating
information.