There are more places to handle, but these are the most critical. If
the modem is removed while a command is in-progress, the mm-callback-info
code will set info->modem to NULL. Make sure we check for that in
callbacks and return a reasonable error. Previous code would just
blindly forge ahead and die on a null dereference.
If the modem becomes invalid (it crashes and resets, for example)
the callback-info's modem_destroyed_cb() function will handle
cleanup. Buf if the callback-info's callback does more work than
just returning the result (like simple_state_machine) it could
double-schedule the callback. Don't let that happen.
We need better modem-removal handling, but this fixes a crash for
now.
Full references prevented destruction of the modem object if
it was unplugged or somehow removed. To fix that using full
references on the modems would require that all usage of
MMCallbackInfo to be aware of the validity of the modem and to
ensure the callback was called whenever the modem became invalid.
That, needless to say, would suck. Since any in-progress calls
can't complete when the modem is invalid anyway, just have the
MMCallbackInfo object return a generic error when the modem goes
away and the call is still in-progress.
Rework the MMCallbackInfo callback invocation.
Always use g_error_literal() where it makes sense.
Replace sleep() calls, with timeouts to not block the whole MM.
Instead of vague "send something, wait something" the responses are now
analyzed by (overridable) parsers. Makes all the modem implementations much
easier since each caller knows without any code whether the call succeeded
or failed.
Another thing that makes modem code simpler (and the whole thing more robust),
is the queueing of sent commands. Each queued command has a command and a
callback which is quaranteed to get called, even if sending failed.
Define and implement error reporting.