static void
setup_ports (MMBroadbandModem *self)
{
    gpointer parser;
    MMAtSerialPort *primary;
    GRegex *regex;

    /* Call parent's setup ports first always */
    MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_wavecom_parent_class)->setup_ports (self);

    /* Set 9600 baudrate by default in the AT port */
    mm_dbg ("Baudrate will be set to 9600 bps...");
    primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
    if (!primary)
        return;

    /* AT+CPIN? replies will never have an OK appended */
    parser = mm_serial_parser_v1_new ();
    regex = g_regex_new ("\\r\\n\\+CPIN: .*\\r\\n",
                         G_REGEX_RAW | G_REGEX_OPTIMIZE,
                         0, NULL);
    mm_serial_parser_v1_set_custom_regex (parser, regex, NULL);
    g_regex_unref (regex);

    mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (primary),
                                           mm_serial_parser_v1_parse,
                                           parser,
                                           mm_serial_parser_v1_destroy);
}
Пример #2
0
gboolean
mm_plugin_base_probe_port (MMPluginBase *self,
                           MMPluginBaseSupportsTask *task,
                           GError **error)
{
    MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
    MMAtSerialPort *serial;
    const char *name;
    GUdevDevice *port;

    g_return_val_if_fail (self != NULL, FALSE);
    g_return_val_if_fail (MM_IS_PLUGIN_BASE (self), FALSE);
    g_return_val_if_fail (task != NULL, FALSE);

    port = mm_plugin_base_supports_task_get_port (task);
    g_assert (port);
    name = g_udev_device_get_name (port);
    g_assert (name);

    serial = mm_at_serial_port_new (name, MM_PORT_TYPE_PRIMARY);
    if (serial == NULL) {
        g_set_error_literal (error, MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL,
                             "Failed to create new serial port.");
        return FALSE;
    }

    g_object_set (serial,
                  MM_SERIAL_PORT_SEND_DELAY, (guint64) 100000,
                  MM_PORT_CARRIER_DETECT, FALSE,
                  NULL);

    mm_at_serial_port_set_response_parser (serial,
                                           mm_serial_parser_v1_parse,
                                           mm_serial_parser_v1_new (),
                                           mm_serial_parser_v1_destroy);

    /* Open the port */
    task_priv->probe_port = serial;
    task_priv->open_id = g_idle_add (try_open, task);
    return TRUE;
}
Пример #3
0
static gboolean
serial_open_at (MMPortProbe *self)
{
    PortProbeRunTask *task = self->priv->task;
    GError *error = NULL;

    task->source_id = 0;

    /* If already cancelled, do nothing else */
    if (port_probe_run_is_cancelled (self))
        return FALSE;

    /* Create AT serial port if not done before */
    if (!task->serial) {
        task->serial = MM_SERIAL_PORT (mm_at_serial_port_new (self->priv->name));
        if (!task->serial) {
            port_probe_run_task_complete (
                task,
                FALSE,
                g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "(%s) couldn't create AT port",
                             self->priv->name));
            return FALSE;
        }

        g_object_set (task->serial,
                      MM_SERIAL_PORT_SEND_DELAY, task->at_send_delay,
                      MM_PORT_CARRIER_DETECT, FALSE,
                      MM_SERIAL_PORT_SPEW_CONTROL, TRUE,
                      NULL);

        mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (task->serial),
                                               mm_serial_parser_v1_parse,
                                               mm_serial_parser_v1_new (),
                                               mm_serial_parser_v1_destroy);
    }

    /* Try to open the port */
    if (!mm_serial_port_open (task->serial, &error)) {
        /* Abort if maximum number of open tries reached */
        if (++task->at_open_tries > 4) {
            /* took too long to open the port; give up */
            port_probe_run_task_complete (
                task,
                FALSE,
                g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "(%s) failed to open port after 4 tries",
                             self->priv->name));
        } else if (g_error_matches (error,
                                    MM_SERIAL_ERROR,
                                    MM_SERIAL_ERROR_OPEN_FAILED_NO_DEVICE)) {
            /* this is nozomi being dumb; try again */
            task->source_id = g_timeout_add_seconds (1,
                                                     (GSourceFunc)serial_open_at,
                                                     self);
        } else {
            port_probe_run_task_complete (
                task,
                FALSE,
                g_error_new (MM_SERIAL_ERROR,
                             MM_SERIAL_ERROR_OPEN_FAILED,
                             "(%s) failed to open port: %s",
                             self->priv->name,
                             (error ? error->message : "unknown error")));
        }

        g_clear_error (&error);
        return FALSE;
    }

    /* success, start probing */
    task->buffer_full_id = g_signal_connect (task->serial,
                                             "buffer-full",
                                             G_CALLBACK (serial_buffer_full),
                                             self);

    mm_serial_port_flash (MM_SERIAL_PORT (task->serial),
                          100,
                          TRUE,
                          (MMSerialFlashFn)serial_flash_done,
                          self);
    return FALSE;
}
Пример #4
0
gboolean
mm_base_modem_grab_port (MMBaseModem *self,
                         const gchar *subsys,
                         const gchar *name,
                         MMPortType ptype,
                         MMAtPortFlag at_pflags,
                         GError **error)
{
    MMPort *port;
    gchar *key;

    g_return_val_if_fail (MM_IS_BASE_MODEM (self), FALSE);
    g_return_val_if_fail (subsys != NULL, FALSE);
    g_return_val_if_fail (name != NULL, FALSE);

    /* Only allow 'tty', 'net' and 'cdc-wdm' ports */
    if (!g_str_equal (subsys, "net") &&
        !g_str_equal (subsys, "tty") &&
        !(g_str_has_prefix (subsys, "usb") && g_str_has_prefix (name, "cdc-wdm"))) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_UNSUPPORTED,
                     "Cannot add port '%s/%s', unhandled subsystem",
                     subsys,
                     name);
        return FALSE;
    }

    /* Check whether we already have it stored */
    key = get_hash_key (subsys, name);
    port = g_hash_table_lookup (self->priv->ports, key);
    if (port) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_UNSUPPORTED,
                     "Cannot add port '%s/%s', already exists",
                     subsys,
                     name);
        g_free (key);
        return FALSE;
    }

    /* Serial ports... */
    if (g_str_equal (subsys, "tty")) {
        if (ptype == MM_PORT_TYPE_QCDM)
            /* QCDM port */
            port = MM_PORT (mm_qcdm_serial_port_new (name));
        else if (ptype == MM_PORT_TYPE_AT) {
            /* AT port */
            port = MM_PORT (mm_at_serial_port_new (name));

            /* Set common response parser */
            mm_at_serial_port_set_response_parser (MM_AT_SERIAL_PORT (port),
                                                   mm_serial_parser_v1_parse,
                                                   mm_serial_parser_v1_new (),
                                                   mm_serial_parser_v1_destroy);
            /* Store flags already */
            mm_at_serial_port_set_flags (MM_AT_SERIAL_PORT (port), at_pflags);
        } else if (ptype == MM_PORT_TYPE_GPS) {
            /* Raw GPS port */
            port = MM_PORT (mm_gps_serial_port_new (name));
        } else {
            g_set_error (error,
                         MM_CORE_ERROR,
                         MM_CORE_ERROR_UNSUPPORTED,
                         "Cannot add port '%s/%s', unhandled serial type",
                         subsys,
                         name);
            g_free (key);
            return FALSE;
        }

        /* For serial ports, enable port timeout checks */
        g_signal_connect (port,
                          "timed-out",
                          G_CALLBACK (serial_port_timed_out_cb),
                          self);
    }
    /* Net ports... */
    else if (g_str_equal (subsys, "net")) {
        port = MM_PORT (g_object_new (MM_TYPE_PORT,
                                      MM_PORT_DEVICE, name,
                                      MM_PORT_SUBSYS, MM_PORT_SUBSYS_NET,
                                      MM_PORT_TYPE, MM_PORT_TYPE_NET,
                                      NULL));
    }
    /* QMI ports... */
    else if (g_str_has_prefix (subsys, "usb") &&
             g_str_has_prefix (name, "cdc-wdm")) {
#if defined WITH_QMI
        port = MM_PORT (mm_qmi_port_new (name));
#else
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_UNSUPPORTED,
                     "Cannot add port '%s/%s', QMI support not available",
                     subsys,
                     name);
        g_free (key);
        return FALSE;
#endif
    }
    else
        /* We already filter out before all non-tty, non-net, non-qmi ports */
        g_assert_not_reached();

    mm_dbg ("(%s) type '%s' claimed by %s",
            name,
            mm_port_type_get_string (ptype),
            mm_base_modem_get_device (self));

    /* Add it to the tracking HT.
     * Note: 'key' and 'port' now owned by the HT. */
    g_hash_table_insert (self->priv->ports, key, port);

    return TRUE;
}