Ejemplo n.º 1
0
static void
port_grabbed (MMGenericCdma *cdma,
              MMPort *port,
              MMAtPortFlags pflags,
              gpointer user_data)
{
    GRegex *regex;
    gboolean evdo0 = FALSE, evdoA = FALSE;

    if (MM_IS_AT_SERIAL_PORT (port)) {
        g_object_set (G_OBJECT (port), MM_PORT_CARRIER_DETECT, FALSE, NULL);

        /* 1x signal level */
        regex = g_regex_new ("\\r\\n\\^RSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
        mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_1x_quality_change, cdma, NULL);
        g_regex_unref (regex);

        g_object_get (G_OBJECT (cdma),
                      MM_GENERIC_CDMA_EVDO_REV0, &evdo0,
                      MM_GENERIC_CDMA_EVDO_REVA, &evdoA,
                      NULL);

        if (evdo0 || evdoA) {
            /* EVDO signal level */
            regex = g_regex_new ("\\r\\n\\^HRSSILVL:(\\d+)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
            mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, handle_evdo_quality_change, cdma, NULL);
            g_regex_unref (regex);
        }
    }
}
Ejemplo n.º 2
0
static gboolean
grab_port (MMModem *modem,
           const char *subsys,
           const char *name,
           MMPortType suggested_type,
           gpointer user_data,
           GError **error)
{
    MMGenericGsm *gsm = MM_GENERIC_GSM (modem);
    MMPortType ptype = MM_PORT_TYPE_IGNORED;
    MMPort *port = NULL;

    if (suggested_type == MM_PORT_TYPE_UNKNOWN) {
        if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_PRIMARY))
                ptype = MM_PORT_TYPE_PRIMARY;
        else if (!mm_generic_gsm_get_at_port (gsm, MM_PORT_TYPE_SECONDARY))
            ptype = MM_PORT_TYPE_SECONDARY;
    } else
        ptype = suggested_type;

    port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
    if (port && MM_IS_AT_SERIAL_PORT (port)) {
        mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
                                               mm_serial_parser_v1_e1_parse,
                                               mm_serial_parser_v1_e1_new (),
                                               mm_serial_parser_v1_e1_destroy);
    }

    return !!port;
}
Ejemplo n.º 3
0
gboolean
mm_base_modem_has_at_port (MMBaseModem *self)
{
    GHashTableIter iter;
    gpointer value;
    gpointer key;

    /* We'll iterate the ht of ports, looking for any port which is AT */
    g_hash_table_iter_init (&iter, self->priv->ports);
    while (g_hash_table_iter_next (&iter, &key, &value)) {
        if (MM_IS_AT_SERIAL_PORT (value))
            return TRUE;
    }

    return FALSE;
}
void
mm_at_serial_port_set_response_parser (MMAtSerialPort *self,
                                       MMAtSerialResponseParserFn fn,
                                       gpointer user_data,
                                       GDestroyNotify notify)
{
    MMAtSerialPortPrivate *priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);

    g_return_if_fail (MM_IS_AT_SERIAL_PORT (self));

    if (priv->response_parser_notify)
        priv->response_parser_notify (priv->response_parser_user_data);

    priv->response_parser_fn = fn;
    priv->response_parser_user_data = user_data;
    priv->response_parser_notify = notify;
}
void
mm_at_serial_port_add_unsolicited_msg_handler (MMAtSerialPort *self,
                                               GRegex *regex,
                                               MMAtSerialUnsolicitedMsgFn callback,
                                               gpointer user_data,
                                               GDestroyNotify notify)
{
    MMAtUnsolicitedMsgHandler *handler;
    MMAtSerialPortPrivate *priv;

    g_return_if_fail (MM_IS_AT_SERIAL_PORT (self));
    g_return_if_fail (regex != NULL);

    handler = g_slice_new (MMAtUnsolicitedMsgHandler);
    handler->regex = g_regex_ref (regex);
    handler->callback = callback;
    handler->user_data = user_data;
    handler->notify = notify;

    priv = MM_AT_SERIAL_PORT_GET_PRIVATE (self);
    priv->unsolicited_msg_handlers = g_slist_append (priv->unsolicited_msg_handlers, handler);
}
void
mm_at_serial_port_queue_command_cached (MMAtSerialPort *self,
                                        const char *command,
                                        guint32 timeout_seconds,
                                        MMAtSerialResponseFn callback,
                                        gpointer user_data)
{
    GByteArray *buf;

    g_return_if_fail (self != NULL);
    g_return_if_fail (MM_IS_AT_SERIAL_PORT (self));
    g_return_if_fail (command != NULL);

    buf = at_command_to_byte_array (command);
    g_return_if_fail (buf != NULL);

    mm_serial_port_queue_command_cached (MM_SERIAL_PORT (self),
                                         buf,
                                         TRUE,
                                         timeout_seconds,
                                         (MMSerialResponseFn) callback,
                                         user_data);
}
Ejemplo n.º 7
0
static gboolean
grab_port (MMModem *modem,
           const char *subsys,
           const char *name,
           MMPortType suggested_type,
           gpointer user_data,
           GError **error)
{
    MMGenericGsm *gsm = MM_GENERIC_GSM (modem);
    MMPortType ptype = MM_PORT_TYPE_IGNORED;
    const char *sys[] = { "tty", "net", NULL };
    GUdevClient *client;
    GUdevDevice *device = NULL;
    MMPort *port = NULL;
    const char *sysfs_path;

    client = g_udev_client_new (sys);
    if (!client) {
        g_set_error (error, 0, 0, "Could not get udev client.");
        return FALSE;
    }

    device = g_udev_client_query_by_subsystem_and_name (client, subsys, name);
    if (!device) {
        g_set_error (error, 0, 0, "Could not get udev device.");
        goto out;
    }

    sysfs_path = g_udev_device_get_sysfs_path (device);
    if (!sysfs_path) {
        g_set_error (error, 0, 0, "Could not get udev device sysfs path.");
        goto out;
    }

    if (!strcmp (subsys, "tty")) {
        char *hsotype_path;
        char *contents = NULL;

        hsotype_path = g_build_filename (sysfs_path, "hsotype", NULL);
        if (g_file_get_contents (hsotype_path, &contents, NULL, NULL)) {
            if (g_str_has_prefix (contents, "Control"))
                ptype = MM_PORT_TYPE_PRIMARY;
            else if (g_str_has_prefix (contents, "Application") || g_str_has_prefix (contents, "Application2"))
                ptype = MM_PORT_TYPE_SECONDARY;
            g_free (contents);
        }
        g_free (hsotype_path);
    }

    port = mm_generic_gsm_grab_port (gsm, subsys, name, ptype, error);
    if (!port)
        goto out;

    if (MM_IS_AT_SERIAL_PORT (port)) {
        g_object_set (G_OBJECT (port), MM_SERIAL_PORT_SEND_DELAY, (guint64) 10000, NULL);
        if (ptype == MM_PORT_TYPE_PRIMARY) {
            GRegex *regex;

            regex = g_regex_new ("_OWANCALL: (\\d),\\s*(\\d)\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
            mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, connection_enabled, modem, NULL);
            g_regex_unref (regex);

            regex = g_regex_new ("\\r\\n\\+PACSP0\\r\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
            mm_at_serial_port_add_unsolicited_msg_handler (MM_AT_SERIAL_PORT (port), regex, NULL, NULL, NULL);
            g_regex_unref (regex);
        }
        option_register_unsolicted_handlers (gsm, MM_AT_SERIAL_PORT (port));
    }

out:
    if (device)
        g_object_unref (device);
    g_object_unref (client);
    return !!port;
}
Ejemplo n.º 8
0
gboolean
mm_base_modem_organize_ports (MMBaseModem *self,
                              GError **error)
{
    GHashTableIter iter;
    MMPort *candidate;
    MMAtPortFlag flags;
    MMAtSerialPort *backup_primary = NULL;
    MMAtSerialPort *primary = NULL;
    MMAtSerialPort *secondary = NULL;
    MMAtSerialPort *backup_secondary = NULL;
    MMQcdmSerialPort *qcdm = NULL;
    MMAtSerialPort *gps_control = NULL;
    MMGpsSerialPort *gps = NULL;
    MMPort *data_primary = NULL;
    GList *data = NULL;
#if defined WITH_QMI
    MMPort *qmi_primary = NULL;
    GList *qmi = NULL;
#endif
    GList *l;

    g_return_val_if_fail (MM_IS_BASE_MODEM (self), FALSE);

    /* If ports have already been organized, just return success */
    if (self->priv->primary)
        return TRUE;

    g_hash_table_iter_init (&iter, self->priv->ports);
    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &candidate)) {
        switch (mm_port_get_port_type (candidate)) {

        case MM_PORT_TYPE_AT:
            g_assert (MM_IS_AT_SERIAL_PORT (candidate));
            flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (candidate));

            if (flags & MM_AT_PORT_FLAG_PRIMARY) {
                if (!primary)
                    primary = MM_AT_SERIAL_PORT (candidate);
                else if (!backup_primary) {
                    /* Just in case the plugin gave us more than one primary
                     * and no secondaries, treat additional primary ports as
                     * secondary.
                     */
                    backup_primary = MM_AT_SERIAL_PORT (candidate);
                }
            }

            if (!data_primary && (flags & MM_AT_PORT_FLAG_PPP))
                data_primary = candidate;

            /* Explicitly flagged secondary ports trump NONE ports for secondary */
            if (flags & MM_AT_PORT_FLAG_SECONDARY) {
                if (!secondary || !(mm_at_serial_port_get_flags (secondary) & MM_AT_PORT_FLAG_SECONDARY))
                    secondary = MM_AT_SERIAL_PORT (candidate);
            }

            if (flags & MM_AT_PORT_FLAG_GPS_CONTROL) {
                if (!gps_control)
                    gps_control = MM_AT_SERIAL_PORT (candidate);
            }

            /* Fallback secondary */
            if (flags == MM_AT_PORT_FLAG_NONE) {
                if (!secondary)
                    secondary = MM_AT_SERIAL_PORT (candidate);
                else if (!backup_secondary)
                    backup_secondary = MM_AT_SERIAL_PORT (candidate);
            }
            break;

        case MM_PORT_TYPE_QCDM:
            g_assert (MM_IS_QCDM_SERIAL_PORT (candidate));
            if (!qcdm)
                qcdm = MM_QCDM_SERIAL_PORT (candidate);
            break;

        case MM_PORT_TYPE_NET:
            /* Net device (if any) is the preferred data port */
            if (!data_primary || MM_IS_AT_SERIAL_PORT (data_primary))
                data_primary = candidate;
            else
                /* All non-primary net ports get added to the list of data ports */
                data = g_list_append (data, candidate);
            break;

        case MM_PORT_TYPE_GPS:
            g_assert (MM_IS_GPS_SERIAL_PORT (candidate));
            if (!gps)
                gps = MM_GPS_SERIAL_PORT (candidate);
            break;

#if defined WITH_QMI
        case MM_PORT_TYPE_QMI:
            if (!qmi_primary)
                qmi_primary = candidate;
            else
                /* All non-primary QMI ports get added to the list of QMI ports */
                qmi = g_list_append (qmi, candidate);
            break;
#endif

        default:
            /* Ignore port */
            break;
        }
    }

    /* Fall back to a secondary port if we didn't find a primary port */
    if (!primary) {
#if defined WITH_QMI
        /* On QMI-based modems we do allow not having a primary AT port */
        if (!secondary && !qmi_primary) {
#else
        if (!secondary) {
#endif
            g_set_error_literal (error,
                                 MM_CORE_ERROR,
                                 MM_CORE_ERROR_FAILED,
                                 "Failed to find primary AT port");
            return FALSE;
        } else {
            primary = secondary;
            secondary = NULL;
        }
    }

    /* If the plugin didn't give us any secondary ports, use any additional
     * primary ports or backup secondary ports as secondary.
     */
    if (!secondary)
        secondary = backup_primary ? backup_primary : backup_secondary;

#if defined WITH_QMI
    /* On QMI-based modems, we need to have at least a net port */
    if (qmi_primary && !data_primary) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Failed to find a net port in the QMI modem");
        return FALSE;
    }
#endif

    /* Data port defaults to primary AT port */
    if (!data_primary)
        data_primary = MM_PORT (primary);
    g_assert (data_primary);

    /* Reset flags on all ports; clear data port first since it might also
     * be the primary or secondary port.
     */
    if (MM_IS_AT_SERIAL_PORT (data_primary))
        mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data_primary), MM_AT_PORT_FLAG_NONE);

    mm_at_serial_port_set_flags (primary, MM_AT_PORT_FLAG_PRIMARY);
    if (secondary)
        mm_at_serial_port_set_flags (secondary, MM_AT_PORT_FLAG_SECONDARY);

    if (MM_IS_AT_SERIAL_PORT (data_primary)) {
        flags = mm_at_serial_port_get_flags (MM_AT_SERIAL_PORT (data_primary));
        mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (data_primary), flags | MM_AT_PORT_FLAG_PPP);
    }

    log_port (self, MM_PORT (primary),      "at (primary)");
    log_port (self, MM_PORT (secondary),    "at (secondary)");
    log_port (self, MM_PORT (data_primary), "data (primary)");
    for (l = data; l; l = g_list_next (l))
        log_port (self, MM_PORT (l->data),  "data (secondary)");
    log_port (self, MM_PORT (qcdm),         "qcdm");
    log_port (self, MM_PORT (gps_control),  "gps (control)");
    log_port (self, MM_PORT (gps),          "gps (nmea)");
#if defined WITH_QMI
    log_port (self, MM_PORT (qmi_primary),  "qmi (primary)");
    for (l = qmi; l; l = g_list_next (l))
        log_port (self, MM_PORT (l->data),  "qmi (secondary)");
#endif

    /* We keep new refs to the objects here */
    self->priv->primary = g_object_ref (primary);
    self->priv->secondary = (secondary ? g_object_ref (secondary) : NULL);
    self->priv->qcdm = (qcdm ? g_object_ref (qcdm) : NULL);
    self->priv->gps_control = (gps_control ? g_object_ref (gps_control) : NULL);
    self->priv->gps = (gps ? g_object_ref (gps) : NULL);

    /* Build the final list of data ports, primary port first */
    self->priv->data = g_list_append (self->priv->data, g_object_ref (data_primary));
    g_list_foreach (data, (GFunc)g_object_ref, NULL);
    self->priv->data = g_list_concat (self->priv->data, data);

#if defined WITH_QMI
    /* Build the final list of QMI ports, primary port first */
    if (qmi_primary) {
        self->priv->qmi = g_list_append (self->priv->qmi, g_object_ref (qmi_primary));
        g_list_foreach (qmi, (GFunc)g_object_ref, NULL);
        self->priv->qmi = g_list_concat (self->priv->qmi, qmi);
    }
#endif

    /* As soon as we get the ports organized, we initialize the modem */
    mm_base_modem_initialize (self,
                              (GAsyncReadyCallback)initialize_ready,
                              NULL);

    return TRUE;
}

/*****************************************************************************/
/* Authorization */

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

static void
authorize_ready (MMAuthProvider *authp,
                 GAsyncResult *res,
                 GSimpleAsyncResult *simple)
{
    GError *error = NULL;

    if (!mm_auth_provider_authorize_finish (authp, res, &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);
}