The initialization sequence doesn't expect any result, so
`mm_base_modem_at_sequence_finish()' will actually return NULL even if there is
no error. Therefore, we base the success of the sequence on the existence of a
GError in the return.
The PluginBase object got modified during the new codebase development, and
therefore we need to ensure that the current codebase doesn't try to load old
plugins.
If the command we're sending doesn't have a callback, don't try
to call NULL. Triggered if the port got closed (because the modem
crashed, or refcounting errors or whatever) with some code like this:
mm_at_serial_port_queue_command (MM_AT_SERIAL_PORT (port), "+CREG=0", 3, NULL, NULL);
If we got an existing modem showing a new port, and the plugin handling that modem
said that only one AT port was expected, we shouldn't be AT-probing it any more.
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.
Instead of the `_in_port()' variants, we'll provide more generic
`_full()' methods. These should be used either if we want to send commands
to a specific port, or if we want to use a specific user-provided GCancellable.
In addition to this user-provided GCancellable, we keep the internal modem-wide
one.
Users of mm_base_modem_at_command_in_port() can now directly pass the result
of mm_base_modem_peek_port_primary() or mm_base_modem_peek_port_secondary(),
which may be NULL if no such port exists in the modem. So we'll gracefully
detect the NULL port and complete the async operation with an error.
* 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.