Beispiel #1
0
static void
check_export_modem (MMManager *self,
                    MMBaseModem *modem)
{
    GError *error = NULL;
    static guint32 id = 0;
    const gchar *modem_physdev;
    const gchar *name;
    const gchar *subsys;
    gchar *path;

    /* A modem is only exported to D-Bus when both of the following are true:
     *
     *   1) the modem is valid
     *   2) all ports the modem provides have either been grabbed or are
     *       unsupported by any plugin
     *
     * This ensures that all the modem's ports are completely ready before
     * any clients can do anything with it.
     *
     * FIXME: if udev or the kernel are really slow giving us ports, there's a
     * chance that a port could show up after the modem is already created and
     * all other ports are already handled.  That chance is very small though.
     */

    modem_physdev = mm_base_modem_get_device (modem);
    g_assert (modem_physdev);

    /* Check for ports that are in the process of being interrogated by plugins */
    if (mm_plugin_manager_is_finding_device_support (self->priv->plugin_manager,
                                                     modem_physdev,
                                                     &subsys,
                                                     &name)) {
        mm_dbg ("(%s/%s): outstanding support task prevents export of '%s'",
                subsys, name, modem_physdev);
        return;
    }

    /* Plugin manager is not trying to find more ports supported by this device,
     * so we can organize the ports now (if not done already). */
    if (!mm_base_modem_organize_ports (modem, &error)) {
        /* If the ports were not properly organized, the modem will be marked as
         * invalid and therefore removed */
        mm_err ("Failed to organize modem ports: '%s'",
                error->message);
        g_error_free (error);
        remove_modem (self, modem);
        return;
    }

    /* If modem not yet valid (not fully initialized), don't export it */
    if (!mm_base_modem_get_valid (modem))
        return;

    /* Don't export already exported modems */
    g_object_get (modem,
                  "g-object-path", &path,
                  NULL);
    if (path) {
        g_free (path);
        mm_dbg ("Modem '%s' already exported", modem_physdev);
        return;
    }

    /* No outstanding port tasks, so if the modem is valid we can export it */
    path = g_strdup_printf (MM_DBUS_MODEM_PREFIX "/%d", id++);
    g_object_set (modem,
                  "g-object-path", path,
                  MM_BASE_MODEM_CONNECTION, self->priv->connection,
                  NULL);
    g_dbus_object_manager_server_export (self->priv->object_manager,
                                         G_DBUS_OBJECT_SKELETON (modem));
    mm_dbg ("Exported modem '%s' at path '%s'", modem_physdev, path);

    /* Once connected, dump additional debug info about the modem */
    debug_modem_info (self, modem, path);
    g_free (path);
}
Beispiel #2
0
MMBaseModem *
mm_plugin_create_modem (MMPlugin  *self,
                        MMDevice *device,
                        GError   **error)
{
    MMBaseModem *modem = NULL;
    GList *port_probes, *l;

    port_probes = mm_device_peek_port_probe_list (device);

    /* Let the plugin create the modem from the port probe results */
    modem = MM_PLUGIN_GET_CLASS (self)->create_modem (MM_PLUGIN (self),
                                                      mm_device_get_path (device),
                                                      mm_device_get_drivers (device),
                                                      mm_device_get_vendor (device),
                                                      mm_device_get_product (device),
                                                      port_probes,
                                                      error);
    if (modem) {
        /* Grab each port */
        for (l = port_probes; l; l = g_list_next (l)) {
            GError *inner_error = NULL;
            MMPortProbe *probe = MM_PORT_PROBE (l->data);
            gboolean grabbed;

            /* If grabbing a port fails, just warn. We'll decide if the modem is
             * valid or not when all ports get organized */

            /* We apply again the subsystem filter, as the port may have been
             * probed and accepted by the generic plugin, which is overwritten
             * by the specific one when needed. */
            if (apply_subsystem_filter (self, mm_port_probe_peek_port (probe))) {
                grabbed = FALSE;
                inner_error = g_error_new (MM_CORE_ERROR,
                                           MM_CORE_ERROR_UNSUPPORTED,
                                           "unsupported subsystem: '%s'",
                                           mm_port_probe_get_port_subsys (probe));
            }
#if !defined WITH_QMI
            else if (mm_port_probe_get_port_type (probe) == MM_PORT_TYPE_NET &&
                     g_str_equal (mm_device_utils_get_port_driver (mm_port_probe_peek_port (probe)),
                                  "qmi_wwan")) {
                grabbed = FALSE;
                inner_error = g_error_new (MM_CORE_ERROR,
                                           MM_CORE_ERROR_UNSUPPORTED,
                                           "ignoring QMI net port");
            }
#endif
            else if (MM_PLUGIN_GET_CLASS (self)->grab_port)
                grabbed = MM_PLUGIN_GET_CLASS (self)->grab_port (MM_PLUGIN (self),
                                                                 modem,
                                                                 probe,
                                                                 &inner_error);
            else
                grabbed = mm_base_modem_grab_port (modem,
                                                   mm_port_probe_get_port_subsys (probe),
                                                   mm_port_probe_get_port_name (probe),
                                                   mm_port_probe_get_port_type (probe),
                                                   MM_AT_PORT_FLAG_NONE,
                                                   &inner_error);
            if (!grabbed) {
                mm_warn ("Could not grab port (%s/%s): '%s'",
                         mm_port_probe_get_port_subsys (MM_PORT_PROBE (l->data)),
                         mm_port_probe_get_port_name (MM_PORT_PROBE (l->data)),
                         inner_error ? inner_error->message : "unknown error");
                g_clear_error (&inner_error);
            }
        }

        /* If organizing ports fails, consider the modem invalid */
        if (!mm_base_modem_organize_ports (modem, error))
            g_clear_object (&modem);
    }

    return modem;
}