/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details:
 *
 * Copyright (C) 2008 - 2009 Novell, Inc.
 * Copyright (C) 2009 - 2012 Red Hat, Inc.
 * Copyright (C) 2011 - 2012 Google, Inc.
 * Copyright (C) 2015 - Marco Bascetta <marco.bascetta@sadel.it>
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>

#include <ModemManager.h>
#define _LIBMM_INSIDE_MM
#include <libmm-glib.h>

#include "mm-base-modem-at.h"
#include "mm-broadband-modem.h"
#include "mm-iface-modem.h"
#include "mm-iface-modem-3gpp.h"
#include "mm-iface-modem-3gpp-ussd.h"
#include "mm-iface-modem-cdma.h"
#include "mm-iface-modem-simple.h"
#include "mm-iface-modem-location.h"
#include "mm-iface-modem-messaging.h"
#include "mm-iface-modem-voice.h"
#include "mm-iface-modem-time.h"
#include "mm-iface-modem-firmware.h"
#include "mm-iface-modem-signal.h"
#include "mm-iface-modem-oma.h"
#include "mm-broadband-bearer.h"
#include "mm-bearer-list.h"
#include "mm-sms-list.h"
#include "mm-sms-part-3gpp.h"
#include "mm-call-list.h"
#include "mm-base-sim.h"
#include "mm-log.h"
#include "mm-modem-helpers.h"
#include "mm-error-helpers.h"
#include "mm-port-serial-qcdm.h"
#include "libqcdm/src/errors.h"
#include "libqcdm/src/commands.h"
#include "libqcdm/src/logs.h"
#include "libqcdm/src/log-items.h"

static void iface_modem_init (MMIfaceModem *iface);
static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface);
static void iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface);
static void iface_modem_cdma_init (MMIfaceModemCdma *iface);
static void iface_modem_simple_init (MMIfaceModemSimple *iface);
static void iface_modem_location_init (MMIfaceModemLocation *iface);
static void iface_modem_messaging_init (MMIfaceModemMessaging *iface);
static void iface_modem_voice_init (MMIfaceModemVoice *iface);
static void iface_modem_time_init (MMIfaceModemTime *iface);
static void iface_modem_signal_init (MMIfaceModemSignal *iface);
static void iface_modem_oma_init (MMIfaceModemOma *iface);
static void iface_modem_firmware_init (MMIfaceModemFirmware *iface);

G_DEFINE_TYPE_EXTENDED (MMBroadbandModem, mm_broadband_modem, MM_TYPE_BASE_MODEM, 0,
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP_USSD, iface_modem_3gpp_ussd_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_CDMA, iface_modem_cdma_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIMPLE, iface_modem_simple_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_VOICE, iface_modem_voice_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_SIGNAL, iface_modem_signal_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_OMA, iface_modem_oma_init)
                        G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init))

enum {
    PROP_0,
    PROP_MODEM_DBUS_SKELETON,
    PROP_MODEM_3GPP_DBUS_SKELETON,
    PROP_MODEM_3GPP_USSD_DBUS_SKELETON,
    PROP_MODEM_CDMA_DBUS_SKELETON,
    PROP_MODEM_SIMPLE_DBUS_SKELETON,
    PROP_MODEM_LOCATION_DBUS_SKELETON,
    PROP_MODEM_MESSAGING_DBUS_SKELETON,
    PROP_MODEM_VOICE_DBUS_SKELETON,
    PROP_MODEM_TIME_DBUS_SKELETON,
    PROP_MODEM_SIGNAL_DBUS_SKELETON,
    PROP_MODEM_OMA_DBUS_SKELETON,
    PROP_MODEM_FIRMWARE_DBUS_SKELETON,
    PROP_MODEM_SIM,
    PROP_MODEM_BEARER_LIST,
    PROP_MODEM_STATE,
    PROP_MODEM_3GPP_REGISTRATION_STATE,
    PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
    PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
    PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
    PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
    PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
    PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE,
    PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED,
    PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED,
    PROP_MODEM_MESSAGING_SMS_LIST,
    PROP_MODEM_MESSAGING_SMS_PDU_MODE,
    PROP_MODEM_MESSAGING_SMS_DEFAULT_STORAGE,
    PROP_MODEM_VOICE_CALL_LIST,
    PROP_MODEM_SIMPLE_STATUS,
    PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
    PROP_LAST
};

/* When CIND is supported, invalid indicators are marked with this value */
#define CIND_INDICATOR_INVALID 255
#define CIND_INDICATOR_IS_VALID(u) (u != CIND_INDICATOR_INVALID)

typedef struct _PortsContext PortsContext;

struct _MMBroadbandModemPrivate {
    /* Broadband modem specific implementation */
    PortsContext *enabled_ports_ctx;
    PortsContext *sim_hot_swap_ports_ctx;
    gboolean modem_init_run;
    gboolean sim_hot_swap_supported;

    /*<--- Modem interface --->*/
    /* Properties */
    GObject *modem_dbus_skeleton;
    MMBaseSim *modem_sim;
    MMBearerList *modem_bearer_list;
    MMModemState modem_state;
    /* Implementation helpers */
    MMModemCharset modem_current_charset;
    gboolean modem_cind_support_checked;
    gboolean modem_cind_supported;
    guint modem_cind_indicator_signal_quality;
    guint modem_cind_min_signal_quality;
    guint modem_cind_max_signal_quality;
    guint modem_cind_indicator_roaming;
    guint modem_cind_indicator_service;

    /*<--- Modem 3GPP interface --->*/
    /* Properties */
    GObject *modem_3gpp_dbus_skeleton;
    MMModem3gppRegistrationState modem_3gpp_registration_state;
    gboolean modem_3gpp_cs_network_supported;
    gboolean modem_3gpp_ps_network_supported;
    gboolean modem_3gpp_eps_network_supported;
    /* Implementation helpers */
    GPtrArray *modem_3gpp_registration_regex;
    MMModem3gppFacility modem_3gpp_ignored_facility_locks;

    /*<--- Modem 3GPP USSD interface --->*/
    /* Properties */
    GObject *modem_3gpp_ussd_dbus_skeleton;
    /* Implementation helpers */
    gboolean use_unencoded_ussd;
    GSimpleAsyncResult *pending_ussd_action;

    /*<--- Modem CDMA interface --->*/
    /* Properties */
    GObject *modem_cdma_dbus_skeleton;
    MMModemCdmaRegistrationState modem_cdma_cdma1x_registration_state;
    MMModemCdmaRegistrationState modem_cdma_evdo_registration_state;
    gboolean modem_cdma_cdma1x_network_supported;
    gboolean modem_cdma_evdo_network_supported;
    GCancellable *modem_cdma_pending_registration_cancellable;
    /* Implementation helpers */
    gboolean checked_sprint_support;
    gboolean has_spservice;
    gboolean has_speri;
    gint evdo_pilot_rssi;

    /*<--- Modem Simple interface --->*/
    /* Properties */
    GObject *modem_simple_dbus_skeleton;
    MMSimpleStatus *modem_simple_status;

    /*<--- Modem Location interface --->*/
    /* Properties */
    GObject *modem_location_dbus_skeleton;

    /*<--- Modem Messaging interface --->*/
    /* Properties */
    GObject *modem_messaging_dbus_skeleton;
    MMSmsList *modem_messaging_sms_list;
    gboolean modem_messaging_sms_pdu_mode;
    MMSmsStorage modem_messaging_sms_default_storage;
    /* Implementation helpers */
    gboolean sms_supported_modes_checked;
    gboolean mem1_storage_locked;
    MMSmsStorage current_sms_mem1_storage;
    gboolean mem2_storage_locked;
    MMSmsStorage current_sms_mem2_storage;

    /*<--- Modem Voice interface --->*/
    /* Properties */
    GObject *modem_voice_dbus_skeleton;
    MMCallList *modem_voice_call_list;

    /*<--- Modem Time interface --->*/
    /* Properties */
    GObject *modem_time_dbus_skeleton;

    /*<--- Modem Signal interface --->*/
    /* Properties */
    GObject *modem_signal_dbus_skeleton;

    /*<--- Modem OMA interface --->*/
    /* Properties */
    GObject *modem_oma_dbus_skeleton;

    /*<--- Modem Firmware interface --->*/
    /* Properties */
    GObject *modem_firmware_dbus_skeleton;
};

/*****************************************************************************/

static gboolean
response_processor_string_ignore_at_errors (MMBaseModem *self,
                                            gpointer none,
                                            const gchar *command,
                                            const gchar *response,
                                            gboolean last_command,
                                            const GError *error,
                                            GVariant **result,
                                            GError **result_error)
{
    if (error) {
        /* Ignore AT errors (ie, ERROR or CMx ERROR) */
        if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command)
            *result_error = g_error_copy (error);

        return FALSE;
    }

    *result = g_variant_new_string (response);
    return TRUE;
}

/*****************************************************************************/
/* Create Bearer (Modem interface) */

static MMBaseBearer *
modem_create_bearer_finish (MMIfaceModem *self,
                            GAsyncResult *res,
                            GError **error)
{
    MMBaseBearer *bearer;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return NULL;

    bearer = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    mm_dbg ("New bearer created at DBus path '%s'", mm_base_bearer_get_path (bearer));

    return g_object_ref (bearer);
}

static void
broadband_bearer_new_ready (GObject *source,
                            GAsyncResult *res,
                            GSimpleAsyncResult *simple)
{
    MMBaseBearer *bearer = NULL;
    GError *error = NULL;

    bearer = mm_broadband_bearer_new_finish (res, &error);
    if (!bearer)
        g_simple_async_result_take_error (simple, error);
    else
        g_simple_async_result_set_op_res_gpointer (simple,
                                                   bearer,
                                                   (GDestroyNotify)g_object_unref);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_create_bearer (MMIfaceModem *self,
                     MMBearerProperties *properties,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
    GSimpleAsyncResult *result;

    /* Set a new ref to the bearer object as result */
    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_create_bearer);

    /* We just create a MMBroadbandBearer */
    mm_dbg ("Creating Broadband bearer in broadband modem");
    mm_broadband_bearer_new (MM_BROADBAND_MODEM (self),
                             properties,
                             NULL, /* cancellable */
                             (GAsyncReadyCallback)broadband_bearer_new_ready,
                             result);
}

/*****************************************************************************/
/* Create SIM (Modem interface) */

static MMBaseSim *
modem_create_sim_finish (MMIfaceModem *self,
                         GAsyncResult *res,
                         GError **error)
{
    return mm_base_sim_new_finish (res, error);
}

static void
modem_create_sim (MMIfaceModem *self,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    /* New generic SIM */
    mm_base_sim_new (MM_BASE_MODEM (self),
                     NULL, /* cancellable */
                     callback,
                     user_data);
}

/*****************************************************************************/
/* Capabilities loading (Modem interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMModemCapability caps;
    MMPortSerialQcdm *qcdm_port;
} LoadCapabilitiesContext;

static void
load_capabilities_context_complete_and_free (LoadCapabilitiesContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    if (ctx->qcdm_port) {
        mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm_port));
        g_object_unref (ctx->qcdm_port);
    }
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_slice_free (LoadCapabilitiesContext, ctx);
}

static MMModemCapability
modem_load_current_capabilities_finish (MMIfaceModem *self,
                                        GAsyncResult *res,
                                        GError **error)
{
    MMModemCapability caps;
    gchar *caps_str;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_CAPABILITY_NONE;

    caps = (MMModemCapability) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
    caps_str = mm_modem_capability_build_string_from_mask (caps);
    mm_dbg ("loaded current capabilities: %s", caps_str);
    g_free (caps_str);
    return caps;
}

static void
current_capabilities_ws46_test_ready (MMBaseModem *self,
                                      GAsyncResult *res,
                                      LoadCapabilitiesContext *ctx)
{
    const gchar *response;

    /* Completely ignore errors in AT+WS46=? */
    response = mm_base_modem_at_command_finish (self, res, NULL);
    if (response &&
        (strstr (response, "28") != NULL ||   /* 4G only */
         strstr (response, "30") != NULL ||   /* 2G/4G */
         strstr (response, "31") != NULL)) {  /* 3G/4G */
        /* Add LTE caps */
        ctx->caps |= MM_MODEM_CAPABILITY_LTE;
    }

    g_simple_async_result_set_op_res_gpointer (
        ctx->result,
        GUINT_TO_POINTER (ctx->caps),
        NULL);
    load_capabilities_context_complete_and_free (ctx);
}

typedef struct {
    gchar *name;
    MMModemCapability bits;
} ModemCaps;

static const ModemCaps modem_caps[] = {
    { "+CGSM",     MM_MODEM_CAPABILITY_GSM_UMTS  },
    { "+CLTE2",    MM_MODEM_CAPABILITY_LTE       }, /* Novatel */
    { "+CLTE1",    MM_MODEM_CAPABILITY_LTE       }, /* Novatel */
    { "+CLTE",     MM_MODEM_CAPABILITY_LTE       },
    { "+CIS707-A", MM_MODEM_CAPABILITY_CDMA_EVDO },
    { "+CIS707A",  MM_MODEM_CAPABILITY_CDMA_EVDO }, /* Cmotech */
    { "+CIS707",   MM_MODEM_CAPABILITY_CDMA_EVDO },
    { "CIS707",    MM_MODEM_CAPABILITY_CDMA_EVDO }, /* Qualcomm Gobi */
    { "+CIS707P",  MM_MODEM_CAPABILITY_CDMA_EVDO },
    { "CIS-856",   MM_MODEM_CAPABILITY_CDMA_EVDO },
    { "+IS-856",   MM_MODEM_CAPABILITY_CDMA_EVDO }, /* Cmotech */
    { "CIS-856-A", MM_MODEM_CAPABILITY_CDMA_EVDO },
    { "CIS-856A",  MM_MODEM_CAPABILITY_CDMA_EVDO }, /* Kyocera KPC680 */
    { "+WIRIDIUM", MM_MODEM_CAPABILITY_IRIDIUM   }, /* Iridium satellite modems */
    { "CDMA 1x",   MM_MODEM_CAPABILITY_CDMA_EVDO }, /* Huawei Data07, ATI reply */
    /* TODO: FCLASS, MS, ES, DS? */
    { NULL }
};

static gboolean
parse_caps_gcap (MMBaseModem *self,
                 gpointer none,
                 const gchar *command,
                 const gchar *response,
                 gboolean last_command,
                 const GError *error,
                 GVariant **variant,
                 GError **result_error)
{
    const ModemCaps *cap = modem_caps;
    guint32 ret = 0;

    if (!response)
        return FALSE;

    /* Some modems (Huawei E160g) won't respond to +GCAP with no SIM, but
     * will respond to ATI.  Ignore the error and continue.
     */
    if (strstr (response, "+CME ERROR:"))
        return FALSE;

    while (cap->name) {
        if (strstr (response, cap->name))
            ret |= cap->bits;
        cap++;
    }

    /* No result built? */
    if (ret == 0)
        return FALSE;

    *variant = g_variant_new_uint32 (ret);
    return TRUE;
}

static gboolean
parse_caps_cpin (MMBaseModem *self,
                 gpointer none,
                 const gchar *command,
                 const gchar *response,
                 gboolean last_command,
                 const GError *error,
                 GVariant **result,
                 GError **result_error)
{
    if (!response)
        return FALSE;

    if (strcasestr (response, "SIM PIN") ||
        strcasestr (response, "SIM PUK") ||
        strcasestr (response, "PH-SIM PIN") ||
        strcasestr (response, "PH-FSIM PIN") ||
        strcasestr (response, "PH-FSIM PUK") ||
        strcasestr (response, "SIM PIN2") ||
        strcasestr (response, "SIM PUK2") ||
        strcasestr (response, "PH-NET PIN") ||
        strcasestr (response, "PH-NET PUK") ||
        strcasestr (response, "PH-NETSUB PIN") ||
        strcasestr (response, "PH-NETSUB PUK") ||
        strcasestr (response, "PH-SP PIN") ||
        strcasestr (response, "PH-SP PUK") ||
        strcasestr (response, "PH-CORP PIN") ||
        strcasestr (response, "PH-CORP PUK") ||
        strcasestr (response, "READY")) {
        /* At least, it's a GSM modem */
        *result = g_variant_new_uint32 (MM_MODEM_CAPABILITY_GSM_UMTS);
        return TRUE;
    }
    return FALSE;
}

static gboolean
parse_caps_cgmm (MMBaseModem *self,
                 gpointer none,
                 const gchar *command,
                 const gchar *response,
                 gboolean last_command,
                 const GError *error,
                 GVariant **result,
                 GError **result_error)
{
    if (!response)
        return FALSE;

    /* This check detects some really old Motorola GPRS dongles and phones */
    if (strstr (response, "GSM900") ||
        strstr (response, "GSM1800") ||
        strstr (response, "GSM1900") ||
        strstr (response, "GSM850")) {
        /* At least, it's a GSM modem */
        *result = g_variant_new_uint32 (MM_MODEM_CAPABILITY_GSM_UMTS);
        return TRUE;
    }
    return FALSE;
}

static const MMBaseModemAtCommand capabilities[] = {
    { "+GCAP",  2, TRUE,  parse_caps_gcap },
    { "I",      1, TRUE,  parse_caps_gcap }, /* yes, really parse as +GCAP */
    { "+CPIN?", 1, FALSE, parse_caps_cpin },
    { "+CGMM",  1, TRUE,  parse_caps_cgmm },
    { NULL }
};

static void
capabilities_sequence_ready (MMBaseModem *self,
                             GAsyncResult *res,
                             LoadCapabilitiesContext *ctx)
{
    GError *error = NULL;
    GVariant *result;

    result = mm_base_modem_at_sequence_finish (self, res, NULL, &error);
    if (!result) {
        if (error)
            g_simple_async_result_take_error (ctx->result, error);
        else {
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "%s",
                                             "Failed to determine modem capabilities.");
        }
        load_capabilities_context_complete_and_free (ctx);
        return;
    }

    ctx->caps = (MMModemCapability)g_variant_get_uint32 (result);

    /* Some modems (e.g. Sierra Wireless MC7710 or ZTE MF820D) won't report LTE
     * capabilities even if they have them. So just run AT+WS46=? as well to see
     * if the current supported modes includes any LTE-specific mode.
     * This is not a big deal, as the AT+WS46=? command is a test command with a
     * cache-able result.
     *
     * E.g.:
     *  AT+WS46=?
     *   +WS46: (12,22,25,28,29)
     *   OK
     *
     */
    if (ctx->caps & MM_MODEM_CAPABILITY_GSM_UMTS &&
        !(ctx->caps & MM_MODEM_CAPABILITY_LTE)) {
        mm_base_modem_at_command (
            MM_BASE_MODEM (ctx->self),
            "+WS46=?",
            3,
            TRUE, /* allow caching, it's a test command */
            (GAsyncReadyCallback)current_capabilities_ws46_test_ready,
            ctx);
        return;
    }

    /* Otherwise, just set the already retrieved capabilities */
    g_simple_async_result_set_op_res_gpointer (
        ctx->result,
        GUINT_TO_POINTER (ctx->caps),
        NULL);
    load_capabilities_context_complete_and_free (ctx);
}

static void
load_current_capabilities_at (LoadCapabilitiesContext *ctx)
{
    /* Launch sequence, we will expect a "u" GVariant */
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (ctx->self),
        capabilities,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        (GAsyncReadyCallback)capabilities_sequence_ready,
        ctx);
}

static void
mode_pref_qcdm_ready (MMPortSerialQcdm *port,
                      GAsyncResult *res,
                      LoadCapabilitiesContext *ctx)
{
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    uint8_t pref = 0;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        /* Fall back to AT checking */
        mm_dbg ("Failed to load NV ModePref: %s", error->message);
        g_error_free (error);
        goto at_caps;
    }

    /* Parse the response */
    result = qcdm_cmd_nv_get_mode_pref_result ((const gchar *)response->data,
                                               response->len,
                                               &err);
    g_byte_array_unref (response);
    if (!result) {
        mm_dbg ("Failed to parse NV ModePref result: %d", err);
        g_byte_array_unref (response);
        goto at_caps;
    }

    err = qcdm_result_get_u8 (result, QCDM_CMD_NV_GET_MODE_PREF_ITEM_MODE_PREF, &pref);
    qcdm_result_unref (result);
    if (err) {
        mm_dbg ("Failed to read NV ModePref: %d", err);
        goto at_caps;
    }

    /* Only parse explicit modes; for 'auto' just fall back to whatever
     * the AT current capabilities probing figures out.
     */
    switch (pref) {
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_1X_HDR_LTE_ONLY:
        ctx->caps |= MM_MODEM_CAPABILITY_LTE;
        /* Fall through */
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_1X_ONLY:
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_HDR_ONLY:
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_1X_HDR_ONLY:
        ctx->caps |= MM_MODEM_CAPABILITY_CDMA_EVDO;
        break;
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_GSM_UMTS_LTE_ONLY:
        ctx->caps |= MM_MODEM_CAPABILITY_LTE;
        /* Fall through */
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_GPRS_ONLY:
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_UMTS_ONLY:
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_GSM_UMTS_ONLY:
        ctx->caps |= MM_MODEM_CAPABILITY_GSM_UMTS;
        break;
    case QCDM_CMD_NV_MODE_PREF_ITEM_MODE_PREF_LTE_ONLY:
        ctx->caps |= MM_MODEM_CAPABILITY_LTE;
        break;
    default:
        break;
    }

    if (ctx->caps != MM_MODEM_CAPABILITY_NONE) {
        g_simple_async_result_set_op_res_gpointer (
            ctx->result,
            GUINT_TO_POINTER (ctx->caps),
            NULL);
        load_capabilities_context_complete_and_free (ctx);
        return;
    }

at_caps:
    load_current_capabilities_at (ctx);
}

static void
load_current_capabilities_qcdm (LoadCapabilitiesContext *ctx)
{
    GByteArray *cmd;
    GError *error = NULL;

    ctx->qcdm_port = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (ctx->self));
    g_assert (ctx->qcdm_port);

    if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm_port), &error)) {
        mm_dbg ("Failed to open QCDM port for NV ModePref request: %s",
                error->message);
        g_error_free (error);
        ctx->qcdm_port = NULL;
        load_current_capabilities_at (ctx);
        return;
    }

    g_object_ref (ctx->qcdm_port);

    cmd = g_byte_array_sized_new (300);
    cmd->len = qcdm_cmd_nv_get_mode_pref_new ((char *) cmd->data, 300, 0);
    g_assert (cmd->len);

    mm_port_serial_qcdm_command (ctx->qcdm_port,
                                 cmd,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)mode_pref_qcdm_ready,
                                 ctx);
    g_byte_array_unref (cmd);
}

static void
modem_load_current_capabilities (MMIfaceModem *self,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
    LoadCapabilitiesContext *ctx;

    mm_dbg ("loading current capabilities...");

    ctx = g_slice_new0 (LoadCapabilitiesContext);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_load_current_capabilities);

    if (mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self)))
        load_current_capabilities_qcdm (ctx);
    else
        load_current_capabilities_at (ctx);
}

/*****************************************************************************/
/* Manufacturer loading (Modem interface) */

static gchar *
sanitize_info_reply (GVariant *v, const char *prefix)
{
    const gchar *reply, *p;
    gchar *sanitized;

    /* Strip any leading command reply */
    reply = g_variant_get_string (v, NULL);
    p = strstr (reply, prefix);
    if (p)
        reply = p + strlen (prefix);
    sanitized = g_strdup (reply);
    return mm_strip_quotes (g_strstrip (sanitized));
}

static gchar *
modem_load_manufacturer_finish (MMIfaceModem *self,
                                GAsyncResult *res,
                                GError **error)
{
    GVariant *result;
    gchar *manufacturer = NULL;

    result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
    if (result) {
        manufacturer = sanitize_info_reply (result, "GMI:");
        mm_dbg ("loaded manufacturer: %s", manufacturer);
    }
    return manufacturer;
}

static const MMBaseModemAtCommand manufacturers[] = {
    { "+CGMI",  3, TRUE, response_processor_string_ignore_at_errors },
    { "+GMI",   3, TRUE, response_processor_string_ignore_at_errors },
    { NULL }
};

static void
modem_load_manufacturer (MMIfaceModem *self,
                         GAsyncReadyCallback callback,
                         gpointer user_data)
{
    mm_dbg ("loading manufacturer...");
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        manufacturers,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        callback,
        user_data);
}

/*****************************************************************************/
/* Model loading (Modem interface) */

static gchar *
modem_load_model_finish (MMIfaceModem *self,
                         GAsyncResult *res,
                         GError **error)
{
    GVariant *result;
    gchar *model = NULL;

    result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
    if (result) {
        model = sanitize_info_reply (result, "GMM:");
        mm_dbg ("loaded model: %s", model);
    }
    return model;
}

static const MMBaseModemAtCommand models[] = {
    { "+CGMM",  3, TRUE, response_processor_string_ignore_at_errors },
    { "+GMM",   3, TRUE, response_processor_string_ignore_at_errors },
    { NULL }
};

static void
modem_load_model (MMIfaceModem *self,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    mm_dbg ("loading model...");
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        models,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        callback,
        user_data);
}

/*****************************************************************************/
/* Revision loading */

static gchar *
modem_load_revision_finish (MMIfaceModem *self,
                            GAsyncResult *res,
                            GError **error)
{
    GVariant *result;
    gchar *revision = NULL;

    result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
    if (result) {
        revision = sanitize_info_reply (result, "GMR:");
        mm_dbg ("loaded revision: %s", revision);
    }
    return revision;
}

static const MMBaseModemAtCommand revisions[] = {
    { "+CGMR",  3, TRUE, response_processor_string_ignore_at_errors },
    { "+GMR",   3, TRUE, response_processor_string_ignore_at_errors },
    { NULL }
};

static void
modem_load_revision (MMIfaceModem *self,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
    mm_dbg ("loading revision...");
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        revisions,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        callback,
        user_data);
}

/*****************************************************************************/
/* Equipment ID loading (Modem interface) */

static gchar *
modem_load_equipment_identifier_finish (MMIfaceModem *self,
                                        GAsyncResult *res,
                                        GError **error)
{
    GVariant *result;
    gchar *equip_id = NULL, *esn = NULL, *meid = NULL, *imei = NULL;

    result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
    if (result) {
        equip_id = sanitize_info_reply (result, "GSN:");

        /* Modems put all sorts of things into the GSN response; sanitize it */
        if (mm_parse_gsn (equip_id, &imei, &meid, &esn)) {
            g_free (equip_id);

            if (imei)
                equip_id = g_strdup (imei);
            else if (meid)
                equip_id = g_strdup (meid);
            else if (esn)
                equip_id = g_strdup (esn);
            g_free (esn);
            g_free (meid);
            g_free (imei);

            g_assert (equip_id);
        } else {
            /* Leave whatever the modem returned alone */
        }
        mm_dbg ("loaded equipment identifier: %s", equip_id);
    }
    return equip_id;
}

static const MMBaseModemAtCommand equipment_identifiers[] = {
    { "+CGSN",  3, TRUE, response_processor_string_ignore_at_errors },
    { "+GSN",   3, TRUE, response_processor_string_ignore_at_errors },
    { NULL }
};

static void
modem_load_equipment_identifier (MMIfaceModem *self,
                                 GAsyncReadyCallback callback,
                                 gpointer user_data)
{
    const MMBaseModemAtCommand *commands = equipment_identifiers;

    mm_dbg ("loading equipment identifier...");

    /* On CDMA-only (non-3GPP) modems, just try +GSN */
    if (mm_iface_modem_is_cdma_only (self))
        commands++;

    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        commands,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        callback,
        user_data);
}

/*****************************************************************************/
/* Device identifier loading (Modem interface) */

typedef struct {
    gchar *ati;
    gchar *ati1;
} DeviceIdentifierContext;

static void
device_identifier_context_free (DeviceIdentifierContext *ctx)
{
    g_free (ctx->ati);
    g_free (ctx->ati1);
    g_free (ctx);
}

static gchar *
modem_load_device_identifier_finish (MMIfaceModem *self,
                                     GAsyncResult *res,
                                     GError **error)
{
    GError *inner_error = NULL;
    gpointer ctx = NULL;
    gchar *device_identifier;

    mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, &ctx, &inner_error);
    if (inner_error) {
        g_propagate_error (error, inner_error);
        return NULL;
    }

    g_assert (ctx != NULL);
    device_identifier = (mm_broadband_modem_create_device_identifier (
                             MM_BROADBAND_MODEM (self),
                             ((DeviceIdentifierContext *)ctx)->ati,
                             ((DeviceIdentifierContext *)ctx)->ati1));
    mm_dbg ("loaded device identifier: %s", device_identifier);
    return device_identifier;
}

static gboolean
parse_ati_reply (MMBaseModem *self,
                 DeviceIdentifierContext *ctx,
                 const gchar *command,
                 const gchar *response,
                 gboolean last_command,
                 const GError *error,
                 GVariant **result,
                 GError **result_error)
{
    /* Store the proper string in the proper place */
    if (!error) {
        if (g_str_equal (command, "ATI1"))
            ctx->ati1 = g_strdup (response);
        else
            ctx->ati = g_strdup (response);
    }

    /* Always keep on, this is a sequence where all the steps should be taken */
    return TRUE;
}

static const MMBaseModemAtCommand device_identifier_steps[] = {
    { "ATI",  3, TRUE, (MMBaseModemAtResponseProcessor)parse_ati_reply },
    { "ATI1", 3, TRUE, (MMBaseModemAtResponseProcessor)parse_ati_reply },
    { NULL }
};

static void
modem_load_device_identifier (MMIfaceModem *self,
                              GAsyncReadyCallback callback,
                              gpointer user_data)
{
    mm_dbg ("loading device identifier...");
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        device_identifier_steps,
        g_new0 (DeviceIdentifierContext, 1),
        (GDestroyNotify)device_identifier_context_free,
        callback,
        user_data);
}

/*****************************************************************************/
/* Load own numbers (Modem interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *qcdm;
} OwnNumbersContext;

static void
own_numbers_context_complete_and_free (OwnNumbersContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    if (ctx->qcdm) {
        mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm));
        g_object_unref (ctx->qcdm);
    }
    g_free (ctx);
}

static GStrv
modem_load_own_numbers_finish (MMIfaceModem *self,
                               GAsyncResult *res,
                               GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return NULL;

    return g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
}

static void
mdn_qcdm_ready (MMPortSerialQcdm *port,
                GAsyncResult *res,
                OwnNumbersContext *ctx)
{
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    const char *numbers[2] = { NULL, NULL };
    GByteArray *response;
    GError *error = NULL;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        own_numbers_context_complete_and_free (ctx);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_nv_get_mdn_result ((const gchar *) response->data,
                                         response->len,
                                         &err);
    g_byte_array_unref (response);
    if (!result) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Failed to parse NV MDN command result: %d",
                                         err);
        own_numbers_context_complete_and_free (ctx);
        return;
    }

    if (qcdm_result_get_string (result, QCDM_CMD_NV_GET_MDN_ITEM_MDN, &numbers[0]) >= 0) {
        gboolean valid = TRUE;
        const char *p = numbers[0];

        /* Returned NV item data is read directly out of NV memory on the card,
         * so minimally verify it.
         */
        if (strlen (numbers[0]) < 6 || strlen (numbers[0]) > 15)
            valid = FALSE;

        /* MDN is always decimal digits; allow + for good measure */
        while (p && *p && valid)
            valid = g_ascii_isdigit (*p++) || (*p == '+');

        if (valid) {
            g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                       g_strdupv ((gchar **) numbers),
                                                       NULL);
        } else {
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "%s",
                                             "MDN from NV memory appears invalid");
        }
    } else {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "%s",
                                         "Failed retrieve MDN");
    }

    qcdm_result_unref (result);
    own_numbers_context_complete_and_free (ctx);
}

static void
modem_load_own_numbers_done (MMIfaceModem *self,
                             GAsyncResult *res,
                             OwnNumbersContext *ctx)
{
    const gchar *result;
    GError *error = NULL;
    GStrv numbers;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!result) {
        /* try QCDM */
        if (ctx->qcdm) {
            GByteArray *mdn;

            g_clear_error (&error);

            mdn = g_byte_array_sized_new (200);
            mdn->len = qcdm_cmd_nv_get_mdn_new ((char *) mdn->data, 200, 0);
            g_assert (mdn->len);

            mm_port_serial_qcdm_command (ctx->qcdm,
                                         mdn,
                                         3,
                                         NULL,
                                         (GAsyncReadyCallback)mdn_qcdm_ready,
                                         ctx);
            g_byte_array_unref (mdn);
            return;
        }
    } else {
        numbers = mm_3gpp_parse_cnum_exec_response (result, &error);
        if (numbers)
            g_simple_async_result_set_op_res_gpointer (ctx->result, numbers, NULL);
    }

    if (error)
        g_simple_async_result_take_error (ctx->result, error);

    own_numbers_context_complete_and_free (ctx);
}

static void
modem_load_own_numbers (MMIfaceModem *self,
                        GAsyncReadyCallback callback,
                        gpointer user_data)
{
    OwnNumbersContext *ctx;
    GError *error = NULL;

    ctx = g_new0 (OwnNumbersContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_load_own_numbers);
    ctx->qcdm = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self));
    if (ctx->qcdm) {
        if (mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm), &error)) {
            ctx->qcdm = g_object_ref (ctx->qcdm);
        } else {
            mm_dbg ("Couldn't open QCDM port: (%d) %s",
                    error ? error->code : -1,
                    error ? error->message : "(unknown)");
            ctx->qcdm = NULL;
        }
    }

    mm_dbg ("loading own numbers...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CNUM",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)modem_load_own_numbers_done,
                              ctx);
}

/*****************************************************************************/
/* Check if unlock required (Modem interface) */

typedef struct {
    const gchar *result;
    MMModemLock code;
} CPinResult;

static CPinResult unlock_results[] = {
    /* Longer entries first so we catch the correct one with strcmp() */
    { "READY",         MM_MODEM_LOCK_NONE           },
    { "SIM PIN2",      MM_MODEM_LOCK_SIM_PIN2       },
    { "SIM PUK2",      MM_MODEM_LOCK_SIM_PUK2       },
    { "SIM PIN",       MM_MODEM_LOCK_SIM_PIN        },
    { "SIM PUK",       MM_MODEM_LOCK_SIM_PUK        },
    { "PH-NETSUB PIN", MM_MODEM_LOCK_PH_NETSUB_PIN  },
    { "PH-NETSUB PUK", MM_MODEM_LOCK_PH_NETSUB_PUK  },
    { "PH-FSIM PIN",   MM_MODEM_LOCK_PH_FSIM_PIN    },
    { "PH-FSIM PUK",   MM_MODEM_LOCK_PH_FSIM_PUK    },
    { "PH-CORP PIN",   MM_MODEM_LOCK_PH_CORP_PIN    },
    { "PH-CORP PUK",   MM_MODEM_LOCK_PH_CORP_PUK    },
    { "PH-SIM PIN",    MM_MODEM_LOCK_PH_SIM_PIN     },
    { "PH-NET PIN",    MM_MODEM_LOCK_PH_NET_PIN     },
    { "PH-NET PUK",    MM_MODEM_LOCK_PH_NET_PUK     },
    { "PH-SP PIN",     MM_MODEM_LOCK_PH_SP_PIN      },
    { "PH-SP PUK",     MM_MODEM_LOCK_PH_SP_PUK      },
    { NULL }
};

static MMModemLock
modem_load_unlock_required_finish (MMIfaceModem *self,
                                   GAsyncResult *res,
                                   GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_LOCK_UNKNOWN;

    return (MMModemLock) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                               G_SIMPLE_ASYNC_RESULT (res)));
}

static void
cpin_query_ready (MMIfaceModem *self,
                  GAsyncResult *res,
                  GSimpleAsyncResult *simple)
{

    MMModemLock lock = MM_MODEM_LOCK_UNKNOWN;
    const gchar *result;
    GError *error = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    if (result &&
        strstr (result, "+CPIN:")) {
        CPinResult *iter = &unlock_results[0];
        const gchar *str;

        str = strstr (result, "+CPIN:") + 6;
        /* Skip possible whitespaces after '+CPIN:' and before the response */
        while (*str == ' ')
            str++;

        /* Some phones (Motorola EZX models) seem to quote the response */
        if (str[0] == '"')
            str++;

        /* Translate the reply */
        while (iter->result) {
            if (g_str_has_prefix (str, iter->result)) {
                lock = iter->code;
                break;
            }
            iter++;
        }
    }

    g_simple_async_result_set_op_res_gpointer (simple,
                                               GUINT_TO_POINTER (lock),
                                               NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_load_unlock_required (MMIfaceModem *self,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_load_unlock_required);

    /* CDMA-only modems don't need this */
    if (mm_iface_modem_is_cdma_only (self)) {
        mm_dbg ("Skipping unlock check in CDMA-only modem...");
        g_simple_async_result_set_op_res_gpointer (result,
                                                   GUINT_TO_POINTER (MM_MODEM_LOCK_NONE),
                                                   NULL);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    mm_dbg ("checking if unlock required...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CPIN?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)cpin_query_ready,
                              result);
}

/*****************************************************************************/
/* Supported modes loading (Modem interface) */

typedef struct {
    GSimpleAsyncResult *result;
    MMBroadbandModem *self;
    MMModemMode mode;
    gboolean run_cnti;
    gboolean run_ws46;
    gboolean run_gcap;
} LoadSupportedModesContext;

static void
load_supported_modes_context_complete_and_free (LoadSupportedModesContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_slice_free (LoadSupportedModesContext, ctx);
}

static GArray *
modem_load_supported_modes_finish (MMIfaceModem *self,
                                   GAsyncResult *res,
                                   GError **error)
{
    GArray *modes;
    MMModemModeCombination mode;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return NULL;

    /* Build a mask with all supported modes */
    modes = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1);
    mode.allowed = (MMModemMode) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                                       G_SIMPLE_ASYNC_RESULT (res)));
    mode.preferred = MM_MODEM_MODE_NONE;
    g_array_append_val (modes, mode);

    return modes;
}

static void load_supported_modes_step (LoadSupportedModesContext *ctx);

static void
supported_modes_gcap_ready (MMBaseModem *self,
                            GAsyncResult *res,
                            LoadSupportedModesContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!error) {
        MMModemMode mode = MM_MODEM_MODE_NONE;

        if (strstr (response, "IS")) {
            /* IS-856 is the EV-DO family */
            if (strstr (response, "856")) {
                if (!ctx->self->priv->modem_cdma_evdo_network_supported) {
                    ctx->self->priv->modem_cdma_evdo_network_supported = TRUE;
                    g_object_notify (G_OBJECT (ctx->self), MM_IFACE_MODEM_CDMA_EVDO_NETWORK_SUPPORTED);
                }
                mm_dbg ("Device allows (CDMA) 3G network mode");
                mode |= MM_MODEM_MODE_3G;
            }
            /* IS-707 is the 1xRTT family, which we consider as 2G */
            if (strstr (response, "707")) {
                if (!ctx->self->priv->modem_cdma_cdma1x_network_supported) {
                    ctx->self->priv->modem_cdma_cdma1x_network_supported = TRUE;
                    g_object_notify (G_OBJECT (ctx->self), MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED);
                }
                mm_dbg ("Device allows (CDMA) 2G network mode");
                mode |= MM_MODEM_MODE_2G;
            }
        }

        /* If no expected mode found, error */
        if (mode == MM_MODEM_MODE_NONE) {
            /* This should really never happen in the default implementation. */
            error = g_error_new (MM_CORE_ERROR,
                                 MM_CORE_ERROR_FAILED,
                                 "Couldn't find specific CDMA mode in capabilities string: '%s'",
                                 response);
        } else {
            /* Keep our results */
            ctx->mode |= mode;
        }
    }

    if (error) {
        mm_dbg ("Generic query of supported CDMA networks failed: '%s'", error->message);
        g_error_free (error);

        /* Use defaults */
        if (ctx->self->priv->modem_cdma_cdma1x_network_supported) {
            mm_dbg ("Assuming device allows (CDMA) 2G network mode");
            ctx->mode |= MM_MODEM_MODE_2G;
        }
        if (ctx->self->priv->modem_cdma_evdo_network_supported) {
            mm_dbg ("Assuming device allows (CDMA) 3G network mode");
            ctx->mode |= MM_MODEM_MODE_3G;
        }
    }

    /* Now keep on with the loading, we're probably finishing now */
    ctx->run_gcap = FALSE;
    load_supported_modes_step (ctx);
}

static void
supported_modes_ws46_test_ready (MMBroadbandModem *self,
                                 GAsyncResult *res,
                                 LoadSupportedModesContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!error) {
        MMModemMode mode = MM_MODEM_MODE_NONE;

        /*
         * More than one numeric ID may appear in the list, that's why
         * they are checked separately.
         *
         * NOTE: Do not skip WS46 prefix; it would break Cinterion handling.
         *
         * From 3GPP TS 27.007 v.11.2.0, section 5.9
         * 12	GSM Digital Cellular Systems (GERAN only)
         * 22	UTRAN only
         * 25	3GPP Systems (GERAN, UTRAN and E-UTRAN)
         * 28	E-UTRAN only
         * 29	GERAN and UTRAN
         * 30	GERAN and E-UTRAN
         * 31	UTRAN and E-UTRAN
         */

        if (strstr (response, "12") != NULL) {
            mm_dbg ("Device allows (3GPP) 2G-only network mode");
            mode |= MM_MODEM_MODE_2G;
        }

        if (strstr (response, "22") != NULL) {
            mm_dbg ("Device allows (3GPP) 3G-only network mode");
            mode |= MM_MODEM_MODE_3G;
        }

        if (strstr (response, "28") != NULL) {
            mm_dbg ("Device allows (3GPP) 4G-only network mode");
            mode |= MM_MODEM_MODE_4G;
        }

        if (strstr (response, "29") != NULL) {
            mm_dbg ("Device allows (3GPP) 2G/3G network mode");
            mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
        }

        if (strstr (response, "30") != NULL) {
            mm_dbg ("Device allows (3GPP) 2G/4G network mode");
            mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G);
        }

        if (strstr (response, "31") != NULL) {
            mm_dbg ("Device allows (3GPP) 3G/4G network mode");
            mode |= (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
        }

        if (strstr (response, "25") != NULL) {
            if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) {
                mm_dbg ("Device allows every supported 3GPP network mode (2G/3G/4G)");
                mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G);
            } else {
                mm_dbg ("Device allows every supported 3GPP network mode (2G/3G)");
                mode |= (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G);
            }
        }

        /* If no expected ID found, log error */
        if (mode == MM_MODEM_MODE_NONE)
            mm_dbg ("Invalid list of supported networks reported by WS46=?: '%s'", response);
        else
            ctx->mode |= mode;
    } else {
        mm_dbg ("Generic query of supported 3GPP networks with WS46=? failed: '%s'", error->message);
        g_error_free (error);
    }

    /* Now keep on with the loading, we may need CDMA-specific checks */
    ctx->run_ws46 = FALSE;
    load_supported_modes_step (ctx);
}

static void
supported_modes_cnti_ready (MMBroadbandModem *self,
                            GAsyncResult *res,
                            LoadSupportedModesContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!error) {
        MMModemMode mode = MM_MODEM_MODE_NONE;
        gchar *lower;

        lower = g_ascii_strdown (response, -1);

        if (g_strstr_len (lower, -1, "gsm") ||
            g_strstr_len (lower, -1, "gprs") ||
            g_strstr_len (lower, -1, "edge")) {
            mm_dbg ("Device allows (3GPP) 2G networks");
            mode |= MM_MODEM_MODE_2G;
        }

        if (g_strstr_len (lower, -1, "umts") ||
            g_strstr_len (lower, -1, "hsdpa") ||
            g_strstr_len (lower, -1, "hsupa") ||
            g_strstr_len (lower, -1, "hspa+")) {
            mm_dbg ("Device allows (3GPP) 3G networks");
            mode |= MM_MODEM_MODE_3G;
        }

        if (g_strstr_len (lower, -1, "lte")) {
            mm_dbg ("Device allows (3GPP) 4G networks");
            mode |= MM_MODEM_MODE_4G;
        }

        g_free (lower);

        /* If no expected ID found, log error */
        if (mode == MM_MODEM_MODE_NONE)
            mm_dbg ("Invalid list of supported networks reported by *CNTI: '%s'", response);
        else
            ctx->mode |= mode;
    } else {
        mm_dbg ("Generic query of supported 3GPP networks with *CNTI failed: '%s'", error->message);
        g_error_free (error);
    }

    /* Now keep on with the loading */
    ctx->run_cnti = FALSE;
    load_supported_modes_step (ctx);
}

static void
load_supported_modes_step (LoadSupportedModesContext *ctx)
{
    if (ctx->run_cnti) {
        mm_base_modem_at_command (
            MM_BASE_MODEM (ctx->self),
            "*CNTI=2",
            3,
            FALSE,
            (GAsyncReadyCallback)supported_modes_cnti_ready,
            ctx);
        return;
    }

    if (ctx->run_ws46) {
        mm_base_modem_at_command (
            MM_BASE_MODEM (ctx->self),
            "+WS46=?",
            3,
            TRUE, /* allow caching, it's a test command */
            (GAsyncReadyCallback)supported_modes_ws46_test_ready,
            ctx);
        return;
    }

    if (ctx->run_gcap) {
        mm_base_modem_at_command (
            MM_BASE_MODEM (ctx->self),
            "+GCAP",
            3,
            TRUE, /* allow caching */
            (GAsyncReadyCallback)supported_modes_gcap_ready,
            ctx);
        return;
    }

    /* All done.
     * If no mode found, error */
    if (ctx->mode == MM_MODEM_MODE_NONE)
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Couldn't retrieve supported modes");
    else
        g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                   GUINT_TO_POINTER (ctx->mode),
                                                   NULL);
    load_supported_modes_context_complete_and_free (ctx);
}

static void
modem_load_supported_modes (MMIfaceModem *self,
                            GAsyncReadyCallback callback,
                            gpointer user_data)
{
    LoadSupportedModesContext *ctx;

    mm_dbg ("loading supported modes...");
    ctx = g_slice_new0 (LoadSupportedModesContext);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_load_supported_modes);
    ctx->mode = MM_MODEM_MODE_NONE;

    if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self))) {
        /* Run +WS46=? and *CNTI=2 */
        ctx->run_ws46 = TRUE;
        ctx->run_cnti = TRUE;
    }

    if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (self))) {
        /* Run +GCAP in order to know if the modem is CDMA1x only or CDMA1x/EV-DO */
        ctx->run_gcap = TRUE;
    }

    load_supported_modes_step (ctx);
}

/*****************************************************************************/
/* Supported IP families loading (Modem interface) */

static MMBearerIpFamily
modem_load_supported_ip_families_finish (MMIfaceModem *self,
                                         GAsyncResult *res,
                                         GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_BEARER_IP_FAMILY_NONE;

    return (MMBearerIpFamily) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                                    G_SIMPLE_ASYNC_RESULT (res)));
}

static void
supported_ip_families_cgdcont_test_ready (MMBaseModem *self,
                                          GAsyncResult *res,
                                          GSimpleAsyncResult *simple)
{
    const gchar *response;
    GError *error = NULL;
    MMBearerIpFamily mask = MM_BEARER_IP_FAMILY_NONE;

    response = mm_base_modem_at_command_finish (self, res, &error);
    if (response) {
        GList *formats, *l;

        formats = mm_3gpp_parse_cgdcont_test_response (response, &error);
        for (l = formats; l; l = g_list_next (l))
            mask |= ((MM3gppPdpContextFormat *)(l->data))->pdp_type;

        mm_3gpp_pdp_context_format_list_free (formats);
    }

    if (error)
        g_simple_async_result_take_error (simple, error);
    else
        g_simple_async_result_set_op_res_gpointer (simple, GUINT_TO_POINTER (mask), NULL);

    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_load_supported_ip_families (MMIfaceModem *self,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
{
    GSimpleAsyncResult *result;

    mm_dbg ("loading supported IP families...");
    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_load_supported_ip_families);

    if (mm_iface_modem_is_cdma_only (MM_IFACE_MODEM (self))) {
        g_simple_async_result_set_op_res_gpointer (
            result,
            GUINT_TO_POINTER (MM_BEARER_IP_FAMILY_IPV4),
            NULL);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    /* Query with CGDCONT=? */
    mm_base_modem_at_command (
        MM_BASE_MODEM (self),
        "+CGDCONT=?",
        3,
        TRUE, /* allow caching, it's a test command */
        (GAsyncReadyCallback)supported_ip_families_cgdcont_test_ready,
        result);
}

/*****************************************************************************/
/* Signal quality loading (Modem interface) */

static void
qcdm_evdo_pilot_sets_log_handle (MMPortSerialQcdm *port,
                                 GByteArray *log_buffer,
                                 gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (user_data);
    QcdmResult *result;
    uint32_t num_active = 0;
    uint32_t pilot_pn = 0;
    uint32_t pilot_energy = 0;
    int32_t rssi_dbm = 0;

    result = qcdm_log_item_evdo_pilot_sets_v2_new ((const char *) log_buffer->data,
                                                   log_buffer->len,
                                                   NULL);
    if (!result)
        return;

    if (!qcdm_log_item_evdo_pilot_sets_v2_get_num (result,
                                                   QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_ACTIVE,
                                                   &num_active)) {
        qcdm_result_unref (result);
        return;
    }

    if (num_active > 0 &&
        qcdm_log_item_evdo_pilot_sets_v2_get_pilot (result,
                                                    QCDM_LOG_ITEM_EVDO_PILOT_SETS_V2_TYPE_ACTIVE,
                                                    0,
                                                    &pilot_pn,
                                                    &pilot_energy,
                                                    &rssi_dbm)) {
        mm_dbg ("EVDO active pilot RSSI: %ddBm", rssi_dbm);
        self->priv->evdo_pilot_rssi = rssi_dbm;
    }

    qcdm_result_unref (result);
}

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerial *port;
} SignalQualityContext;

static void
signal_quality_context_complete_and_free (SignalQualityContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    if (ctx->port)
        g_object_unref (ctx->port);
    g_free (ctx);
}

static guint
modem_load_signal_quality_finish (MMIfaceModem *self,
                                  GAsyncResult *res,
                                  GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return 0;

    return GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                 G_SIMPLE_ASYNC_RESULT (res)));
}

static guint
signal_quality_evdo_pilot_sets (MMBroadbandModem *self)
{
    gint dbm;

    if (self->priv->modem_cdma_evdo_registration_state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
        return 0;

    if (self->priv->evdo_pilot_rssi >= 0)
        return 0;

    dbm = CLAMP (self->priv->evdo_pilot_rssi, -113, -51);
    return 100 - ((dbm + 51) * 100 / (-113 + 51));
}

static void
signal_quality_csq_ready (MMBroadbandModem *self,
                          GAsyncResult *res,
                          SignalQualityContext *ctx)
{
    GError *error = NULL;
    GVariant *result;
    const gchar *result_str;

    result = mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        signal_quality_context_complete_and_free (ctx);
        return;
    }

    result_str = g_variant_get_string (result, NULL);
    if (result_str) {
        /* Got valid reply */
        int quality;
        int ber;

        result_str = mm_strip_tag (result_str, "+CSQ:");
        if (sscanf (result_str, "%d, %d", &quality, &ber)) {
            if (quality == 99) {
                /* 99 can mean unknown, no service, etc.  But the modem may
                 * also only report CDMA 1x quality in CSQ, so try EVDO via
                 * QCDM log messages too.
                 */
                quality = signal_quality_evdo_pilot_sets (self);
            } else {
                /* Normalize the quality */
                quality = CLAMP (quality, 0, 31) * 100 / 31;
            }
            g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                       GUINT_TO_POINTER (quality),
                                                       NULL);
            signal_quality_context_complete_and_free (ctx);
            return;
        }
    }

    g_simple_async_result_set_error (ctx->result,
                                     MM_CORE_ERROR,
                                     MM_CORE_ERROR_FAILED,
                                     "Could not parse signal quality results");
    signal_quality_context_complete_and_free (ctx);
}

/* Some modems want +CSQ, others want +CSQ?, and some of both types
 * will return ERROR if they don't get the command they want.  So
 * try the other command if the first one fails.
 */
static const MMBaseModemAtCommand signal_quality_csq_sequence[] = {
    { "+CSQ",  3, TRUE, response_processor_string_ignore_at_errors },
    { "+CSQ?", 3, TRUE, response_processor_string_ignore_at_errors },
    { NULL }
};

static void
signal_quality_csq (SignalQualityContext *ctx)
{
    mm_base_modem_at_sequence_full (
        MM_BASE_MODEM (ctx->self),
        MM_PORT_SERIAL_AT (ctx->port),
        signal_quality_csq_sequence,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        NULL, /* cancellable */
        (GAsyncReadyCallback)signal_quality_csq_ready,
        ctx);
}

static guint
normalize_ciev_cind_signal_quality (guint quality,
                                    guint min,
                                    guint max)
{
    if (!max) {
        /* If we didn't get a max, assume it was 5. Note that we do allow
         * 0, meaning no signal at all. */
        return (quality <= 5) ? (quality * 20) : 100;
    }

    if (quality >= min &&
        quality <= max)
        return ((100 * (quality - min)) / (max - min));

    /* Value out of range, assume no signal here. Some modems (Cinterion
     * for example) will send out-of-range values when they cannot get
     * the signal strength. */
    return 0;
}

static void
signal_quality_cind_ready (MMBroadbandModem *self,
                           GAsyncResult *res,
                           SignalQualityContext *ctx)
{
    GError *error = NULL;
    const gchar *result;
    GByteArray *indicators;
    guint quality = 0;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_clear_error (&error);
        goto try_csq;
    }

    indicators = mm_3gpp_parse_cind_read_response (result, &error);
    if (!indicators) {
        mm_dbg ("(%s) Could not parse CIND signal quality results: %s",
                mm_port_get_device (MM_PORT (ctx->port)),
                error->message);
        g_clear_error (&error);
        goto try_csq;
    }

    if (indicators->len < self->priv->modem_cind_indicator_signal_quality) {
        mm_dbg ("(%s) Could not parse CIND signal quality results; signal "
                "index (%u) outside received range (0-%u)",
                mm_port_get_device (MM_PORT (ctx->port)),
                self->priv->modem_cind_indicator_signal_quality,
                indicators->len);
    } else {
        quality = g_array_index (indicators,
                                 guint8,
                                 self->priv->modem_cind_indicator_signal_quality);
        quality = normalize_ciev_cind_signal_quality (quality,
                                                      self->priv->modem_cind_min_signal_quality,
                                                      self->priv->modem_cind_max_signal_quality);
    }
    g_byte_array_free (indicators, TRUE);

    if (quality > 0) {
        /* +CIND success */
        g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                   GUINT_TO_POINTER (quality),
                                                   NULL);
        signal_quality_context_complete_and_free (ctx);
        return;
    }

try_csq:
    /* Always fall back to +CSQ if for whatever reason +CIND failed.  Also,
     * some QMI-based devices say they support signal via CIND, but always
     * report zero even though they have signal.  So if we get zero signal
     * from +CIND, try CSQ too.  (bgo #636040)
     */
    signal_quality_csq (ctx);
}

static void
signal_quality_cind (SignalQualityContext *ctx)
{
    mm_base_modem_at_command_full (MM_BASE_MODEM (ctx->self),
                                   MM_PORT_SERIAL_AT (ctx->port),
                                   "+CIND?",
                                   3,
                                   FALSE,
                                   FALSE, /* raw */
                                   NULL, /* cancellable */
                                   (GAsyncReadyCallback)signal_quality_cind_ready,
                                   ctx);
}

static void
signal_quality_qcdm_ready (MMPortSerialQcdm *port,
                           GAsyncResult *res,
                           SignalQualityContext *ctx)
{
    QcdmResult *result;
    guint32 num = 0, quality = 0, i;
    gfloat best_db = -28;
    gint err = QCDM_SUCCESS;
    GByteArray *response;
    GError *error = NULL;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        signal_quality_context_complete_and_free (ctx);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_pilot_sets_result ((const gchar *) response->data,
                                         response->len,
                                         &err);
    g_byte_array_unref (response);
    if (!result) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Failed to parse pilot sets command result: %d",
                                         err);
        signal_quality_context_complete_and_free (ctx);
        return;
    }

    qcdm_cmd_pilot_sets_result_get_num (result, QCDM_CMD_PILOT_SETS_TYPE_ACTIVE, &num);
    for (i = 0; i < num; i++) {
        guint32 pn_offset = 0, ecio = 0;
        gfloat db = 0;

        qcdm_cmd_pilot_sets_result_get_pilot (result,
                                              QCDM_CMD_PILOT_SETS_TYPE_ACTIVE,
                                              i,
                                              &pn_offset,
                                              &ecio,
                                              &db);
        best_db = MAX (db, best_db);
    }
    qcdm_result_unref (result);

    if (num > 0) {
        #define BEST_ECIO 3
        #define WORST_ECIO 25

        /* EC/IO dB ranges from roughly 0 to -31 dB.  Lower == worse.  We
         * really only care about -3 to -25 dB though, since that's about what
         * you'll see in real-world usage.
         */
        best_db = CLAMP (ABS (best_db), BEST_ECIO, WORST_ECIO) - BEST_ECIO;
        quality = (guint32) (100 - (best_db * 100 / (WORST_ECIO - BEST_ECIO)));
    }

    g_simple_async_result_set_op_res_gpointer (ctx->result,
                                               GUINT_TO_POINTER (quality),
                                               NULL);
    signal_quality_context_complete_and_free (ctx);
}

static void
signal_quality_qcdm (SignalQualityContext *ctx)
{
    GByteArray *pilot_sets;
    guint quality;

    /* If EVDO is active try that signal strength first */
    quality = signal_quality_evdo_pilot_sets (ctx->self);
    if (quality > 0) {
        g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                   GUINT_TO_POINTER (quality),
                                                   NULL);
        signal_quality_context_complete_and_free (ctx);
        return;
    }

    /* Use CDMA1x pilot EC/IO if we can */
    pilot_sets = g_byte_array_sized_new (25);
    pilot_sets->len = qcdm_cmd_pilot_sets_new ((char *) pilot_sets->data, 25);
    g_assert (pilot_sets->len);

    mm_port_serial_qcdm_command (MM_PORT_SERIAL_QCDM (ctx->port),
                                 pilot_sets,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)signal_quality_qcdm_ready,
                                 ctx);
    g_byte_array_unref (pilot_sets);
}

static void
modem_load_signal_quality (MMIfaceModem *self,
                           GAsyncReadyCallback callback,
                           gpointer user_data)
{
    SignalQualityContext *ctx;
    GError *error = NULL;

    mm_dbg ("loading signal quality...");
    ctx = g_new0 (SignalQualityContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_load_signal_quality);

    /* Check whether we can get a non-connected AT port */
    ctx->port = (MMPortSerial *)mm_base_modem_get_best_at_port (MM_BASE_MODEM (self), &error);
    if (ctx->port) {
        if (MM_BROADBAND_MODEM (self)->priv->modem_cind_supported &&
            CIND_INDICATOR_IS_VALID (MM_BROADBAND_MODEM (self)->priv->modem_cind_indicator_signal_quality))
            signal_quality_cind (ctx);
        else
            signal_quality_csq (ctx);
        return;
    }

    /* If no best AT port available (all connected), try with QCDM ports */
    ctx->port = (MMPortSerial *)mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
    if (ctx->port) {
        g_error_free (error);
        signal_quality_qcdm (ctx);
        return;
    }

    /* Return the error we got when getting best AT port */
    g_simple_async_result_take_error (ctx->result, error);
    signal_quality_context_complete_and_free (ctx);
}

/*****************************************************************************/
/* Load access technology (Modem interface) */

typedef struct {
    MMModemAccessTechnology access_technologies;
    guint mask;
} AccessTechAndMask;

static gboolean
modem_load_access_technologies_finish (MMIfaceModem *self,
                                       GAsyncResult *res,
                                       MMModemAccessTechnology *access_technologies,
                                       guint *mask,
                                       GError **error)
{
    AccessTechAndMask *tech;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    tech = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    g_assert (tech);

    *access_technologies = tech->access_technologies;
    *mask = tech->mask;
    return TRUE;
}

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *port;

    guint32 opmode;
    guint32 sysmode;
    gboolean hybrid;

    gboolean wcdma_open;
    gboolean evdo_open;

    MMModemAccessTechnology fallback_act;
    guint fallback_mask;
} AccessTechContext;

static void
access_tech_context_complete_and_free (AccessTechContext *ctx,
                                       GError *error, /* takes ownership */
                                       gboolean idle)
{
    AccessTechAndMask *tech;
    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
    guint mask = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;

    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        goto done;
    }

    if (ctx->fallback_mask) {
        mm_dbg ("Fallback access technology: 0x%08x", ctx->fallback_act);
        act = ctx->fallback_act;
        mask = ctx->fallback_mask;
        goto done;
    }

    mm_dbg ("QCDM operating mode: %d", ctx->opmode);
    mm_dbg ("QCDM system mode: %d", ctx->sysmode);
    mm_dbg ("QCDM hybrid pref: %d", ctx->hybrid);
    mm_dbg ("QCDM WCDMA open: %d", ctx->wcdma_open);
    mm_dbg ("QCDM EVDO open: %d", ctx->evdo_open);

    if (ctx->opmode == QCDM_CMD_CM_SUBSYS_STATE_INFO_OPERATING_MODE_ONLINE) {
        switch (ctx->sysmode) {
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_CDMA:
            if (!ctx->hybrid || !ctx->evdo_open) {
                act = MM_MODEM_ACCESS_TECHNOLOGY_1XRTT;
                mask = MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK;
                break;
            }
            /* Fall through */
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_HDR:
            /* Assume EVDOr0; can't yet determine r0 vs. rA with QCDM */
            if (ctx->evdo_open)
                act = MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
            mask = MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK;
            break;
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GSM:
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_WCDMA:
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_GW:
            if (ctx->wcdma_open) {
                /* Assume UMTS; can't yet determine UMTS/HSxPA/HSPA+ with QCDM */
                act = MM_MODEM_ACCESS_TECHNOLOGY_UMTS;
            } else {
                /* Assume GPRS; can't yet determine GSM/GPRS/EDGE with QCDM */
                act = MM_MODEM_ACCESS_TECHNOLOGY_GPRS;
            }
            mask = MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK;
            break;
        case QCDM_CMD_CM_SUBSYS_STATE_INFO_SYSTEM_MODE_LTE:
            act = MM_MODEM_ACCESS_TECHNOLOGY_LTE;
            mask = MM_IFACE_MODEM_3GPP_ALL_ACCESS_TECHNOLOGIES_MASK;
            break;
        }
    }

done:
    if (error == NULL) {
        tech = g_new0 (AccessTechAndMask, 1);
        tech->access_technologies = act;
        tech->mask = mask;
        g_simple_async_result_set_op_res_gpointer (ctx->result, tech, g_free);
    }

    if (idle)
        g_simple_async_result_complete_in_idle (ctx->result);
    else
        g_simple_async_result_complete (ctx->result);

    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    if (ctx->port)
        g_object_unref (ctx->port);
    g_free (ctx);
}

static void
access_tech_qcdm_wcdma_ready (MMPortSerialQcdm *port,
                              GAsyncResult *res,
                              AccessTechContext *ctx)
{
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    guint8 l1;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_wcdma_subsys_state_info_result ((const gchar *) response->data,
                                                      response->len,
                                                      &err);
    g_byte_array_unref (response);
    if (result) {
        qcdm_result_get_u8 (result, QCDM_CMD_WCDMA_SUBSYS_STATE_INFO_ITEM_L1_STATE, &l1);
        qcdm_result_unref (result);

        if (l1 == QCDM_WCDMA_L1_STATE_PCH ||
            l1 == QCDM_WCDMA_L1_STATE_FACH ||
            l1 == QCDM_WCDMA_L1_STATE_DCH)
            ctx->wcdma_open = TRUE;
    }

    access_tech_context_complete_and_free (ctx, NULL, FALSE);
}

static void
access_tech_qcdm_gsm_ready (MMPortSerialQcdm *port,
                            GAsyncResult *res,
                            AccessTechContext *ctx)
{
    GByteArray *cmd;
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    guint8 opmode = 0;
    guint8 sysmode = 0;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_gsm_subsys_state_info_result ((const gchar *) response->data,
                                                    response->len,
                                                    &err);
    g_byte_array_unref (response);
    if (!result) {
        error = g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Failed to parse GSM subsys command result: %d",
                             err);
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    qcdm_result_get_u8 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_OP_MODE, &opmode);
    qcdm_result_get_u8 (result, QCDM_CMD_GSM_SUBSYS_STATE_INFO_ITEM_CM_SYS_MODE, &sysmode);
    qcdm_result_unref (result);

    ctx->opmode = opmode;
    ctx->sysmode = sysmode;

    /* WCDMA subsystem state */
    cmd = g_byte_array_sized_new (50);
    cmd->len = qcdm_cmd_wcdma_subsys_state_info_new ((char *) cmd->data, 50);
    g_assert (cmd->len);

    mm_port_serial_qcdm_command (port,
                                 cmd,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)access_tech_qcdm_wcdma_ready,
                                 ctx);
    g_byte_array_unref (cmd);
}

static void
access_tech_qcdm_hdr_ready (MMPortSerialQcdm *port,
                            GAsyncResult *res,
                            AccessTechContext *ctx)
{
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    guint8 session = 0;
    guint8 almp = 0;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_hdr_subsys_state_info_result ((const gchar *) response->data,
                                                    response->len,
                                                    &err);
    g_byte_array_unref (response);
    if (result) {
        qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, &session);
        qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, &almp);
        qcdm_result_unref (result);

        if (session == QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_OPEN &&
            (almp == QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_IDLE ||
             almp == QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_CONNECTED))
            ctx->evdo_open = TRUE;
    }

    access_tech_context_complete_and_free (ctx, NULL, FALSE);
}

static void
access_tech_qcdm_cdma_ready (MMPortSerialQcdm *port,
                             GAsyncResult *res,
                             AccessTechContext *ctx)
{
    GByteArray *cmd;
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    guint32 hybrid;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_cm_subsys_state_info_result ((const gchar *) response->data,
                                                   response->len,
                                                   &err);
    g_byte_array_unref (response);
    if (!result) {
        error = g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Failed to parse CM subsys command result: %d",
                             err);
        access_tech_context_complete_and_free (ctx, error, FALSE);
        return;
    }

    qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, &ctx->opmode);
    qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, &ctx->sysmode);
    qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_HYBRID_PREF, &hybrid);
    qcdm_result_unref (result);

    ctx->hybrid = !!hybrid;

    /* HDR subsystem state */
    cmd = g_byte_array_sized_new (50);
    cmd->len = qcdm_cmd_hdr_subsys_state_info_new ((char *) cmd->data, 50);
    g_assert (cmd->len);

    mm_port_serial_qcdm_command (port,
                                 cmd,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)access_tech_qcdm_hdr_ready,
                                 ctx);
    g_byte_array_unref (cmd);
}

static void
access_tech_from_cdma_registration_state (MMBroadbandModem *self,
                                          AccessTechContext *ctx)
{
    gboolean cdma1x_registered = FALSE;
    gboolean evdo_registered = FALSE;

    if (self->priv->modem_cdma_evdo_registration_state > MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
        evdo_registered = TRUE;

    if (self->priv->modem_cdma_cdma1x_registration_state > MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
        cdma1x_registered = TRUE;

    if (self->priv->modem_cdma_evdo_network_supported && evdo_registered) {
        ctx->fallback_act = MM_MODEM_ACCESS_TECHNOLOGY_EVDO0;
        ctx->fallback_mask = MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK;
    } else if (self->priv->modem_cdma_cdma1x_network_supported && cdma1x_registered) {
        ctx->fallback_act = MM_MODEM_ACCESS_TECHNOLOGY_1XRTT;
        ctx->fallback_mask = MM_IFACE_MODEM_CDMA_ALL_ACCESS_TECHNOLOGIES_MASK;
    }

    mm_dbg ("EVDO registration: %d", self->priv->modem_cdma_evdo_registration_state);
    mm_dbg ("CDMA1x registration: %d", self->priv->modem_cdma_cdma1x_registration_state);
    mm_dbg ("Fallback access tech: 0x%08x", ctx->fallback_act);
}

static void
modem_load_access_technologies (MMIfaceModem *self,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
{
    AccessTechContext *ctx;
    GByteArray *cmd;
    GError *error = NULL;

    /* For modems where only QCDM provides detailed information, try to
     * get access technologies via the various QCDM subsystems or from
     * registration state
     */
    ctx = g_new0 (AccessTechContext, 1);
    ctx->self = g_object_ref (self);
    ctx->port = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_load_access_technologies);

    if (!ctx->port) {
        if (mm_iface_modem_is_cdma (self)) {
            /* If we don't have a QCDM port but the modem is CDMA-only, then
             * guess access technologies from the registration information.
             */
            access_tech_from_cdma_registration_state (MM_BROADBAND_MODEM (self), ctx);
        } else {
            error = g_error_new_literal (MM_CORE_ERROR,
                                         MM_CORE_ERROR_UNSUPPORTED,
                                         "Cannot get 3GPP access technology without a QCDM port");
        }
        access_tech_context_complete_and_free (ctx, error, TRUE);
        return;
    }

    mm_dbg ("loading access technologies via QCDM...");

    /* FIXME: we may want to run both the CDMA and 3GPP in sequence to ensure
     * that a multi-mode device that's in CDMA-mode but still has 3GPP capabilities
     * will get the correct access tech, since the 3GPP check is run first.
     */

    if (mm_iface_modem_is_3gpp (self)) {
        cmd = g_byte_array_sized_new (50);
        cmd->len = qcdm_cmd_gsm_subsys_state_info_new ((char *) cmd->data, 50);
        g_assert (cmd->len);

        mm_port_serial_qcdm_command (ctx->port,
                                     cmd,
                                     3,
                                     NULL,
                                     (GAsyncReadyCallback)access_tech_qcdm_gsm_ready,
                                     ctx);
        g_byte_array_unref (cmd);
        return;
    }

    if (mm_iface_modem_is_cdma (self)) {
        cmd = g_byte_array_sized_new (50);
        cmd->len = qcdm_cmd_cm_subsys_state_info_new ((char *) cmd->data, 50);
        g_assert (cmd->len);

        mm_port_serial_qcdm_command (ctx->port,
                                     cmd,
                                     3,
                                     NULL,
                                     (GAsyncReadyCallback)access_tech_qcdm_cdma_ready,
                                     ctx);
        g_byte_array_unref (cmd);
        return;
    }

    g_assert_not_reached ();
}

/*****************************************************************************/
/* Setup/Cleanup unsolicited events (3GPP interface) */

static gboolean
modem_3gpp_setup_cleanup_unsolicited_events_finish (MMIfaceModem3gpp *self,
                                                    GAsyncResult *res,
                                                    GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
ciev_received (MMPortSerialAt *port,
               GMatchInfo *info,
               MMBroadbandModem *self)
{
    gint ind = 0;
    gchar *item;

    item = g_match_info_fetch (info, 1);
    if (item)
        ind = atoi (item);

    /* Handle signal quality change indication */
    if (ind == self->priv->modem_cind_indicator_signal_quality ||
        g_str_equal (item, "signal")) {
        gchar *value;

        value = g_match_info_fetch (info, 2);
        if (value) {
            gint quality = 0;

            quality = atoi (value);

            mm_iface_modem_update_signal_quality (
                MM_IFACE_MODEM (self),
                normalize_ciev_cind_signal_quality (quality,
                                                    self->priv->modem_cind_min_signal_quality,
                                                    self->priv->modem_cind_max_signal_quality));
            g_free (value);
        }
    }

    g_free (item);

    /* FIXME: handle roaming and service indicators.
     * ... wait, arent these already handle by unsolicited CREG responses? */
}

static void
set_unsolicited_events_handlers (MMBroadbandModem *self,
                                 gboolean enable)
{
    MMPortSerialAt *ports[2];
    GRegex *ciev_regex;
    guint i;

    ciev_regex = mm_3gpp_ciev_regex_get ();
    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Enable unsolicited events in given port */
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        /* Set/unset unsolicited CIEV event handler */
        mm_dbg ("(%s) %s 3GPP unsolicited events handlers",
                mm_port_get_device (MM_PORT (ports[i])),
                enable ? "Setting" : "Removing");
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            ciev_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) ciev_received : NULL,
            enable ? self : NULL,
            NULL);
    }

    g_regex_unref (ciev_regex);
}

static void
cind_format_check_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    GHashTable *indicators = NULL;
    GError *error = NULL;
    const gchar *result;
    MM3gppCindResponse *r;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error ||
        !(indicators = mm_3gpp_parse_cind_test_response (result, &error))) {
        /* unsupported indications */
        mm_dbg ("Marking indications as unsupported: '%s'", error->message);
        g_error_free (error);
        g_simple_async_result_set_op_res_gboolean (simple, TRUE);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* Mark CIND as being supported and find the proper indexes for the
     * indicators. */
    self->priv->modem_cind_supported = TRUE;

    /* Check if we support signal quality indications */
    r = g_hash_table_lookup (indicators, "signal");
    if (r) {
        self->priv->modem_cind_indicator_signal_quality = mm_3gpp_cind_response_get_index (r);
        self->priv->modem_cind_min_signal_quality = mm_3gpp_cind_response_get_min (r);
        self->priv->modem_cind_max_signal_quality = mm_3gpp_cind_response_get_max (r);

        mm_dbg ("Modem supports signal quality indications via CIND at index '%u'"
                "(min: %u, max: %u)",
                self->priv->modem_cind_indicator_signal_quality,
                self->priv->modem_cind_min_signal_quality,
                self->priv->modem_cind_max_signal_quality);
    } else
        self->priv->modem_cind_indicator_signal_quality = CIND_INDICATOR_INVALID;

    /* Check if we support roaming indications */
    r = g_hash_table_lookup (indicators, "roam");
    if (r) {
        self->priv->modem_cind_indicator_roaming = mm_3gpp_cind_response_get_index (r);
        mm_dbg ("Modem supports roaming indications via CIND at index '%u'",
                self->priv->modem_cind_indicator_roaming);
    } else
        self->priv->modem_cind_indicator_roaming = CIND_INDICATOR_INVALID;

    /* Check if we support service indications */
    r = g_hash_table_lookup (indicators, "service");
    if (r) {
        self->priv->modem_cind_indicator_service = mm_3gpp_cind_response_get_index (r);
        mm_dbg ("Modem supports service indications via CIND at index '%u'",
                self->priv->modem_cind_indicator_service);
    } else
        self->priv->modem_cind_indicator_service = CIND_INDICATOR_INVALID;

    g_hash_table_destroy (indicators);

    /* Now, keep on setting up the ports */
    set_unsolicited_events_handlers (self, TRUE);

    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_3gpp_setup_unsolicited_events (MMIfaceModem3gpp *_self,
                                     GAsyncReadyCallback callback,
                                     gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_setup_unsolicited_events);

    /* Load supported indicators */
    if (!self->priv->modem_cind_support_checked) {
        mm_dbg ("Checking indicator support...");
        self->priv->modem_cind_support_checked = TRUE;
        mm_base_modem_at_command (MM_BASE_MODEM (self),
                                  "+CIND=?",
                                  3,
                                  TRUE,
                                  (GAsyncReadyCallback)cind_format_check_ready,
                                  result);
        return;
    }

    /* If supported, go on */
    if (self->priv->modem_cind_supported)
        set_unsolicited_events_handlers (self, TRUE);

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

static void
modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *_self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_cleanup_unsolicited_events);

    /* If supported, go on */
    if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported)
        set_unsolicited_events_handlers (self, FALSE);

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Enabling/disabling unsolicited events (3GPP interface) */

typedef struct {
    MMBroadbandModem *self;
    gchar *command;
    gboolean enable;
    GSimpleAsyncResult *result;
    gboolean cmer_primary_done;
    gboolean cmer_secondary_done;
} UnsolicitedEventsContext;

static void
unsolicited_events_context_complete_and_free (UnsolicitedEventsContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx->command);
    g_free (ctx);
}

static gboolean
modem_3gpp_enable_disable_unsolicited_events_finish (MMIfaceModem3gpp *self,
                                                     GAsyncResult *res,
                                                     GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void run_unsolicited_events_setup (UnsolicitedEventsContext *ctx);

static void
unsolicited_events_setup_ready (MMBroadbandModem *self,
                                GAsyncResult *res,
                                UnsolicitedEventsContext *ctx)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!error) {
        /* Run on next port, if any */
        run_unsolicited_events_setup (ctx);
        return;
    }

    mm_dbg ("Couldn't %s event reporting: '%s'",
            ctx->enable ? "enable" : "disable",
            error->message);
    g_error_free (error);
    /* Consider this operation complete, ignoring errors */
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    unsolicited_events_context_complete_and_free (ctx);
}

static void
run_unsolicited_events_setup (UnsolicitedEventsContext *ctx)
{
    MMPortSerialAt *port = NULL;

    if (!ctx->cmer_primary_done) {
        ctx->cmer_primary_done = TRUE;
        port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self));
    } else if (!ctx->cmer_secondary_done) {
        ctx->cmer_secondary_done = TRUE;
        port = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (ctx->self));
    }

    /* Enable unsolicited events in given port */
    if (port) {
        mm_base_modem_at_command_full (MM_BASE_MODEM (ctx->self),
                                       port,
                                       ctx->command,
                                       3,
                                       FALSE,
                                       FALSE, /* raw */
                                       NULL, /* cancellable */
                                       (GAsyncReadyCallback)unsolicited_events_setup_ready,
                                       ctx);
        return;
    }

    /* If no more ports, we're fully done now */
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    unsolicited_events_context_complete_and_free (ctx);
}

static void
modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *_self,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_enable_unsolicited_events);

    /* If supported, go on */
    if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
        UnsolicitedEventsContext *ctx;

        ctx = g_new0 (UnsolicitedEventsContext, 1);
        ctx->self = g_object_ref (self);
        ctx->enable = TRUE;
        ctx->command = g_strdup ("+CMER=3,0,0,1");
        ctx->result = result;
        run_unsolicited_events_setup (ctx);
        return;
    }

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

static void
modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *_self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_disable_unsolicited_events);

    /* If supported, go on */
    if (self->priv->modem_cind_support_checked && self->priv->modem_cind_supported) {
        UnsolicitedEventsContext *ctx;

        ctx = g_new0 (UnsolicitedEventsContext, 1);
        ctx->self = g_object_ref (self);
        ctx->command = g_strdup ("+CMER=0");
        ctx->result = result;
        run_unsolicited_events_setup (ctx);
        return;
    }

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Setting modem charset (Modem interface) */

typedef struct {
    GSimpleAsyncResult *result;
    MMModemCharset charset;
    /* Commands to try in the sequence:
     *  First one with quotes
     *  Second without.
     *  + last NUL */
    MMBaseModemAtCommand charset_commands[3];
} SetupCharsetContext;

static void
setup_charset_context_free (SetupCharsetContext *ctx)
{
    g_object_unref (ctx->result);
    g_free (ctx->charset_commands[0].command);
    g_free (ctx->charset_commands[1].command);
    g_free (ctx);
}

static gboolean
modem_setup_charset_finish (MMIfaceModem *self,
                            GAsyncResult *res,
                            GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    return TRUE;
}

static void
current_charset_query_ready (MMBroadbandModem *self,
                             GAsyncResult *res,
                             SetupCharsetContext *ctx)
{
    GError *error = NULL;
    const gchar *response;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!response)
        g_simple_async_result_take_error (ctx->result, error);
    else {
        MMModemCharset current;
        const gchar *p;

        p = response;
        if (g_str_has_prefix (p, "+CSCS:"))
            p += 6;
        while (*p == ' ')
            p++;

        current = mm_modem_charset_from_string (p);
        if (ctx->charset != current)
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Modem failed to change character set to %s",
                                             mm_modem_charset_to_string (ctx->charset));
        else {
            /* We'll keep track ourselves of the current charset.
             * TODO: Make this a property so that plugins can also store it. */
            self->priv->modem_current_charset = current;
            g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        }
    }

    g_simple_async_result_complete (ctx->result);
    setup_charset_context_free (ctx);
}

static void
charset_change_ready (MMBroadbandModem *self,
                      GAsyncResult *res,
                      SetupCharsetContext *ctx)
{
    GError *error = NULL;

    mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        g_simple_async_result_complete (ctx->result);
        setup_charset_context_free (ctx);
        return;
    }

    /* Check whether we did properly set the charset */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CSCS?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)current_charset_query_ready,
                              ctx);
}

static void
modem_setup_charset (MMIfaceModem *self,
                     MMModemCharset charset,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
    SetupCharsetContext *ctx;
    const gchar *charset_str;

    /* NOTE: we already notified that CDMA-only modems couldn't load supported
     * charsets, so we'll never get here in such a case */
    g_assert (mm_iface_modem_is_cdma_only (self) == FALSE);

    /* Build charset string to use */
    charset_str = mm_modem_charset_to_string (charset);
    if (!charset_str) {
        g_simple_async_report_error_in_idle (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Unhandled character set 0x%X",
                                             charset);
        return;
    }

    /* Setup context, including commands to try */
    ctx = g_new0 (SetupCharsetContext, 1);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_setup_charset);
    ctx->charset = charset;
    /* First try, with quotes */
    ctx->charset_commands[0].command = g_strdup_printf ("+CSCS=\"%s\"", charset_str);
    ctx->charset_commands[0].timeout = 3;
    ctx->charset_commands[0].allow_cached = FALSE;
    ctx->charset_commands[0].response_processor = mm_base_modem_response_processor_no_result;
    /* Second try.
     * Some modems puke if you include the quotes around the character
     * set name, so lets try it again without them.
     */
    ctx->charset_commands[1].command = g_strdup_printf ("+CSCS=%s", charset_str);
    ctx->charset_commands[1].timeout = 3;
    ctx->charset_commands[1].allow_cached = FALSE;
    ctx->charset_commands[1].response_processor = mm_base_modem_response_processor_no_result;

    /* Launch sequence */
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        ctx->charset_commands,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        (GAsyncReadyCallback)charset_change_ready,
        ctx);
}

/*****************************************************************************/
/* Loading supported charsets (Modem interface) */

static MMModemCharset
modem_load_supported_charsets_finish (MMIfaceModem *self,
                                      GAsyncResult *res,
                                      GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_CHARSET_UNKNOWN;

    return GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                 G_SIMPLE_ASYNC_RESULT (res)));
}

static void
cscs_format_check_ready (MMBaseModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    MMModemCharset charsets = MM_MODEM_CHARSET_UNKNOWN;
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error)
        g_simple_async_result_take_error (simple, error);
    else if (!mm_3gpp_parse_cscs_test_response (response, &charsets))
        g_simple_async_result_set_error (
            simple,
            MM_CORE_ERROR,
            MM_CORE_ERROR_FAILED,
            "Failed to parse the supported character "
            "sets response");
    else
        g_simple_async_result_set_op_res_gpointer (simple,
                                                   GUINT_TO_POINTER (charsets),
                                                   NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_load_supported_charsets (MMIfaceModem *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_load_supported_charsets);

    /* CDMA-only modems don't need this */
    if (mm_iface_modem_is_cdma_only (self)) {
        mm_dbg ("Skipping supported charset loading in CDMA-only modem...");
        g_simple_async_result_set_op_res_gpointer (result,
                                                   GUINT_TO_POINTER (MM_MODEM_CHARSET_UNKNOWN),
                                                   NULL);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CSCS=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cscs_format_check_ready,
                              result);
}

/*****************************************************************************/
/* configuring flow control (Modem interface) */

static gboolean
modem_setup_flow_control_finish (MMIfaceModem *self,
                                 GAsyncResult *res,
                                 GError **error)
{
    /* Completely ignore errors */
    return TRUE;
}

static void
modem_setup_flow_control (MMIfaceModem *self,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
    GSimpleAsyncResult *result;

    /* By default, try to set XOFF/XON flow control */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+IFC=1,1",
                              3,
                              FALSE,
                              NULL,
                              NULL);

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_setup_flow_control);
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Power state loading (Modem interface) */

static MMModemPowerState
load_power_state_finish (MMIfaceModem *self,
                         GAsyncResult *res,
                         GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_POWER_STATE_UNKNOWN;

    return (MMModemPowerState)GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}

static void
cfun_query_ready (MMBaseModem *self,
                  GAsyncResult *res,
                  GSimpleAsyncResult *simple)
{
    const gchar *result;
    MMModemPowerState state;
    GError *error = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!result || !mm_3gpp_parse_cfun_query_generic_response (result, &state, &error))
        g_simple_async_result_take_error (simple, error);
    else
        g_simple_async_result_set_op_res_gpointer (simple, GUINT_TO_POINTER (state), NULL);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
load_power_state (MMIfaceModem *self,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        load_power_state);

    /* CDMA-only modems don't need this */
    if (mm_iface_modem_is_cdma_only (self)) {
        mm_dbg ("Assuming full power state in CDMA-only modem...");
        g_simple_async_result_set_op_res_gpointer (result, GUINT_TO_POINTER (MM_MODEM_POWER_STATE_ON), NULL);
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    mm_dbg ("loading power state...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CFUN?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)cfun_query_ready,
                              result);
}

/*****************************************************************************/
/* Powering up the modem (Modem interface) */

static gboolean
modem_power_up_finish (MMIfaceModem *self,
                       GAsyncResult *res,
                       GError **error)
{
    /* By default, errors in the power up command are ignored.
     * Plugins wanting to treat power up errors should subclass the power up
     * handling. */
    return TRUE;
}

static void
modem_power_up (MMIfaceModem *self,
                GAsyncReadyCallback callback,
                gpointer user_data)
{
    GSimpleAsyncResult *result;

    /* CDMA-only modems don't need this */
    if (mm_iface_modem_is_cdma_only (self))
        mm_dbg ("Skipping Power-up in CDMA-only modem...");
    else
        mm_base_modem_at_command (MM_BASE_MODEM (self),
                                  "+CFUN=1",
                                  5,
                                  FALSE,
                                  NULL,
                                  NULL);

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_power_up);
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Sending a command to the modem (Modem interface) */

static const gchar *
modem_command_finish (MMIfaceModem *self,
                      GAsyncResult *res,
                      GError **error)
{
    return mm_base_modem_at_command_finish (MM_BASE_MODEM (self),
                                            res,
                                            error);
}

static void
modem_command (MMIfaceModem *self,
               const gchar *cmd,
               guint timeout,
               GAsyncReadyCallback callback,
               gpointer user_data)
{

    mm_base_modem_at_command (MM_BASE_MODEM (self), cmd, timeout,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* IMEI loading (3GPP interface) */

static gchar *
modem_3gpp_load_imei_finish (MMIfaceModem3gpp *self,
                             GAsyncResult *res,
                             GError **error)
{
    const gchar *result;
    gchar *imei = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    result = mm_strip_tag (result, "+CGSN:");
    mm_parse_gsn (result, &imei, NULL, NULL);
    mm_dbg ("loaded IMEI: %s", imei);
    return imei;
}

static void
modem_3gpp_load_imei (MMIfaceModem3gpp *self,
                      GAsyncReadyCallback callback,
                      gpointer user_data)
{
    mm_dbg ("loading IMEI...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CGSN",
                              3,
                              TRUE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Facility locks status loading (3GPP interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    guint current;
    MMModem3gppFacility facilities;
    MMModem3gppFacility locks;
} LoadEnabledFacilityLocksContext;

static void get_next_facility_lock_status (LoadEnabledFacilityLocksContext *ctx);

static void
load_enabled_facility_locks_context_complete_and_free (LoadEnabledFacilityLocksContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static MMModem3gppFacility
modem_3gpp_load_enabled_facility_locks_finish (MMIfaceModem3gpp *self,
                                               GAsyncResult *res,
                                               GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_3GPP_FACILITY_NONE;

    return ((MMModem3gppFacility) GPOINTER_TO_UINT (
                g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res))));
}

static void
clck_single_query_ready (MMBaseModem *self,
                         GAsyncResult *res,
                         LoadEnabledFacilityLocksContext *ctx)
{
    const gchar *response;
    gboolean enabled = FALSE;

    response = mm_base_modem_at_command_finish (self, res, NULL);
    if (response &&
        mm_3gpp_parse_clck_write_response (response, &enabled) &&
        enabled) {
        ctx->locks |= (1 << ctx->current);
    } else {
        /* On errors, we'll just assume disabled */
        ctx->locks &= ~(1 << ctx->current);
    }

    /* And go on with the next one */
    ctx->current++;
    get_next_facility_lock_status (ctx);
}

static void
get_next_facility_lock_status (LoadEnabledFacilityLocksContext *ctx)
{
    guint i;

    for (i = ctx->current; i < sizeof (MMModem3gppFacility) * 8; i++) {
        guint32 facility = 1u << i;

        /* Found the next one to query! */
        if (ctx->facilities & facility) {
            gchar *cmd;

            /* Keep the current one */
            ctx->current = i;

            /* Query current */
            cmd = g_strdup_printf ("+CLCK=\"%s\",2",
                                   mm_3gpp_facility_to_acronym (facility));
            mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                                      cmd,
                                      3,
                                      FALSE,
                                      (GAsyncReadyCallback)clck_single_query_ready,
                                      ctx);
            g_free (cmd);
            return;
        }
    }

    /* No more facilities to query, all done */
    g_simple_async_result_set_op_res_gpointer (ctx->result,
                                               GUINT_TO_POINTER (ctx->locks),
                                               NULL);
    load_enabled_facility_locks_context_complete_and_free (ctx);
}

static void
clck_test_ready (MMBaseModem *self,
                 GAsyncResult *res,
                 LoadEnabledFacilityLocksContext *ctx)
{
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (self, res, &error);
    if (!response) {
        g_simple_async_result_take_error (ctx->result, error);
        load_enabled_facility_locks_context_complete_and_free (ctx);
        return;
    }

    if (!mm_3gpp_parse_clck_test_response (response, &ctx->facilities)) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Couldn't parse list of available lock facilities: '%s'",
                                         response);
        load_enabled_facility_locks_context_complete_and_free (ctx);
        return;
    }

    /* Ignore facility locks specified by the plugins */
    if (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_ignored_facility_locks) {
        gchar *str;

        str = mm_modem_3gpp_facility_build_string_from_mask (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_ignored_facility_locks);
        mm_dbg ("Ignoring facility locks: '%s'", str);
        g_free (str);

        ctx->facilities &= ~MM_BROADBAND_MODEM (self)->priv->modem_3gpp_ignored_facility_locks;
    }

    /* Go on... */
    get_next_facility_lock_status (ctx);
}

static void
modem_3gpp_load_enabled_facility_locks (MMIfaceModem3gpp *self,
                                        GAsyncReadyCallback callback,
                                        gpointer user_data)
{
    LoadEnabledFacilityLocksContext *ctx;

    ctx = g_new (LoadEnabledFacilityLocksContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_3gpp_load_enabled_facility_locks);
    ctx->facilities = MM_MODEM_3GPP_FACILITY_NONE;
    ctx->locks = MM_MODEM_3GPP_FACILITY_NONE;
    ctx->current = 0;

    mm_dbg ("loading enabled facility locks...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CLCK=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)clck_test_ready,
                              ctx);
}

/*****************************************************************************/
/* Operator Code loading (3GPP interface) */

static gchar *
modem_3gpp_load_operator_code_finish (MMIfaceModem3gpp *self,
                                      GAsyncResult *res,
                                      GError **error)
{
    const gchar *result;
    gchar *operator_code = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    if (!mm_3gpp_parse_cops_read_response (result,
                                           NULL, /* mode */
                                           NULL, /* format */
                                           &operator_code,
                                           NULL, /* act */
                                           error))
        return NULL;

    mm_dbg ("loaded Operator Code: %s", operator_code);
    return operator_code;
}

static void
modem_3gpp_load_operator_code (MMIfaceModem3gpp *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    mm_dbg ("loading Operator Code...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+COPS=3,2;+COPS?",
                              3,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Operator Name loading (3GPP interface) */

static gchar *
modem_3gpp_load_operator_name_finish (MMIfaceModem3gpp *self,
                                      GAsyncResult *res,
                                      GError **error)
{
    const gchar *result;
    gchar *operator_name = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    if (!mm_3gpp_parse_cops_read_response (result,
                                           NULL, /* mode */
                                           NULL, /* format */
                                           &operator_name,
                                           NULL, /* act */
                                           error))
        return NULL;

    mm_3gpp_normalize_operator_name (&operator_name, MM_BROADBAND_MODEM (self)->priv->modem_current_charset);
    if (operator_name)
        mm_dbg ("loaded Operator Name: %s", operator_name);
    return operator_name;
}

static void
modem_3gpp_load_operator_name (MMIfaceModem3gpp *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    mm_dbg ("loading Operator Name...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+COPS=3,0;+COPS?",
                              3,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Subscription State Loading (3GPP interface) */

static MMModem3gppSubscriptionState
modem_3gpp_load_subscription_state_finish (MMIfaceModem3gpp *self,
                                           GAsyncResult *res,
                                           GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN;

    return (MMModem3gppSubscriptionState) GPOINTER_TO_UINT (
        g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)));
}

static void
modem_3gpp_load_subscription_state (MMIfaceModem3gpp *self,
                                    GAsyncReadyCallback callback,
                                    gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_load_subscription_state);

    g_simple_async_result_set_op_res_gpointer (
        result,
        GUINT_TO_POINTER (MM_MODEM_3GPP_SUBSCRIPTION_STATE_UNKNOWN),
        NULL);

    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Unsolicited registration messages handling (3GPP interface) */

static gboolean
modem_3gpp_setup_unsolicited_registration_events_finish (MMIfaceModem3gpp *self,
                                                         GAsyncResult *res,
                                                         GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
registration_state_changed (MMPortSerialAt *port,
                            GMatchInfo *match_info,
                            MMBroadbandModem *self)
{
    MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
    gulong lac = 0, cell_id = 0;
    MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
    gboolean cgreg = FALSE;
    gboolean cereg = FALSE;
    GError *error = NULL;

    if (!mm_3gpp_parse_creg_response (match_info,
                                      &state,
                                      &lac,
                                      &cell_id,
                                      &act,
                                      &cgreg,
                                      &cereg,
                                      &error)) {
        mm_warn ("error parsing unsolicited registration: %s",
                 error && error->message ? error->message : "(unknown)");
        g_clear_error (&error);
        return;
    }

    /* Report new registration state */
    if (cgreg)
        mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
    else if (cereg)
        mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
    else
        mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);

    /* Only update access technologies from CREG/CGREG response if the modem
     * doesn't have custom commands for access technology loading, otherwise
     * we fight with the custom commands.  Plus CREG/CGREG access technologies
     * don't have fine-grained distinction between HSxPA or GPRS/EDGE, etc.
     */
    if (MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies == modem_load_access_technologies ||
        MM_IFACE_MODEM_GET_INTERFACE (self)->load_access_technologies == NULL)
        mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), act);

    mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), lac, cell_id);
}

static void
modem_3gpp_setup_unsolicited_registration_events (MMIfaceModem3gpp *self,
                                                  GAsyncReadyCallback callback,
                                                  gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *ports[2];
    GPtrArray *array;
    guint i;
    guint j;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_setup_unsolicited_registration_events);

    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Set up CREG unsolicited message handlers in both ports */
    array = mm_3gpp_creg_regex_get (FALSE);
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        mm_dbg ("(%s) setting up 3GPP unsolicited registration messages handlers",
                mm_port_get_device (MM_PORT (ports[i])));
        for (j = 0; j < array->len; j++) {
            mm_port_serial_at_add_unsolicited_msg_handler (
                MM_PORT_SERIAL_AT (ports[i]),
                (GRegex *) g_ptr_array_index (array, j),
                (MMPortSerialAtUnsolicitedMsgFn)registration_state_changed,
                self,
                NULL);
        }
    }
    mm_3gpp_creg_regex_destroy (array);

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Unsolicited registration messages cleaning up (3GPP interface) */

static gboolean
modem_3gpp_cleanup_unsolicited_registration_events_finish (MMIfaceModem3gpp *self,
                                                           GAsyncResult *res,
                                                           GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
modem_3gpp_cleanup_unsolicited_registration_events (MMIfaceModem3gpp *self,
                                                    GAsyncReadyCallback callback,
                                                    gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *ports[2];
    GPtrArray *array;
    guint i;
    guint j;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_cleanup_unsolicited_registration_events);

    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Set up CREG unsolicited message handlers in both ports */
    array = mm_3gpp_creg_regex_get (FALSE);
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        mm_dbg ("(%s) cleaning up unsolicited registration messages handlers",
                mm_port_get_device (MM_PORT (ports[i])));

        for (j = 0; j < array->len; j++) {
            mm_port_serial_at_add_unsolicited_msg_handler (
                MM_PORT_SERIAL_AT (ports[i]),
                (GRegex *) g_ptr_array_index (array, j),
                NULL,
                NULL,
                NULL);
        }
    }
    mm_3gpp_creg_regex_destroy (array);

    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Scan networks (3GPP interface) */

static GList *
modem_3gpp_scan_networks_finish (MMIfaceModem3gpp *self,
                                 GAsyncResult *res,
                                 GError **error)
{
    const gchar *result;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    return mm_3gpp_parse_cops_test_response (result, error);
}

static void
modem_3gpp_scan_networks (MMIfaceModem3gpp *self,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+COPS=?",
                              300,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Register in network (3GPP interface) */

static gboolean
modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self,
                                       GAsyncResult *res,
                                       GError **error)
{
    return !!mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, error);
}

static void
modem_3gpp_register_in_network (MMIfaceModem3gpp *self,
                                const gchar *operator_id,
                                GCancellable *cancellable,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
{
    gchar *command;

    /* If the user sent a specific network to use, lock it in. */
    if (operator_id)
        command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id);
    /* If no specific network was given, and the modem is not registered and not
     * searching, kick it to search for a network. Also do auto registration if
     * the modem had been set to manual registration last time but now is not.
     */
    else
        /* Note that '+COPS=0,,' (same but with commas) won't work in some Nokia
         * phones */
        command = g_strdup ("+COPS=0");

    mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                   mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL),
                                   command,
                                   120,
                                   FALSE,
                                   FALSE, /* raw */
                                   cancellable,
                                   callback,
                                   user_data);
    g_free (command);
}

/*****************************************************************************/
/* Registration checks (3GPP interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    gboolean cs_supported;
    gboolean ps_supported;
    gboolean eps_supported;
    gboolean run_cs;
    gboolean run_ps;
    gboolean run_eps;
    gboolean running_cs;
    gboolean running_ps;
    gboolean running_eps;
    GError *cs_error;
    GError *ps_error;
    GError *eps_error;
} RunRegistrationChecksContext;

static void
run_registration_checks_context_complete_and_free (RunRegistrationChecksContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    if (ctx->cs_error)
        g_error_free (ctx->cs_error);
    if (ctx->ps_error)
        g_error_free (ctx->ps_error);
    if (ctx->eps_error)
        g_error_free (ctx->eps_error);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self,
                                           GAsyncResult *res,
                                           GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void run_registration_checks_context_step (RunRegistrationChecksContext *ctx);

static void
registration_status_check_ready (MMBroadbandModem *self,
                                 GAsyncResult *res,
                                 RunRegistrationChecksContext *ctx)
{
    const gchar *response;
    GError *error = NULL;
    GMatchInfo *match_info;
    guint i;
    gboolean parsed;
    gboolean cgreg;
    gboolean cereg;
    MMModem3gppRegistrationState state;
    MMModemAccessTechnology act;
    gulong lac;
    gulong cid;

    /* Only one must be running */
    g_assert ((ctx->running_cs ? 1 : 0) +
              (ctx->running_ps ? 1 : 0) +
              (ctx->running_eps ? 1 : 0) == 1);

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (!response) {
        g_assert (error != NULL);
        if (ctx->running_cs)
            ctx->cs_error = error;
        else if (ctx->running_ps)
            ctx->ps_error = error;
        else
            ctx->eps_error = error;

        run_registration_checks_context_step (ctx);
        return;
    }

    /* Unsolicited registration status handlers will usually process the
     * response for us, but just in case they don't, do that here.
     */
    if (!response[0]) {
        /* Done */
        run_registration_checks_context_step (ctx);
        return;
    }

    /* Try to match the response */
    for (i = 0;
         i < self->priv->modem_3gpp_registration_regex->len;
         i++) {
        if (g_regex_match ((GRegex *)g_ptr_array_index (
                               self->priv->modem_3gpp_registration_regex, i),
                           response,
                           0,
                           &match_info))
            break;
        g_match_info_free (match_info);
        match_info = NULL;
    }

    if (!match_info) {
        error = g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Unknown registration status response: '%s'",
                             response);
        if (ctx->running_cs)
            ctx->cs_error = error;
        else if (ctx->running_ps)
            ctx->ps_error = error;
        else
            ctx->eps_error = error;

        run_registration_checks_context_step (ctx);
        return;
    }

    cgreg = FALSE;
    cereg = FALSE;
    state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
    act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
    lac = 0;
    cid = 0;
    parsed = mm_3gpp_parse_creg_response (match_info,
                                          &state,
                                          &lac,
                                          &cid,
                                          &act,
                                          &cgreg,
                                          &cereg,
                                          &error);
    g_match_info_free (match_info);

    if (!parsed) {
        if (!error)
            error = g_error_new (MM_CORE_ERROR,
                                 MM_CORE_ERROR_FAILED,
                                 "Error parsing registration response: '%s'",
                                 response);
        if (ctx->running_cs)
            ctx->cs_error = error;
        else if (ctx->running_ps)
            ctx->ps_error = error;
        else
            ctx->eps_error = error;
        run_registration_checks_context_step (ctx);
        return;
    }

    /* Report new registration state */
    if (cgreg) {
        if (ctx->running_cs)
            mm_dbg ("Got PS registration state when checking CS registration state");
        else if (ctx->running_eps)
            mm_dbg ("Got PS registration state when checking EPS registration state");
        mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
    } else if (cereg) {
        if (ctx->running_cs)
            mm_dbg ("Got EPS registration state when checking CS registration state");
        else if (ctx->running_ps)
            mm_dbg ("Got EPS registration state when checking PS registration state");
        mm_iface_modem_3gpp_update_eps_registration_state (MM_IFACE_MODEM_3GPP (self), state);
    } else {
        if (ctx->running_ps)
            mm_dbg ("Got CS registration state when checking PS registration state");
        else if (ctx->running_eps)
            mm_dbg ("Got CS registration state when checking EPS registration state");
        mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), state);
    }

    mm_iface_modem_3gpp_update_access_technologies (MM_IFACE_MODEM_3GPP (self), act);
    mm_iface_modem_3gpp_update_location (MM_IFACE_MODEM_3GPP (self), lac, cid);

    run_registration_checks_context_step (ctx);
}

static void
run_registration_checks_context_step (RunRegistrationChecksContext *ctx)
{
    ctx->running_cs = FALSE;
    ctx->running_ps = FALSE;
    ctx->running_eps = FALSE;

    if (ctx->run_cs) {
        ctx->running_cs = TRUE;
        ctx->run_cs = FALSE;
        /* Check current CS-registration state. */
        mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                                  "+CREG?",
                                  10,
                                  FALSE,
                                  (GAsyncReadyCallback)registration_status_check_ready,
                                  ctx);
        return;
    }

    if (ctx->run_ps) {
        ctx->running_ps = TRUE;
        ctx->run_ps = FALSE;
        /* Check current PS-registration state. */
        mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                                  "+CGREG?",
                                  10,
                                  FALSE,
                                  (GAsyncReadyCallback)registration_status_check_ready,
                                  ctx);
        return;
    }

    if (ctx->run_eps) {
        ctx->running_eps = TRUE;
        ctx->run_eps = FALSE;
        /* Check current EPS-registration state. */
        mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                                  "+CEREG?",
                                  10,
                                  FALSE,
                                  (GAsyncReadyCallback)registration_status_check_ready,
                                  ctx);
        return;
    }

    /* If all run checks returned errors we fail */
    if ((ctx->cs_supported || ctx->ps_supported || ctx->eps_supported) &&
        (!ctx->cs_supported || ctx->cs_error) &&
        (!ctx->ps_supported || ctx->ps_error) &&
        (!ctx->eps_supported || ctx->eps_error)) {
        /* Prefer the EPS, and then PS error if any */
        if (ctx->eps_error) {
            g_simple_async_result_set_from_error (ctx->result, ctx->eps_error);
            ctx->eps_error = NULL;
        } else if (ctx->ps_error) {
            g_simple_async_result_set_from_error (ctx->result, ctx->ps_error);
            ctx->ps_error = NULL;
        } else if (ctx->cs_error) {
            g_simple_async_result_set_from_error (ctx->result, ctx->cs_error);
            ctx->cs_error = NULL;
        } else
            g_assert_not_reached ();
    } else
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);

    run_registration_checks_context_complete_and_free (ctx);
}

static void
modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self,
                                    gboolean cs_supported,
                                    gboolean ps_supported,
                                    gboolean eps_supported,
                                    GAsyncReadyCallback callback,
                                    gpointer user_data)
{
    RunRegistrationChecksContext *ctx;

    ctx = g_new0 (RunRegistrationChecksContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_3gpp_run_registration_checks);
    ctx->cs_supported = cs_supported;
    ctx->ps_supported = ps_supported;
    ctx->eps_supported = eps_supported;
    ctx->run_cs = cs_supported;
    ctx->run_ps = ps_supported;
    ctx->run_eps = eps_supported;

    run_registration_checks_context_step (ctx);
}

/*****************************************************************************/
/* Enable/Disable unsolicited registration events (3GPP interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    gboolean enable; /* TRUE for enabling, FALSE for disabling */
    gboolean run_cs;
    gboolean run_ps;
    gboolean run_eps;
    gboolean running_cs;
    gboolean running_ps;
    gboolean running_eps;
    GError *cs_error;
    GError *ps_error;
    GError *eps_error;
    gboolean secondary_sequence;
    gboolean secondary_done;
} UnsolicitedRegistrationEventsContext;

static void
unsolicited_registration_events_context_complete_and_free (UnsolicitedRegistrationEventsContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    if (ctx->cs_error)
        g_error_free (ctx->cs_error);
    if (ctx->ps_error)
        g_error_free (ctx->ps_error);
    if (ctx->eps_error)
        g_error_free (ctx->eps_error);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static UnsolicitedRegistrationEventsContext *
unsolicited_registration_events_context_new (MMBroadbandModem *self,
                                             gboolean enable,
                                             gboolean cs_supported,
                                             gboolean ps_supported,
                                             gboolean eps_supported,
                                             GAsyncReadyCallback callback,
                                             gpointer user_data)
{
    UnsolicitedRegistrationEventsContext *ctx;

    ctx = g_new0 (UnsolicitedRegistrationEventsContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             unsolicited_registration_events_context_new);
    ctx->enable = enable;
    ctx->run_cs = cs_supported;
    ctx->run_ps = ps_supported;
    ctx->run_eps = eps_supported;

    return ctx;
}

static gboolean
modem_3gpp_enable_disable_unsolicited_registration_events_finish (MMIfaceModem3gpp *self,
                                                                  GAsyncResult *res,
                                                                  GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static gboolean
parse_registration_setup_reply (MMBaseModem *self,
                                gpointer none,
                                const gchar *command,
                                const gchar *response,
                                gboolean last_command,
                                const GError *error,
                                GVariant **result,
                                GError **result_error)
{
    /* If error, try next command */
    if (error)
        return FALSE;

    /* Set COMMAND as result! */
    *result = g_variant_new_string (command);
    return TRUE;
}

static const MMBaseModemAtCommand cs_registration_sequence[] = {
    /* Enable unsolicited registration notifications in CS network, with location */
    { "+CREG=2", 3, FALSE, parse_registration_setup_reply },
    /* Enable unsolicited registration notifications in CS network, without location */
    { "+CREG=1", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static const MMBaseModemAtCommand cs_unregistration_sequence[] = {
    /* Disable unsolicited registration notifications in CS network */
    { "+CREG=0", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static const MMBaseModemAtCommand ps_registration_sequence[] = {
    /* Enable unsolicited registration notifications in PS network, with location */
    { "+CGREG=2", 3, FALSE, parse_registration_setup_reply },
    /* Enable unsolicited registration notifications in PS network, without location */
    { "+CGREG=1", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static const MMBaseModemAtCommand ps_unregistration_sequence[] = {
    /* Disable unsolicited registration notifications in PS network */
    { "+CGREG=0", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static const MMBaseModemAtCommand eps_registration_sequence[] = {
    /* Enable unsolicited registration notifications in EPS network, with location */
    { "+CEREG=2", 3, FALSE, parse_registration_setup_reply },
    /* Enable unsolicited registration notifications in EPS network, without location */
    { "+CEREG=1", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static const MMBaseModemAtCommand eps_unregistration_sequence[] = {
    /* Disable unsolicited registration notifications in PS network */
    { "+CEREG=0", 3, FALSE, parse_registration_setup_reply },
    { NULL }
};

static void unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsContext *ctx);

static void
unsolicited_registration_events_sequence_ready (MMBroadbandModem *self,
                                                GAsyncResult *res,
                                                UnsolicitedRegistrationEventsContext *ctx)
{
    GError *error = NULL;
    GVariant *command;
    MMPortSerialAt *secondary;

    /* Only one must be running */
    g_assert ((ctx->running_cs ? 1 : 0) +
              (ctx->running_ps ? 1 : 0) +
              (ctx->running_eps ? 1 : 0) == 1);

    if (ctx->secondary_done) {
        if (ctx->secondary_sequence)
            mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error);
        else
            mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error);

        if (error) {
            mm_dbg ("%s unsolicited registration events in secondary port failed: '%s'",
                    ctx->enable ? "Enabling" : "Disabling",
                    error->message);
            /* Keep errors reported */
            if (ctx->running_cs && !ctx->cs_error)
                ctx->cs_error = error;
            else if (ctx->running_ps && !ctx->ps_error)
                ctx->ps_error = error;
            else if (ctx->running_eps && !ctx->eps_error)
                ctx->eps_error = error;
            else
                g_error_free (error);
        } else {
            /* If successful in secondary port, cleanup primary error if any */
            if (ctx->running_cs && ctx->cs_error) {
                g_error_free (ctx->cs_error);
                ctx->cs_error = NULL;
            }
            else if (ctx->running_ps && ctx->ps_error) {
                g_error_free (ctx->ps_error);
                ctx->ps_error = NULL;
            }
            else if (ctx->running_eps && ctx->eps_error) {
                g_error_free (ctx->eps_error);
                ctx->eps_error = NULL;
            }
        }

        /* Done with primary and secondary, keep on */
        unsolicited_registration_events_context_step (ctx);
        return;
    }

    /*  We just run the sequence in the primary port */
    command = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error);
    if (!command) {
        if (!error)
            error = g_error_new (MM_CORE_ERROR,
                                 MM_CORE_ERROR_FAILED,
                                 "AT sequence failed");
        mm_dbg ("%s unsolicited registration events in primary port failed: '%s'",
                ctx->enable ? "Enabling" : "Disabling",
                error->message);
        /* Keep errors reported */
        if (ctx->running_cs)
            ctx->cs_error = error;
        else if (ctx->running_ps)
            ctx->ps_error = error;
        else
            ctx->eps_error = error;
        /* Even if primary failed, go on and try to enable in secondary port */
    }

    secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
    if (secondary) {
        const MMBaseModemAtCommand *registration_sequence = NULL;

        ctx->secondary_done = TRUE;

        /* Now use the same registration setup in secondary port, if any */
        if (command) {
            mm_base_modem_at_command_full (
                MM_BASE_MODEM (self),
                secondary,
                g_variant_get_string (command, NULL),
                3,
                FALSE,
                FALSE, /* raw */
                NULL, /* cancellable */
                (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
                ctx);
            return;
        }

        /* If primary failed, run the whole sequence in secondary */
        ctx->secondary_sequence = TRUE;
        if (ctx->running_cs)
            registration_sequence = ctx->enable ? cs_registration_sequence : cs_unregistration_sequence;
        else if (ctx->running_ps)
            registration_sequence = ctx->enable ? ps_registration_sequence : ps_unregistration_sequence;
        else
            registration_sequence = ctx->enable ? eps_registration_sequence : eps_unregistration_sequence;
        mm_base_modem_at_sequence_full (
            MM_BASE_MODEM (self),
            secondary,
            registration_sequence,
            NULL,  /* response processor context */
            NULL,  /* response processor context free */
            NULL, /* cancellable */
            (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
            ctx);
        return;
    }

    /* We're done */
    unsolicited_registration_events_context_step (ctx);
}

static void
unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsContext *ctx)
{
    ctx->running_cs = FALSE;
    ctx->running_ps = FALSE;
    ctx->running_eps = FALSE;
    ctx->secondary_done = FALSE;

    if (ctx->run_cs) {
        ctx->running_cs = TRUE;
        ctx->run_cs = FALSE;
        mm_base_modem_at_sequence_full (
            MM_BASE_MODEM (ctx->self),
            mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)),
            ctx->enable ? cs_registration_sequence : cs_unregistration_sequence,
            NULL,  /* response processor context */
            NULL,  /* response processor context free */
            NULL,  /* cancellable */
            (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
            ctx);
        return;
    }

    if (ctx->run_ps) {
        ctx->running_ps = TRUE;
        ctx->run_ps = FALSE;
        mm_base_modem_at_sequence_full (
            MM_BASE_MODEM (ctx->self),
            mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)),
            ctx->enable ? ps_registration_sequence : ps_unregistration_sequence,
            NULL,  /* response processor context */
            NULL,  /* response processor context free */
            NULL,  /* cancellable */
            (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
            ctx);
        return;
    }

    if (ctx->run_eps) {
        ctx->running_eps = TRUE;
        ctx->run_eps = FALSE;
        mm_base_modem_at_sequence_full (
            MM_BASE_MODEM (ctx->self),
            mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)),
            ctx->enable ? eps_registration_sequence : eps_unregistration_sequence,
            NULL,  /* response processor context */
            NULL,  /* response processor context free */
            NULL,  /* cancellable */
            (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready,
            ctx);
        return;
    }

    /* All done!
     * If we have any error reported, we'll propagate it. EPS errors take
     * precedence over PS errors and PS errors take precedence over CS errors. */
    if (ctx->eps_error) {
        g_simple_async_result_take_error (ctx->result, ctx->eps_error);
        ctx->eps_error = NULL;
    } else if (ctx->ps_error) {
        g_simple_async_result_take_error (ctx->result, ctx->ps_error);
        ctx->ps_error = NULL;
    } else if (ctx->cs_error) {
        g_simple_async_result_take_error (ctx->result, ctx->cs_error);
        ctx->cs_error = NULL;
    } else
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    unsolicited_registration_events_context_complete_and_free (ctx);
}

static void
modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp *self,
                                                    gboolean cs_supported,
                                                    gboolean ps_supported,
                                                    gboolean eps_supported,
                                                    GAsyncReadyCallback callback,
                                                    gpointer user_data)
{
    unsolicited_registration_events_context_step (
        unsolicited_registration_events_context_new (MM_BROADBAND_MODEM (self),
                                                     FALSE,
                                                     cs_supported,
                                                     ps_supported,
                                                     eps_supported,
                                                     callback,
                                                     user_data));
}

static void
modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self,
                                                   gboolean cs_supported,
                                                   gboolean ps_supported,
                                                   gboolean eps_supported,
                                                   GAsyncReadyCallback callback,
                                                   gpointer user_data)
{
    unsolicited_registration_events_context_step (
        unsolicited_registration_events_context_new (MM_BROADBAND_MODEM (self),
                                                     TRUE,
                                                     cs_supported,
                                                     ps_supported,
                                                     eps_supported,
                                                     callback,
                                                     user_data));
}

/*****************************************************************************/
/* Cancel USSD (3GPP/USSD interface) */

static gboolean
modem_3gpp_ussd_cancel_finish (MMIfaceModem3gppUssd *self,
                               GAsyncResult *res,
                               GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cancel_command_ready (MMBroadbandModem *self,
                      GAsyncResult *res,
                      GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error)
        g_simple_async_result_take_error (simple, error);
    else
        g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);

    /* Complete the pending action, if any */
    if (self->priv->pending_ussd_action) {
        g_simple_async_result_set_error (self->priv->pending_ussd_action,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_CANCELLED,
                                         "USSD session was cancelled");
        g_simple_async_result_complete_in_idle (self->priv->pending_ussd_action);
        g_object_unref (self->priv->pending_ussd_action);
        self->priv->pending_ussd_action = NULL;
    }

    mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
                                           MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE);
}

static void
modem_3gpp_ussd_cancel (MMIfaceModem3gppUssd *self,
                        GAsyncReadyCallback callback,
                        gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_ussd_cancel);

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CUSD=2",
                              10,
                              TRUE,
                              (GAsyncReadyCallback)cancel_command_ready,
                              result);
}

/*****************************************************************************/
/* Send command (3GPP/USSD interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    gchar *command;
    gboolean current_is_unencoded;
    gboolean encoded_used;
    gboolean unencoded_used;
} Modem3gppUssdSendContext;

static void
modem_3gpp_ussd_send_context_complete_and_free (Modem3gppUssdSendContext *ctx)
{
    /* We check for result, as we may have already set it in
     * priv->pending_ussd_request */
    if (ctx->result) {
        g_simple_async_result_complete_in_idle (ctx->result);
        g_object_unref (ctx->result);
    }
    g_object_unref (ctx->self);
    g_free (ctx->command);
    g_slice_free (Modem3gppUssdSendContext, ctx);
}

static const gchar *
modem_3gpp_ussd_send_finish (MMIfaceModem3gppUssd *self,
                             GAsyncResult *res,
                             GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return NULL;

    /* We can return the string as constant because it is owned by the async
     * result, which will be valid during the whole call of its callback, which
     * is when we're actually calling finish() */
    return (const gchar *)g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
}

static void modem_3gpp_ussd_context_step (Modem3gppUssdSendContext *ctx);

static void cusd_process_string (MMBroadbandModem *self,
                                 const gchar *str);

static void
ussd_send_command_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         Modem3gppUssdSendContext *ctx)
{
    GError *error = NULL;
    const gchar *reply;

    g_assert (ctx->result == NULL);

    reply = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        /* Some immediate error happened when sending the USSD request */
        mm_dbg ("Error sending USSD request: '%s'", error->message);
        g_error_free (error);

        if (self->priv->pending_ussd_action) {
            /* Recover result */
            ctx->result = self->priv->pending_ussd_action;
            self->priv->pending_ussd_action = NULL;
            modem_3gpp_ussd_context_step (ctx);
            return;
        }

        /* So the USSD action was completed already... */
        mm_dbg ("USSD action already completed via URCs");
        modem_3gpp_ussd_send_context_complete_and_free (ctx);
        return;
    }

    /* Cache the hint for the next time we send something */
    if (!ctx->self->priv->use_unencoded_ussd &&
        ctx->current_is_unencoded) {
        mm_dbg ("Will assume we want unencoded USSD commands");
        ctx->self->priv->use_unencoded_ussd = TRUE;
    } else if (ctx->self->priv->use_unencoded_ussd &&
               !ctx->current_is_unencoded) {
        mm_dbg ("Will assume we want encoded USSD commands");
        ctx->self->priv->use_unencoded_ussd = FALSE;
    }

    if (!self->priv->pending_ussd_action)
        mm_dbg ("USSD operation finished already via URCs");
    else if (reply && reply[0]) {
        reply = mm_strip_tag (reply, "+CUSD:");
        cusd_process_string (ctx->self, reply);
    }

    modem_3gpp_ussd_send_context_complete_and_free (ctx);
}

static void
modem_3gpp_ussd_context_send_encoded (Modem3gppUssdSendContext *ctx)
{
    gchar *at_command = NULL;
    GError *error = NULL;
    guint scheme = 0;
    gchar *encoded;

    /* Encode USSD command */
    encoded = mm_iface_modem_3gpp_ussd_encode (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                               ctx->command,
                                               &scheme,
                                               &error);
    if (!encoded) {
        mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                               MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE);
        g_simple_async_result_take_error (ctx->result, error);
        modem_3gpp_ussd_send_context_complete_and_free (ctx);
        return;
    }

    /* Build AT command */
    ctx->encoded_used = TRUE;
    ctx->current_is_unencoded = FALSE;
    at_command = g_strdup_printf ("+CUSD=1,\"%s\",%d", encoded, scheme);
    g_free (encoded);

    /* Cache the action, as it may be completed via URCs.
     * There shouldn't be any previous action pending. */
    g_warn_if_fail (ctx->self->priv->pending_ussd_action == NULL);
    ctx->self->priv->pending_ussd_action = ctx->result;
    ctx->result = NULL;

    mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                              at_command,
                              10,
                              FALSE,
                              (GAsyncReadyCallback)ussd_send_command_ready,
                              ctx);
    g_free (at_command);
}

static void
modem_3gpp_ussd_context_send_unencoded (Modem3gppUssdSendContext *ctx)
{
    gchar *at_command = NULL;

    /* Build AT command with action unencoded */
    ctx->unencoded_used = TRUE;
    ctx->current_is_unencoded = TRUE;
    at_command = g_strdup_printf ("+CUSD=1,\"%s\",%d",
                                  ctx->command,
                                  MM_MODEM_GSM_USSD_SCHEME_7BIT);

    /* Cache the action, as it may be completed via URCs.
     * There shouldn't be any previous action pending. */
    g_warn_if_fail (ctx->self->priv->pending_ussd_action == NULL);
    ctx->self->priv->pending_ussd_action = ctx->result;
    ctx->result = NULL;

    mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                              at_command,
                              10,
                              FALSE,
                              (GAsyncReadyCallback)ussd_send_command_ready,
                              ctx);
    g_free (at_command);
}

static void
modem_3gpp_ussd_context_step (Modem3gppUssdSendContext *ctx)
{
    if (ctx->encoded_used &&
        ctx->unencoded_used) {
        mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                               MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE);
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Sending USSD command failed");
        modem_3gpp_ussd_send_context_complete_and_free (ctx);
        return;
    }

    if (ctx->self->priv->use_unencoded_ussd) {
        if (!ctx->unencoded_used)
            modem_3gpp_ussd_context_send_unencoded (ctx);
        else if (!ctx->encoded_used)
            modem_3gpp_ussd_context_send_encoded (ctx);
        else
            g_assert_not_reached ();
    } else {
        if (!ctx->encoded_used)
            modem_3gpp_ussd_context_send_encoded (ctx);
        else if (!ctx->unencoded_used)
            modem_3gpp_ussd_context_send_unencoded (ctx);
        else
            g_assert_not_reached ();
    }
}

static void
modem_3gpp_ussd_send (MMIfaceModem3gppUssd *self,
                      const gchar *command,
                      GAsyncReadyCallback callback,
                      gpointer user_data)
{
    Modem3gppUssdSendContext *ctx;

    ctx = g_slice_new0 (Modem3gppUssdSendContext);
    /* We're going to steal the string result in finish() so we must have a
     * callback specified. */
    g_assert (callback != NULL);
    ctx->self = g_object_ref (self);
    ctx->command = g_strdup (command);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_3gpp_ussd_send);

    mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
                                           MM_MODEM_3GPP_USSD_SESSION_STATE_ACTIVE);

    modem_3gpp_ussd_context_step (ctx);
}

/*****************************************************************************/
/* USSD Encode/Decode (3GPP/USSD interface) */

static gchar *
modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
                        const gchar *command,
                        guint *scheme,
                        GError **error)
{
    MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
    GByteArray *ussd_command;
    gchar *hex = NULL;

    ussd_command = g_byte_array_new ();

    /* encode to the current charset */
    if (mm_modem_charset_byte_array_append (ussd_command,
                                            command,
                                            FALSE,
                                            broadband->priv->modem_current_charset)) {
        *scheme = MM_MODEM_GSM_USSD_SCHEME_7BIT;
        /* convert to hex representation */
        hex = mm_utils_bin2hexstr (ussd_command->data, ussd_command->len);
    }

    g_byte_array_free (ussd_command, TRUE);

    return hex;
}

static gchar *
modem_3gpp_ussd_decode (MMIfaceModem3gppUssd *self,
                        const gchar *reply,
                        GError **error)
{
    MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);

    return mm_modem_charset_hex_to_utf8 (reply,
                                         broadband->priv->modem_current_charset);
}

/*****************************************************************************/
/* Setup/Cleanup unsolicited result codes (3GPP/USSD interface) */

static gboolean
modem_3gpp_ussd_setup_cleanup_unsolicited_result_codes_finish (MMIfaceModem3gppUssd *self,
                                                               GAsyncResult *res,
                                                               GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static gchar *
decode_ussd_response (MMBroadbandModem *self,
                      const gchar *reply,
                      GError **error)
{
    gchar *p;
    gchar *str;
    gchar *decoded;

    /* Look for the first ',' */
    p = strchr (reply, ',');
    if (!p) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_FAILED,
                     "Cannot decode USSD response (%s): missing field separator",
                     reply);
        return NULL;
    }

    /* Assume the string is the next field, and strip quotes. While doing this,
     * we also skip any other additional field we may have afterwards */
    if (p[1] == '"') {
        str = g_strdup (&p[2]);
        p = strchr (str, '"');
        if (p)
            *p = '\0';
    } else {
        str = g_strdup (&p[1]);
        p = strchr (str, ',');
        if (p)
            *p = '\0';
    }

    /* If reply doesn't seem to be hex; just return itself... */
    if (!mm_utils_ishexstr (str))
        decoded = g_strdup (str);
    else
        decoded = mm_iface_modem_3gpp_ussd_decode (MM_IFACE_MODEM_3GPP_USSD (self), str, error);

    g_free (str);

    return decoded;
}

static void
cusd_process_string (MMBroadbandModem *self,
                     const gchar *str)
{
    MMModem3gppUssdSessionState ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_IDLE;

    if (!str || !isdigit (*str)) {
        if (self->priv->pending_ussd_action)
            g_simple_async_result_set_error (self->priv->pending_ussd_action,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Invalid USSD response received: '%s'",
                                             str ? str : "(none)");
        else
            mm_warn ("Received invalid USSD network-initiated request: '%s'",
                     str ? str : "(none)");
    } else {
        gint status;

        status = g_ascii_digit_value (*str);
        switch (status) {
        case 0: /* no further action required */ {
            gchar *converted;
            GError *error = NULL;

            converted = decode_ussd_response (self, str, &error);
            if (self->priv->pending_ussd_action) {
                /* Response to the user's request */
                if (error)
                    g_simple_async_result_take_error (self->priv->pending_ussd_action, error);
                else
                    g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
                                                               converted,
                                                               g_free);
            } else {
                if (error) {
                    mm_warn ("Invalid network initiated USSD notification: %s",
                             error->message);
                    g_error_free (error);
                } else {
                    /* Network-initiated USSD-Notify */
                    mm_iface_modem_3gpp_ussd_update_network_notification (
                        MM_IFACE_MODEM_3GPP_USSD (self),
                        converted);
                    g_free (converted);
                }
            }
            break;
        }

        case 1: /* further action required */ {
            gchar *converted;
            GError *error = NULL;

            ussd_state = MM_MODEM_3GPP_USSD_SESSION_STATE_USER_RESPONSE;
            converted = decode_ussd_response (self, str, &error);
            if (self->priv->pending_ussd_action) {
                if (error)
                    g_simple_async_result_take_error (self->priv->pending_ussd_action, error);
                else
                    g_simple_async_result_set_op_res_gpointer (self->priv->pending_ussd_action,
                                                               converted,
                                                               g_free);
            } else {
                if (error) {
                    mm_warn ("Invalid network initiated USSD request: %s",
                             error->message);
                    g_error_free (error);
                } else {
                    /* Network-initiated USSD-Request */
                    mm_iface_modem_3gpp_ussd_update_network_request (
                        MM_IFACE_MODEM_3GPP_USSD (self),
                        converted);
                    g_free (converted);
                }
            }
            break;
        }

        case 2:
            if (self->priv->pending_ussd_action)
                g_simple_async_result_set_error (self->priv->pending_ussd_action,
                                                 MM_CORE_ERROR,
                                                 MM_CORE_ERROR_CANCELLED,
                                                 "USSD terminated by network.");
            break;

        case 4:
            if (self->priv->pending_ussd_action)
                g_simple_async_result_set_error (self->priv->pending_ussd_action,
                                                 MM_CORE_ERROR,
                                                 MM_CORE_ERROR_UNSUPPORTED,
                                                 "Operation not supported.");
            break;

        default:
            if (self->priv->pending_ussd_action)
                g_simple_async_result_set_error (self->priv->pending_ussd_action,
                                                 MM_CORE_ERROR,
                                                 MM_CORE_ERROR_FAILED,
                                                 "Unhandled USSD reply: %s (%d)",
                                                 str,
                                                 status);
            break;
        }
    }

    mm_iface_modem_3gpp_ussd_update_state (MM_IFACE_MODEM_3GPP_USSD (self),
                                           ussd_state);

    /* Complete the pending action */
    if (self->priv->pending_ussd_action) {
        g_simple_async_result_complete_in_idle (self->priv->pending_ussd_action);
        g_object_unref (self->priv->pending_ussd_action);
        self->priv->pending_ussd_action = NULL;
    }
}

static void
cusd_received (MMPortSerialAt *port,
               GMatchInfo *info,
               MMBroadbandModem *self)
{
    gchar *str;

    mm_dbg ("Unsolicited USSD URC received");
    str = g_match_info_fetch (info, 1);
    cusd_process_string (self, str);
    g_free (str);
}

static void
set_unsolicited_result_code_handlers (MMIfaceModem3gppUssd *self,
                                      gboolean enable,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *ports[2];
    GRegex *cusd_regex;
    guint i;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        set_unsolicited_events_handlers);

    cusd_regex = mm_3gpp_cusd_regex_get ();
    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Enable unsolicited result codes in given port */
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;
        /* Set/unset unsolicited CUSD event handler */
        mm_dbg ("(%s) %s unsolicited result code handlers",
                mm_port_get_device (MM_PORT (ports[i])),
                enable ? "Setting" : "Removing");
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            cusd_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) cusd_received : NULL,
            enable ? self : NULL,
            NULL);
    }

    g_regex_unref (cusd_regex);
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

static void
modem_3gpp_ussd_setup_unsolicited_result_codes (MMIfaceModem3gppUssd *self,
                                                GAsyncReadyCallback callback,
                                                gpointer user_data)
{
    set_unsolicited_result_code_handlers (self, TRUE, callback, user_data);
}

static void
modem_3gpp_ussd_cleanup_unsolicited_result_codes (MMIfaceModem3gppUssd *self,
                                                  GAsyncReadyCallback callback,
                                                  gpointer user_data)
{
    set_unsolicited_result_code_handlers (self, FALSE, callback, user_data);
}

/*****************************************************************************/
/* Enable/Disable URCs (3GPP/USSD interface) */

static gboolean
modem_3gpp_ussd_enable_disable_unsolicited_result_codes_finish (MMIfaceModem3gppUssd *self,
                                                                GAsyncResult *res,
                                                                GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
urc_enable_disable_ready (MMBroadbandModem *self,
                          GAsyncResult *res,
                          GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_3gpp_ussd_disable_unsolicited_result_codes (MMIfaceModem3gppUssd *self,
                                                  GAsyncReadyCallback callback,
                                                  gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_ussd_disable_unsolicited_result_codes);

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CUSD=0",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)urc_enable_disable_ready,
                              result);
}

static void
modem_3gpp_ussd_enable_unsolicited_result_codes (MMIfaceModem3gppUssd *self,
                                                 GAsyncReadyCallback callback,
                                                 gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_ussd_enable_unsolicited_result_codes);

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CUSD=1",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)urc_enable_disable_ready,
                              result);
}

/*****************************************************************************/
/* Check if USSD supported (3GPP/USSD interface) */

static gboolean
modem_3gpp_ussd_check_support_finish (MMIfaceModem3gppUssd *self,
                                      GAsyncResult *res,
                                      GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cusd_format_check_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_3gpp_ussd_check_support (MMIfaceModem3gppUssd *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_3gpp_ussd_check_support);

    /* Check USSD support */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CUSD=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cusd_format_check_ready,
                              result);
}

/*****************************************************************************/
/* Check if Messaging supported (Messaging interface) */

static gboolean
modem_messaging_check_support_finish (MMIfaceModemMessaging *self,
                                      GAsyncResult *res,
                                      GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cnmi_format_check_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* CNMI command is supported; assume we have full messaging capabilities */
    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_messaging_check_support (MMIfaceModemMessaging *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_check_support);

    /* We assume that CDMA-only modems don't have messaging capabilities */
    if (mm_iface_modem_is_cdma_only (MM_IFACE_MODEM (self))) {
        g_simple_async_result_set_error (
            result,
            MM_CORE_ERROR,
            MM_CORE_ERROR_UNSUPPORTED,
            "CDMA-only modems don't have messaging capabilities");
        g_simple_async_result_complete_in_idle (result);
        g_object_unref (result);
        return;
    }

    /* Check CNMI support */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CNMI=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cnmi_format_check_ready,
                              result);
}

/*****************************************************************************/
/* Load supported SMS storages (Messaging interface) */

typedef struct {
    GArray *mem1;
    GArray *mem2;
    GArray *mem3;
} SupportedStoragesResult;

static void
supported_storages_result_free (SupportedStoragesResult *result)
{
    if (result->mem1)
        g_array_unref (result->mem1);
    if (result->mem2)
        g_array_unref (result->mem2);
    if (result->mem3)
        g_array_unref (result->mem3);
    g_free (result);
}

static gboolean
modem_messaging_load_supported_storages_finish (MMIfaceModemMessaging *self,
                                                GAsyncResult *res,
                                                GArray **mem1,
                                                GArray **mem2,
                                                GArray **mem3,
                                                GError **error)
{
    SupportedStoragesResult *result;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    result = (SupportedStoragesResult *)g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *mem1 = g_array_ref (result->mem1);
    *mem2 = g_array_ref (result->mem2);
    *mem3 = g_array_ref (result->mem3);

    return TRUE;
}

static void
cpms_format_check_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    const gchar *response;
    GError *error = NULL;
    SupportedStoragesResult *result;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    result = g_new0 (SupportedStoragesResult, 1);

    /* Parse reply */
    if (!mm_3gpp_parse_cpms_test_response (response,
                                           &result->mem1,
                                           &result->mem2,
                                           &result->mem3)) {
        g_simple_async_result_set_error (simple,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Couldn't parse supported storages reply: '%s'",
                                         response);
        supported_storages_result_free (result);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    g_simple_async_result_set_op_res_gpointer (simple,
                                               result,
                                               (GDestroyNotify)supported_storages_result_free);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_messaging_load_supported_storages (MMIfaceModemMessaging *self,
                                         GAsyncReadyCallback callback,
                                         gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_load_supported_storages);

    /* Check support storages */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CPMS=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cpms_format_check_ready,
                              result);
}

/*****************************************************************************/
/* Init current SMS storages (Messaging interface) */

static gboolean
modem_messaging_init_current_storages_finish (MMIfaceModemMessaging *_self,
                                              GAsyncResult *res,
                                              GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cpms_query_ready (MMBroadbandModem *self,
                  GAsyncResult *res,
                  GSimpleAsyncResult *simple)
{
    const gchar *response;
    GError *error = NULL;
    MMSmsStorage mem1;
    MMSmsStorage mem2;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* Parse reply */
    if (!mm_3gpp_parse_cpms_query_response (response,
                                            &mem1,
                                            &mem2,
                                            &error)) {
        g_simple_async_result_take_error (simple, error);
    } else {
        self->priv->current_sms_mem1_storage = mem1;
        self->priv->current_sms_mem2_storage = mem2;

        mm_dbg ("Current storages initialized:");
        mm_dbg ("  mem1 (list/read/delete) storages: '%s'",
                mm_common_build_sms_storages_string (&mem1, 1));
        mm_dbg ("  mem2 (write/send) storages:       '%s'",
                mm_common_build_sms_storages_string (&mem2, 1));
    }

    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_messaging_init_current_storages (MMIfaceModemMessaging *self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_init_current_storages);

    /* Check support storages */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CPMS?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cpms_query_ready,
                              result);
}

/*****************************************************************************/
/* Lock/unlock SMS storage (Messaging interface implementation helper)
 *
 * The basic commands to work with SMS storages play with AT+CPMS and three
 * different storages: mem1, mem2 and mem3.
 *   'mem1' is the storage for reading, listing and deleting.
 *   'mem2' is the storage for writing and sending from storage.
 *   'mem3' is the storage for receiving.
 *
 * When a command is to be issued for a specific storage, we need a way to
 * lock the access so that other actions are forbidden until the current one
 * finishes. Just think of two sequential actions to store two different
 * SMS into 2 different storages. If the second action is run while the first
 * one is still running, we should issue a RETRY error.
 *
 * Note that mem3 cannot be locked; we just set the default mem3 and that's it.
 *
 * When we unlock the storage, we don't go back to the default storage
 * automatically, we just keep track of which is the current one and only go to
 * the default one if needed.
 */

void
mm_broadband_modem_unlock_sms_storages (MMBroadbandModem *self,
                                        gboolean mem1,
                                        gboolean mem2)
{
    if (mem1) {
        g_assert (self->priv->mem1_storage_locked);
        self->priv->mem1_storage_locked = FALSE;
    }

    if (mem2) {
        g_assert (self->priv->mem2_storage_locked);
        self->priv->mem2_storage_locked = FALSE;
    }
}

gboolean
mm_broadband_modem_lock_sms_storages_finish (MMBroadbandModem *self,
                                             GAsyncResult *res,
                                             GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

typedef struct {
    GSimpleAsyncResult *result;
    MMBroadbandModem *self;
    MMSmsStorage previous_mem1;
    gboolean mem1_locked;
    MMSmsStorage previous_mem2;
    gboolean mem2_locked;
} LockSmsStoragesContext;

static void
lock_sms_storages_context_complete_and_free (LockSmsStoragesContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_slice_free (LockSmsStoragesContext, ctx);
}

static void
lock_storages_cpms_set_ready (MMBaseModem *self,
                              GAsyncResult *res,
                              LockSmsStoragesContext *ctx)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (self, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        /* Reset previous storages and set unlocked */
        if (ctx->mem1_locked) {
            ctx->self->priv->current_sms_mem1_storage = ctx->previous_mem1;
            ctx->self->priv->mem1_storage_locked = FALSE;
        }
        if (ctx->mem2_locked) {
            ctx->self->priv->current_sms_mem2_storage = ctx->previous_mem2;
            ctx->self->priv->mem2_storage_locked = FALSE;
        }
    }
    else
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);

    lock_sms_storages_context_complete_and_free (ctx);
}

void
mm_broadband_modem_lock_sms_storages (MMBroadbandModem *self,
                                      MMSmsStorage mem1, /* reading/listing/deleting */
                                      MMSmsStorage mem2, /* storing/sending */
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    LockSmsStoragesContext *ctx;
    gchar *cmd;
    gchar *mem1_str = NULL;
    gchar *mem2_str = NULL;

    /* If storages are currently locked by someone else, just return an
     * error */
    if ((mem1 != MM_SMS_STORAGE_UNKNOWN && self->priv->mem1_storage_locked) ||
        (mem2 != MM_SMS_STORAGE_UNKNOWN && self->priv->mem2_storage_locked)) {
        g_simple_async_report_error_in_idle (
            G_OBJECT (self),
            callback,
            user_data,
            MM_CORE_ERROR,
            MM_CORE_ERROR_RETRY,
            "SMS storage currently locked, try again later");
        return;
    }

    /* We allow locking either just one or both */
    g_assert (mem1 != MM_SMS_STORAGE_UNKNOWN ||
              mem2 != MM_SMS_STORAGE_UNKNOWN);

    ctx = g_slice_new0 (LockSmsStoragesContext);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             mm_broadband_modem_lock_sms_storages);

    if (mem1 != MM_SMS_STORAGE_UNKNOWN) {
        ctx->mem1_locked = TRUE;
        ctx->previous_mem1 = self->priv->current_sms_mem1_storage;
        self->priv->mem1_storage_locked = TRUE;
        self->priv->current_sms_mem1_storage = mem1;
        mem1_str = g_ascii_strup (mm_sms_storage_get_string (self->priv->current_sms_mem1_storage), -1);
    }

    if (mem2 != MM_SMS_STORAGE_UNKNOWN) {
        ctx->mem2_locked = TRUE;
        ctx->previous_mem2 = self->priv->current_sms_mem2_storage;
        self->priv->mem2_storage_locked = TRUE;
        self->priv->current_sms_mem2_storage = mem2;
        mem2_str = g_ascii_strup (mm_sms_storage_get_string (self->priv->current_sms_mem2_storage), -1);

        if (mem1 == MM_SMS_STORAGE_UNKNOWN) {
            /* Some modems may not support empty string parameters. Then if mem1 is
             * UNKNOWN, we send again the already locked mem1 value in place of an
             * empty string. This way we also avoid to confuse the environment of
             * other async operation that have potentially locked mem1 previoulsy.
             * */
            mem1_str = g_ascii_strup (mm_sms_storage_get_string (self->priv->current_sms_mem1_storage), -1);
        }
    }

    /* We don't touch 'mem3' here */

    mm_dbg ("Locking SMS storages to: mem1 (%s), mem2 (%s)...",
            mem1_str ? mem1_str : "none",
            mem2_str ? mem2_str : "none");

    if (mem2_str)
        cmd = g_strdup_printf ("+CPMS=\"%s\",\"%s\"",
                               mem1_str ? mem1_str : "",
                               mem2_str);
    else if (mem1_str)
        cmd = g_strdup_printf ("+CPMS=\"%s\"", mem1_str);
    else
        g_assert_not_reached ();

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              cmd,
                              3,
                              FALSE,
                              (GAsyncReadyCallback)lock_storages_cpms_set_ready,
                              ctx);
    g_free (mem1_str);
    g_free (mem2_str);
    g_free (cmd);
}

/*****************************************************************************/
/* Set default SMS storage (Messaging interface) */

static gboolean
modem_messaging_set_default_storage_finish (MMIfaceModemMessaging *self,
                                            GAsyncResult *res,
                                            GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cpms_set_ready (MMBroadbandModem *self,
                GAsyncResult *res,
                GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error)
        g_simple_async_result_take_error (simple, error);
    else
        g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_messaging_set_default_storage (MMIfaceModemMessaging *_self,
                                     MMSmsStorage storage,
                                     GAsyncReadyCallback callback,
                                     gpointer user_data)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (_self);
    gchar *cmd;
    GSimpleAsyncResult *result;
    gchar *mem1_str;
    gchar *mem_str;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_set_default_storage);

    /* Set defaults as current */
    self->priv->current_sms_mem2_storage = storage;

    /* We provide the current sms storage for mem1 if not UNKNOWN */
    mem1_str = g_ascii_strup (mm_sms_storage_get_string (self->priv->current_sms_mem1_storage), -1);

    mem_str = g_ascii_strup (mm_sms_storage_get_string (storage), -1);
    cmd = g_strdup_printf ("+CPMS=\"%s\",\"%s\",\"%s\"",
                           mem1_str ? mem1_str : "",
                           mem_str,
                           mem_str);
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              cmd,
                              3,
                              FALSE,
                              (GAsyncReadyCallback)cpms_set_ready,
                              result);
    g_free (mem1_str);
    g_free (mem_str);
    g_free (cmd);
}

/*****************************************************************************/
/* Setup SMS format (Messaging interface) */

static gboolean
modem_messaging_setup_sms_format_finish (MMIfaceModemMessaging *self,
                                         GAsyncResult *res,
                                         GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
cmgf_set_ready (MMBroadbandModem *self,
                GAsyncResult *res,
                GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        mm_dbg ("Failed to set preferred SMS mode: '%s'; assuming text mode'",
                error->message);
        g_error_free (error);
        self->priv->modem_messaging_sms_pdu_mode = FALSE;
    } else
        mm_dbg ("Successfully set preferred SMS mode: '%s'",
                self->priv->modem_messaging_sms_pdu_mode ? "PDU" : "text");

    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
set_preferred_sms_format (MMBroadbandModem *self,
                          GSimpleAsyncResult *result)
{
    gchar *cmd;

    cmd = g_strdup_printf ("+CMGF=%s",
                           self->priv->modem_messaging_sms_pdu_mode ? "0" : "1");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              cmd,
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cmgf_set_ready,
                              result);
    g_free (cmd);
}

static void
cmgf_format_check_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GSimpleAsyncResult *simple)
{
    GError *error = NULL;
    const gchar *response;
    gboolean sms_pdu_supported = FALSE;
    gboolean sms_text_supported = FALSE;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error ||
        !mm_3gpp_parse_cmgf_test_response (response,
                                           &sms_pdu_supported,
                                           &sms_text_supported,
                                           &error)) {
        mm_dbg ("Failed to query supported SMS modes: '%s'",
                error->message);
        g_error_free (error);
    }

    /* Only use text mode if PDU mode not supported */
    self->priv->modem_messaging_sms_pdu_mode = TRUE;
    if (!sms_pdu_supported) {
        if (sms_text_supported) {
            mm_dbg ("PDU mode not supported, will try to use Text mode");
            self->priv->modem_messaging_sms_pdu_mode = FALSE;
        } else
            mm_dbg ("Neither PDU nor Text modes are reported as supported; "
                    "will anyway default to PDU mode");
    }

    self->priv->sms_supported_modes_checked = TRUE;

    set_preferred_sms_format (self, simple);
}

static void
modem_messaging_setup_sms_format (MMIfaceModemMessaging *self,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_setup_sms_format);

    /* If we already checked for supported SMS types, go on to select the
     * preferred format. */
    if (MM_BROADBAND_MODEM (self)->priv->sms_supported_modes_checked) {
        set_preferred_sms_format (MM_BROADBAND_MODEM (self), result);
        return;
    }

    /* Check supported SMS formats */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CMGF=?",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)cmgf_format_check_ready,
                              result);
}

/*****************************************************************************/
/* Setup/cleanup messaging related unsolicited events (Messaging interface) */

static gboolean
modem_messaging_setup_cleanup_unsolicited_events_finish (MMIfaceModemMessaging *self,
                                                         GAsyncResult *res,
                                                         GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    guint idx;
} SmsPartContext;

static void
sms_part_context_complete_and_free (SmsPartContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static void
sms_part_ready (MMBroadbandModem *self,
                GAsyncResult *res,
                SmsPartContext *ctx)
{
    MMSmsPart *part;
    MM3gppPduInfo *info;
    const gchar *response;
    GError *error = NULL;

    /* Always always always unlock mem1 storage. Warned you've been. */
    mm_broadband_modem_unlock_sms_storages (self, TRUE, FALSE);

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        /* We're really ignoring this error afterwards, as we don't have a callback
         * passed to the async operation, so just log the error here. */
        mm_warn ("Couldn't retrieve SMS part: '%s'",
                 error->message);
        g_simple_async_result_take_error (ctx->result, error);
        sms_part_context_complete_and_free (ctx);
        return;
    }

    info = mm_3gpp_parse_cmgr_read_response (response, ctx->idx, &error);
    if (!info) {
        mm_warn ("Couldn't parse SMS part: '%s'",
                 error->message);
        g_simple_async_result_take_error (ctx->result, error);
        sms_part_context_complete_and_free (ctx);
        return;
    }

    part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, &error);
    if (part) {
        mm_dbg ("Correctly parsed PDU (%d)", ctx->idx);
        mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                            part,
                                            MM_SMS_STATE_RECEIVED,
                                            self->priv->modem_messaging_sms_default_storage);
    } else {
        /* Don't treat the error as critical */
        mm_dbg ("Error parsing PDU (%d): %s", ctx->idx, error->message);
        g_error_free (error);
    }

    /* All done */
    mm_3gpp_pdu_info_free (info);
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    sms_part_context_complete_and_free (ctx);
}

static void
indication_lock_storages_ready (MMBroadbandModem *self,
                                GAsyncResult *res,
                                SmsPartContext *ctx)
{
    gchar *command;
    GError *error = NULL;

    if (!mm_broadband_modem_lock_sms_storages_finish (self, res, &error)) {
        /* TODO: we should either make this lock() never fail, by automatically
         * retrying after some time, or otherwise retry here. */
        g_simple_async_result_take_error (ctx->result, error);
        sms_part_context_complete_and_free (ctx);
        return;
    }

    /* Storage now set and locked */

    /* Retrieve the message */
    command = g_strdup_printf ("+CMGR=%d", ctx->idx);
    mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                              command,
                              10,
                              FALSE,
                              (GAsyncReadyCallback)sms_part_ready,
                              ctx);
    g_free (command);
}

static void
cmti_received (MMPortSerialAt *port,
               GMatchInfo *info,
               MMBroadbandModem *self)
{
    SmsPartContext *ctx;
    guint idx = 0;
    MMSmsStorage storage;
    gchar *str;

    if (!mm_get_uint_from_match_info (info, 2, &idx))
        return;

    /* The match info gives us in which storage the index applies */
    str = mm_get_string_unquoted_from_match_info (info, 1);
    storage = mm_common_get_sms_storage_from_string (str, NULL);
    if (storage == MM_SMS_STORAGE_UNKNOWN) {
        mm_dbg ("Skipping CMTI indication, unknown storage '%s' reported", str);
        g_free (str);
        return;
    }
    g_free (str);

    /* Don't signal multiple times if there are multiple CMTI notifications for a message */
    if (mm_sms_list_has_part (self->priv->modem_messaging_sms_list,
                              storage,
                              idx)) {
        mm_dbg ("Skipping CMTI indication, part already processed");
        return;
    }

    ctx = g_new0 (SmsPartContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self), NULL, NULL, cmti_received);
    ctx->idx = idx;

    /* First, request to set the proper storage to read from */
    mm_broadband_modem_lock_sms_storages (ctx->self,
                                          storage,
                                          MM_SMS_STORAGE_UNKNOWN,
                                          (GAsyncReadyCallback)indication_lock_storages_ready,
                                          ctx);
}

static void
cds_received (MMPortSerialAt *port,
              GMatchInfo *info,
              MMBroadbandModem *self)
{
    GError *error = NULL;
    MMSmsPart *part;
    guint length;
    gchar *pdu;

    mm_dbg ("Got new non-stored message indication");

    if (!mm_get_uint_from_match_info (info, 1, &length))
        return;

    pdu = g_match_info_fetch (info, 2);
    if (!pdu)
        return;

    part = mm_sms_part_3gpp_new_from_pdu (SMS_PART_INVALID_INDEX, pdu, &error);
    if (part) {
        mm_dbg ("Correctly parsed non-stored PDU");
        mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                            part,
                                            MM_SMS_STATE_RECEIVED,
                                            MM_SMS_STORAGE_UNKNOWN);
    } else {
        /* Don't treat the error as critical */
        mm_dbg ("Error parsing non-stored PDU: %s", error->message);
        g_error_free (error);
    }
}

static void
set_messaging_unsolicited_events_handlers (MMIfaceModemMessaging *self,
                                           gboolean enable,
                                           GAsyncReadyCallback callback,
                                           gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *ports[2];
    GRegex *cmti_regex;
    GRegex *cds_regex;
    guint i;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        set_messaging_unsolicited_events_handlers);

    cmti_regex = mm_3gpp_cmti_regex_get ();
    cds_regex = mm_3gpp_cds_regex_get ();
    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Add messaging unsolicited events handler for port primary and secondary */
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        /* Set/unset unsolicited CMTI event handler */
        mm_dbg ("(%s) %s messaging unsolicited events handlers",
                mm_port_get_device (MM_PORT (ports[i])),
                enable ? "Setting" : "Removing");
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            cmti_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) cmti_received : NULL,
            enable ? self : NULL,
            NULL);
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            cds_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) cds_received : NULL,
            enable ? self : NULL,
            NULL);
    }

    g_regex_unref (cmti_regex);
    g_regex_unref (cds_regex);
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

static void
modem_messaging_setup_unsolicited_events (MMIfaceModemMessaging *self,
                                          GAsyncReadyCallback callback,
                                          gpointer user_data)
{
    set_messaging_unsolicited_events_handlers (self, TRUE, callback, user_data);
}

static void
modem_messaging_cleanup_unsolicited_events (MMIfaceModemMessaging *self,
                                            GAsyncReadyCallback callback,
                                            gpointer user_data)
{
    set_messaging_unsolicited_events_handlers (self, FALSE, callback, user_data);
}

/*****************************************************************************/
/* Enable unsolicited events (SMS indications) (Messaging interface) */

static gboolean
modem_messaging_enable_unsolicited_events_finish (MMIfaceModemMessaging *self,
                                                  GAsyncResult *res,
                                                  GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static gboolean
cnmi_response_processor (MMBaseModem *self,
                         gpointer none,
                         const gchar *command,
                         const gchar *response,
                         gboolean last_command,
                         const GError *error,
                         GVariant **result,
                         GError **result_error)
{
    if (error) {
        /* If we get a not-supported error and we're not in the last command, we
         * won't set 'result_error', so we'll keep on the sequence */
        if (!g_error_matches (error, MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_NOT_SUPPORTED) ||
            last_command)
            *result_error = g_error_copy (error);

        return FALSE;
    }

    *result = NULL;
    return TRUE;
}

static const MMBaseModemAtCommand cnmi_sequence[] = {
    { "+CNMI=2,1,2,1,0", 3, FALSE, cnmi_response_processor },

    /* Many Qualcomm-based devices don't support <ds> of '1', despite
     * reporting they support it in the +CNMI=? response.  But they do
     * accept '2'.
     */
    { "+CNMI=2,1,2,2,0", 3, FALSE, cnmi_response_processor },

    /* Last resort: turn off delivery status reports altogether */
    { "+CNMI=2,1,2,0,0", 3, FALSE, cnmi_response_processor },
    { NULL }
};

static void
modem_messaging_enable_unsolicited_events_secondary_ready (MMBaseModem *self,
                                                           GAsyncResult *res,
                                                           GSimpleAsyncResult *final_result)
{
    GError *inner_error = NULL;
    MMPortSerialAt *secondary;

    secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Since the secondary is not required, we don't propagate the error anywhere */
    mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &inner_error);
    if (inner_error) {
        mm_dbg ("(%s) Unable to enable messaging unsolicited events on modem secondary: %s",
                mm_port_get_device (MM_PORT (secondary)),
                inner_error->message);
        g_error_free (inner_error);
    }

    mm_dbg ("(%s) Messaging unsolicited events enabled on secondary",
            mm_port_get_device (MM_PORT (secondary)));

    g_simple_async_result_complete (final_result);
    g_object_unref (final_result);
}

static void
modem_messaging_enable_unsolicited_events_primary_ready (MMBaseModem *self,
                                                         GAsyncResult *res,
                                                         GSimpleAsyncResult *final_result)
{
    GError *inner_error = NULL;
    MMPortSerialAt *primary;
    MMPortSerialAt *secondary;

    primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &inner_error);
    if (inner_error) {
        g_simple_async_result_take_error (final_result, inner_error);
        g_simple_async_result_complete (final_result);
        g_object_unref (final_result);
        return;
    }

    mm_dbg ("(%s) Messaging unsolicited events enabled on primary",
            mm_port_get_device (MM_PORT (primary)));

    /* Try to enable unsolicited events for secondary port */
    if (secondary) {
        mm_dbg ("(%s) Enabling messaging unsolicited events on secondary port",
                mm_port_get_device (MM_PORT (secondary)));
        mm_base_modem_at_sequence_full (
            MM_BASE_MODEM (self),
            secondary,
            cnmi_sequence,
            NULL, /* response_processor_context */
            NULL, /* response_processor_context_free */
            NULL,
            (GAsyncReadyCallback)modem_messaging_enable_unsolicited_events_secondary_ready,
            final_result);
        return;
    }

    g_simple_async_result_complete (final_result);
    g_object_unref (final_result);
}

static void
modem_messaging_enable_unsolicited_events (MMIfaceModemMessaging *self,
                                           GAsyncReadyCallback callback,
                                           gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *primary;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_messaging_enable_unsolicited_events);

    primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));

    /* Enable unsolicited events for primary port */
    mm_dbg ("(%s) Enabling messaging unsolicited events on primary port",
            mm_port_get_device (MM_PORT (primary)));
    mm_base_modem_at_sequence_full (
        MM_BASE_MODEM (self),
        primary,
        cnmi_sequence,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        NULL,
        (GAsyncReadyCallback)modem_messaging_enable_unsolicited_events_primary_ready,
        result);
}

/*****************************************************************************/
/* Load initial list of SMS parts (Messaging interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMSmsStorage list_storage;
} ListPartsContext;

static void
list_parts_context_complete_and_free (ListPartsContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_messaging_load_initial_sms_parts_finish (MMIfaceModemMessaging *self,
                                               GAsyncResult *res,
                                               GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static MMSmsState
sms_state_from_str (const gchar *str)
{
    /* We merge unread and read messages in the same state */
    if (strstr (str, "REC"))
        return MM_SMS_STATE_RECEIVED;

    /* look for 'unsent' BEFORE looking for 'sent' */
    if (strstr (str, "UNSENT"))
        return MM_SMS_STATE_STORED;

    if (strstr (str, "SENT"))
        return MM_SMS_STATE_SENT;

    return MM_SMS_STATE_UNKNOWN;
}

static MMSmsPduType
sms_pdu_type_from_str (const gchar *str)
{
    /* We merge unread and read messages in the same state */
    if (strstr (str, "REC"))
        return MM_SMS_PDU_TYPE_DELIVER;

    if (strstr (str, "STO"))
        return MM_SMS_PDU_TYPE_SUBMIT;

    return MM_SMS_PDU_TYPE_UNKNOWN;
}

static void
sms_text_part_list_ready (MMBroadbandModem *self,
                          GAsyncResult *res,
                          ListPartsContext *ctx)
{
    GRegex *r;
    GMatchInfo *match_info = NULL;
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        list_parts_context_complete_and_free (ctx);
        return;
    }

    /* +CMGL: <index>,<stat>,<oa/da>,[alpha],<scts><CR><LF><data><CR><LF> */
    r = g_regex_new ("\\+CMGL:\\s*(\\d+)\\s*,\\s*([^,]*),\\s*([^,]*),\\s*([^,]*),\\s*([^\\r\\n]*)\\r\\n([^\\r\\n]*)",
                     0, 0, NULL);
    g_assert (r);

    if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_INVALID_ARGS,
                                         "Couldn't parse SMS list response");
        list_parts_context_complete_and_free (ctx);
        g_match_info_free (match_info);
        g_regex_unref (r);
        return;
    }

    while (g_match_info_matches (match_info)) {
        MMSmsPart *part;
        guint matches, idx;
        gchar *number, *timestamp, *text, *ucs2_text, *stat;
        gsize ucs2_len = 0;
        GByteArray *raw;

        matches = g_match_info_get_match_count (match_info);
        if (matches != 7) {
            mm_dbg ("Failed to match entire CMGL response (count %d)", matches);
            goto next;
        }

        if (!mm_get_uint_from_match_info (match_info, 1, &idx)) {
            mm_dbg ("Failed to convert message index");
            goto next;
        }

        /* Get part state */
        stat = mm_get_string_unquoted_from_match_info (match_info, 2);
        if (!stat) {
            mm_dbg ("Failed to get part status");
            goto next;
        }

        /* Get and parse number */
        number = mm_get_string_unquoted_from_match_info (match_info, 3);
        if (!number) {
            mm_dbg ("Failed to get message sender number");
            g_free (stat);
            goto next;
        }

        number = mm_broadband_modem_take_and_convert_to_utf8 (MM_BROADBAND_MODEM (self),
                                                              number);

        /* Get and parse timestamp (always expected in ASCII) */
        timestamp = mm_get_string_unquoted_from_match_info (match_info, 5);

        /* Get and parse text */
        text = mm_broadband_modem_take_and_convert_to_utf8 (MM_BROADBAND_MODEM (self),
                                                            g_match_info_fetch (match_info, 6));

        /* The raw SMS data can only be GSM, UCS2, or unknown (8-bit), so we
         * need to convert to UCS2 here.
         */
        ucs2_text = g_convert (text, -1, "UCS-2BE//TRANSLIT", "UTF-8", NULL, &ucs2_len, NULL);
        g_assert (ucs2_text);
        raw = g_byte_array_sized_new (ucs2_len);
        g_byte_array_append (raw, (const guint8 *) ucs2_text, ucs2_len);
        g_free (ucs2_text);

        /* all take() methods pass ownership of the value as well */
        part = mm_sms_part_new (idx,
                                sms_pdu_type_from_str (stat));
        mm_sms_part_take_number (part, number);
        mm_sms_part_take_timestamp (part, timestamp);
        mm_sms_part_take_text (part, text);
        mm_sms_part_take_data (part, raw);
        mm_sms_part_set_class (part, -1);

        mm_dbg ("Correctly parsed SMS list entry (%d)", idx);
        mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                            part,
                                            sms_state_from_str (stat),
                                            ctx->list_storage);
        g_free (stat);
next:
        g_match_info_next (match_info, NULL);
    }
    g_match_info_free (match_info);
    g_regex_unref (r);

    /* We consider all done */
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    list_parts_context_complete_and_free (ctx);
}

static MMSmsState
sms_state_from_index (guint index)
{
    /* We merge unread and read messages in the same state */
    switch (index) {
    case 0: /* received, unread */
    case 1: /* received, read */
        return MM_SMS_STATE_RECEIVED;
    case 2:
        return MM_SMS_STATE_STORED;
    case 3:
        return MM_SMS_STATE_SENT;
    default:
        return MM_SMS_STATE_UNKNOWN;
    }
}

static void
sms_pdu_part_list_ready (MMBroadbandModem *self,
                         GAsyncResult *res,
                         ListPartsContext *ctx)
{
    const gchar *response;
    GError *error = NULL;
    GList *info_list;
    GList *l;

    /* Always always always unlock mem1 storage. Warned you've been. */
    mm_broadband_modem_unlock_sms_storages (self, TRUE, FALSE);

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        list_parts_context_complete_and_free (ctx);
        return;
    }

    info_list = mm_3gpp_parse_pdu_cmgl_response (response, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        list_parts_context_complete_and_free (ctx);
        return;
    }

    for (l = info_list; l; l = g_list_next (l)) {
        MM3gppPduInfo *info = l->data;
        MMSmsPart *part;

        part = mm_sms_part_3gpp_new_from_pdu (info->index, info->pdu, &error);
        if (part) {
            mm_dbg ("Correctly parsed PDU (%d)", info->index);
            mm_iface_modem_messaging_take_part (MM_IFACE_MODEM_MESSAGING (self),
                                                part,
                                                sms_state_from_index (info->status),
                                                ctx->list_storage);
        } else {
            /* Don't treat the error as critical */
            mm_dbg ("Error parsing PDU (%d): %s", info->index, error->message);
            g_clear_error (&error);
        }
    }

    mm_3gpp_pdu_info_list_free (info_list);

    /* We consider all done */
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    list_parts_context_complete_and_free (ctx);
}

static void
list_parts_lock_storages_ready (MMBroadbandModem *self,
                                GAsyncResult *res,
                                ListPartsContext *ctx)
{
    GError *error = NULL;

    if (!mm_broadband_modem_lock_sms_storages_finish (self, res, &error)) {
        /* TODO: we should either make this lock() never fail, by automatically
         * retrying after some time, or otherwise retry here. */
        g_simple_async_result_take_error (ctx->result, error);
        list_parts_context_complete_and_free (ctx);
        return;
    }

    /* Storage now set and locked */

    /* Get SMS parts from ALL types.
     * Different command to be used if we are on Text or PDU mode */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              (MM_BROADBAND_MODEM (self)->priv->modem_messaging_sms_pdu_mode ?
                               "+CMGL=4" :
                               "+CMGL=\"ALL\""),
                              20,
                              FALSE,
                              (GAsyncReadyCallback) (MM_BROADBAND_MODEM (self)->priv->modem_messaging_sms_pdu_mode ?
                                                     sms_pdu_part_list_ready :
                                                     sms_text_part_list_ready),
                              ctx);
}

static void
modem_messaging_load_initial_sms_parts (MMIfaceModemMessaging *self,
                                        MMSmsStorage storage,
                                        GAsyncReadyCallback callback,
                                        gpointer user_data)
{
    ListPartsContext *ctx;

    ctx = g_new0 (ListPartsContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_messaging_load_initial_sms_parts);
    ctx->list_storage = storage;

    mm_dbg ("Listing SMS parts in storage '%s'",
            mm_sms_storage_get_string (storage));

    /* First, request to set the proper storage to read from */
    mm_broadband_modem_lock_sms_storages (ctx->self,
                                          storage,
                                          MM_SMS_STORAGE_UNKNOWN,
                                          (GAsyncReadyCallback)list_parts_lock_storages_ready,
                                          ctx);
}

/*****************************************************************************/
/* Create SMS (Messaging interface) */

static MMBaseSms *
modem_messaging_create_sms (MMIfaceModemMessaging *self)
{
    return mm_base_sms_new (MM_BASE_MODEM (self));
}

/*****************************************************************************/
/* Check if Voice supported (Voice interface) */

static gboolean
modem_voice_check_support_finish (MMIfaceModemVoice *self,
                                  GAsyncResult *res,
                                  GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
ath_format_check_ready (MMBroadbandModem *self,
                        GAsyncResult *res,
                        GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (simple, error);
        g_simple_async_result_complete (simple);
        g_object_unref (simple);
        return;
    }

    /* ATH command is supported; assume we have full voice capabilities */
    g_simple_async_result_set_op_res_gboolean (simple, TRUE);
    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_voice_check_support (MMIfaceModemVoice *self,
                           GAsyncReadyCallback callback,
                           gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_voice_check_support);

    /* We assume that all modems have voice capabilities, but ... */

    /* Check ATH support */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "H",
                              3,
                              TRUE,
                              (GAsyncReadyCallback)ath_format_check_ready,
                              result);
}

/*****************************************************************************/
/* Setup/cleanup voice related unsolicited events (Voice interface) */

static gboolean
modem_voice_setup_cleanup_unsolicited_events_finish (MMIfaceModemVoice *self,
                                                     GAsyncResult *res,
                                                     GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
ring_received (MMPortSerialAt *port,
               GMatchInfo *info,
               MMBroadbandModem *self)
{
    mm_dbg ("Ringing");
    mm_iface_modem_voice_create_incoming_call (MM_IFACE_MODEM_VOICE (self));
}

static void
cring_received (MMPortSerialAt *port,
                GMatchInfo *info,
                MMBroadbandModem *self)
{
    /* The match info gives us in which storage the index applies */
    gchar *str;

    /* We could have "VOICE" or "DATA". Now consider only "VOICE" */

    str = mm_get_string_unquoted_from_match_info (info, 1);
    mm_dbg ("Ringing (%s)", str);
    g_free (str);

    mm_iface_modem_voice_create_incoming_call (MM_IFACE_MODEM_VOICE (self));
}

static void
clip_received (MMPortSerialAt *port,
               GMatchInfo *info,
               MMBroadbandModem *self)
{
    /* The match info gives us in which storage the index applies */
    gchar *str;

    str = mm_get_string_unquoted_from_match_info (info, 1);

    if (str) {
        guint validity  = 0;
        guint type      = 0;

        mm_get_uint_from_match_info (info, 2, &type);
        mm_get_uint_from_match_info (info, 3, &validity);

        mm_dbg ("Caller ID received: number '%s', type '%d', validity '%d'", str, type, validity);

        mm_iface_modem_voice_update_incoming_call_number (MM_IFACE_MODEM_VOICE (self), str, type, validity);

        g_free (str);
    }
}

static void
set_voice_unsolicited_events_handlers (MMIfaceModemVoice *self,
                                       gboolean enable,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    GSimpleAsyncResult *result;
    MMPortSerialAt *ports[2];
    GRegex *cring_regex;
    GRegex *ring_regex;
    GRegex *clip_regex;
    guint i;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        set_voice_unsolicited_events_handlers);

    cring_regex = mm_voice_cring_regex_get ();
    ring_regex  = mm_voice_ring_regex_get ();
    clip_regex  = mm_voice_clip_regex_get ();
    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    /* Enable unsolicited events in given port */
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        /* Set/unset unsolicited CMTI event handler */
        mm_dbg ("(%s) %s voice unsolicited events handlers",
                mm_port_get_device (MM_PORT (ports[i])),
                enable ? "Setting" : "Removing");
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            cring_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) cring_received : NULL,
            enable ? self : NULL,
            NULL);
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            ring_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) ring_received : NULL,
            enable ? self : NULL,
            NULL);
        mm_port_serial_at_add_unsolicited_msg_handler (
            ports[i],
            clip_regex,
            enable ? (MMPortSerialAtUnsolicitedMsgFn) clip_received : NULL,
            enable ? self : NULL,
            NULL);
    }

    g_regex_unref (clip_regex);
    g_regex_unref (cring_regex);
    g_regex_unref (ring_regex);
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

static void
modem_voice_setup_unsolicited_events (MMIfaceModemVoice *self,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    set_voice_unsolicited_events_handlers (self, TRUE, callback, user_data);
}

static void
modem_voice_cleanup_unsolicited_events (MMIfaceModemVoice *self,
                                        GAsyncReadyCallback callback,
                                        gpointer user_data)
{
    set_voice_unsolicited_events_handlers (self, FALSE, callback, user_data);
}

/*****************************************************************************/
/* Enable unsolicited events (CALL indications) (Voice interface) */

static gboolean
modem_voice_enable_unsolicited_events_finish (MMIfaceModemVoice *self,
                                              GAsyncResult *res,
                                              GError **error)
{
    GError *inner_error = NULL;

    mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &inner_error);
    if (inner_error) {
        g_propagate_error (error, inner_error);
        return FALSE;
    }

    return TRUE;
}

static gboolean
ring_response_processor (MMBaseModem *self,
                         gpointer none,
                         const gchar *command,
                         const gchar *response,
                         gboolean last_command,
                         const GError *error,
                         GVariant **result,
                         GError **result_error)
{
    if (error) {
        /* If we get a not-supported error and we're not in the last command, we
         * won't set 'result_error', so we'll keep on the sequence */
        if (!g_error_matches (error, MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_NOT_SUPPORTED) ||
            last_command)
            *result_error = g_error_copy (error);

        return TRUE;
    }

    *result = NULL;
    return FALSE;
}

static const MMBaseModemAtCommand ring_sequence[] = {
    /* Show caller number on RING. */
    { "+CLIP=1", 3, FALSE, ring_response_processor },
    /* Show difference between data call and voice call */
    { "+CRC=1", 3, FALSE, ring_response_processor },
    { NULL }
};

static void
modem_voice_enable_unsolicited_events (MMIfaceModemVoice *self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    mm_base_modem_at_sequence (
        MM_BASE_MODEM (self),
        ring_sequence,
        NULL, /* response_processor_context */
        NULL, /* response_processor_context_free */
        callback,
        user_data);
}

/*****************************************************************************/
/* Create CALL (Voice interface) */

static MMBaseCall *
modem_voice_create_call (MMIfaceModemVoice *self)
{
    return mm_base_call_new (MM_BASE_MODEM (self));
}

/*****************************************************************************/
/* ESN loading (CDMA interface) */

static gchar *
modem_cdma_load_esn_finish (MMIfaceModemCdma *self,
                            GAsyncResult *res,
                            GError **error)
{
    const gchar *result;
    gchar *esn = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    result = mm_strip_tag (result, "+GSN:");
    mm_parse_gsn (result, NULL, NULL, &esn);
    mm_dbg ("loaded ESN: %s", esn);
    return esn;
}

static void
modem_cdma_load_esn (MMIfaceModemCdma *self,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
    mm_dbg ("loading ESN...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+GSN",
                              3,
                              TRUE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* MEID loading (CDMA interface) */

static gchar *
modem_cdma_load_meid_finish (MMIfaceModemCdma *self,
                             GAsyncResult *res,
                             GError **error)
{
    const gchar *result;
    gchar *meid = NULL;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!result)
        return NULL;

    result = mm_strip_tag (result, "+GSN:");
    mm_parse_gsn (result, NULL, &meid, NULL);
    mm_dbg ("loaded MEID: %s", meid);
    return meid;
}

static void
modem_cdma_load_meid (MMIfaceModemCdma *self,
                      GAsyncReadyCallback callback,
                      gpointer user_data)
{
    /* Some devices return both the MEID and the ESN in the +GSN response */
    mm_dbg ("loading MEID...");
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+GSN",
                              3,
                              TRUE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Setup/Cleanup unsolicited events (CDMA interface) */

typedef struct {
    MMBroadbandModem *self;
    gboolean setup;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *qcdm;
} CdmaUnsolicitedEventsContext;

static void
cdma_unsolicited_events_context_complete_and_free (CdmaUnsolicitedEventsContext *ctx,
                                                   gboolean close_port,
                                                   GError *error)
{
    if (error)
        g_simple_async_result_take_error (ctx->result, error);
    else
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    g_simple_async_result_complete_in_idle (ctx->result);

    g_clear_object (&ctx->result);
    g_clear_object (&ctx->self);

    if (ctx->qcdm && close_port)
        mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm));
    g_clear_object (&ctx->qcdm);

    g_free (ctx);
}

static void
logcmd_qcdm_ready (MMPortSerialQcdm *port,
                   GAsyncResult *res,
                   CdmaUnsolicitedEventsContext *ctx)
{
    QcdmResult *result;
    gint err = QCDM_SUCCESS;
    GByteArray *response;
    GError *error = NULL;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        cdma_unsolicited_events_context_complete_and_free (ctx, TRUE, error);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_log_config_set_mask_result ((const gchar *) response->data,
                                                  response->len,
                                                  &err);
    g_byte_array_unref (response);
    if (!result) {
        error = g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Failed to parse Log Config Set Mask command result: %d",
                             err);
        cdma_unsolicited_events_context_complete_and_free (ctx, TRUE, error);
        return;
    }

    mm_port_serial_qcdm_add_unsolicited_msg_handler (port,
                                                     DM_LOG_ITEM_EVDO_PILOT_SETS_V2,
                                                     ctx->setup ? qcdm_evdo_pilot_sets_log_handle : NULL,
                                                     ctx->self,
                                                     NULL);

    qcdm_result_unref (result);

    /* Balance the mm_port_seral_open() from modem_cdma_setup_cleanup_unsolicited_events().
     * We want to close it in either case:
     *  (a) we're cleaning up and setup opened the port
     *  (b) if it was unexpectedly closed before cleanup and thus cleanup opened it
     *
     * Setup should leave the port open to allow log messages to be received
     * and sent to handlers.
     */
    cdma_unsolicited_events_context_complete_and_free (ctx, ctx->setup ? FALSE : TRUE, NULL);
}

static void
modem_cdma_setup_cleanup_unsolicited_events (MMBroadbandModem *self,
                                             gboolean setup,
                                             GAsyncReadyCallback callback,
                                             gpointer user_data)
{
    CdmaUnsolicitedEventsContext *ctx;
    GByteArray *logcmd;
    uint16_t log_items[] = { DM_LOG_ITEM_EVDO_PILOT_SETS_V2, 0 };
    GError *error = NULL;

    ctx = g_new0 (CdmaUnsolicitedEventsContext, 1);
    ctx->self = g_object_ref (self);
    ctx->setup = TRUE;
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_setup_cleanup_unsolicited_events);
    ctx->qcdm = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
    if (!ctx->qcdm) {
        cdma_unsolicited_events_context_complete_and_free (ctx, FALSE, NULL);
        return;
    }

    /* Setup must open the QCDM port and keep it open to receive unsolicited
     * events.  Cleanup expects the port to already be opened from setup, but
     * if not we still want to open it and try to disable log messages.
     */
    if (setup || !mm_port_serial_is_open (MM_PORT_SERIAL (ctx->qcdm))) {
        if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm), &error)) {
            cdma_unsolicited_events_context_complete_and_free (ctx, FALSE, error);
            return;
        }
    }

    logcmd = g_byte_array_sized_new (512);
    logcmd->len = qcdm_cmd_log_config_set_mask_new ((char *) logcmd->data,
                                                    512,
                                                    0x01,  /* Equipment ID */
                                                    setup ? log_items : NULL);
    assert (logcmd->len);

    mm_port_serial_qcdm_command (ctx->qcdm,
                                 logcmd,
                                 5,
                                 NULL,
                                 (GAsyncReadyCallback)logcmd_qcdm_ready,
                                 ctx);
    g_byte_array_unref (logcmd);
}

static gboolean
modem_cdma_setup_cleanup_unsolicited_events_finish (MMIfaceModemCdma *self,
                                                    GAsyncResult *res,
                                                    GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
modem_cdma_setup_unsolicited_events (MMIfaceModemCdma *self,
                                     GAsyncReadyCallback callback,
                                     gpointer user_data)
{
    modem_cdma_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM (self),
                                                 TRUE,
                                                 callback,
                                                 user_data);
}

static void
modem_cdma_cleanup_unsolicited_events (MMIfaceModemCdma *self,
                                       GAsyncReadyCallback callback,
                                       gpointer user_data)
{
    modem_cdma_setup_cleanup_unsolicited_events (MM_BROADBAND_MODEM (self),
                                                 FALSE,
                                                 callback,
                                                 user_data);
}

/*****************************************************************************/
/* HDR state check (CDMA interface) */

typedef struct {
    guint8 hybrid_mode;
    guint8 session_state;
    guint8 almp_state;
} HdrStateResults;

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *qcdm;
} HdrStateContext;

static void
hdr_state_context_complete_and_free (HdrStateContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->qcdm);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_cdma_get_hdr_state_finish (MMIfaceModemCdma *self,
                                 GAsyncResult *res,
                                 guint8 *hybrid_mode,
                                 guint8 *session_state,
                                 guint8 *almp_state,
                                 GError **error)
{
    HdrStateResults *results;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *hybrid_mode = results->hybrid_mode;
    *session_state = results->session_state;
    *almp_state = results->almp_state;
    return TRUE;
}

static void
hdr_subsys_state_info_ready (MMPortSerialQcdm *port,
                             GAsyncResult *res,
                             HdrStateContext *ctx)
{
    QcdmResult *result;
    HdrStateResults *results;
    gint err = QCDM_SUCCESS;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        g_simple_async_result_set_from_error (ctx->result, error);
        hdr_state_context_complete_and_free (ctx);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_hdr_subsys_state_info_result ((const gchar *) response->data,
                                                    response->len,
                                                    &err);
    g_byte_array_unref (response);
    if (!result) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Failed to parse HDR subsys state info command result: %d",
                                         err);
        hdr_state_context_complete_and_free (ctx);
        return;
    }

    /* Build results */
    results = g_new0 (HdrStateResults, 1);
    qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_HDR_HYBRID_MODE, &results->hybrid_mode);
    results->session_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_SESSION_STATE_CLOSED;
    qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_SESSION_STATE, &results->session_state);
    results->almp_state = QCDM_CMD_HDR_SUBSYS_STATE_INFO_ALMP_STATE_INACTIVE;
    qcdm_result_get_u8 (result, QCDM_CMD_HDR_SUBSYS_STATE_INFO_ITEM_ALMP_STATE, &results->almp_state);
    qcdm_result_unref (result);

    g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
    hdr_state_context_complete_and_free (ctx);
}

static void
modem_cdma_get_hdr_state (MMIfaceModemCdma *self,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
    MMPortSerialQcdm *qcdm;
    HdrStateContext *ctx;
    GByteArray *hdrstate;

    qcdm = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self));
    if (!qcdm) {
        g_simple_async_report_error_in_idle (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_UNSUPPORTED,
                                             "Cannot get HDR state without a QCDM port");
        return;
    }

    /* Setup context */
    ctx = g_new0 (HdrStateContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_get_hdr_state);
    ctx->qcdm = g_object_ref (qcdm);

    /* Setup command */
    hdrstate = g_byte_array_sized_new (25);
    hdrstate->len = qcdm_cmd_hdr_subsys_state_info_new ((gchar *) hdrstate->data, 25);
    g_assert (hdrstate->len);

    mm_port_serial_qcdm_command (ctx->qcdm,
                                 hdrstate,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)hdr_subsys_state_info_ready,
                                 ctx);
    g_byte_array_unref (hdrstate);
}

/*****************************************************************************/
/* Call Manager state check (CDMA interface) */

typedef struct {
    guint system_mode;
    guint operating_mode;
} CallManagerStateResults;

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *qcdm;
} CallManagerStateContext;

static void
call_manager_state_context_complete_and_free (CallManagerStateContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->qcdm);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_cdma_get_call_manager_state_finish (MMIfaceModemCdma *self,
                                          GAsyncResult *res,
                                          guint *system_mode,
                                          guint *operating_mode,
                                          GError **error)
{
    CallManagerStateResults *results;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *system_mode = results->system_mode;
    *operating_mode = results->operating_mode;
    return TRUE;
}

static void
cm_subsys_state_info_ready (MMPortSerialQcdm *port,
                            GAsyncResult *res,
                            CallManagerStateContext *ctx)
{
    QcdmResult *result;
    CallManagerStateResults *results;
    gint err = QCDM_SUCCESS;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        call_manager_state_context_complete_and_free (ctx);
        return;
    }

    /* Parse the response */
    result = qcdm_cmd_cm_subsys_state_info_result ((const gchar *) response->data,
                                                   response->len,
                                                   &err);
    g_byte_array_unref (response);
    if (!result) {
        g_simple_async_result_set_error (ctx->result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_FAILED,
                                         "Failed to parse CM subsys state info command result: %d",
                                         err);
        call_manager_state_context_complete_and_free (ctx);
        return;
    }

    /* Build results */
    results = g_new0 (CallManagerStateResults, 1);
    qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_OPERATING_MODE, &results->operating_mode);
    qcdm_result_get_u32 (result, QCDM_CMD_CM_SUBSYS_STATE_INFO_ITEM_SYSTEM_MODE, &results->system_mode);
    qcdm_result_unref (result);

    g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
    call_manager_state_context_complete_and_free (ctx);
}

static void
modem_cdma_get_call_manager_state (MMIfaceModemCdma *self,
                                   GAsyncReadyCallback callback,
                                   gpointer user_data)
{
    MMPortSerialQcdm *qcdm;
    CallManagerStateContext *ctx;
    GByteArray *cmstate;

    qcdm = mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self));
    if (!qcdm) {
        g_simple_async_report_error_in_idle (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_UNSUPPORTED,
                                             "Cannot get call manager state without a QCDM port");
        return;
    }

    /* Setup context */
    ctx = g_new0 (CallManagerStateContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_get_call_manager_state);
    ctx->qcdm = g_object_ref (qcdm);

    /* Setup command */
    cmstate = g_byte_array_sized_new (25);
    cmstate->len = qcdm_cmd_cm_subsys_state_info_new ((gchar *) cmstate->data, 25);
    g_assert (cmstate->len);

    mm_port_serial_qcdm_command (ctx->qcdm,
                                 cmstate,
                                 3,
                                 NULL,
                                 (GAsyncReadyCallback)cm_subsys_state_info_ready,
                                 ctx);
    g_byte_array_unref (cmstate);
}

/*****************************************************************************/
/* Serving System check (CDMA interface) */

typedef struct {
    guint sid;
    guint nid;
    guint class;
    guint band;
} Cdma1xServingSystemResults;

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialQcdm *qcdm;
} Cdma1xServingSystemContext;

static void
cdma1x_serving_system_context_complete_and_free (Cdma1xServingSystemContext *ctx)
{
    g_simple_async_result_complete (ctx->result);
    if (ctx->qcdm)
        g_object_unref (ctx->qcdm);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static GError *
cdma1x_serving_system_no_service_error (void)
{
    /* NOTE: update get_cdma1x_serving_system_ready() in mm-iface-modem-cdma.c
     * if this error changes */
    return g_error_new_literal (MM_MOBILE_EQUIPMENT_ERROR,
                                MM_MOBILE_EQUIPMENT_ERROR_NO_NETWORK,
                                "No CDMA service");
}

static gboolean
modem_cdma_get_cdma1x_serving_system_finish (MMIfaceModemCdma *self,
                                             GAsyncResult *res,
                                             guint *class,
                                             guint *band,
                                             guint *sid,
                                             guint *nid,
                                             GError **error)
{
    Cdma1xServingSystemResults *results;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    results = (Cdma1xServingSystemResults *)g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *sid = results->sid;
    *nid = results->nid;
    *class = results->class;
    *band = results->band;
    return TRUE;
}

static void
css_query_ready (MMIfaceModemCdma *self,
                 GAsyncResult *res,
                 Cdma1xServingSystemContext *ctx)
{
    GError *error = NULL;
    const gchar *result;
    gint class = 0;
    gint sid = MM_MODEM_CDMA_SID_UNKNOWN;
    gint num;
    guchar band = 'Z';
    gboolean class_ok = FALSE;
    gboolean band_ok = FALSE;
    gboolean success = FALSE;
    Cdma1xServingSystemResults *results;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        cdma1x_serving_system_context_complete_and_free (ctx);
        return;
    }

    /* Strip any leading command tag and spaces */
    result = mm_strip_tag (result, "+CSS:");
    num = sscanf (result, "? , %d", &sid);
    if (num == 1) {
        /* UTStarcom and Huawei modems that use IS-707-A format; note that
         * this format obviously doesn't have other indicators like band and
         * class and thus SID 0 will be reported as "no service" (see below).
         */
        class = 0;
        band = 'Z';
        success = TRUE;
    } else {
        GRegex *r;
        GMatchInfo *match_info;

        /* Format is "<band_class>,<band>,<sid>" */
        r = g_regex_new ("\\s*([^,]*?)\\s*,\\s*([^,]*?)\\s*,\\s*(\\d+)", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
        if (!r) {
            g_simple_async_result_set_error (
                ctx->result,
                MM_CORE_ERROR,
                MM_CORE_ERROR_FAILED,
                "Could not parse Serving System results (regex creation failed).");
            cdma1x_serving_system_context_complete_and_free (ctx);
            return;
        }

        g_regex_match (r, result, 0, &match_info);
        if (g_match_info_get_match_count (match_info) >= 3) {
            gint override_class = 0;
            gchar *str;

            /* band class */
            str = g_match_info_fetch (match_info, 1);
            class = mm_cdma_normalize_class (str);
            g_free (str);

            /* band */
            str = g_match_info_fetch (match_info, 2);
            band = mm_cdma_normalize_band (str, &override_class);
            if (override_class)
                class = override_class;
            g_free (str);

            /* sid */
            str = g_match_info_fetch (match_info, 3);
            if (!mm_get_int_from_str (str, &sid))
                sid = MM_MODEM_CDMA_SID_UNKNOWN;
            g_free (str);

            success = TRUE;
        }

        g_match_info_free (match_info);
        g_regex_unref (r);
    }

    if (!success) {
        g_simple_async_result_set_error (
            ctx->result,
            MM_CORE_ERROR,
            MM_CORE_ERROR_FAILED,
            "Could not parse Serving System results");
        cdma1x_serving_system_context_complete_and_free (ctx);
        return;
    }

    /* Normalize the SID */
    if (sid < 0 || sid > 32767)
        sid = MM_MODEM_CDMA_SID_UNKNOWN;

    if (class == 1 || class == 2)
        class_ok = TRUE;
    if (band != 'Z')
        band_ok = TRUE;

    /* Return 'no service' if none of the elements of the +CSS response
     * indicate that the modem has service.  Note that this allows SID 0
     * when at least one of the other elements indicates service.
     * Normally we'd treat SID 0 as 'no service' but some modems
     * (Sierra 5725) sometimes return SID 0 even when registered.
     */
    if (sid == 0 && !class_ok && !band_ok)
        sid = MM_MODEM_CDMA_SID_UNKNOWN;

    /* 99999 means unknown/no service */
    if (sid == MM_MODEM_CDMA_SID_UNKNOWN) {
        g_simple_async_result_take_error (ctx->result,
                                          cdma1x_serving_system_no_service_error ());
        cdma1x_serving_system_context_complete_and_free (ctx);
        return;
    }

    results = g_new0 (Cdma1xServingSystemResults, 1);
    results->sid = sid;
    results->band = band;
    results->class = class;
    /* No means to get NID with AT commands right now */
    results->nid = MM_MODEM_CDMA_NID_UNKNOWN;

    g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
    cdma1x_serving_system_context_complete_and_free (ctx);
}

static void
qcdm_cdma_status_ready (MMPortSerialQcdm *port,
                        GAsyncResult *res,
                        Cdma1xServingSystemContext *ctx)
{
    Cdma1xServingSystemResults *results;
    QcdmResult *result = NULL;
    guint32 sid = MM_MODEM_CDMA_SID_UNKNOWN;
    guint32 nid = MM_MODEM_CDMA_NID_UNKNOWN;
    guint32 rxstate = 0;
    gint err = QCDM_SUCCESS;
    GError *error = NULL;
    GByteArray *response;

    response = mm_port_serial_qcdm_command_finish (port, res, &error);
    if (error ||
        (result = qcdm_cmd_cdma_status_result ((const gchar *) response->data,
                                               response->len,
                                               &err)) == NULL) {
        if (err != QCDM_SUCCESS)
            mm_dbg ("Failed to parse cdma status command result: %d", err);
        /* If there was some error, fall back to use +CSS like we did before QCDM */
        mm_base_modem_at_command (MM_BASE_MODEM (ctx->self),
                                  "+CSS?",
                                  3,
                                  FALSE,
                                  (GAsyncReadyCallback)css_query_ready,
                                  ctx);
        if (error)
            g_error_free (error);
        if (response)
            g_byte_array_unref (response);
        return;
    }

    g_byte_array_unref (response);

    qcdm_result_get_u32 (result, QCDM_CMD_CDMA_STATUS_ITEM_RX_STATE, &rxstate);
    qcdm_result_get_u32 (result, QCDM_CMD_CDMA_STATUS_ITEM_SID, &sid);
    qcdm_result_get_u32 (result, QCDM_CMD_CDMA_STATUS_ITEM_NID, &nid);
    qcdm_result_unref (result);

    /* 99999 means unknown/no service */
    if (rxstate == QCDM_CMD_CDMA_STATUS_RX_STATE_ENTERING_CDMA) {
        sid = MM_MODEM_CDMA_SID_UNKNOWN;
        nid = MM_MODEM_CDMA_NID_UNKNOWN;
    }

    mm_dbg ("CDMA 1x Status RX state: %d", rxstate);
    mm_dbg ("CDMA 1x Status SID: %d", sid);
    mm_dbg ("CDMA 1x Status NID: %d", nid);

    results = g_new0 (Cdma1xServingSystemResults, 1);
    results->sid = sid;
    results->nid = nid;
    if (sid != MM_MODEM_CDMA_SID_UNKNOWN) {
        results->band = 'Z';
        results->class = 0;
    }

    g_simple_async_result_set_op_res_gpointer (ctx->result, results, (GDestroyNotify)g_free);
    cdma1x_serving_system_context_complete_and_free (ctx);
}

static void
modem_cdma_get_cdma1x_serving_system (MMIfaceModemCdma *self,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    Cdma1xServingSystemContext *ctx;

    /* Setup context */
    ctx = g_new0 (Cdma1xServingSystemContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_get_cdma1x_serving_system);
    ctx->qcdm = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));

    if (ctx->qcdm) {
        GByteArray *cdma_status;

        /* Setup command */
        cdma_status = g_byte_array_sized_new (25);
        cdma_status->len = qcdm_cmd_cdma_status_new ((char *) cdma_status->data, 25);
        g_assert (cdma_status->len);
        mm_port_serial_qcdm_command (ctx->qcdm,
                                     cdma_status,
                                     3,
                                     NULL,
                                     (GAsyncReadyCallback)qcdm_cdma_status_ready,
                                     ctx);
        g_byte_array_unref (cdma_status);
        return;
    }

    /* Try with AT if we don't have QCDM */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CSS?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)css_query_ready,
                              ctx);
}

/*****************************************************************************/
/* Service status, analog/digital check (CDMA interface) */

static gboolean
modem_cdma_get_service_status_finish (MMIfaceModemCdma *self,
                                      GAsyncResult *res,
                                      gboolean *has_cdma_service,
                                      GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    *has_cdma_service = g_simple_async_result_get_op_res_gboolean (G_SIMPLE_ASYNC_RESULT (res));
    return TRUE;
}

static void
cad_query_ready (MMIfaceModemCdma *self,
                 GAsyncResult *res,
                 GSimpleAsyncResult *simple)
{
    GError *error = NULL;
    const gchar *result;

    result = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error)
        g_simple_async_result_take_error (simple, error);
    else {
        guint cad;

        /* Strip any leading command tag and spaces */
        result = mm_strip_tag (result, "+CAD:");
        if (!mm_get_uint_from_str (result, &cad))
            g_simple_async_result_set_error (simple,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_FAILED,
                                             "Failed to parse +CAD response '%s'",
                                             result);
        else
            /* 1 == CDMA service */
            g_simple_async_result_set_op_res_gboolean (simple, (cad == 1));
    }

    g_simple_async_result_complete (simple);
    g_object_unref (simple);
}

static void
modem_cdma_get_service_status (MMIfaceModemCdma *self,
                               GAsyncReadyCallback callback,
                               gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_cdma_get_service_status);

    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CAD?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)cad_query_ready,
                              result);
}

/*****************************************************************************/
/* Detailed registration state (CDMA interface) */

typedef struct {
    MMModemCdmaRegistrationState detailed_cdma1x_state;
    MMModemCdmaRegistrationState detailed_evdo_state;
} DetailedRegistrationStateResults;

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    MMPortSerialAt *port;
    MMModemCdmaRegistrationState cdma1x_state;
    MMModemCdmaRegistrationState evdo_state;
    GError *error;
} DetailedRegistrationStateContext;

static void
detailed_registration_state_context_complete_and_free (DetailedRegistrationStateContext *ctx)
{
    if (ctx->error)
        g_simple_async_result_take_error (ctx->result, ctx->error);
    else {
        DetailedRegistrationStateResults *results;

        results = g_new (DetailedRegistrationStateResults, 1);
        results->detailed_cdma1x_state = ctx->cdma1x_state;
        results->detailed_evdo_state = ctx->evdo_state;
        g_simple_async_result_set_op_res_gpointer (ctx->result, results, g_free);
    }

    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->port);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_cdma_get_detailed_registration_state_finish (MMIfaceModemCdma *self,
                                                   GAsyncResult *res,
                                                   MMModemCdmaRegistrationState *detailed_cdma1x_state,
                                                   MMModemCdmaRegistrationState *detailed_evdo_state,
                                                   GError **error)
{
    DetailedRegistrationStateResults *results;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *detailed_cdma1x_state = results->detailed_cdma1x_state;
    *detailed_evdo_state = results->detailed_evdo_state;
    return TRUE;
}

static void
speri_ready (MMIfaceModemCdma *self,
             GAsyncResult *res,
             DetailedRegistrationStateContext *ctx)
{
    gboolean roaming = FALSE;
    const gchar *response;
    GError *error = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        /* silently discard SPERI errors */
        g_error_free (error);
        detailed_registration_state_context_complete_and_free (ctx);
        return;
    }

    /* Try to parse the results */
    response = mm_strip_tag (response, "$SPERI:");
    if (!response ||
        !mm_cdma_parse_eri (response, &roaming, NULL, NULL)) {
        mm_warn ("Couldn't parse SPERI response '%s'", response);
        detailed_registration_state_context_complete_and_free (ctx);
        return;
    }

    if (roaming) {
        /* Change the 1x and EVDO registration states to roaming if they were
         * anything other than UNKNOWN.
         */
        if (ctx->cdma1x_state > MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
            ctx->cdma1x_state = MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING;
        if (ctx->evdo_state > MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)
            ctx->evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING;
    } else {
        /* Change 1x and/or EVDO registration state to home if home/roaming wasn't previously known */
        if (ctx->cdma1x_state == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED)
            ctx->cdma1x_state = MM_MODEM_CDMA_REGISTRATION_STATE_HOME;
        if (ctx->evdo_state == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED)
            ctx->evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_HOME;
    }

    detailed_registration_state_context_complete_and_free (ctx);
}

static void
spservice_ready (MMIfaceModemCdma *self,
                 GAsyncResult *res,
                 DetailedRegistrationStateContext *ctx)
{
    const gchar *response;
    MMModemCdmaRegistrationState cdma1x_state;
    MMModemCdmaRegistrationState evdo_state;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &ctx->error);
    if (ctx->error) {
        detailed_registration_state_context_complete_and_free (ctx);
        return;
    }

    /* Try to parse the results */
    cdma1x_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
    evdo_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
    if (!mm_cdma_parse_spservice_read_response (response,
                                                &cdma1x_state,
                                                &evdo_state)) {
        ctx->error = g_error_new (MM_CORE_ERROR,
                                  MM_CORE_ERROR_FAILED,
                                  "Couldn't parse SPSERVICE response '%s'",
                                  response);
        detailed_registration_state_context_complete_and_free (ctx);
        return;
    }

    /* Store new intermediate results */
    ctx->cdma1x_state = cdma1x_state;
    ctx->evdo_state = evdo_state;

    /* If SPERI not supported, we're done */
    if (!ctx->self->priv->has_speri) {
        detailed_registration_state_context_complete_and_free (ctx);
        return;
    }

    /* Get roaming status to override generic registration state */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "$SPERI?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)speri_ready,
                              ctx);
}

static void
modem_cdma_get_detailed_registration_state (MMIfaceModemCdma *self,
                                            MMModemCdmaRegistrationState cdma1x_state,
                                            MMModemCdmaRegistrationState evdo_state,
                                            GAsyncReadyCallback callback,
                                            gpointer user_data)
{
    MMPortSerialAt *port;
    GError *error = NULL;
    DetailedRegistrationStateContext *ctx;

    /* The default implementation to get detailed registration state
     * requires the use of an AT port; so if we cannot get any, just
     * return the error */
    port = mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), &error);
    if (!port) {
        g_simple_async_report_take_gerror_in_idle (G_OBJECT (self),
                                                   callback,
                                                   user_data,
                                                   error);
        return;
    }

    /* Setup context */
    ctx = g_new0 (DetailedRegistrationStateContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_get_detailed_registration_state);
    ctx->port = g_object_ref (port);
    ctx->cdma1x_state = cdma1x_state;
    ctx->evdo_state = evdo_state;

    /* NOTE: If we get this generic implementation of getting detailed
     * registration state called, we DO know that we have Sprint commands
     * supported, we checked it in setup_registration_checks() */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+SPSERVICE?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)spservice_ready,
                              ctx);
}

/*****************************************************************************/
/* Setup registration checks (CDMA interface) */

typedef struct {
    gboolean skip_qcdm_call_manager_step;
    gboolean skip_qcdm_hdr_step;
    gboolean skip_at_cdma_service_status_step;
    gboolean skip_at_cdma1x_serving_system_step;
    gboolean skip_detailed_registration_state;
} SetupRegistrationChecksResults;

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    GError *error;
    gboolean has_qcdm_port;
    gboolean has_sprint_commands;
} SetupRegistrationChecksContext;

static void
setup_registration_checks_context_complete_and_free (SetupRegistrationChecksContext *ctx)
{
    if (ctx->error)
        g_simple_async_result_take_error (ctx->result, ctx->error);
    else {
        SetupRegistrationChecksResults *results;

        results = g_new0 (SetupRegistrationChecksResults, 1);

        /* Skip QCDM steps if no QCDM port */
        if (!ctx->has_qcdm_port) {
            mm_dbg ("Will skip all QCDM-based registration checks");
            results->skip_qcdm_call_manager_step = TRUE;
            results->skip_qcdm_hdr_step = TRUE;
        }

        if (MM_IFACE_MODEM_CDMA_GET_INTERFACE (ctx->self)->get_detailed_registration_state ==
            modem_cdma_get_detailed_registration_state) {
            /* Skip CDMA1x Serving System check if we have Sprint specific
             * commands AND if the default detailed registration checker
             * is the generic one. Implementations knowing that their
             * CSS response is undesired, should either setup NULL callbacks
             * for the specific step, or subclass this setup and return
             * FALSE themselves. */
            if (ctx->has_sprint_commands) {
                mm_dbg ("Will skip CDMA1x Serving System check, "
                        "we do have Sprint commands");
                results->skip_at_cdma1x_serving_system_step = TRUE;
            } else {
                /* If there aren't Sprint specific commands, and the detailed
                 * registration state getter wasn't subclassed, skip the step */
                mm_dbg ("Will skip generic detailed registration check, we "
                        "don't have Sprint commands");
                results->skip_detailed_registration_state = TRUE;
            }
        }

        g_simple_async_result_set_op_res_gpointer (ctx->result, results, g_free);
    }

    g_simple_async_result_complete_in_idle (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_cdma_setup_registration_checks_finish (MMIfaceModemCdma *self,
                                             GAsyncResult *res,
                                             gboolean *skip_qcdm_call_manager_step,
                                             gboolean *skip_qcdm_hdr_step,
                                             gboolean *skip_at_cdma_service_status_step,
                                             gboolean *skip_at_cdma1x_serving_system_step,
                                             gboolean *skip_detailed_registration_state,
                                             GError **error)
{
    SetupRegistrationChecksResults *results;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    results = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    *skip_qcdm_call_manager_step = results->skip_qcdm_call_manager_step;
    *skip_qcdm_hdr_step = results->skip_qcdm_hdr_step;
    *skip_at_cdma_service_status_step = results->skip_at_cdma_service_status_step;
    *skip_at_cdma1x_serving_system_step = results->skip_at_cdma1x_serving_system_step;
    *skip_detailed_registration_state = results->skip_detailed_registration_state;
    return TRUE;
}

static void
speri_check_ready (MMIfaceModemCdma *self,
                   GAsyncResult *res,
                   SetupRegistrationChecksContext *ctx)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error)
        g_error_free (error);
    else
        /* We DO have SPERI */
        ctx->self->priv->has_speri = TRUE;

    /* All done */
    ctx->self->priv->checked_sprint_support = TRUE;
    setup_registration_checks_context_complete_and_free (ctx);
}

static void
spservice_check_ready (MMIfaceModemCdma *self,
                       GAsyncResult *res,
                       SetupRegistrationChecksContext *ctx)
{
    GError *error = NULL;

    mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error);
    if (error) {
        g_error_free (error);
        ctx->self->priv->checked_sprint_support = TRUE;
        setup_registration_checks_context_complete_and_free (ctx);
        return;
    }

    /* We DO have SPSERVICE, look for SPERI */
    ctx->has_sprint_commands = TRUE;
    ctx->self->priv->has_spservice = TRUE;
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "$SPERI?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)speri_check_ready,
                              ctx);
}

static void
modem_cdma_setup_registration_checks (MMIfaceModemCdma *self,
                                      GAsyncReadyCallback callback,
                                      gpointer user_data)
{
    SetupRegistrationChecksContext *ctx;

    ctx = g_new0 (SetupRegistrationChecksContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_setup_registration_checks);

    /* Check if we have a QCDM port */
    ctx->has_qcdm_port = !!mm_base_modem_peek_port_qcdm (MM_BASE_MODEM (self));

    /* If we have cached results of Sprint command checking, use them */
    if (ctx->self->priv->checked_sprint_support) {
        ctx->has_sprint_commands = ctx->self->priv->has_spservice;

        /* Completes in idle */
        setup_registration_checks_context_complete_and_free (ctx);
        return;
    }

    /* Otherwise, launch Sprint command checks. */
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+SPSERVICE?",
                              3,
                              FALSE,
                              (GAsyncReadyCallback)spservice_check_ready,
                              ctx);
}

/*****************************************************************************/
/* Register in network (CDMA interface) */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    GCancellable *cancellable;
    GTimer *timer;
    guint max_registration_time;
} RegisterInCdmaNetworkContext;

static void
register_in_cdma_network_context_complete_and_free (RegisterInCdmaNetworkContext *ctx)
{
    /* If our cancellable reference is still around, clear it */
    if (ctx->self->priv->modem_cdma_pending_registration_cancellable ==
        ctx->cancellable) {
        g_clear_object (&ctx->self->priv->modem_cdma_pending_registration_cancellable);
    }

    if (ctx->timer)
        g_timer_destroy (ctx->timer);

    g_simple_async_result_complete (ctx->result);
    g_object_unref (ctx->result);
    g_object_unref (ctx->cancellable);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
modem_cdma_register_in_network_finish (MMIfaceModemCdma *self,
                                       GAsyncResult *res,
                                       GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

#undef REG_IS_IDLE
#define REG_IS_IDLE(state)                              \
    (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN)

#undef REG_IS_DONE
#define REG_IS_DONE(state)                                  \
    (state == MM_MODEM_CDMA_REGISTRATION_STATE_HOME ||      \
     state == MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING ||   \
     state == MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED)

static void run_cdma_registration_checks_ready (MMBroadbandModem *self,
                                                GAsyncResult *res,
                                                RegisterInCdmaNetworkContext *ctx);

static gboolean
run_cdma_registration_checks_again (RegisterInCdmaNetworkContext *ctx)
{
    /* Get fresh registration state */
    mm_iface_modem_cdma_run_registration_checks (
        MM_IFACE_MODEM_CDMA (ctx->self),
        (GAsyncReadyCallback)run_cdma_registration_checks_ready,
        ctx);
    return G_SOURCE_REMOVE;
}

static void
run_cdma_registration_checks_ready (MMBroadbandModem *self,
                                    GAsyncResult *res,
                                    RegisterInCdmaNetworkContext *ctx)
{
    GError *error = NULL;

    mm_iface_modem_cdma_run_registration_checks_finish (MM_IFACE_MODEM_CDMA (self), res, &error);

    if (error) {
        mm_dbg ("CDMA registration check failed: '%s'", error->message);
        mm_iface_modem_cdma_update_cdma1x_registration_state (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
            MM_MODEM_CDMA_SID_UNKNOWN,
            MM_MODEM_CDMA_NID_UNKNOWN);
        mm_iface_modem_cdma_update_evdo_registration_state (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
        mm_iface_modem_cdma_update_access_technologies (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);

        g_simple_async_result_take_error (ctx->result, error);
        register_in_cdma_network_context_complete_and_free (ctx);
        return;
    }

    /* If we got registered in at least one CDMA network, end registration checks */
    if (REG_IS_DONE (self->priv->modem_cdma_cdma1x_registration_state) ||
        REG_IS_DONE (self->priv->modem_cdma_evdo_registration_state)) {
        mm_dbg ("Modem is currently registered in a CDMA network "
                "(CDMA1x: '%s', EV-DO: '%s')",
                REG_IS_DONE (self->priv->modem_cdma_cdma1x_registration_state) ? "yes" : "no",
                REG_IS_DONE (self->priv->modem_cdma_evdo_registration_state) ? "yes" : "no");
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        register_in_cdma_network_context_complete_and_free (ctx);
        return;
    }

    /* Don't spend too much time waiting to get registered */
    if (g_timer_elapsed (ctx->timer, NULL) > ctx->max_registration_time) {
        mm_dbg ("CDMA registration check timed out");
        mm_iface_modem_cdma_update_cdma1x_registration_state (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
            MM_MODEM_CDMA_SID_UNKNOWN,
            MM_MODEM_CDMA_NID_UNKNOWN);
        mm_iface_modem_cdma_update_evdo_registration_state (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
        mm_iface_modem_cdma_update_access_technologies (
            MM_IFACE_MODEM_CDMA (self),
            MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN);
        g_simple_async_result_take_error (
            ctx->result,
            mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT));
        register_in_cdma_network_context_complete_and_free (ctx);
        return;
    }

    /* Check again in a few seconds. */
    mm_dbg ("Modem not yet registered in a CDMA network... will recheck soon");
    g_timeout_add_seconds (3,
                           (GSourceFunc)run_cdma_registration_checks_again,
                           ctx);
}

static void
modem_cdma_register_in_network (MMIfaceModemCdma *self,
                                guint max_registration_time,
                                GAsyncReadyCallback callback,
                                gpointer user_data)
{
    MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
    RegisterInCdmaNetworkContext *ctx;

    /* (Try to) cancel previous registration request */
    if (broadband->priv->modem_cdma_pending_registration_cancellable) {
        g_cancellable_cancel (broadband->priv->modem_cdma_pending_registration_cancellable);
        g_clear_object (&broadband->priv->modem_cdma_pending_registration_cancellable);
    }

    ctx = g_new0 (RegisterInCdmaNetworkContext, 1);
    ctx->self = g_object_ref (self);
    ctx->max_registration_time = max_registration_time;
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             modem_cdma_register_in_network);
    ctx->cancellable = g_cancellable_new ();

    /* Keep an accessible reference to the cancellable, so that we can cancel
     * previous request when needed */
    broadband->priv->modem_cdma_pending_registration_cancellable =
        g_object_ref (ctx->cancellable);

    /* Get fresh registration state */
    ctx->timer = g_timer_new ();
    mm_iface_modem_cdma_run_registration_checks (
        MM_IFACE_MODEM_CDMA (self),
        (GAsyncReadyCallback)run_cdma_registration_checks_ready,
        ctx);
}

/*****************************************************************************/
/* Load location capabilities (Location interface) */

static MMModemLocationSource
modem_location_load_capabilities_finish (MMIfaceModemLocation *self,
                                         GAsyncResult *res,
                                         GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return MM_MODEM_LOCATION_SOURCE_NONE;

    return (MMModemLocationSource) GPOINTER_TO_UINT (g_simple_async_result_get_op_res_gpointer (
                                                         G_SIMPLE_ASYNC_RESULT (res)));
}

static void
modem_location_load_capabilities (MMIfaceModemLocation *self,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        modem_location_load_capabilities);

    /* Default location capabilities supported by the generic broadband
     * implementation are only LAC-CI in 3GPP-enabled modems. And even this,
     * will only be true if the modem supports CREG/CGREG=2 */
    if (!mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self)))
        g_simple_async_result_set_op_res_gpointer (result,
                                                   GUINT_TO_POINTER (MM_MODEM_LOCATION_SOURCE_NONE),
                                                   NULL);
    else
        g_simple_async_result_set_op_res_gpointer (result,
                                                   GUINT_TO_POINTER (MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI),
                                                   NULL);

    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Enable location gathering (Location interface) */

static gboolean
enable_location_gathering_finish (MMIfaceModemLocation *self,
                                  GAsyncResult *res,
                                  GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static void
enable_location_gathering (MMIfaceModemLocation *self,
                           MMModemLocationSource source,
                           GAsyncReadyCallback callback,
                           gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self),
                                        callback,
                                        user_data,
                                        enable_location_gathering);

    /* 3GPP modems need to re-run registration checks when enabling the 3GPP
     * location source, so that we get up to date LAC/CI location information.
     * Note that we don't care for when the registration checks get finished.
     */
    if (source == MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI &&
        mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self))) {
        /* Reload registration to get LAC/CI */
        mm_iface_modem_3gpp_run_registration_checks (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
        /* Reload registration information to get MCC/MNC */
        if (MM_BROADBAND_MODEM (self)->priv->modem_3gpp_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME ||
            MM_BROADBAND_MODEM (self)->priv->modem_3gpp_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING)
            mm_iface_modem_3gpp_reload_current_registration_info (MM_IFACE_MODEM_3GPP (self), NULL, NULL);
    }

    /* Done we are */
    g_simple_async_result_set_op_res_gboolean (result, TRUE);
    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/
/* Load network time (Time interface) */

static gchar *
modem_time_load_network_time_finish (MMIfaceModemTime *self,
                                     GAsyncResult *res,
                                     GError **error)
{
    const gchar *response;
    gchar *result = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!response)
        return NULL;
    if (!mm_parse_cclk_response (response, &result, NULL, error))
        return NULL;
    return result;
}

static void
modem_time_load_network_time (MMIfaceModemTime *self,
                              GAsyncReadyCallback callback,
                              gpointer user_data)
{
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CCLK?",
                              3,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Load network timezone (Time interface) */

static MMNetworkTimezone *
modem_time_load_network_timezone_finish (MMIfaceModemTime *self,
                                         GAsyncResult *res,
                                         GError **error)
{
    const gchar *response;
    MMNetworkTimezone *tz = NULL;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!response)
        return NULL;
    if (!mm_parse_cclk_response (response, NULL, &tz, error))
        return NULL;
    return tz;
}

static void
modem_time_load_network_timezone (MMIfaceModemTime *self,
                                  GAsyncReadyCallback callback,
                                  gpointer user_data)
{
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CCLK?",
                              3,
                              FALSE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Check support (Time interface) */

static const MMBaseModemAtCommand time_check_sequence[] = {
    { "+CTZU=1",  3, TRUE, mm_base_modem_response_processor_no_result_continue },
    { "+CCLK?",   3, TRUE, mm_base_modem_response_processor_string },
    { NULL }
};

static gboolean
modem_time_check_support_finish (MMIfaceModemTime *self,
                                 GAsyncResult *res,
                                 GError **error)
{
    return !!mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error);
}

static void
modem_time_check_support (MMIfaceModemTime *self,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
    mm_base_modem_at_sequence (MM_BASE_MODEM (self),
                               time_check_sequence,
                               NULL, /* response_processor_context */
                               NULL, /* response_processor_context_free */
                               callback,
                               user_data);
}

/*****************************************************************************/
/* Check support (Signal interface) */

static gboolean
modem_signal_check_support_finish (MMIfaceModemSignal  *self,
                                   GAsyncResult        *res,
                                   GError             **error)
{
    return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
}

static void
modem_signal_check_support (MMIfaceModemSignal  *self,
                            GAsyncReadyCallback  callback,
                            gpointer             user_data)
{
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CESQ=?",
                              3,
                              TRUE,
                              callback,
                              user_data);
}

/*****************************************************************************/
/* Load extended signal information (Signal interface) */

static gboolean
modem_signal_load_values_finish (MMIfaceModemSignal  *self,
                                 GAsyncResult        *res,
                                 MMSignal           **cdma,
                                 MMSignal           **evdo,
                                 MMSignal           **gsm,
                                 MMSignal           **umts,
                                 MMSignal           **lte,
                                 GError             **error)
{
    const gchar *response;

    response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error);
    if (!response || !mm_3gpp_cesq_response_to_signal_info (response, gsm, umts, lte, error))
        return FALSE;

    /* No 3GPP2 support */
    if (cdma)
        *cdma = NULL;
    if (evdo)
        *evdo = NULL;
    return TRUE;
}

static void
modem_signal_load_values (MMIfaceModemSignal  *self,
                          GCancellable        *cancellable,
                          GAsyncReadyCallback  callback,
                          gpointer             user_data)
{
    mm_base_modem_at_command (MM_BASE_MODEM (self),
                              "+CESQ",
                              3,
                              TRUE,
                              callback,
                              user_data);
}

/*****************************************************************************/

static const gchar *primary_init_sequence[] = {
    /* Ensure echo is off */
    "E0",
    /* Get word responses */
    "V1",
    /* Extended numeric codes */
    "+CMEE=1",
    /* Report all call status */
    "X4",
    /* Assert DCD when carrier detected */
    "&C1",
    NULL
};

static const gchar *secondary_init_sequence[] = {
    /* Ensure echo is off */
    "E0",
    NULL
};

static void
setup_ports (MMBroadbandModem *self)
{
    MMPortSerialAt *ports[2];
    GRegex *regex;
    GPtrArray *array;
    gint i, j;

    ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));

    if (ports[0])
        g_object_set (ports[0],
                      MM_PORT_SERIAL_AT_INIT_SEQUENCE, primary_init_sequence,
                      NULL);

    if (ports[1])
        g_object_set (ports[1],
                      MM_PORT_SERIAL_AT_INIT_SEQUENCE, secondary_init_sequence,
                      NULL);

    /* Cleanup all unsolicited message handlers in all AT ports */

    /* Set up CREG unsolicited message handlers, with NULL callbacks */
    array = mm_3gpp_creg_regex_get (FALSE);
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        for (j = 0; j < array->len; j++) {
            mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
                                                           (GRegex *)g_ptr_array_index (array, j),
                                                           NULL,
                                                           NULL,
                                                           NULL);
        }
    }
    mm_3gpp_creg_regex_destroy (array);

    /* Set up CIEV unsolicited message handler, with NULL callback */
    regex = mm_3gpp_ciev_regex_get ();
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
                                                       regex,
                                                       NULL,
                                                       NULL,
                                                       NULL);
    }
    g_regex_unref (regex);

    /* Set up CMTI unsolicited message handler, with NULL callback */
    regex = mm_3gpp_cmti_regex_get ();
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
                                                       regex,
                                                       NULL,
                                                       NULL,
                                                       NULL);
    }
    g_regex_unref (regex);

    /* Set up CUSD unsolicited message handler, with NULL callback */
    regex = mm_3gpp_cusd_regex_get ();
    for (i = 0; i < 2; i++) {
        if (!ports[i])
            continue;

        mm_port_serial_at_add_unsolicited_msg_handler (MM_PORT_SERIAL_AT (ports[i]),
                                                       regex,
                                                       NULL,
                                                       NULL,
                                                       NULL);
    }
    g_regex_unref (regex);
}

/*****************************************************************************/
/* Generic ports open/close context */

struct _PortsContext {
    volatile gint ref_count;

    MMPortSerialAt *primary;
    gboolean primary_open;
    MMPortSerialAt *secondary;
    gboolean secondary_open;
    MMPortSerialQcdm *qcdm;
    gboolean qcdm_open;
};

static PortsContext *
ports_context_ref (PortsContext *ctx)
{
    g_atomic_int_inc (&ctx->ref_count);
    return ctx;
}

static void
ports_context_unref (PortsContext *ctx)
{
    if (g_atomic_int_dec_and_test (&ctx->ref_count)) {
        if (ctx->primary) {
            if (ctx->primary_open)
                mm_port_serial_close (MM_PORT_SERIAL (ctx->primary));
            g_object_unref (ctx->primary);
        }
        if (ctx->secondary) {
            if (ctx->secondary_open)
                mm_port_serial_close (MM_PORT_SERIAL (ctx->secondary));
            g_object_unref (ctx->secondary);
        }
        if (ctx->qcdm) {
            if (ctx->qcdm_open)
                mm_port_serial_close (MM_PORT_SERIAL (ctx->qcdm));
            g_object_unref (ctx->qcdm);
        }
        g_free (ctx);
    }
}

/*****************************************************************************/
/* Initialization started/stopped */

static gboolean
initialization_stopped (MMBroadbandModem *self,
                        gpointer user_data,
                        GError **error)
{
    PortsContext *ctx = (PortsContext *)user_data;

    if (ctx)
        ports_context_unref (ctx);
    return TRUE;
}

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    PortsContext *ports;
} InitializationStartedContext;

static void
initialization_started_context_complete_and_free (InitializationStartedContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    ports_context_unref (ctx->ports);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gpointer
initialization_started_finish (MMBroadbandModem *self,
                               GAsyncResult *res,
                               GError **error)
{
    gpointer ref;

    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return NULL;

    ref = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res));
    return ref ? ports_context_ref (ref) : NULL;
}

static gboolean
open_ports_initialization (MMBroadbandModem *self,
                           PortsContext *ctx,
                           GError **error)
{
    ctx->primary = mm_base_modem_get_port_primary (MM_BASE_MODEM (self));
    if (!ctx->primary) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_FAILED,
                     "Couldn't get primary port");
        return FALSE;
    }

    /* Open and send first commands to the primary serial port.
     * We do keep the primary port open during the whole initialization
     * sequence. Note that this port is not really passed to the interfaces,
     * they will get the primary port themselves. */
    if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->primary), error)) {
        g_prefix_error (error, "Couldn't open primary port: ");
        return FALSE;
    }

    ctx->primary_open = TRUE;

    /* Try to disable echo */
    mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                   ctx->primary,
                                   "E0", 3,
                                   FALSE, FALSE, NULL, NULL, NULL);
    /* Try to get extended errors */
    mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                   ctx->primary,
                                   "+CMEE=1", 3,
                                   FALSE, FALSE, NULL, NULL, NULL);

    return TRUE;
}

static void
initialization_started (MMBroadbandModem *self,
                        GAsyncReadyCallback callback,
                        gpointer user_data)
{
    GError *error = NULL;
    InitializationStartedContext *ctx;

    ctx = g_new0 (InitializationStartedContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             initialization_started);
    ctx->ports = g_new0 (PortsContext, 1);
    ctx->ports->ref_count = 1;

    if (!open_ports_initialization (self, ctx->ports, &error)) {
        g_prefix_error (&error, "Couldn't open ports during modem initialization: ");
        g_simple_async_result_take_error (ctx->result, error);
    } else
        g_simple_async_result_set_op_res_gpointer (ctx->result,
                                                   ports_context_ref (ctx->ports),
                                                   (GDestroyNotify)ports_context_unref);

    initialization_started_context_complete_and_free (ctx);
}

/*****************************************************************************/
/* Disabling stopped */

static gboolean
disabling_stopped (MMBroadbandModem *self,
                   GError **error)
{
    if (self->priv->enabled_ports_ctx) {
        ports_context_unref (self->priv->enabled_ports_ctx);
        self->priv->enabled_ports_ctx = NULL;
    }

    if (self->priv->sim_hot_swap_ports_ctx) {
        ports_context_unref (self->priv->sim_hot_swap_ports_ctx);
        self->priv->sim_hot_swap_ports_ctx = NULL;
    }
    return TRUE;
}

/*****************************************************************************/
/* Initializing the modem (during first enabling) */

static gboolean
enabling_modem_init_finish (MMBroadbandModem *self,
                            GAsyncResult *res,
                            GError **error)
{
    return !!mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, error);
}

static void
enabling_modem_init (MMBroadbandModem *self,
                     GAsyncReadyCallback callback,
                     gpointer user_data)
{
    /* Init command. ITU rec v.250 (6.1.1) says:
     *   The DTE should not include additional commands on the same command line
     *   after the Z command because such commands may be ignored.
     * So run ATZ alone.
     */
    mm_base_modem_at_command_full (MM_BASE_MODEM (self),
                                   mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)),
                                   "Z",
                                   6,
                                   FALSE,
                                   FALSE,
                                   NULL, /* cancellable */
                                   callback,
                                   user_data);
}

/*****************************************************************************/
/* Enabling started */

typedef struct {
    MMBroadbandModem *self;
    GSimpleAsyncResult *result;
    PortsContext *ports;
    gboolean modem_init_required;
} EnablingStartedContext;

static void
enabling_started_context_complete_and_free (EnablingStartedContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    ports_context_unref (ctx->ports);
    g_object_unref (ctx->result);
    g_object_unref (ctx->self);
    g_slice_free (EnablingStartedContext, ctx);
}

static gboolean
enabling_started_finish (MMBroadbandModem *self,
                         GAsyncResult *res,
                         GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

static gboolean
enabling_after_modem_init_timeout (EnablingStartedContext *ctx)
{
    /* Reset init sequence enabled flags and run them explicitly */
    g_object_set (ctx->ports->primary,
                  MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, TRUE,
                  NULL);
    mm_port_serial_at_run_init_sequence (ctx->ports->primary);
    if (ctx->ports->secondary) {
        g_object_set (ctx->ports->secondary,
                      MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, TRUE,
                      NULL);
        mm_port_serial_at_run_init_sequence (ctx->ports->secondary);
    }

    /* Store enabled ports context and complete */
    ctx->self->priv->enabled_ports_ctx = ports_context_ref (ctx->ports);
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    enabling_started_context_complete_and_free (ctx);
    return G_SOURCE_REMOVE;
}

static void
enabling_modem_init_ready (MMBroadbandModem *self,
                           GAsyncResult *res,
                           EnablingStartedContext *ctx)
{
    GError *error = NULL;

    if (!MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_modem_init_finish (self, res, &error)) {
        g_simple_async_result_take_error (ctx->result, error);
        enabling_started_context_complete_and_free (ctx);
        return;
    }

    /* Specify that the modem init was run once */
    ctx->self->priv->modem_init_run = TRUE;

    /* After the modem init sequence, give a 500ms period for the modem to settle */
    mm_dbg ("Giving some time to settle the modem...");
    g_timeout_add (500, (GSourceFunc)enabling_after_modem_init_timeout, ctx);
}

static void
enabling_flash_done (MMPortSerial *port,
                     GAsyncResult *res,
                     EnablingStartedContext *ctx)
{
    GError *error = NULL;

    if (!mm_port_serial_flash_finish (port, res, &error)) {
        g_prefix_error (&error, "Primary port flashing failed: ");
        g_simple_async_result_take_error (ctx->result, error);
        enabling_started_context_complete_and_free (ctx);
        return;
    }

    if (ctx->modem_init_required) {
        mm_dbg ("Running modem initialization sequence...");
        MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_modem_init (ctx->self,
                                                                       (GAsyncReadyCallback)enabling_modem_init_ready,
                                                                       ctx);
        return;
    }

    /* Store enabled ports context and complete */
    ctx->self->priv->enabled_ports_ctx = ports_context_ref (ctx->ports);
    g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
    enabling_started_context_complete_and_free (ctx);
}

static gboolean
open_ports_enabling (MMBroadbandModem *self,
                     PortsContext *ctx,
                     gboolean modem_init_required,
                     GError **error)
{
    /* Open primary */
    ctx->primary = mm_base_modem_get_port_primary (MM_BASE_MODEM (self));
    if (!ctx->primary) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_FAILED,
                     "Couldn't get primary port");
        return FALSE;
    }

    /* If we'll need to run modem initialization, disable port init sequence */
    if (modem_init_required)
        g_object_set (ctx->primary,
                      MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, FALSE,
                      NULL);


    if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->primary), error)) {
        g_prefix_error (error, "Couldn't open primary port: ");
        return FALSE;
    }

    ctx->primary_open = TRUE;

    /* Open secondary (optional) */
    ctx->secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self));
    if (ctx->secondary) {
        /* If we'll need to run modem initialization, disable port init sequence */
        if (modem_init_required)
            g_object_set (ctx->secondary,
                          MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED, FALSE,
                          NULL);
        if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->secondary), error)) {
            g_prefix_error (error, "Couldn't open secondary port: ");
            return FALSE;
        }
        ctx->secondary_open = TRUE;
    }

    /* Open qcdm (optional) */
    ctx->qcdm = mm_base_modem_get_port_qcdm (MM_BASE_MODEM (self));
    if (ctx->qcdm) {
        if (!mm_port_serial_open (MM_PORT_SERIAL (ctx->qcdm), error)) {
            g_prefix_error (error, "Couldn't open QCDM port: ");
            return FALSE;
        }
        ctx->qcdm_open = TRUE;
    }

    return TRUE;
}

static void
enabling_started (MMBroadbandModem *self,
                  GAsyncReadyCallback callback,
                  gpointer user_data)
{
    GError *error = NULL;
    EnablingStartedContext *ctx;

    ctx = g_slice_new0 (EnablingStartedContext);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self),
                                             callback,
                                             user_data,
                                             enabling_started);
    ctx->ports = g_new0 (PortsContext, 1);
    ctx->ports->ref_count = 1;

    /* Skip modem initialization if the device was hotplugged OR if we already
     * did it (i.e. don't reinitialize if the modem got disabled and enabled
     * again) */
    if (ctx->self->priv->modem_init_run)
        mm_dbg ("Skipping modem initialization: not first enabling");
    else if (mm_base_modem_get_hotplugged (MM_BASE_MODEM (ctx->self))) {
        ctx->self->priv->modem_init_run = TRUE;
        mm_dbg ("Skipping modem initialization: device hotplugged");
    } else if (!MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_modem_init ||
               !MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_modem_init_finish)
        mm_dbg ("Skipping modem initialization: not required");
    else
        ctx->modem_init_required = TRUE;

    /* Enabling */
    if (!open_ports_enabling (self, ctx->ports, ctx->modem_init_required, &error)) {
        g_prefix_error (&error, "Couldn't open ports during modem enabling: ");
        g_simple_async_result_take_error (ctx->result, error);
        enabling_started_context_complete_and_free (ctx);
        return;
    }

    /* Ports were correctly opened, now flash the primary port */
    mm_dbg ("Flashing primary AT port before enabling...");
    mm_port_serial_flash (MM_PORT_SERIAL (ctx->ports->primary),
                          100,
                          FALSE,
                          (GAsyncReadyCallback)enabling_flash_done,
                          ctx);
}

/*****************************************************************************/
/* First registration checks */

static void
modem_3gpp_run_registration_checks_ready (MMIfaceModem3gpp *self,
                                          GAsyncResult *res)
{
    GError *error = NULL;

    if (!mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error)) {
        mm_warn ("Initial 3GPP registration check failed: %s", error->message);
        g_error_free (error);
        return;
    }
    mm_dbg ("Initial 3GPP registration checks finished");
}

static void
modem_cdma_run_registration_checks_ready (MMIfaceModemCdma *self,
                                          GAsyncResult *res)
{
    GError *error = NULL;

    if (!mm_iface_modem_cdma_run_registration_checks_finish (self, res, &error)) {
        mm_warn ("Initial CDMA registration check failed: %s", error->message);
        g_error_free (error);
        return;
    }
    mm_dbg ("Initial CDMA registration checks finished");
}

static gboolean
schedule_initial_registration_checks_cb (MMBroadbandModem *self)
{
    if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self)))
        mm_iface_modem_3gpp_run_registration_checks (MM_IFACE_MODEM_3GPP (self),
                                                     (GAsyncReadyCallback) modem_3gpp_run_registration_checks_ready,
                                                     NULL);
    if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (self)))
        mm_iface_modem_cdma_run_registration_checks (MM_IFACE_MODEM_CDMA (self),
                                                     (GAsyncReadyCallback) modem_cdma_run_registration_checks_ready,
                                                     NULL);
    /* We got a full reference, so balance it out here */
    g_object_unref (self);
    return G_SOURCE_REMOVE;
}

static void
schedule_initial_registration_checks (MMBroadbandModem *self)
{
    g_idle_add ((GSourceFunc) schedule_initial_registration_checks_cb, g_object_ref (self));
}

/*****************************************************************************/

typedef enum {
    DISABLING_STEP_FIRST,
    DISABLING_STEP_WAIT_FOR_FINAL_STATE,
    DISABLING_STEP_DISCONNECT_BEARERS,
    DISABLING_STEP_IFACE_SIMPLE,
    DISABLING_STEP_IFACE_FIRMWARE,
    DISABLING_STEP_IFACE_SIGNAL,
    DISABLING_STEP_IFACE_OMA,
    DISABLING_STEP_IFACE_TIME,
    DISABLING_STEP_IFACE_MESSAGING,
    DISABLING_STEP_IFACE_VOICE,
    DISABLING_STEP_IFACE_LOCATION,
    DISABLING_STEP_IFACE_CONTACTS,
    DISABLING_STEP_IFACE_CDMA,
    DISABLING_STEP_IFACE_3GPP_USSD,
    DISABLING_STEP_IFACE_3GPP,
    DISABLING_STEP_IFACE_MODEM,
    DISABLING_STEP_LAST,
} DisablingStep;

typedef struct {
    MMBroadbandModem *self;
    GCancellable *cancellable;
    GSimpleAsyncResult *result;
    DisablingStep step;
    MMModemState previous_state;
    gboolean disabled;
} DisablingContext;

static void disabling_step (DisablingContext *ctx);

static void
disabling_context_complete_and_free (DisablingContext *ctx)
{
    GError *error = NULL;

    g_simple_async_result_complete_in_idle (ctx->result);

    if (MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->disabling_stopped &&
        !MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->disabling_stopped (ctx->self, &error)) {
        mm_warn ("Error when stopping the disabling sequence: %s", error->message);
        g_error_free (error);
    }

    if (ctx->disabled)
        mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                     MM_MODEM_STATE_DISABLED,
                                     MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);
    else if (ctx->previous_state != MM_MODEM_STATE_DISABLED) {
        /* Fallback to previous state */
        mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                     ctx->previous_state,
                                     MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
    }

    g_object_unref (ctx->result);
    if (ctx->cancellable)
        g_object_unref (ctx->cancellable);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
disabling_context_complete_and_free_if_cancelled (DisablingContext *ctx)
{
    if (!g_cancellable_is_cancelled (ctx->cancellable))
        return FALSE;

    g_simple_async_result_set_error (ctx->result,
                                     MM_CORE_ERROR,
                                     MM_CORE_ERROR_CANCELLED,
                                     "Disabling cancelled");
    disabling_context_complete_and_free (ctx);
    return TRUE;
}

static gboolean
disable_finish (MMBaseModem *self,
               GAsyncResult *res,
               GError **error)
{
    return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error);
}

#undef INTERFACE_DISABLE_READY_FN
#define INTERFACE_DISABLE_READY_FN(NAME,TYPE,FATAL_ERRORS)              \
    static void                                                         \
    NAME##_disable_ready (MMBroadbandModem *self,                       \
                          GAsyncResult *result,                         \
                          DisablingContext *ctx)                        \
    {                                                                   \
        GError *error = NULL;                                           \
                                                                        \
        if (!mm_##NAME##_disable_finish (TYPE (self),                   \
                                         result,                        \
                                         &error)) {                     \
            if (FATAL_ERRORS) {                                         \
                g_simple_async_result_take_error (ctx->result, error);  \
                disabling_context_complete_and_free (ctx);              \
                return;                                                 \
            }                                                           \
                                                                        \
            mm_dbg ("Couldn't disable interface: '%s'",                 \
                    error->message);                                    \
            g_error_free (error);                                       \
            return;                                                     \
        }                                                               \
                                                                        \
        /* Go on to next step */                                        \
        ctx->step++;                                                    \
        disabling_step (ctx);                                           \
    }

INTERFACE_DISABLE_READY_FN (iface_modem,           MM_IFACE_MODEM,           TRUE)
INTERFACE_DISABLE_READY_FN (iface_modem_3gpp,      MM_IFACE_MODEM_3GPP,      TRUE)
INTERFACE_DISABLE_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, TRUE)
INTERFACE_DISABLE_READY_FN (iface_modem_cdma,      MM_IFACE_MODEM_CDMA,      TRUE)
INTERFACE_DISABLE_READY_FN (iface_modem_location,  MM_IFACE_MODEM_LOCATION,  FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_voice,     MM_IFACE_MODEM_VOICE,     FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_signal,    MM_IFACE_MODEM_SIGNAL,    FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_time,      MM_IFACE_MODEM_TIME,      FALSE)
INTERFACE_DISABLE_READY_FN (iface_modem_oma,       MM_IFACE_MODEM_OMA,       FALSE)

static void
bearer_list_disconnect_all_bearers_ready (MMBearerList *list,
                                          GAsyncResult *res,
                                          DisablingContext *ctx)
{
    GError *error = NULL;

    if (!mm_bearer_list_disconnect_all_bearers_finish (list, res, &error)) {
        g_simple_async_result_take_error (ctx->result, error);
        disabling_context_complete_and_free (ctx);
        return;
    }

    /* Go on to next step */
    ctx->step++;
    disabling_step (ctx);
}

static void
disabling_wait_for_final_state_ready (MMIfaceModem *self,
                                      GAsyncResult *res,
                                      DisablingContext *ctx)
{
    GError *error = NULL;

    ctx->previous_state = mm_iface_modem_wait_for_final_state_finish (self, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        disabling_context_complete_and_free (ctx);
        return;
    }

    switch (ctx->previous_state) {
    case MM_MODEM_STATE_UNKNOWN:
    case MM_MODEM_STATE_FAILED:
    case MM_MODEM_STATE_LOCKED:
    case MM_MODEM_STATE_DISABLED:
        /* Just return success, don't relaunch disabling.
         * Note that we do consider here UNKNOWN and FAILED status on purpose,
         * as the MMManager will try to disable every modem before removing
         * it. */
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        disabling_context_complete_and_free (ctx);
        return;
    default:
        break;
    }

    /* We're in a final state now, go on */

    mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                 MM_MODEM_STATE_DISABLING,
                                 MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);

    ctx->step++;
    disabling_step (ctx);
}

static void
disabling_step (DisablingContext *ctx)
{
    /* Don't run new steps if we're cancelled */
    if (disabling_context_complete_and_free_if_cancelled (ctx))
        return;

    switch (ctx->step) {
    case DISABLING_STEP_FIRST:
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_WAIT_FOR_FINAL_STATE:
        mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self),
                                             MM_MODEM_STATE_UNKNOWN, /* just any */
                                             (GAsyncReadyCallback)disabling_wait_for_final_state_ready,
                                             ctx);
        return;

    case DISABLING_STEP_DISCONNECT_BEARERS:
        if (ctx->self->priv->modem_bearer_list) {
            mm_bearer_list_disconnect_all_bearers (
                ctx->self->priv->modem_bearer_list,
                (GAsyncReadyCallback)bearer_list_disconnect_all_bearers_ready,
                ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_SIMPLE:
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_FIRMWARE:
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_SIGNAL:
        if (ctx->self->priv->modem_signal_dbus_skeleton) {
            mm_dbg ("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),
                                           (GAsyncReadyCallback)iface_modem_signal_disable_ready,
                                           ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_OMA:
        if (ctx->self->priv->modem_oma_dbus_skeleton) {
            mm_dbg ("Modem has OMA capabilities, disabling the OMA interface...");
            /* Disabling the Modem Oma interface */
            mm_iface_modem_oma_disable (MM_IFACE_MODEM_OMA (ctx->self),
                                        (GAsyncReadyCallback)iface_modem_oma_disable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_TIME:
        if (ctx->self->priv->modem_time_dbus_skeleton) {
            mm_dbg ("Modem has time capabilities, disabling the Time interface...");
            /* Disabling the Modem Time interface */
            mm_iface_modem_time_disable (MM_IFACE_MODEM_TIME (ctx->self),
                                         (GAsyncReadyCallback)iface_modem_time_disable_ready,
                                         ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_MESSAGING:
        if (ctx->self->priv->modem_messaging_dbus_skeleton) {
            mm_dbg ("Modem has messaging capabilities, disabling the Messaging interface...");
            /* Disabling the Modem Messaging interface */
            mm_iface_modem_messaging_disable (MM_IFACE_MODEM_MESSAGING (ctx->self),
                                              (GAsyncReadyCallback)iface_modem_messaging_disable_ready,
                                              ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_VOICE:
        if (ctx->self->priv->modem_voice_dbus_skeleton) {
            mm_dbg ("Modem has voice capabilities, disabling the Voice interface...");
            /* Disabling the Modem Voice interface */
            mm_iface_modem_voice_disable (MM_IFACE_MODEM_VOICE (ctx->self),
                                          (GAsyncReadyCallback)iface_modem_voice_disable_ready,
                                          ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_LOCATION:
        if (ctx->self->priv->modem_location_dbus_skeleton) {
            mm_dbg ("Modem has location capabilities, disabling the Location interface...");
            /* Disabling the Modem Location interface */
            mm_iface_modem_location_disable (MM_IFACE_MODEM_LOCATION (ctx->self),
                                             (GAsyncReadyCallback)iface_modem_location_disable_ready,
                                             ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_CONTACTS:
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_CDMA:
        if (ctx->self->priv->modem_cdma_dbus_skeleton) {
            mm_dbg ("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),
                                        (GAsyncReadyCallback)iface_modem_cdma_disable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_3GPP_USSD:
        if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) {
            mm_dbg ("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),
                                              (GAsyncReadyCallback)iface_modem_3gpp_ussd_disable_ready,
                                              ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_3GPP:
        if (ctx->self->priv->modem_3gpp_dbus_skeleton) {
            mm_dbg ("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),
                                        (GAsyncReadyCallback)iface_modem_3gpp_disable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_IFACE_MODEM:
        /* This skeleton may be NULL when mm_base_modem_disable() gets called at
         * the same time as modem object disposal. */
        if (ctx->self->priv->modem_dbus_skeleton) {
            /* Disabling the Modem interface */
            mm_iface_modem_disable (MM_IFACE_MODEM (ctx->self),
                                    (GAsyncReadyCallback)iface_modem_disable_ready,
                                    ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case DISABLING_STEP_LAST:
        ctx->disabled = TRUE;
        /* All disabled without errors! */
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        disabling_context_complete_and_free (ctx);
        return;
    }

    g_assert_not_reached ();
}

static void
disable (MMBaseModem *self,
         GCancellable *cancellable,
         GAsyncReadyCallback callback,
         gpointer user_data)
{
    DisablingContext *ctx;

    ctx = g_new0 (DisablingContext, 1);
    ctx->self = g_object_ref (self);
    ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, disable);
    ctx->cancellable = (cancellable ? g_object_ref (cancellable) : NULL);
    ctx->step = DISABLING_STEP_FIRST;

    disabling_step (ctx);
}

/*****************************************************************************/

typedef enum {
    ENABLING_STEP_FIRST,
    ENABLING_STEP_WAIT_FOR_FINAL_STATE,
    ENABLING_STEP_STARTED,
    ENABLING_STEP_IFACE_MODEM,
    ENABLING_STEP_IFACE_3GPP,
    ENABLING_STEP_IFACE_3GPP_USSD,
    ENABLING_STEP_IFACE_CDMA,
    ENABLING_STEP_IFACE_CONTACTS,
    ENABLING_STEP_IFACE_LOCATION,
    ENABLING_STEP_IFACE_MESSAGING,
    ENABLING_STEP_IFACE_VOICE,
    ENABLING_STEP_IFACE_TIME,
    ENABLING_STEP_IFACE_SIGNAL,
    ENABLING_STEP_IFACE_OMA,
    ENABLING_STEP_IFACE_FIRMWARE,
    ENABLING_STEP_IFACE_SIMPLE,
    ENABLING_STEP_LAST,
} EnablingStep;

typedef struct {
    MMBroadbandModem *self;
    GCancellable *cancellable;
    GSimpleAsyncResult *result;
    EnablingStep step;
    MMModemState previous_state;
    gboolean enabled;
} EnablingContext;

static void enabling_step (EnablingContext *ctx);

static void
enabling_context_complete_and_free (EnablingContext *ctx)
{
    g_simple_async_result_complete_in_idle (ctx->result);
    g_object_unref (ctx->result);

    if (ctx->enabled)
        mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                     MM_MODEM_STATE_ENABLED,
                                     MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);
    else if (ctx->previous_state != MM_MODEM_STATE_ENABLED) {
        /* Fallback to previous state */
        mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                     ctx->previous_state,
                                     MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);
    }

    g_object_unref (ctx->cancellable);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
enabling_context_complete_and_free_if_cancelled (EnablingContext *ctx)
{
    if (!g_cancellable_is_cancelled (ctx->cancellable))
        return FALSE;

    g_simple_async_result_set_error (ctx->result,
                                     MM_CORE_ERROR,
                                     MM_CORE_ERROR_CANCELLED,
                                     "Enabling cancelled");
    enabling_context_complete_and_free (ctx);
    return TRUE;
}

static gboolean
enable_finish (MMBaseModem *self,
               GAsyncResult *res,
               GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    return TRUE;
}

#undef INTERFACE_ENABLE_READY_FN
#define INTERFACE_ENABLE_READY_FN(NAME,TYPE,FATAL_ERRORS)               \
    static void                                                         \
    NAME##_enable_ready (MMBroadbandModem *self,                        \
                         GAsyncResult *result,                          \
                         EnablingContext *ctx)                          \
    {                                                                   \
        GError *error = NULL;                                           \
                                                                        \
        if (!mm_##NAME##_enable_finish (TYPE (self),                    \
                                        result,                         \
                                        &error)) {                      \
            if (FATAL_ERRORS) {                                         \
                g_simple_async_result_take_error (ctx->result, error);  \
                enabling_context_complete_and_free (ctx);               \
                return;                                                 \
            }                                                           \
                                                                        \
            mm_dbg ("Couldn't enable interface: '%s'",                  \
                    error->message);                                    \
            g_error_free (error);                                       \
        }                                                               \
                                                                        \
        /* Go on to next step */                                        \
        ctx->step++;                                                    \
        enabling_step (ctx);                                            \
    }

INTERFACE_ENABLE_READY_FN (iface_modem,           MM_IFACE_MODEM,           TRUE)
INTERFACE_ENABLE_READY_FN (iface_modem_3gpp,      MM_IFACE_MODEM_3GPP,      TRUE)
INTERFACE_ENABLE_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, TRUE)
INTERFACE_ENABLE_READY_FN (iface_modem_cdma,      MM_IFACE_MODEM_CDMA,      TRUE)
INTERFACE_ENABLE_READY_FN (iface_modem_location,  MM_IFACE_MODEM_LOCATION,  FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_voice,     MM_IFACE_MODEM_VOICE,     FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_signal,    MM_IFACE_MODEM_SIGNAL,    FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_time,      MM_IFACE_MODEM_TIME,      FALSE)
INTERFACE_ENABLE_READY_FN (iface_modem_oma,       MM_IFACE_MODEM_OMA,       FALSE)

static void
enabling_started_ready (MMBroadbandModem *self,
                        GAsyncResult *result,
                        EnablingContext *ctx)
{
    GError *error = NULL;

    if (!MM_BROADBAND_MODEM_GET_CLASS (self)->enabling_started_finish (self, result, &error)) {
        g_simple_async_result_take_error (ctx->result, error);
        enabling_context_complete_and_free (ctx);
        return;
    }

    /* Go on to next step */
    ctx->step++;
    enabling_step (ctx);
}

static void
enabling_wait_for_final_state_ready (MMIfaceModem *self,
                                     GAsyncResult *res,
                                     EnablingContext *ctx)
{
    GError *error = NULL;

    ctx->previous_state = mm_iface_modem_wait_for_final_state_finish (self, res, &error);
    if (error) {
        g_simple_async_result_take_error (ctx->result, error);
        enabling_context_complete_and_free (ctx);
        return;
    }

    if (ctx->previous_state >= MM_MODEM_STATE_ENABLED) {
        /* Just return success, don't relaunch enabling */
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        enabling_context_complete_and_free (ctx);
        return;
    }

    /* We're in a final state now, go on */

    mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                 MM_MODEM_STATE_ENABLING,
                                 MM_MODEM_STATE_CHANGE_REASON_USER_REQUESTED);

    ctx->step++;
    enabling_step (ctx);
}

static void
enabling_step (EnablingContext *ctx)
{
    /* Don't run new steps if we're cancelled */
    if (enabling_context_complete_and_free_if_cancelled (ctx))
        return;

    switch (ctx->step) {
    case ENABLING_STEP_FIRST:
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_WAIT_FOR_FINAL_STATE:
        mm_iface_modem_wait_for_final_state (MM_IFACE_MODEM (ctx->self),
                                             MM_MODEM_STATE_UNKNOWN, /* just any */
                                             (GAsyncReadyCallback)enabling_wait_for_final_state_ready,
                                             ctx);
        return;

    case ENABLING_STEP_STARTED:
        if (MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_started &&
            MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_started_finish) {
            MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->enabling_started (ctx->self,
                                                                        (GAsyncReadyCallback)enabling_started_ready,
                                                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_MODEM:
        g_assert (ctx->self->priv->modem_dbus_skeleton != NULL);
        /* Enabling the Modem interface */
        mm_iface_modem_enable (MM_IFACE_MODEM (ctx->self),
                               ctx->cancellable,
                               (GAsyncReadyCallback)iface_modem_enable_ready,
                               ctx);
        return;

    case ENABLING_STEP_IFACE_3GPP:
        if (ctx->self->priv->modem_3gpp_dbus_skeleton) {
            mm_dbg ("Modem has 3GPP capabilities, enabling the Modem 3GPP interface...");
            /* Enabling the Modem 3GPP interface */
            mm_iface_modem_3gpp_enable (MM_IFACE_MODEM_3GPP (ctx->self),
                                        ctx->cancellable,
                                        (GAsyncReadyCallback)iface_modem_3gpp_enable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_3GPP_USSD:
        if (ctx->self->priv->modem_3gpp_ussd_dbus_skeleton) {
            mm_dbg ("Modem has 3GPP/USSD capabilities, enabling the Modem 3GPP/USSD interface...");
            mm_iface_modem_3gpp_ussd_enable (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                             (GAsyncReadyCallback)iface_modem_3gpp_ussd_enable_ready,
                                             ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_CDMA:
        if (ctx->self->priv->modem_cdma_dbus_skeleton) {
            mm_dbg ("Modem has CDMA capabilities, enabling the Modem CDMA interface...");
            /* Enabling the Modem CDMA interface */
            mm_iface_modem_cdma_enable (MM_IFACE_MODEM_CDMA (ctx->self),
                                        ctx->cancellable,
                                        (GAsyncReadyCallback)iface_modem_cdma_enable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_CONTACTS:
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_LOCATION:
        if (ctx->self->priv->modem_location_dbus_skeleton) {
            mm_dbg ("Modem has location capabilities, enabling the Location interface...");
            /* Enabling the Modem Location interface */
            mm_iface_modem_location_enable (MM_IFACE_MODEM_LOCATION (ctx->self),
                                            ctx->cancellable,
                                            (GAsyncReadyCallback)iface_modem_location_enable_ready,
                                            ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_MESSAGING:
        if (ctx->self->priv->modem_messaging_dbus_skeleton) {
            mm_dbg ("Modem has messaging capabilities, enabling the Messaging interface...");
            /* Enabling the Modem Messaging interface */
            mm_iface_modem_messaging_enable (MM_IFACE_MODEM_MESSAGING (ctx->self),
                                             ctx->cancellable,
                                             (GAsyncReadyCallback)iface_modem_messaging_enable_ready,
                                             ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_VOICE:
        if (ctx->self->priv->modem_voice_dbus_skeleton) {
            mm_dbg ("Modem has voice capabilities, enabling the Voice interface...");
            /* Enabling the Modem Voice interface */
            mm_iface_modem_voice_enable (MM_IFACE_MODEM_VOICE (ctx->self),
                                             ctx->cancellable,
                                             (GAsyncReadyCallback)iface_modem_voice_enable_ready,
                                             ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_TIME:
        if (ctx->self->priv->modem_time_dbus_skeleton) {
            mm_dbg ("Modem has time capabilities, enabling the Time interface...");
            /* Enabling the Modem Time interface */
            mm_iface_modem_time_enable (MM_IFACE_MODEM_TIME (ctx->self),
                                        ctx->cancellable,
                                        (GAsyncReadyCallback)iface_modem_time_enable_ready,
                                        ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_SIGNAL:
        if (ctx->self->priv->modem_signal_dbus_skeleton) {
            mm_dbg ("Modem has extended signal reporting capabilities, enabling the Signal interface...");
            /* Enabling the Modem Signal interface */
            mm_iface_modem_signal_enable (MM_IFACE_MODEM_SIGNAL (ctx->self),
                                          ctx->cancellable,
                                          (GAsyncReadyCallback)iface_modem_signal_enable_ready,
                                          ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_OMA:
        if (ctx->self->priv->modem_oma_dbus_skeleton) {
            mm_dbg ("Modem has OMA capabilities, enabling the OMA interface...");
            /* Enabling the Modem Oma interface */
            mm_iface_modem_oma_enable (MM_IFACE_MODEM_OMA (ctx->self),
                                       ctx->cancellable,
                                       (GAsyncReadyCallback)iface_modem_oma_enable_ready,
                                       ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_FIRMWARE:
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_IFACE_SIMPLE:
        /* Fall down to next step */
        ctx->step++;

    case ENABLING_STEP_LAST:
        ctx->enabled = TRUE;

        /* Once all interfaces have been enabled, trigger registration checks in
         * 3GPP and CDMA modems. We have to do this at this point so that e.g.
         * location interface gets proper registration related info reported.
         *
         * We do this in an idle so that we don't mess up the logs at this point
         * with the new requests being triggered.
         */
        schedule_initial_registration_checks (ctx->self);

        /* All enabled without errors! */
        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        enabling_context_complete_and_free (ctx);
        return;
    }

    g_assert_not_reached ();
}

static void
enable (MMBaseModem *self,
        GCancellable *cancellable,
        GAsyncReadyCallback callback,
        gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, enable);

    /* Check state before launching modem enabling */
    switch (MM_BROADBAND_MODEM (self)->priv->modem_state) {
    case MM_MODEM_STATE_UNKNOWN:
        /* We should never have a UNKNOWN->ENABLED transition */
        g_assert_not_reached ();
        break;

    case MM_MODEM_STATE_FAILED:
    case MM_MODEM_STATE_INITIALIZING:
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_WRONG_STATE,
                                         "Cannot enable modem: "
                                         "device not fully initialized yet");
        break;

    case MM_MODEM_STATE_LOCKED:
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_WRONG_STATE,
                                         "Cannot enable modem: device locked");
        break;

    case MM_MODEM_STATE_DISABLED: {
        EnablingContext *ctx;

        ctx = g_new0 (EnablingContext, 1);
        ctx->self = g_object_ref (self);
        ctx->result = result;
        ctx->cancellable = g_object_ref (cancellable);
        ctx->step = ENABLING_STEP_FIRST;
        enabling_step (ctx);
        return;
    }

    case MM_MODEM_STATE_DISABLING:
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_WRONG_STATE,
                                         "Cannot enable modem: "
                                         "currently being disabled");
        break;

    case MM_MODEM_STATE_ENABLING:
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_IN_PROGRESS,
                                         "Cannot enable modem: "
                                         "already being enabled");
        break;

    case MM_MODEM_STATE_ENABLED:
    case MM_MODEM_STATE_SEARCHING:
    case MM_MODEM_STATE_REGISTERED:
    case MM_MODEM_STATE_DISCONNECTING:
    case MM_MODEM_STATE_CONNECTING:
    case MM_MODEM_STATE_CONNECTED:
        /* Just return success, don't relaunch enabling */
        g_simple_async_result_set_op_res_gboolean (result, TRUE);
        break;
    }

    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/

typedef enum {
    INITIALIZE_STEP_FIRST,
    INITIALIZE_STEP_SETUP_PORTS,
    INITIALIZE_STEP_STARTED,
    INITIALIZE_STEP_SETUP_SIMPLE_STATUS,
    INITIALIZE_STEP_IFACE_MODEM,
    INITIALIZE_STEP_IFACE_3GPP,
    INITIALIZE_STEP_IFACE_3GPP_USSD,
    INITIALIZE_STEP_IFACE_CDMA,
    INITIALIZE_STEP_IFACE_CONTACTS,
    INITIALIZE_STEP_IFACE_LOCATION,
    INITIALIZE_STEP_IFACE_MESSAGING,
    INITIALIZE_STEP_IFACE_VOICE,
    INITIALIZE_STEP_IFACE_TIME,
    INITIALIZE_STEP_IFACE_SIGNAL,
    INITIALIZE_STEP_IFACE_OMA,
    INITIALIZE_STEP_IFACE_FIRMWARE,
    INITIALIZE_STEP_SIM_HOT_SWAP,
    INITIALIZE_STEP_IFACE_SIMPLE,
    INITIALIZE_STEP_LAST,
} InitializeStep;

typedef struct {
    MMBroadbandModem *self;
    GCancellable *cancellable;
    GSimpleAsyncResult *result;
    InitializeStep step;
    gpointer ports_ctx;
} InitializeContext;

static void initialize_step (InitializeContext *ctx);

static void
initialize_context_complete_and_free (InitializeContext *ctx)
{
    GError *error = NULL;

    g_simple_async_result_complete_in_idle (ctx->result);

    if (ctx->ports_ctx &&
        MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_stopped &&
        !MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_stopped (ctx->self, ctx->ports_ctx, &error)) {
        mm_warn ("Error when stopping the initialization sequence: %s", error->message);
        g_error_free (error);
    }

    g_object_unref (ctx->result);
    g_object_unref (ctx->cancellable);
    g_object_unref (ctx->self);
    g_free (ctx);
}

static gboolean
initialize_context_complete_and_free_if_cancelled (InitializeContext *ctx)
{
    if (!g_cancellable_is_cancelled (ctx->cancellable))
        return FALSE;

    g_simple_async_result_set_error (ctx->result,
                                     MM_CORE_ERROR,
                                     MM_CORE_ERROR_CANCELLED,
                                     "Initialization cancelled");
    initialize_context_complete_and_free (ctx);
    return TRUE;
}

static gboolean
initialize_finish (MMBaseModem *self,
                   GAsyncResult *res,
                   GError **error)
{
    if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error))
        return FALSE;

    return TRUE;
}

static void
initialization_started_ready (MMBroadbandModem *self,
                              GAsyncResult *result,
                              InitializeContext *ctx)
{
    GError *error = NULL;
    gpointer ports_ctx;

    /* May return NULL without error */
    ports_ctx = MM_BROADBAND_MODEM_GET_CLASS (self)->initialization_started_finish (self, result, &error);
    if (error) {
        mm_warn ("Couldn't start initialization: %s", error->message);
        g_error_free (error);

        /* There is no Modem interface yet, so just update the variable directly */
        ctx->self->priv->modem_state = MM_MODEM_STATE_FAILED;

        /* Just jump to the last step */
        ctx->step = INITIALIZE_STEP_LAST;
        initialize_step (ctx);
        return;
    }

    /* Keep the ctx for later use when stopping initialization */
    ctx->ports_ctx = ports_ctx;

    /* Go on to next step */
    ctx->step++;
    initialize_step (ctx);
}

static void
iface_modem_initialize_ready (MMBroadbandModem *self,
                              GAsyncResult *result,
                              InitializeContext *ctx)
{
    GError *error = NULL;

    /* If the modem interface fails to get initialized, we will move the modem
     * to a FAILED state. Note that in this case we still export the interface. */
    if (!mm_iface_modem_initialize_finish (MM_IFACE_MODEM (self), result, &error)) {
        MMModemStateFailedReason failed_reason = MM_MODEM_STATE_FAILED_REASON_UNKNOWN;

        /* Report the new FAILED state */
        mm_warn ("Modem couldn't be initialized: %s", error->message);

        if (g_error_matches (error,
                             MM_MOBILE_EQUIPMENT_ERROR,
                             MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED))
            failed_reason = MM_MODEM_STATE_FAILED_REASON_SIM_MISSING;
        else if (g_error_matches (error,
                                  MM_MOBILE_EQUIPMENT_ERROR,
                                  MM_MOBILE_EQUIPMENT_ERROR_SIM_FAILURE) ||
                 g_error_matches (error,
                                  MM_MOBILE_EQUIPMENT_ERROR,
                                  MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG))
            failed_reason = MM_MODEM_STATE_FAILED_REASON_SIM_MISSING;

        g_error_free (error);

        mm_iface_modem_update_failed_state (MM_IFACE_MODEM (self), failed_reason);

        /* Jump to the firmware step. We allow firmware switching even in failed
         * state */
        ctx->step = INITIALIZE_STEP_IFACE_FIRMWARE;
        initialize_step (ctx);
        return;
    }

    /* bind simple properties */
    mm_iface_modem_bind_simple_status (MM_IFACE_MODEM (self),
                                       self->priv->modem_simple_status);

    /* If we find ourselves in a LOCKED state, we shouldn't keep on
     * the initialization sequence. Instead, we will re-initialize once
     * we are unlocked. */
    if (ctx->self->priv->modem_state == MM_MODEM_STATE_LOCKED) {
        /* Jump to the Firmware interface. We do allow modems to export
         * both the Firmware and Simple interfaces when locked. */
        ctx->step = INITIALIZE_STEP_IFACE_FIRMWARE;
        initialize_step (ctx);
        return;
    }

    /* Go on to next step */
    ctx->step++;
    initialize_step (ctx);
}

#undef INTERFACE_INIT_READY_FN
#define INTERFACE_INIT_READY_FN(NAME,TYPE,FATAL_ERRORS)                 \
    static void                                                         \
    NAME##_initialize_ready (MMBroadbandModem *self,                    \
                             GAsyncResult *result,                      \
                             InitializeContext *ctx)                    \
    {                                                                   \
        GError *error = NULL;                                           \
                                                                        \
        if (!mm_##NAME##_initialize_finish (TYPE (self), result, &error)) { \
            if (FATAL_ERRORS) {                                         \
                mm_warn ("Couldn't initialize interface: '%s'",         \
                         error->message);                               \
                g_error_free (error);                                   \
                                                                        \
                /* Report the new FAILED state */                       \
                mm_iface_modem_update_failed_state (MM_IFACE_MODEM (self), \
                                                    MM_MODEM_STATE_FAILED_REASON_UNKNOWN); \
                                                                        \
                /* Just jump to the last step */                        \
                ctx->step = INITIALIZE_STEP_LAST;                       \
                initialize_step (ctx);                                  \
                return;                                                 \
            }                                                           \
                                                                        \
            mm_dbg ("Couldn't initialize interface: '%s'",              \
                    error->message);                                    \
            /* Just shutdown this interface */                          \
            mm_##NAME##_shutdown (TYPE (self));                         \
            g_error_free (error);                                       \
        } else {                                                        \
            /* bind simple properties */                                \
            mm_##NAME##_bind_simple_status (TYPE (self), self->priv->modem_simple_status); \
        }                                                               \
                                                                        \
        /* Go on to next step */                                        \
        ctx->step++;                                                    \
        initialize_step (ctx);                                          \
    }

INTERFACE_INIT_READY_FN (iface_modem_3gpp,      MM_IFACE_MODEM_3GPP,      TRUE)
INTERFACE_INIT_READY_FN (iface_modem_3gpp_ussd, MM_IFACE_MODEM_3GPP_USSD, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_cdma,      MM_IFACE_MODEM_CDMA,      TRUE)
INTERFACE_INIT_READY_FN (iface_modem_location,  MM_IFACE_MODEM_LOCATION,  FALSE)
INTERFACE_INIT_READY_FN (iface_modem_messaging, MM_IFACE_MODEM_MESSAGING, FALSE)
INTERFACE_INIT_READY_FN (iface_modem_voice,     MM_IFACE_MODEM_VOICE,     FALSE)
INTERFACE_INIT_READY_FN (iface_modem_time,      MM_IFACE_MODEM_TIME,      FALSE)
INTERFACE_INIT_READY_FN (iface_modem_signal,    MM_IFACE_MODEM_SIGNAL,    FALSE)
INTERFACE_INIT_READY_FN (iface_modem_oma,       MM_IFACE_MODEM_OMA,       FALSE)
INTERFACE_INIT_READY_FN (iface_modem_firmware,  MM_IFACE_MODEM_FIRMWARE,  FALSE)

static void
initialize_step (InitializeContext *ctx)
{
    /* Don't run new steps if we're cancelled */
    if (initialize_context_complete_and_free_if_cancelled (ctx))
        return;

    switch (ctx->step) {
    case INITIALIZE_STEP_FIRST:
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_SETUP_PORTS:
        if (MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->setup_ports)
            MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->setup_ports (ctx->self);
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_STARTED:
        if (MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_started &&
            MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_started_finish) {
            MM_BROADBAND_MODEM_GET_CLASS (ctx->self)->initialization_started (ctx->self,
                                                                              (GAsyncReadyCallback)initialization_started_ready,
                                                                              ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_SETUP_SIMPLE_STATUS:
        /* Simple status must be created before any interface initialization,
         * so that interfaces add and bind the properties they want to export.
         */
        if (!ctx->self->priv->modem_simple_status)
            ctx->self->priv->modem_simple_status = mm_simple_status_new ();
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_MODEM:
        /* Initialize the Modem interface */
        mm_iface_modem_initialize (MM_IFACE_MODEM (ctx->self),
                                   ctx->cancellable,
                                   (GAsyncReadyCallback)iface_modem_initialize_ready,
                                   ctx);
        return;

    case INITIALIZE_STEP_IFACE_3GPP:
        if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (ctx->self))) {
            /* Initialize the 3GPP interface */
            mm_iface_modem_3gpp_initialize (MM_IFACE_MODEM_3GPP (ctx->self),
                                            ctx->cancellable,
                                            (GAsyncReadyCallback)iface_modem_3gpp_initialize_ready,
                                            ctx);
            return;
        }

        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_3GPP_USSD:
        if (mm_iface_modem_is_3gpp (MM_IFACE_MODEM (ctx->self))) {
            /* Initialize the 3GPP/USSD interface */
            mm_iface_modem_3gpp_ussd_initialize (MM_IFACE_MODEM_3GPP_USSD (ctx->self),
                                                 (GAsyncReadyCallback)iface_modem_3gpp_ussd_initialize_ready,
                                                 ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_CDMA:
        if (mm_iface_modem_is_cdma (MM_IFACE_MODEM (ctx->self))) {
            /* Initialize the CDMA interface */
            mm_iface_modem_cdma_initialize (MM_IFACE_MODEM_CDMA (ctx->self),
                                            ctx->cancellable,
                                            (GAsyncReadyCallback)iface_modem_cdma_initialize_ready,
                                            ctx);
            return;
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_CONTACTS:
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_LOCATION:
        /* Initialize the Location interface */
        mm_iface_modem_location_initialize (MM_IFACE_MODEM_LOCATION (ctx->self),
                                            ctx->cancellable,
                                            (GAsyncReadyCallback)iface_modem_location_initialize_ready,
                                            ctx);
        return;

    case INITIALIZE_STEP_IFACE_MESSAGING:
        /* Initialize the Messaging interface */
        mm_iface_modem_messaging_initialize (MM_IFACE_MODEM_MESSAGING (ctx->self),
                                             ctx->cancellable,
                                             (GAsyncReadyCallback)iface_modem_messaging_initialize_ready,
                                             ctx);
        return;

    case INITIALIZE_STEP_IFACE_VOICE:
        /* Initialize the Voice interface */
        mm_iface_modem_voice_initialize (MM_IFACE_MODEM_VOICE (ctx->self),
                                         ctx->cancellable,
                                         (GAsyncReadyCallback)iface_modem_voice_initialize_ready,
                                         ctx);
        return;

    case INITIALIZE_STEP_IFACE_TIME:
        /* Initialize the Time interface */
        mm_iface_modem_time_initialize (MM_IFACE_MODEM_TIME (ctx->self),
                                        ctx->cancellable,
                                        (GAsyncReadyCallback)iface_modem_time_initialize_ready,
                                        ctx);
        return;

    case INITIALIZE_STEP_IFACE_SIGNAL:
        /* Initialize the Signal interface */
        mm_iface_modem_signal_initialize (MM_IFACE_MODEM_SIGNAL (ctx->self),
                                          ctx->cancellable,
                                          (GAsyncReadyCallback)iface_modem_signal_initialize_ready,
                                          ctx);
        return;

    case INITIALIZE_STEP_IFACE_OMA:
        /* Initialize the Oma interface */
        mm_iface_modem_oma_initialize (MM_IFACE_MODEM_OMA (ctx->self),
                                       ctx->cancellable,
                                       (GAsyncReadyCallback)iface_modem_oma_initialize_ready,
                                       ctx);
        return;

    case INITIALIZE_STEP_IFACE_FIRMWARE:
        /* Initialize the Firmware interface */
        mm_iface_modem_firmware_initialize (MM_IFACE_MODEM_FIRMWARE (ctx->self),
                                            ctx->cancellable,
                                            (GAsyncReadyCallback)iface_modem_firmware_initialize_ready,
                                            ctx);
        return;

    case INITIALIZE_STEP_SIM_HOT_SWAP:
        {
            gboolean is_sim_hot_swap_supported = FALSE;

            g_object_get (ctx->self,
                          MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, &is_sim_hot_swap_supported,
                          NULL);

            if (is_sim_hot_swap_supported) {
                PortsContext *ports;
                GError *error = NULL;

                mm_dbg ("Creating PortsContext for SIM hot swap.");

                ports = g_new0 (PortsContext, 1);
                ports->ref_count = 1;

                if (!open_ports_enabling (ctx->self, ports, FALSE, &error)) {
                    mm_warn ("Couldn't open ports during Modem SIM hot swap enabling: %s", error? error->message : "unknown reason");
                    g_error_free (error);
                } else
                    ctx->self->priv->sim_hot_swap_ports_ctx = ports_context_ref (ports);

                ports_context_unref (ports);
            }
        }
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_IFACE_SIMPLE:
        if (ctx->self->priv->modem_state != MM_MODEM_STATE_FAILED)
            mm_iface_modem_simple_initialize (MM_IFACE_MODEM_SIMPLE (ctx->self));
        /* Fall down to next step */
        ctx->step++;

    case INITIALIZE_STEP_LAST:
        if (ctx->self->priv->modem_state == MM_MODEM_STATE_FAILED) {


            if (!ctx->self->priv->modem_dbus_skeleton) {
                /* Error setting up ports. Abort without even exporting the
                 * Modem interface */
                g_simple_async_result_set_error (ctx->result,
                                                 MM_CORE_ERROR,
                                                 MM_CORE_ERROR_ABORTED,
                                                 "Modem is unusable, "
                                                 "cannot fully initialize");
            } else {
                /* Fatal SIM, firmware, or modem failure :-( */
                gboolean is_sim_hot_swap_supported = FALSE;
                MMModemStateFailedReason reason =
                    mm_gdbus_modem_get_state_failed_reason (
                        (MmGdbusModem*)ctx->self->priv->modem_dbus_skeleton);

                g_object_get (ctx->self,
                             MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED,
                             &is_sim_hot_swap_supported,
                             NULL);

                if (reason == MM_MODEM_STATE_FAILED_REASON_SIM_MISSING &&
                    is_sim_hot_swap_supported &&
                    ctx->self->priv->sim_hot_swap_ports_ctx) {
                        mm_info ("SIM is missing, but the modem supports SIM hot swap. Waiting for SIM...");
                        g_simple_async_result_set_error (ctx->result,
                                                         MM_CORE_ERROR,
                                                         MM_CORE_ERROR_WRONG_STATE,
                                                         "Modem is unusable due to SIM missing, "
                                                         "cannot fully initialize, "
                                                         "waiting for SIM insertion.");
                } else {
                    mm_dbg ("SIM is missing and Modem does not support SIM Hot Swap");
                    g_simple_async_result_set_error (ctx->result,
                                                     MM_CORE_ERROR,
                                                     MM_CORE_ERROR_WRONG_STATE,
                                                     "Modem is unusable, "
                                                     "cannot fully initialize");
                }

                /* Ensure we only leave the Modem, OMA, and Firmware interfaces
                 * around.  A failure could be caused by firmware issues, which
                 * a firmware update, switch, or provisioning could fix.
                 */
                mm_iface_modem_3gpp_shutdown (MM_IFACE_MODEM_3GPP (ctx->self));
                mm_iface_modem_3gpp_ussd_shutdown (MM_IFACE_MODEM_3GPP_USSD (ctx->self));
                mm_iface_modem_cdma_shutdown (MM_IFACE_MODEM_CDMA (ctx->self));
                mm_iface_modem_location_shutdown (MM_IFACE_MODEM_LOCATION (ctx->self));
                mm_iface_modem_messaging_shutdown (MM_IFACE_MODEM_MESSAGING (ctx->self));
                mm_iface_modem_voice_shutdown (MM_IFACE_MODEM_VOICE (ctx->self));
                mm_iface_modem_time_shutdown (MM_IFACE_MODEM_TIME (ctx->self));
                mm_iface_modem_simple_shutdown (MM_IFACE_MODEM_SIMPLE (ctx->self));
            }
            initialize_context_complete_and_free (ctx);
            return;
        }

        if (ctx->self->priv->modem_state == MM_MODEM_STATE_LOCKED) {
            /* We're locked :-/ */
            g_simple_async_result_set_error (ctx->result,
                                             MM_CORE_ERROR,
                                             MM_CORE_ERROR_WRONG_STATE,
                                             "Modem is currently locked, "
                                             "cannot fully initialize");
            initialize_context_complete_and_free (ctx);
            return;
        }

        /* All initialized without errors!
         * Set as disabled (a.k.a. initialized) */
        mm_iface_modem_update_state (MM_IFACE_MODEM (ctx->self),
                                     MM_MODEM_STATE_DISABLED,
                                     MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);

        g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE);
        initialize_context_complete_and_free (ctx);
        return;
    }

    g_assert_not_reached ();
}

static void
initialize (MMBaseModem *self,
            GCancellable *cancellable,
            GAsyncReadyCallback callback,
            gpointer user_data)
{
    GSimpleAsyncResult *result;

    result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, initialize);

    /* Check state before launching modem initialization */
    switch (MM_BROADBAND_MODEM (self)->priv->modem_state) {
    case MM_MODEM_STATE_FAILED:
        /* NOTE: this will only happen if we ever support hot-plugging SIMs */
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_WRONG_STATE,
                                         "Cannot initialize modem: "
                                         "device is unusable");
        break;

    case MM_MODEM_STATE_UNKNOWN:
    case MM_MODEM_STATE_LOCKED: {
        InitializeContext *ctx;

        ctx = g_new0 (InitializeContext, 1);
        ctx->self = g_object_ref (self);
        ctx->cancellable = g_object_ref (cancellable);
        ctx->result = result;
        ctx->step = INITIALIZE_STEP_FIRST;

        /* Set as being initialized, even if we were locked before */
        mm_iface_modem_update_state (MM_IFACE_MODEM (self),
                                     MM_MODEM_STATE_INITIALIZING,
                                     MM_MODEM_STATE_CHANGE_REASON_UNKNOWN);

        initialize_step (ctx);
        return;
    }

    case MM_MODEM_STATE_INITIALIZING:
        g_simple_async_result_set_error (result,
                                         MM_CORE_ERROR,
                                         MM_CORE_ERROR_IN_PROGRESS,
                                         "Cannot initialize modem: "
                                         "already being initialized");
        break;

    case MM_MODEM_STATE_DISABLED:
    case MM_MODEM_STATE_DISABLING:
    case MM_MODEM_STATE_ENABLING:
    case MM_MODEM_STATE_ENABLED:
    case MM_MODEM_STATE_SEARCHING:
    case MM_MODEM_STATE_REGISTERED:
    case MM_MODEM_STATE_DISCONNECTING:
    case MM_MODEM_STATE_CONNECTING:
    case MM_MODEM_STATE_CONNECTED:
        /* Just return success, don't relaunch initialization */
        g_simple_async_result_set_op_res_gboolean (result, TRUE);
        break;
    }

    g_simple_async_result_complete_in_idle (result);
    g_object_unref (result);
}

/*****************************************************************************/

gchar *
mm_broadband_modem_take_and_convert_to_utf8 (MMBroadbandModem *self,
                                             gchar *str)
{
    /* should only be used AFTER current charset is set */
    if (self->priv->modem_current_charset == MM_MODEM_CHARSET_UNKNOWN)
        return str;

    return mm_charset_take_and_convert_to_utf8 (str,
                                                self->priv->modem_current_charset);
}

gchar *
mm_broadband_modem_take_and_convert_to_current_charset (MMBroadbandModem *self,
                                                        gchar *str)
{
    /* should only be used AFTER current charset is set */
    if (self->priv->modem_current_charset == MM_MODEM_CHARSET_UNKNOWN)
        return str;

    return mm_utf8_take_and_convert_to_charset (str, self->priv->modem_current_charset);
}

MMModemCharset
mm_broadband_modem_get_current_charset (MMBroadbandModem *self)
{
    return self->priv->modem_current_charset;
}

gchar *
mm_broadband_modem_create_device_identifier (MMBroadbandModem *self,
                                             const gchar *ati,
                                             const gchar *ati1)
{
    return (mm_create_device_identifier (
                mm_base_modem_get_vendor_id (MM_BASE_MODEM (self)),
                mm_base_modem_get_product_id (MM_BASE_MODEM (self)),
                ati,
                ati1,
                mm_gdbus_modem_get_equipment_identifier (
                    MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
                mm_gdbus_modem_get_revision (
                    MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
                mm_gdbus_modem_get_model (
                    MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton)),
                mm_gdbus_modem_get_manufacturer (
                    MM_GDBUS_MODEM (MM_BROADBAND_MODEM (self)->priv->modem_dbus_skeleton))));
}


/*****************************************************************************/
static void
after_hotswap_event_disable_ready (MMBaseModem *self,
                                   GAsyncResult *res,
                                   gpointer user_data)
{
    GError *error = NULL;
    mm_base_modem_disable_finish (self, res, &error);
    if (error) {
        mm_err ("Disable modem error: %s", error->message);
        g_error_free (error);
    } else {
        mm_base_modem_set_valid (MM_BASE_MODEM (self), FALSE);
    }
}

void
mm_broadband_modem_update_sim_hot_swap_detected (MMBroadbandModem *self)
{
    if (self->priv->sim_hot_swap_ports_ctx) {
        mm_dbg ("Releasing SIM hot swap ports context");
        ports_context_unref (self->priv->sim_hot_swap_ports_ctx);
        self->priv->sim_hot_swap_ports_ctx = NULL;
    }

    mm_base_modem_set_reprobe (MM_BASE_MODEM (self), TRUE);
    mm_base_modem_disable (MM_BASE_MODEM (self),
                           (GAsyncReadyCallback) after_hotswap_event_disable_ready,
                           NULL);
}

/*****************************************************************************/

MMBroadbandModem *
mm_broadband_modem_new (const gchar *device,
                        const gchar **drivers,
                        const gchar *plugin,
                        guint16 vendor_id,
                        guint16 product_id)
{
    return g_object_new (MM_TYPE_BROADBAND_MODEM,
                         MM_BASE_MODEM_DEVICE, device,
                         MM_BASE_MODEM_DRIVERS, drivers,
                         MM_BASE_MODEM_PLUGIN, plugin,
                         MM_BASE_MODEM_VENDOR_ID, vendor_id,
                         MM_BASE_MODEM_PRODUCT_ID, product_id,
                         NULL);
}

static void
set_property (GObject *object,
              guint prop_id,
              const GValue *value,
              GParamSpec *pspec)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (object);

    switch (prop_id) {
    case PROP_MODEM_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_dbus_skeleton);
        self->priv->modem_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_3GPP_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_3gpp_dbus_skeleton);
        self->priv->modem_3gpp_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_3GPP_USSD_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_3gpp_ussd_dbus_skeleton);
        self->priv->modem_3gpp_ussd_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_CDMA_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_cdma_dbus_skeleton);
        self->priv->modem_cdma_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_SIMPLE_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_simple_dbus_skeleton);
        self->priv->modem_simple_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_LOCATION_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_location_dbus_skeleton);
        self->priv->modem_location_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_MESSAGING_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_messaging_dbus_skeleton);
        self->priv->modem_messaging_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_VOICE_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_voice_dbus_skeleton);
        self->priv->modem_voice_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_TIME_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_time_dbus_skeleton);
        self->priv->modem_time_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_SIGNAL_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_signal_dbus_skeleton);
        self->priv->modem_signal_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_OMA_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_oma_dbus_skeleton);
        self->priv->modem_oma_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_FIRMWARE_DBUS_SKELETON:
        g_clear_object (&self->priv->modem_firmware_dbus_skeleton);
        self->priv->modem_firmware_dbus_skeleton = g_value_dup_object (value);
        break;
    case PROP_MODEM_SIM:
        g_clear_object (&self->priv->modem_sim);
        self->priv->modem_sim = g_value_dup_object (value);
        break;
    case PROP_MODEM_BEARER_LIST:
        g_clear_object (&self->priv->modem_bearer_list);
        self->priv->modem_bearer_list = g_value_dup_object (value);
        break;
    case PROP_MODEM_STATE:
        self->priv->modem_state = g_value_get_enum (value);
        break;
    case PROP_MODEM_3GPP_REGISTRATION_STATE:
        self->priv->modem_3gpp_registration_state = g_value_get_enum (value);
        break;
    case PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED:
        self->priv->modem_3gpp_cs_network_supported = g_value_get_boolean (value);
        break;
    case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
        self->priv->modem_3gpp_ps_network_supported = g_value_get_boolean (value);
        break;
    case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
        self->priv->modem_3gpp_eps_network_supported = g_value_get_boolean (value);
        break;
    case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS:
        self->priv->modem_3gpp_ignored_facility_locks = g_value_get_flags (value);
        break;
    case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
        self->priv->modem_cdma_cdma1x_registration_state = g_value_get_enum (value);
        break;
    case PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE:
        self->priv->modem_cdma_evdo_registration_state = g_value_get_enum (value);
        break;
    case PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED:
        self->priv->modem_cdma_cdma1x_network_supported = g_value_get_boolean (value);
        break;
    case PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED:
        self->priv->modem_cdma_evdo_network_supported = g_value_get_boolean (value);
        break;
    case PROP_MODEM_MESSAGING_SMS_LIST:
        g_clear_object (&self->priv->modem_messaging_sms_list);
        self->priv->modem_messaging_sms_list = g_value_dup_object (value);
        break;
    case PROP_MODEM_VOICE_CALL_LIST:
        g_clear_object (&self->priv->modem_voice_call_list);
        self->priv->modem_voice_call_list = g_value_dup_object (value);
        break;
    case PROP_MODEM_MESSAGING_SMS_PDU_MODE:
        self->priv->modem_messaging_sms_pdu_mode = g_value_get_boolean (value);
        break;
    case PROP_MODEM_MESSAGING_SMS_DEFAULT_STORAGE:
        self->priv->modem_messaging_sms_default_storage = g_value_get_enum (value);
        break;
    case PROP_MODEM_SIMPLE_STATUS:
        g_clear_object (&self->priv->modem_simple_status);
        self->priv->modem_simple_status = g_value_dup_object (value);
        break;
    case PROP_MODEM_SIM_HOT_SWAP_SUPPORTED:
        self->priv->sim_hot_swap_supported = g_value_get_boolean (value);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
    }
}

static void
get_property (GObject *object,
              guint prop_id,
              GValue *value,
              GParamSpec *pspec)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (object);

    switch (prop_id) {
    case PROP_MODEM_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_dbus_skeleton);
        break;
    case PROP_MODEM_3GPP_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_3gpp_dbus_skeleton);
        break;
    case PROP_MODEM_3GPP_USSD_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_3gpp_ussd_dbus_skeleton);
        break;
    case PROP_MODEM_CDMA_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_cdma_dbus_skeleton);
        break;
    case PROP_MODEM_SIMPLE_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_simple_dbus_skeleton);
        break;
    case PROP_MODEM_LOCATION_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_location_dbus_skeleton);
        break;
    case PROP_MODEM_MESSAGING_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_messaging_dbus_skeleton);
        break;
    case PROP_MODEM_VOICE_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_voice_dbus_skeleton);
        break;
    case PROP_MODEM_TIME_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_time_dbus_skeleton);
        break;
    case PROP_MODEM_SIGNAL_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_signal_dbus_skeleton);
        break;
    case PROP_MODEM_OMA_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_oma_dbus_skeleton);
        break;
    case PROP_MODEM_FIRMWARE_DBUS_SKELETON:
        g_value_set_object (value, self->priv->modem_firmware_dbus_skeleton);
        break;
    case PROP_MODEM_SIM:
        g_value_set_object (value, self->priv->modem_sim);
        break;
    case PROP_MODEM_BEARER_LIST:
        g_value_set_object (value, self->priv->modem_bearer_list);
        break;
    case PROP_MODEM_STATE:
        g_value_set_enum (value, self->priv->modem_state);
        break;
    case PROP_MODEM_3GPP_REGISTRATION_STATE:
        g_value_set_enum (value, self->priv->modem_3gpp_registration_state);
        break;
    case PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED:
        g_value_set_boolean (value, self->priv->modem_3gpp_cs_network_supported);
        break;
    case PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED:
        g_value_set_boolean (value, self->priv->modem_3gpp_ps_network_supported);
        break;
    case PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED:
        g_value_set_boolean (value, self->priv->modem_3gpp_eps_network_supported);
        break;
    case PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS:
        g_value_set_flags (value, self->priv->modem_3gpp_ignored_facility_locks);
        break;
    case PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE:
        g_value_set_enum (value, self->priv->modem_cdma_cdma1x_registration_state);
        break;
    case PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE:
        g_value_set_enum (value, self->priv->modem_cdma_evdo_registration_state);
        break;
    case PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED:
        g_value_set_boolean (value, self->priv->modem_cdma_cdma1x_network_supported);
        break;
    case PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED:
        g_value_set_boolean (value, self->priv->modem_cdma_evdo_network_supported);
        break;
    case PROP_MODEM_MESSAGING_SMS_LIST:
        g_value_set_object (value, self->priv->modem_messaging_sms_list);
        break;
    case PROP_MODEM_VOICE_CALL_LIST:
        g_value_set_object (value, self->priv->modem_voice_call_list);
        break;
    case PROP_MODEM_MESSAGING_SMS_PDU_MODE:
        g_value_set_boolean (value, self->priv->modem_messaging_sms_pdu_mode);
        break;
    case PROP_MODEM_MESSAGING_SMS_DEFAULT_STORAGE:
        g_value_set_enum (value, self->priv->modem_messaging_sms_default_storage);
        break;
    case PROP_MODEM_SIMPLE_STATUS:
        g_value_set_object (value, self->priv->modem_simple_status);
        break;
    case PROP_MODEM_SIM_HOT_SWAP_SUPPORTED:
        g_value_set_boolean (value, self->priv->sim_hot_swap_supported);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
        break;
    }
}

static void
mm_broadband_modem_init (MMBroadbandModem *self)
{
    /* Initialize private data */
    self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
                                              MM_TYPE_BROADBAND_MODEM,
                                              MMBroadbandModemPrivate);
    self->priv->modem_state = MM_MODEM_STATE_UNKNOWN;
    self->priv->modem_3gpp_registration_regex = mm_3gpp_creg_regex_get (TRUE);
    self->priv->modem_current_charset = MM_MODEM_CHARSET_UNKNOWN;
    self->priv->modem_3gpp_registration_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN;
    self->priv->modem_3gpp_cs_network_supported = TRUE;
    self->priv->modem_3gpp_ps_network_supported = TRUE;
    self->priv->modem_3gpp_eps_network_supported = FALSE;
    self->priv->modem_3gpp_ignored_facility_locks = MM_MODEM_3GPP_FACILITY_NONE;
    self->priv->modem_cdma_cdma1x_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
    self->priv->modem_cdma_evdo_registration_state = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
    self->priv->modem_cdma_cdma1x_network_supported = TRUE;
    self->priv->modem_cdma_evdo_network_supported = TRUE;
    self->priv->modem_messaging_sms_default_storage = MM_SMS_STORAGE_UNKNOWN;
    self->priv->current_sms_mem1_storage = MM_SMS_STORAGE_UNKNOWN;
    self->priv->current_sms_mem2_storage = MM_SMS_STORAGE_UNKNOWN;
    self->priv->sim_hot_swap_supported = FALSE;
}

static void
finalize (GObject *object)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (object);

    if (self->priv->enabled_ports_ctx)
        ports_context_unref (self->priv->enabled_ports_ctx);

    if (self->priv->modem_3gpp_registration_regex)
        mm_3gpp_creg_regex_destroy (self->priv->modem_3gpp_registration_regex);

    G_OBJECT_CLASS (mm_broadband_modem_parent_class)->finalize (object);
}

static void
dispose (GObject *object)
{
    MMBroadbandModem *self = MM_BROADBAND_MODEM (object);

    if (self->priv->modem_dbus_skeleton) {
        mm_iface_modem_shutdown (MM_IFACE_MODEM (object));
        g_clear_object (&self->priv->modem_dbus_skeleton);
    }

    if (self->priv->modem_3gpp_dbus_skeleton) {
        mm_iface_modem_3gpp_shutdown (MM_IFACE_MODEM_3GPP (object));
        g_clear_object (&self->priv->modem_3gpp_dbus_skeleton);
    }

    if (self->priv->modem_3gpp_ussd_dbus_skeleton) {
        mm_iface_modem_3gpp_ussd_shutdown (MM_IFACE_MODEM_3GPP_USSD (object));
        g_clear_object (&self->priv->modem_3gpp_ussd_dbus_skeleton);
    }

    if (self->priv->modem_cdma_dbus_skeleton) {
        mm_iface_modem_cdma_shutdown (MM_IFACE_MODEM_CDMA (object));
        g_clear_object (&self->priv->modem_cdma_dbus_skeleton);
    }

    if (self->priv->modem_location_dbus_skeleton) {
        mm_iface_modem_location_shutdown (MM_IFACE_MODEM_LOCATION (object));
        g_clear_object (&self->priv->modem_location_dbus_skeleton);
    }

    if (self->priv->modem_messaging_dbus_skeleton) {
        mm_iface_modem_messaging_shutdown (MM_IFACE_MODEM_MESSAGING (object));
        g_clear_object (&self->priv->modem_messaging_dbus_skeleton);
    }

    if (self->priv->modem_voice_dbus_skeleton) {
        mm_iface_modem_voice_shutdown (MM_IFACE_MODEM_VOICE (object));
        g_clear_object (&self->priv->modem_voice_dbus_skeleton);
    }

    if (self->priv->modem_time_dbus_skeleton) {
        mm_iface_modem_time_shutdown (MM_IFACE_MODEM_TIME (object));
        g_clear_object (&self->priv->modem_time_dbus_skeleton);
    }

    if (self->priv->modem_simple_dbus_skeleton) {
        mm_iface_modem_simple_shutdown (MM_IFACE_MODEM_SIMPLE (object));
        g_clear_object (&self->priv->modem_simple_dbus_skeleton);
    }

    g_clear_object (&self->priv->modem_sim);
    g_clear_object (&self->priv->modem_bearer_list);
    g_clear_object (&self->priv->modem_messaging_sms_list);
    g_clear_object (&self->priv->modem_voice_call_list);
    g_clear_object (&self->priv->modem_simple_status);

    G_OBJECT_CLASS (mm_broadband_modem_parent_class)->dispose (object);
}

static void
iface_modem_init (MMIfaceModem *iface)
{
    /* Initialization steps */
    iface->load_current_capabilities = modem_load_current_capabilities;
    iface->load_current_capabilities_finish = modem_load_current_capabilities_finish;
    iface->load_manufacturer = modem_load_manufacturer;
    iface->load_manufacturer_finish = modem_load_manufacturer_finish;
    iface->load_model = modem_load_model;
    iface->load_model_finish = modem_load_model_finish;
    iface->load_revision = modem_load_revision;
    iface->load_revision_finish = modem_load_revision_finish;
    iface->load_equipment_identifier = modem_load_equipment_identifier;
    iface->load_equipment_identifier_finish = modem_load_equipment_identifier_finish;
    iface->load_device_identifier = modem_load_device_identifier;
    iface->load_device_identifier_finish = modem_load_device_identifier_finish;
    iface->load_own_numbers = modem_load_own_numbers;
    iface->load_own_numbers_finish = modem_load_own_numbers_finish;
    iface->load_unlock_required = modem_load_unlock_required;
    iface->load_unlock_required_finish = modem_load_unlock_required_finish;
    iface->create_sim = modem_create_sim;
    iface->create_sim_finish = modem_create_sim_finish;
    iface->load_supported_modes = modem_load_supported_modes;
    iface->load_supported_modes_finish = modem_load_supported_modes_finish;
    iface->load_power_state = load_power_state;
    iface->load_power_state_finish = load_power_state_finish;
    iface->load_supported_ip_families = modem_load_supported_ip_families;
    iface->load_supported_ip_families_finish = modem_load_supported_ip_families_finish;

    /* Enabling steps */
    iface->modem_power_up = modem_power_up;
    iface->modem_power_up_finish = modem_power_up_finish;
    iface->setup_flow_control = modem_setup_flow_control;
    iface->setup_flow_control_finish = modem_setup_flow_control_finish;
    iface->load_supported_charsets = modem_load_supported_charsets;
    iface->load_supported_charsets_finish = modem_load_supported_charsets_finish;
    iface->setup_charset = modem_setup_charset;
    iface->setup_charset_finish = modem_setup_charset_finish;

    /* Additional actions */
    iface->load_signal_quality = modem_load_signal_quality;
    iface->load_signal_quality_finish = modem_load_signal_quality_finish;
    iface->create_bearer = modem_create_bearer;
    iface->create_bearer_finish = modem_create_bearer_finish;
    iface->command = modem_command;
    iface->command_finish = modem_command_finish;

    iface->load_access_technologies = modem_load_access_technologies;
    iface->load_access_technologies_finish = modem_load_access_technologies_finish;
}

static void
iface_modem_3gpp_init (MMIfaceModem3gpp *iface)
{
    /* Initialization steps */
    iface->load_imei = modem_3gpp_load_imei;
    iface->load_imei_finish = modem_3gpp_load_imei_finish;
    iface->load_enabled_facility_locks = modem_3gpp_load_enabled_facility_locks;
    iface->load_enabled_facility_locks_finish = modem_3gpp_load_enabled_facility_locks_finish;

    /* Enabling steps */
    iface->setup_unsolicited_events = modem_3gpp_setup_unsolicited_events;
    iface->setup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
    iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events;
    iface->enable_unsolicited_events_finish = modem_3gpp_enable_disable_unsolicited_events_finish;
    iface->setup_unsolicited_registration_events = modem_3gpp_setup_unsolicited_registration_events;
    iface->setup_unsolicited_registration_events_finish = modem_3gpp_setup_unsolicited_registration_events_finish;
    iface->enable_unsolicited_registration_events = modem_3gpp_enable_unsolicited_registration_events;
    iface->enable_unsolicited_registration_events_finish = modem_3gpp_enable_disable_unsolicited_registration_events_finish;

    /* Disabling steps */
    iface->disable_unsolicited_events = modem_3gpp_disable_unsolicited_events;
    iface->disable_unsolicited_events_finish = modem_3gpp_enable_disable_unsolicited_events_finish;
    iface->cleanup_unsolicited_events = modem_3gpp_cleanup_unsolicited_events;
    iface->cleanup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish;
    iface->disable_unsolicited_registration_events = modem_3gpp_disable_unsolicited_registration_events;
    iface->disable_unsolicited_registration_events_finish = modem_3gpp_enable_disable_unsolicited_registration_events_finish;
    iface->cleanup_unsolicited_registration_events = modem_3gpp_cleanup_unsolicited_registration_events;
    iface->cleanup_unsolicited_registration_events_finish = modem_3gpp_cleanup_unsolicited_registration_events_finish;

    /* Additional actions */
    iface->load_operator_code = modem_3gpp_load_operator_code;
    iface->load_operator_code_finish = modem_3gpp_load_operator_code_finish;
    iface->load_operator_name = modem_3gpp_load_operator_name;
    iface->load_operator_name_finish = modem_3gpp_load_operator_name_finish;
    iface->load_subscription_state = modem_3gpp_load_subscription_state;
    iface->load_subscription_state_finish = modem_3gpp_load_subscription_state_finish;
    iface->run_registration_checks = modem_3gpp_run_registration_checks;
    iface->run_registration_checks_finish = modem_3gpp_run_registration_checks_finish;
    iface->register_in_network = modem_3gpp_register_in_network;
    iface->register_in_network_finish = modem_3gpp_register_in_network_finish;
    iface->scan_networks = modem_3gpp_scan_networks;
    iface->scan_networks_finish = modem_3gpp_scan_networks_finish;
}

static void
iface_modem_3gpp_ussd_init (MMIfaceModem3gppUssd *iface)
{
    /* Initialization steps */
    iface->check_support = modem_3gpp_ussd_check_support;
    iface->check_support_finish = modem_3gpp_ussd_check_support_finish;

    /* Enabling steps */
    iface->setup_unsolicited_result_codes = modem_3gpp_ussd_setup_unsolicited_result_codes;
    iface->setup_unsolicited_result_codes_finish = modem_3gpp_ussd_setup_cleanup_unsolicited_result_codes_finish;
    iface->enable_unsolicited_result_codes = modem_3gpp_ussd_enable_unsolicited_result_codes;
    iface->enable_unsolicited_result_codes_finish = modem_3gpp_ussd_enable_disable_unsolicited_result_codes_finish;

    /* Disabling steps */
    iface->cleanup_unsolicited_result_codes_finish = modem_3gpp_ussd_setup_cleanup_unsolicited_result_codes_finish;
    iface->cleanup_unsolicited_result_codes = modem_3gpp_ussd_cleanup_unsolicited_result_codes;
    iface->disable_unsolicited_result_codes = modem_3gpp_ussd_disable_unsolicited_result_codes;
    iface->disable_unsolicited_result_codes_finish = modem_3gpp_ussd_enable_disable_unsolicited_result_codes_finish;

    /* Additional actions */
    iface->encode = modem_3gpp_ussd_encode;
    iface->decode = modem_3gpp_ussd_decode;
    iface->send = modem_3gpp_ussd_send;
    iface->send_finish = modem_3gpp_ussd_send_finish;
    iface->cancel = modem_3gpp_ussd_cancel;
    iface->cancel_finish = modem_3gpp_ussd_cancel_finish;
}

static void
iface_modem_cdma_init (MMIfaceModemCdma *iface)
{
    /* Initialization steps */
    iface->load_esn = modem_cdma_load_esn;
    iface->load_esn_finish = modem_cdma_load_esn_finish;
    iface->load_meid = modem_cdma_load_meid;
    iface->load_meid_finish = modem_cdma_load_meid_finish;

    /* Registration check steps */
    iface->setup_unsolicited_events = modem_cdma_setup_unsolicited_events;
    iface->setup_unsolicited_events_finish = modem_cdma_setup_cleanup_unsolicited_events_finish;
    iface->cleanup_unsolicited_events = modem_cdma_cleanup_unsolicited_events;
    iface->cleanup_unsolicited_events_finish = modem_cdma_setup_cleanup_unsolicited_events_finish;
    iface->setup_registration_checks = modem_cdma_setup_registration_checks;
    iface->setup_registration_checks_finish = modem_cdma_setup_registration_checks_finish;
    iface->get_call_manager_state = modem_cdma_get_call_manager_state;
    iface->get_call_manager_state_finish = modem_cdma_get_call_manager_state_finish;
    iface->get_hdr_state = modem_cdma_get_hdr_state;
    iface->get_hdr_state_finish = modem_cdma_get_hdr_state_finish;
    iface->get_service_status = modem_cdma_get_service_status;
    iface->get_service_status_finish = modem_cdma_get_service_status_finish;
    iface->get_cdma1x_serving_system = modem_cdma_get_cdma1x_serving_system;
    iface->get_cdma1x_serving_system_finish = modem_cdma_get_cdma1x_serving_system_finish;
    iface->get_detailed_registration_state = modem_cdma_get_detailed_registration_state;
    iface->get_detailed_registration_state_finish = modem_cdma_get_detailed_registration_state_finish;

    /* Additional actions */
    iface->register_in_network = modem_cdma_register_in_network;
    iface->register_in_network_finish = modem_cdma_register_in_network_finish;
}

static void
iface_modem_simple_init (MMIfaceModemSimple *iface)
{
}

static void
iface_modem_location_init (MMIfaceModemLocation *iface)
{
    iface->load_capabilities = modem_location_load_capabilities;
    iface->load_capabilities_finish = modem_location_load_capabilities_finish;
    iface->enable_location_gathering = enable_location_gathering;
    iface->enable_location_gathering_finish = enable_location_gathering_finish;
}

static void
iface_modem_messaging_init (MMIfaceModemMessaging *iface)
{
    iface->check_support = modem_messaging_check_support;
    iface->check_support_finish = modem_messaging_check_support_finish;
    iface->load_supported_storages = modem_messaging_load_supported_storages;
    iface->load_supported_storages_finish = modem_messaging_load_supported_storages_finish;
    iface->set_default_storage = modem_messaging_set_default_storage;
    iface->set_default_storage_finish = modem_messaging_set_default_storage_finish;
    iface->setup_sms_format = modem_messaging_setup_sms_format;
    iface->setup_sms_format_finish = modem_messaging_setup_sms_format_finish;
    iface->load_initial_sms_parts = modem_messaging_load_initial_sms_parts;
    iface->load_initial_sms_parts_finish = modem_messaging_load_initial_sms_parts_finish;
    iface->setup_unsolicited_events = modem_messaging_setup_unsolicited_events;
    iface->setup_unsolicited_events_finish = modem_messaging_setup_cleanup_unsolicited_events_finish;
    iface->enable_unsolicited_events = modem_messaging_enable_unsolicited_events;
    iface->enable_unsolicited_events_finish = modem_messaging_enable_unsolicited_events_finish;
    iface->cleanup_unsolicited_events = modem_messaging_cleanup_unsolicited_events;
    iface->cleanup_unsolicited_events_finish = modem_messaging_setup_cleanup_unsolicited_events_finish;
    iface->create_sms = modem_messaging_create_sms;
    iface->init_current_storages = modem_messaging_init_current_storages;
    iface->init_current_storages_finish = modem_messaging_init_current_storages_finish;
}

static void
iface_modem_voice_init (MMIfaceModemVoice *iface)
{
    iface->check_support = modem_voice_check_support;
    iface->check_support_finish = modem_voice_check_support_finish;
    iface->setup_unsolicited_events = modem_voice_setup_unsolicited_events;
    iface->setup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish;
    iface->enable_unsolicited_events = modem_voice_enable_unsolicited_events;
    iface->enable_unsolicited_events_finish = modem_voice_enable_unsolicited_events_finish;
    iface->cleanup_unsolicited_events = modem_voice_cleanup_unsolicited_events;
    iface->cleanup_unsolicited_events_finish = modem_voice_setup_cleanup_unsolicited_events_finish;
    iface->create_call = modem_voice_create_call;
}

static void
iface_modem_time_init (MMIfaceModemTime *iface)
{
    iface->check_support = modem_time_check_support;
    iface->check_support_finish = modem_time_check_support_finish;
    iface->load_network_time = modem_time_load_network_time;
    iface->load_network_time_finish = modem_time_load_network_time_finish;
    iface->load_network_timezone = modem_time_load_network_timezone;
    iface->load_network_timezone_finish = modem_time_load_network_timezone_finish;
}

static void
iface_modem_signal_init (MMIfaceModemSignal *iface)
{
    iface->check_support        = modem_signal_check_support;
    iface->check_support_finish = modem_signal_check_support_finish;
    iface->load_values          = modem_signal_load_values;
    iface->load_values_finish   = modem_signal_load_values_finish;
}

static void
iface_modem_oma_init (MMIfaceModemOma *iface)
{
}

static void
iface_modem_firmware_init (MMIfaceModemFirmware *iface)
{
}

static void
mm_broadband_modem_class_init (MMBroadbandModemClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
    MMBaseModemClass *base_modem_class = MM_BASE_MODEM_CLASS (klass);

    g_type_class_add_private (object_class, sizeof (MMBroadbandModemPrivate));

    /* Virtual methods */
    object_class->set_property = set_property;
    object_class->get_property = get_property;
    object_class->dispose = dispose;
    object_class->finalize = finalize;

    base_modem_class->initialize = initialize;
    base_modem_class->initialize_finish = initialize_finish;
    base_modem_class->enable = enable;
    base_modem_class->enable_finish = enable_finish;
    base_modem_class->disable = disable;
    base_modem_class->disable_finish = disable_finish;

    klass->setup_ports = setup_ports;
    klass->initialization_started = initialization_started;
    klass->initialization_started_finish = initialization_started_finish;
    klass->initialization_stopped = initialization_stopped;
    klass->enabling_started = enabling_started;
    klass->enabling_started_finish = enabling_started_finish;
    klass->enabling_modem_init = enabling_modem_init;
    klass->enabling_modem_init_finish = enabling_modem_init_finish;
    klass->disabling_stopped = disabling_stopped;

    g_object_class_override_property (object_class,
                                      PROP_MODEM_DBUS_SKELETON,
                                      MM_IFACE_MODEM_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_DBUS_SKELETON,
                                      MM_IFACE_MODEM_3GPP_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_USSD_DBUS_SKELETON,
                                      MM_IFACE_MODEM_3GPP_USSD_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_CDMA_DBUS_SKELETON,
                                      MM_IFACE_MODEM_CDMA_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_SIMPLE_DBUS_SKELETON,
                                      MM_IFACE_MODEM_SIMPLE_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_LOCATION_DBUS_SKELETON,
                                      MM_IFACE_MODEM_LOCATION_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_MESSAGING_DBUS_SKELETON,
                                      MM_IFACE_MODEM_MESSAGING_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_VOICE_DBUS_SKELETON,
                                      MM_IFACE_MODEM_VOICE_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_TIME_DBUS_SKELETON,
                                      MM_IFACE_MODEM_TIME_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_SIGNAL_DBUS_SKELETON,
                                      MM_IFACE_MODEM_SIGNAL_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_OMA_DBUS_SKELETON,
                                      MM_IFACE_MODEM_OMA_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_FIRMWARE_DBUS_SKELETON,
                                      MM_IFACE_MODEM_FIRMWARE_DBUS_SKELETON);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_SIM,
                                      MM_IFACE_MODEM_SIM);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_BEARER_LIST,
                                      MM_IFACE_MODEM_BEARER_LIST);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_STATE,
                                      MM_IFACE_MODEM_STATE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_REGISTRATION_STATE,
                                      MM_IFACE_MODEM_3GPP_REGISTRATION_STATE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_CS_NETWORK_SUPPORTED,
                                      MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_PS_NETWORK_SUPPORTED,
                                      MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_EPS_NETWORK_SUPPORTED,
                                      MM_IFACE_MODEM_3GPP_EPS_NETWORK_SUPPORTED);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_3GPP_IGNORED_FACILITY_LOCKS,
                                      MM_IFACE_MODEM_3GPP_IGNORED_FACILITY_LOCKS);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_CDMA_CDMA1X_REGISTRATION_STATE,
                                      MM_IFACE_MODEM_CDMA_CDMA1X_REGISTRATION_STATE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_CDMA_EVDO_REGISTRATION_STATE,
                                      MM_IFACE_MODEM_CDMA_EVDO_REGISTRATION_STATE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED,
                                      MM_IFACE_MODEM_CDMA_CDMA1X_NETWORK_SUPPORTED);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_CDMA_EVDO_NETWORK_SUPPORTED,
                                      MM_IFACE_MODEM_CDMA_EVDO_NETWORK_SUPPORTED);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_MESSAGING_SMS_LIST,
                                      MM_IFACE_MODEM_MESSAGING_SMS_LIST);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_VOICE_CALL_LIST,
                                      MM_IFACE_MODEM_VOICE_CALL_LIST);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_MESSAGING_SMS_PDU_MODE,
                                      MM_IFACE_MODEM_MESSAGING_SMS_PDU_MODE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_MESSAGING_SMS_DEFAULT_STORAGE,
                                      MM_IFACE_MODEM_MESSAGING_SMS_DEFAULT_STORAGE);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_SIMPLE_STATUS,
                                      MM_IFACE_MODEM_SIMPLE_STATUS);

    g_object_class_override_property (object_class,
                                      PROP_MODEM_SIM_HOT_SWAP_SUPPORTED,
                                      MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED);
}
