broadband-modem: run implicit disabling if enabling fails

The disabling sequence is updated so that the steps to disable the
interfaces never fail. This is done so that the modem is not left
in an "inconsistent" enabled state, if e.g. the modem is enabled and
one of the disabling steps for the interfaces ends up failing. In this
case, it is preferred to say that the modem is disabled, than having
it wrongly enabled.

The enabling sequence is updated so that if any of the steps to enable
the interfaces fail, we end up running an implicit disabling operation
to disable all the interfaces. This is to attempt to cleanup whatever
we had enabled during the enabling operation, including e.g. the open
ports context.
This commit is contained in:
Aleksander Morgado
2020-06-07 15:16:49 +02:00
parent 408e9f327e
commit 7e3863897e

View File

@@ -10421,9 +10421,13 @@ schedule_initial_registration_checks (MMBroadbandModem *self)
/*****************************************************************************/ /*****************************************************************************/
typedef enum { typedef enum {
/* When user requests a disable operation, the process starts here */
DISABLING_STEP_FIRST, DISABLING_STEP_FIRST,
DISABLING_STEP_WAIT_FOR_FINAL_STATE, DISABLING_STEP_WAIT_FOR_FINAL_STATE,
DISABLING_STEP_DISCONNECT_BEARERS, DISABLING_STEP_DISCONNECT_BEARERS,
/* When the disabling is launched due to a failed enable, the process
* starts here */
DISABLING_STEP_FIRST_AFTER_ENABLE_FAILED,
DISABLING_STEP_IFACE_SIMPLE, DISABLING_STEP_IFACE_SIMPLE,
DISABLING_STEP_IFACE_FIRMWARE, DISABLING_STEP_IFACE_FIRMWARE,
DISABLING_STEP_IFACE_VOICE, DISABLING_STEP_IFACE_VOICE,
@@ -10441,9 +10445,10 @@ typedef enum {
typedef struct { typedef struct {
MMBroadbandModem *self; MMBroadbandModem *self;
DisablingStep step; gboolean state_updates;
MMModemState previous_state; DisablingStep step;
gboolean disabled; MMModemState previous_state;
gboolean disabled;
} DisablingContext; } DisablingContext;
static void disabling_step (GTask *task); static void disabling_step (GTask *task);
@@ -10459,15 +10464,18 @@ disabling_context_free (DisablingContext *ctx)
g_error_free (error); g_error_free (error);
} }
if (ctx->disabled) /* Only perform state updates if we're asked to do so */
mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self), if (ctx->state_updates) {
MM_MODEM_STATE_DISABLED, if (ctx->disabled)
MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED); mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
else if (ctx->previous_state != MM_MODEM_STATE_DISABLED) { MM_MODEM_STATE_DISABLED,
/* Fallback to previous state */ MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);
mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self), else if (ctx->previous_state != MM_MODEM_STATE_DISABLED) {
ctx->previous_state, /* Fallback to previous state */
MM_MODEM_STATE_CHANGE_REASON_UNKNOWN); mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
ctx->previous_state,
MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
}
} }
g_object_unref (ctx->self); g_object_unref (ctx->self);
@@ -10475,42 +10483,34 @@ disabling_context_free (DisablingContext *ctx)
} }
static gboolean static gboolean
disable_finish (MMBaseModem *self, common_disable_finish (MMBroadbandModem *self,
GAsyncResult *res, GAsyncResult *res,
GError **error) GError **error)
{ {
return g_task_propagate_boolean (G_TASK (res), error); return g_task_propagate_boolean (G_TASK (res), error);
} }
#undef INTERFACE_DISABLE_READY_FN #undef INTERFACE_DISABLE_READY_FN
#define INTERFACE_DISABLE_READY_FN(NAME,TYPE,FATAL_ERRORS) \ #define INTERFACE_DISABLE_READY_FN(NAME,TYPE,WARN_ERRORS) \
static void \ static void \
NAME##_disable_ready (MMBroadbandModem *self, \ NAME##_disable_ready (MMBroadbandModem *self, \
GAsyncResult *result, \ GAsyncResult *result, \
GTask *task) \ GTask *task) \
{ \ { \
DisablingContext *ctx; \ DisablingContext *ctx; \
GError *error = NULL; \ g_autoptr(GError) error = NULL; \
\ \
if (!mm_##NAME##_disable_finish (TYPE (self), \ if (!mm_##NAME##_disable_finish (TYPE (self), result, &error)) { \
result, \ if (WARN_ERRORS) \
&error)) { \ mm_obj_warn (self, "couldn't disable interface: %s", error->message); \
if (FATAL_ERRORS) { \ else \
g_task_return_error (task, error); \ mm_obj_dbg (self, "couldn't disable interface: %s", error->message); \
g_object_unref (task); \ } \
return; \ \
} \ /* Go on to next step */ \
\ ctx = g_task_get_task_data (task); \
mm_obj_dbg (self, "couldn't disable interface: %s", \ ctx->step++; \
error->message); \ disabling_step (task); \
g_error_free (error); \
return; \
} \
\
/* Go on to next step */ \
ctx = g_task_get_task_data (task); \
ctx->step++; \
disabling_step (task); \
} }
INTERFACE_DISABLE_READY_FN (iface_modem, MM_IFACE_MODEM, TRUE) INTERFACE_DISABLE_READY_FN (iface_modem, MM_IFACE_MODEM, TRUE)
@@ -10588,6 +10588,7 @@ disabling_wait_for_final_state_ready (MMIfaceModem *self,
/* We're in a final state now, go on */ /* We're in a final state now, go on */
g_assert (ctx->state_updates);
mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self), mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
MM_MODEM_STATE_DISABLING, MM_MODEM_STATE_DISABLING,
MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED); MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);
@@ -10601,11 +10602,6 @@ disabling_step (GTask *task)
{ {
DisablingContext *ctx; DisablingContext *ctx;
/* Don't run new steps if we're cancelled */
if (g_task_return_error_if_cancelled (task)) {
g_object_unref (task);
return;
}
ctx = g_task_get_task_data (task); ctx = g_task_get_task_data (task);
switch (ctx->step) { switch (ctx->step) {
@@ -10614,6 +10610,11 @@ disabling_step (GTask *task)
/* fall through */ /* fall through */
case DISABLING_STEP_WAIT_FOR_FINAL_STATE: case DISABLING_STEP_WAIT_FOR_FINAL_STATE:
/* cancellability allowed at this point */
if (g_task_return_error_if_cancelled (task)) {
g_object_unref (task);
return;
}
mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self), mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self),
MM_MODEM_STATE_UNKNOWN, /* just any */ MM_MODEM_STATE_UNKNOWN, /* just any */
(GAsyncReadyCallback)disabling_wait_for_final_state_ready, (GAsyncReadyCallback)disabling_wait_for_final_state_ready,
@@ -10621,6 +10622,11 @@ disabling_step (GTask *task)
return; return;
case DISABLING_STEP_DISCONNECT_BEARERS: case DISABLING_STEP_DISCONNECT_BEARERS:
/* cancellability allowed at this point */
if (g_task_return_error_if_cancelled (task)) {
g_object_unref (task);
return;
}
if (ctx->self->priv->modem_bearer_list) { if (ctx->self->priv->modem_bearer_list) {
mm_bearer_list_disconnect_all_bearers ( mm_bearer_list_disconnect_all_bearers (
ctx->self->priv->modem_bearer_list, ctx->self->priv->modem_bearer_list,
@@ -10631,6 +10637,14 @@ disabling_step (GTask *task)
ctx->step++; ctx->step++;
/* fall through */ /* fall through */
case DISABLING_STEP_FIRST_AFTER_ENABLE_FAILED:
/* From this point onwards, the disabling sequence will NEVER fail, all
* errors will be treated as non-fatal, including a possible task
* cancellation. */
g_task_set_check_cancellable (task, FALSE);
ctx->step++;
/* fall through */
case DISABLING_STEP_IFACE_SIMPLE: case DISABLING_STEP_IFACE_SIMPLE:
ctx->step++; ctx->step++;
/* fall through */ /* fall through */
@@ -10642,7 +10656,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_VOICE: case DISABLING_STEP_IFACE_VOICE:
if (ctx->self->priv->modem_voice_dbus_skeleton) { if (ctx->self->priv->modem_voice_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has voice capabilities, disabling the Voice interface..."); mm_obj_dbg (ctx->self, "modem has voice capabilities, disabling the Voice interface...");
/* Disabling the Modem Voice interface */
mm_iface_modem_voice_disable (MM_IFACE_MODEM_VOICE (ctx->self), mm_iface_modem_voice_disable (MM_IFACE_MODEM_VOICE (ctx->self),
(GAsyncReadyCallback)iface_modem_voice_disable_ready, (GAsyncReadyCallback)iface_modem_voice_disable_ready,
task); task);
@@ -10654,7 +10667,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_SIGNAL: case DISABLING_STEP_IFACE_SIGNAL:
if (ctx->self->priv->modem_signal_dbus_skeleton) { if (ctx->self->priv->modem_signal_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has extended signal reporting capabilities, disabling the Signal interface..."); mm_obj_dbg (ctx->self, "modem has extended signal reporting capabilities, disabling the Signal interface...");
/* Disabling the Modem Signal interface */
mm_iface_modem_signal_disable (MM_IFACE_MODEM_SIGNAL (ctx->self), mm_iface_modem_signal_disable (MM_IFACE_MODEM_SIGNAL (ctx->self),
(GAsyncReadyCallback)iface_modem_signal_disable_ready, (GAsyncReadyCallback)iface_modem_signal_disable_ready,
task); task);
@@ -10666,7 +10678,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_OMA: case DISABLING_STEP_IFACE_OMA:
if (ctx->self->priv->modem_oma_dbus_skeleton) { if (ctx->self->priv->modem_oma_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has OMA capabilities, disabling the OMA interface..."); mm_obj_dbg (ctx->self, "modem has OMA capabilities, disabling the OMA interface...");
/* Disabling the Modem Oma interface */
mm_iface_modem_oma_disable (MM_IFACE_MODEM_OMA (ctx->self), mm_iface_modem_oma_disable (MM_IFACE_MODEM_OMA (ctx->self),
(GAsyncReadyCallback)iface_modem_oma_disable_ready, (GAsyncReadyCallback)iface_modem_oma_disable_ready,
task); task);
@@ -10678,7 +10689,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_TIME: case DISABLING_STEP_IFACE_TIME:
if (ctx->self->priv->modem_time_dbus_skeleton) { if (ctx->self->priv->modem_time_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has time capabilities, disabling the Time interface..."); mm_obj_dbg (ctx->self, "modem has time capabilities, disabling the Time interface...");
/* Disabling the Modem Time interface */
mm_iface_modem_time_disable (MM_IFACE_MODEM_TIME (ctx->self), mm_iface_modem_time_disable (MM_IFACE_MODEM_TIME (ctx->self),
(GAsyncReadyCallback)iface_modem_time_disable_ready, (GAsyncReadyCallback)iface_modem_time_disable_ready,
task); task);
@@ -10690,7 +10700,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_MESSAGING: case DISABLING_STEP_IFACE_MESSAGING:
if (ctx->self->priv->modem_messaging_dbus_skeleton) { if (ctx->self->priv->modem_messaging_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has messaging capabilities, disabling the Messaging interface..."); mm_obj_dbg (ctx->self, "modem has messaging capabilities, disabling the Messaging interface...");
/* Disabling the Modem Messaging interface */
mm_iface_modem_messaging_disable (MM_IFACE_MODEM_MESSAGING (ctx->self), mm_iface_modem_messaging_disable (MM_IFACE_MODEM_MESSAGING (ctx->self),
(GAsyncReadyCallback)iface_modem_messaging_disable_ready, (GAsyncReadyCallback)iface_modem_messaging_disable_ready,
task); task);
@@ -10702,7 +10711,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_LOCATION: case DISABLING_STEP_IFACE_LOCATION:
if (ctx->self->priv->modem_location_dbus_skeleton) { if (ctx->self->priv->modem_location_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has location capabilities, disabling the Location interface..."); mm_obj_dbg (ctx->self, "modem has location capabilities, disabling the Location interface...");
/* Disabling the Modem Location interface */
mm_iface_modem_location_disable (MM_IFACE_MODEM_LOCATION (ctx->self), mm_iface_modem_location_disable (MM_IFACE_MODEM_LOCATION (ctx->self),
(GAsyncReadyCallback)iface_modem_location_disable_ready, (GAsyncReadyCallback)iface_modem_location_disable_ready,
task); task);
@@ -10714,7 +10722,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_CDMA: case DISABLING_STEP_IFACE_CDMA:
if (ctx->self->priv->modem_cdma_dbus_skeleton) { if (ctx->self->priv->modem_cdma_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has CDMA capabilities, disabling the Modem CDMA interface..."); mm_obj_dbg (ctx->self, "modem has CDMA capabilities, disabling the Modem CDMA interface...");
/* Disabling the Modem CDMA interface */
mm_iface_modem_cdma_disable (MM_IFACE_MODEM_CDMA (ctx->self), mm_iface_modem_cdma_disable (MM_IFACE_MODEM_CDMA (ctx->self),
(GAsyncReadyCallback)iface_modem_cdma_disable_ready, (GAsyncReadyCallback)iface_modem_cdma_disable_ready,
task); task);
@@ -10726,7 +10733,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_3GPP_USSD: case DISABLING_STEP_IFACE_3GPP_USSD:
if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) { if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has 3GPP/USSD capabilities, disabling the Modem 3GPP/USSD interface..."); mm_obj_dbg (ctx->self, "modem has 3GPP/USSD capabilities, disabling the Modem 3GPP/USSD interface...");
/* Disabling the Modem 3GPP USSD interface */
mm_iface_modem_3gpp_ussd_disable (MM_IFACE_MODEM_3GPP_USSD (ctx->self), mm_iface_modem_3gpp_ussd_disable (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
(GAsyncReadyCallback)iface_modem_3gpp_ussd_disable_ready, (GAsyncReadyCallback)iface_modem_3gpp_ussd_disable_ready,
task); task);
@@ -10738,7 +10744,6 @@ disabling_step (GTask *task)
case DISABLING_STEP_IFACE_3GPP: case DISABLING_STEP_IFACE_3GPP:
if (ctx->self->priv->modem_3gpp_dbus_skeleton) { if (ctx->self->priv->modem_3gpp_dbus_skeleton) {
mm_obj_dbg (ctx->self, "modem has 3GPP capabilities, disabling the Modem 3GPP interface..."); mm_obj_dbg (ctx->self, "modem has 3GPP capabilities, disabling the Modem 3GPP interface...");
/* Disabling the Modem 3GPP interface */
mm_iface_modem_3gpp_disable (MM_IFACE_MODEM_3GPP (ctx->self), mm_iface_modem_3gpp_disable (MM_IFACE_MODEM_3GPP (ctx->self),
(GAsyncReadyCallback)iface_modem_3gpp_disable_ready, (GAsyncReadyCallback)iface_modem_3gpp_disable_ready,
task); task);
@@ -10751,7 +10756,7 @@ disabling_step (GTask *task)
/* This skeleton may be NULL when mm_base_modem_disable() gets called at /* This skeleton may be NULL when mm_base_modem_disable() gets called at
* the same time as modem object disposal. */ * the same time as modem object disposal. */
if (ctx->self->priv->modem_dbus_skeleton) { if (ctx->self->priv->modem_dbus_skeleton) {
/* Disabling the Modem interface */ mm_obj_dbg (ctx->self, "disabling the Modem interface...");
mm_iface_modem_disable (MM_IFACE_MODEM (ctx->self), mm_iface_modem_disable (MM_IFACE_MODEM (ctx->self),
(GAsyncReadyCallback)iface_modem_disable_ready, (GAsyncReadyCallback)iface_modem_disable_ready,
task); task);
@@ -10761,8 +10766,8 @@ disabling_step (GTask *task)
/* fall through */ /* fall through */
case DISABLING_STEP_LAST: case DISABLING_STEP_LAST:
ctx->disabled = TRUE;
/* All disabled without errors! */ /* All disabled without errors! */
ctx->disabled = TRUE;
g_task_return_boolean (task, TRUE); g_task_return_boolean (task, TRUE);
g_object_unref (task); g_object_unref (task);
return; return;
@@ -10775,17 +10780,20 @@ disabling_step (GTask *task)
} }
static void static void
disable (MMBaseModem *self, common_disable (MMBroadbandModem *self,
GCancellable *cancellable, gboolean state_updates,
GAsyncReadyCallback callback, DisablingStep first_step,
gpointer user_data) GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{ {
DisablingContext *ctx; DisablingContext *ctx;
GTask *task; GTask *task;
ctx = g_new0 (DisablingContext, 1); ctx = g_new0 (DisablingContext, 1);
ctx->self = g_object_ref (self); ctx->self = g_object_ref (self);
ctx->step = DISABLING_STEP_FIRST; ctx->state_updates = state_updates;
ctx->step = first_step;
task = g_task_new (self, cancellable, callback, user_data); task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)disabling_context_free); g_task_set_task_data (task, ctx, (GDestroyNotify)disabling_context_free);
@@ -10793,6 +10801,55 @@ disable (MMBaseModem *self,
disabling_step (task); disabling_step (task);
} }
/* Implicit disabling after failed enable */
static gboolean
enable_failed_finish (MMBroadbandModem *self,
GAsyncResult *res,
GError **error)
{
/* The implicit disabling should never ever fail */
g_assert (common_disable_finish (self, res, NULL));
return TRUE;
}
static void
enable_failed (MMBroadbandModem *self,
GAsyncReadyCallback callback,
gpointer user_data)
{
common_disable (self,
FALSE, /* don't perform state updates */
DISABLING_STEP_FIRST_AFTER_ENABLE_FAILED,
NULL, /* no cancellable */
callback,
user_data);
}
/* User-requested disable operation */
static gboolean
disable_finish (MMBaseModem *self,
GAsyncResult *res,
GError **error)
{
return common_disable_finish (MM_BROADBAND_MODEM (self), res, error);
}
static void
disable (MMBaseModem *self,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
common_disable (MM_BROADBAND_MODEM (self),
TRUE, /* perform state updates */
DISABLING_STEP_FIRST_AFTER_ENABLE_FAILED,
cancellable,
callback,
user_data);
}
/*****************************************************************************/ /*****************************************************************************/
typedef enum { typedef enum {
@@ -10816,9 +10873,10 @@ typedef enum {
typedef struct { typedef struct {
MMBroadbandModem *self; MMBroadbandModem *self;
EnablingStep step; EnablingStep step;
MMModemState previous_state; MMModemState previous_state;
gboolean enabled; gboolean enabled;
GError *saved_error;
} EnablingContext; } EnablingContext;
static void enabling_step (GTask *task); static void enabling_step (GTask *task);
@@ -10826,6 +10884,8 @@ static void enabling_step (GTask *task);
static void static void
enabling_context_free (EnablingContext *ctx) enabling_context_free (EnablingContext *ctx)
{ {
g_assert (!ctx->saved_error);
if (ctx->enabled) if (ctx->enabled)
mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self), mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
MM_MODEM_STATE_ENABLED, MM_MODEM_STATE_ENABLED,
@@ -10849,34 +10909,51 @@ enable_finish (MMBaseModem *self,
return g_task_propagate_boolean (G_TASK (res), error); return g_task_propagate_boolean (G_TASK (res), error);
} }
static void
enable_failed_ready (MMBroadbandModem *self,
GAsyncResult *res,
GTask *task)
{
EnablingContext *ctx;
ctx = g_task_get_task_data (task);
/* The disabling run after a failed enable will never fail */
g_assert (enable_failed_finish (self, res, NULL));
g_assert (ctx->saved_error);
g_task_return_error (task, g_steal_pointer (&ctx->saved_error));
g_object_unref (task);
}
#undef INTERFACE_ENABLE_READY_FN #undef INTERFACE_ENABLE_READY_FN
#define INTERFACE_ENABLE_READY_FN(NAME,TYPE,FATAL_ERRORS) \ #define INTERFACE_ENABLE_READY_FN(NAME,TYPE,FATAL_ERRORS) \
static void \ static void \
NAME##_enable_ready (MMBroadbandModem *self, \ NAME##_enable_ready (MMBroadbandModem *self, \
GAsyncResult *result, \ GAsyncResult *result, \
GTask *task) \ GTask *task) \
{ \ { \
EnablingContext *ctx; \ EnablingContext *ctx; \
GError *error = NULL; \ g_autoptr(GError) error = NULL; \
\ \
if (!mm_##NAME##_enable_finish (TYPE (self), \ ctx = g_task_get_task_data (task); \
result, \ \
&error)) { \ if (!mm_##NAME##_enable_finish (TYPE (self), result, &error)) { \
if (FATAL_ERRORS) { \ if (FATAL_ERRORS) { \
g_task_return_error (task, error); \ mm_obj_warn (self, "couldn't enable interface: '%s'", error->message); \
g_object_unref (task); \ g_assert (!ctx->saved_error); \
return; \ ctx->saved_error = g_steal_pointer (&error); \
} \ mm_obj_dbg (self, "running implicit disable after failed enable..."); \
\ enable_failed (self, (GAsyncReadyCallback) enable_failed_ready, task); \
mm_obj_dbg (self, "couldn't enable interface: '%s'", \ return; \
error->message); \ } \
g_error_free (error); \ \
} \ mm_obj_dbg (self, "couldn't enable interface: '%s'", error->message); \
\ } \
/* Go on to next step */ \ \
ctx = g_task_get_task_data (task); \ /* Go on to next step */ \
ctx->step++; \ ctx->step++; \
enabling_step (task); \ enabling_step (task); \
} }
INTERFACE_ENABLE_READY_FN (iface_modem, MM_IFACE_MODEM, TRUE) INTERFACE_ENABLE_READY_FN (iface_modem, MM_IFACE_MODEM, TRUE)
@@ -10981,6 +11058,9 @@ enabling_step (GTask *task)
/* fall through */ /* fall through */
case ENABLING_STEP_IFACE_MODEM: case ENABLING_STEP_IFACE_MODEM:
/* From now on, the failure to enable one of the mandatory interfaces
* will trigger the implicit disabling process */
g_assert (ctx->self->priv->modem_dbus_skeleton != NULL); g_assert (ctx->self->priv->modem_dbus_skeleton != NULL);
/* Enabling the Modem interface */ /* Enabling the Modem interface */
mm_iface_modem_enable (MM_IFACE_MODEM (ctx->self), mm_iface_modem_enable (MM_IFACE_MODEM (ctx->self),