static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered Sierra modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    if (sierra_port_probe_list_is_icera (probes))
        return MM_BASE_MODEM (mm_broadband_modem_sierra_icera_new (sysfs_path,
                                                                   drivers,
                                                                   mm_plugin_get_name (self),
                                                                   vendor,
                                                                   product));

    return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
                                                         drivers,
                                                         mm_plugin_get_name (self),
                                                         vendor,
                                                         product));
}
static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
    propagate_port_mode_results (probes);

#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered Huawei modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    return MM_BASE_MODEM (mm_broadband_modem_huawei_new (sysfs_path,
                                                         drivers,
                                                         mm_plugin_get_name (self),
                                                         vendor,
                                                         product));
}
MM_PLUGIN_DEFINE_MAJOR_VERSION
MM_PLUGIN_DEFINE_MINOR_VERSION

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

static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered SimTech modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

    return MM_BASE_MODEM (mm_broadband_modem_simtech_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
}
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *devfile, *sysfs_path;
    guint32 caps;
    MMPortType ptype = MM_PORT_TYPE_UNKNOWN;

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

    devfile = g_udev_device_get_device_file (port);
    if (!devfile) {
        g_set_error (error, 0, 0, "Could not get port's sysfs file.");
        return NULL;
    }

    subsys = g_udev_device_get_subsystem (port);
    name = g_udev_device_get_name (port);

    /* Is it a GSM secondary port? */
    if (g_object_get_data (G_OBJECT (task), TAG_SIERRA_SECONDARY_PORT))
        ptype = MM_PORT_TYPE_SECONDARY;

    caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
    sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
    if (!existing) {
        if ((caps & MM_PLUGIN_BASE_PORT_CAP_GSM) || (ptype != MM_PORT_TYPE_UNKNOWN)) {
            modem = mm_modem_sierra_gsm_new (sysfs_path,
                                             mm_plugin_base_supports_task_get_driver (task),
                                             mm_plugin_get_name (MM_PLUGIN (base)));
        } else if (caps & CAP_CDMA) {
            modem = mm_modem_sierra_cdma_new (sysfs_path,
                                              mm_plugin_base_supports_task_get_driver (task),
                                              mm_plugin_get_name (MM_PLUGIN (base)),
                                              !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856),
                                              !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856_A));
        }

        if (modem) {
            if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) {
                g_object_unref (modem);
                return NULL;
            }
        }
    } else if (get_level_for_capabilities (caps) || (ptype != MM_PORT_TYPE_UNKNOWN)) {
        modem = existing;
        if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error))
            return NULL;
    }

    return modem;
}
Exemple #5
0
static void
grab_port (MMManager *manager,
           MMPlugin *plugin,
           GUdevDevice *device,
           GUdevDevice *physical_device)
{
    GError *error = NULL;
    MMBaseModem *modem;
    MMBaseModem *existing;

    existing = g_hash_table_lookup (manager->priv->modems,
                                    g_udev_device_get_sysfs_path (physical_device));

    /* While grabbing the first port, modem will get created */
    modem = mm_plugin_grab_port (plugin,
                                 g_udev_device_get_subsystem (device),
                                 g_udev_device_get_name (device),
                                 existing,
                                 &error);
    if (!modem) {
        mm_warn ("plugin '%s' claimed to support %s/%s but couldn't: (%d) %s",
                 mm_plugin_get_name (plugin),
                 g_udev_device_get_subsystem (device),
                 g_udev_device_get_name (device),
                 error ? error->code : -1,
                 (error && error->message) ? error->message : "(unknown)");
        g_clear_error (&error);

        if (existing)
            check_export_modem (manager, existing);
        return;
    }

    mm_info ("(%s): modem %s claimed port %s",
             mm_plugin_get_name (plugin),
             mm_base_modem_get_device (modem),
             g_udev_device_get_name (device));

    if (existing) {
        g_assert (existing == modem);
        check_export_modem (manager, modem);
    } else {
        /* If the modem was just created, store it */
        add_modem (manager, modem, plugin);
    }
}
static void
suggest_supports_info_result (MMPluginManager *self,
                              const gchar *physdev_path,
                              MMPlugin *suggested_plugin)
{
    SupportsInfoList *list;
    GSList *l;

    list = g_hash_table_lookup (self->priv->supports,
                                physdev_path);

    if (!list)
        return;

    /* Look for support infos on the same physical path */
    for (l = list->info_list;
         l;
         l = g_slist_next (l)) {
        SupportsInfo *info = l->data;

        if (!info->best_plugin &&
            !info->suggested_plugin) {
            /* TODO: Cancel probing in the port if the plugin being
             * checked right now is not the one being suggested.
             */
            mm_dbg ("(%s): (%s) suggested plugin for port",
                    mm_plugin_get_name (suggested_plugin),
                    info->name);
            info->suggested_plugin = suggested_plugin;

            /* If we got a task deferred until a suggestion comes,
             * complete it */
            if (info->defer_until_suggested) {
                mm_dbg ("(%s): (%s) deferred task completed, got suggested plugin",
                        mm_plugin_get_name (suggested_plugin),
                        info->name);
                /* Schedule checking support, which will end the operation */
                info->best_plugin = info->suggested_plugin;
                info->current = NULL;
                info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle,
                                              info);
            }
        }
    }
}
static MMBaseModem *
grab_port (MMPluginBase *base,
           MMBaseModem *existing,
           MMPortProbe *probe,
           GError **error)
{
    MMBaseModem *modem = NULL;
    const gchar *name, *subsys;
    guint16 vendor = 0, product = 0;

    /* The Motorola plugin cannot do anything with non-AT ports */
    if (!mm_port_probe_is_at (probe)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_UNSUPPORTED,
                             "Ignoring non-AT port");
        return NULL;
    }

    subsys = mm_port_probe_get_port_subsys (probe);
    name = mm_port_probe_get_port_name (probe);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Could not get modem product ID");
        return NULL;
    }

    /* If this is the first port being grabbed, create a new modem object */
    if (!existing)
        modem = MM_BASE_MODEM (mm_broadband_modem_motorola_new (
                                   mm_port_probe_get_port_physdev (probe),
                                   mm_port_probe_get_port_driver (probe),
                                   mm_plugin_get_name (MM_PLUGIN (base)),
                                   vendor,
                                   product));

    if (!mm_base_modem_grab_port (existing ? existing : modem,
                                  subsys,
                                  name,
                                  MM_PORT_TYPE_AT, /* we only allow AT ports here */
                                  MM_AT_PORT_FLAG_NONE,
                                  error)) {
        if (modem)
            g_object_unref (modem);
        return NULL;
    }

    return existing ? existing : modem;
}
static MMBaseModem *
grab_port (MMPluginBase *base,
           MMBaseModem *existing,
           MMPortProbe *probe,
           GError **error)
{
    MMBaseModem *modem = NULL;
    const gchar *name, *subsys, *driver;
    guint16 vendor = 0, product = 0;

    /* The Gobi plugin only handles AT and QCDM ports (for now) */
    if (!mm_port_probe_is_at (probe) && !mm_port_probe_is_qcdm (probe)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_UNSUPPORTED,
                             "Ignoring non-AT/non-QCDM port");
        return NULL;
    }

    subsys = mm_port_probe_get_port_subsys (probe);
    name = mm_port_probe_get_port_name (probe);
    driver = mm_port_probe_get_port_driver (probe);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Could not get modem product ID");
        return NULL;
    }

    /* If this is the first port being grabbed, create a new modem object */
    if (!existing)
        modem = MM_BASE_MODEM (mm_broadband_modem_gobi_new (mm_port_probe_get_port_physdev (probe),
                                                            driver,
                                                            mm_plugin_get_name (MM_PLUGIN (base)),
                                                            vendor,
                                                            product));

    if (!mm_base_modem_grab_port (existing ? existing : modem,
                                  subsys,
                                  name,
                                  mm_port_probe_get_port_type (probe),
                                  MM_AT_PORT_FLAG_NONE,
                                  error)) {
        if (modem)
            g_object_unref (modem);
        return NULL;
    }

    return existing ? existing : modem;
}
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *sysfs_path;
    guint32 caps;
    guint16 vendor = 0, product = 0;
    MMPortType ptype;

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

    subsys = g_udev_device_get_subsystem (port);
    name = g_udev_device_get_name (port);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error (error, 0, 0, "Could not get modem product ID.");
        return NULL;
    }

    caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
    ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);
    sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
    if (!existing) {
        if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
            modem = mm_modem_wavecom_gsm_new (sysfs_path,
                                              mm_plugin_base_supports_task_get_driver (task),
                                              mm_plugin_get_name (MM_PLUGIN (base)),
                                              vendor,
                                              product);
        }

        if (modem) {
            if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error)) {
                g_object_unref (modem);
                return NULL;
            }
        }
    } else if (get_level_for_capabilities (caps)) {
        modem = existing;
        if (!mm_modem_grab_port (modem, subsys, name, ptype, MM_AT_PORT_FLAG_NONE, NULL, error))
            return NULL;
    }

    return modem;
}
static MMBaseModem *
grab_port (MMPluginBase *base,
           MMBaseModem *existing,
           MMPortProbe *probe,
           GError **error)
{
    MMBaseModem *modem = NULL;
    const gchar *name, *subsys, *driver;
    guint16 vendor = 0, product = 0;

    /* The Iridium plugin cannot do anything with non-AT ports */
    if (!mm_port_probe_is_at (probe)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_UNSUPPORTED,
                             "Ignoring non-AT port");
        return NULL;
    }

    subsys = mm_port_probe_get_port_subsys (probe);
    name = mm_port_probe_get_port_name (probe);
    driver = mm_port_probe_get_port_driver (probe);

    /* Try to get Product IDs from udev. Note that it is not an error
     * if we can't get them in our case, as we also support serial
     * modems. */
    mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product);

    /* If this is the first port being grabbed, create a new modem object */
    if (!existing)
        modem = MM_BASE_MODEM (mm_broadband_modem_iridium_new (
                                   mm_port_probe_get_port_physdev (probe),
                                   driver,
                                   mm_plugin_get_name (MM_PLUGIN (base)),
                                   vendor,
                                   product));

    if (!mm_base_modem_grab_port (existing ? existing : modem,
                                  subsys,
                                  name,
                                  MM_PORT_TYPE_AT, /* we only allow AT ports here */
                                  MM_AT_PORT_FLAG_NONE,
                                  error)) {
        if (modem)
            g_object_unref (modem);
        return NULL;
    }

    return existing ? existing : modem;
}
static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
    return MM_BASE_MODEM (mm_broadband_modem_thuraya_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
}
Exemple #12
0
static void
find_port_support_ready_cb (MMPluginManager *plugin_manager,
                            GAsyncResult *result,
                            FindPortSupportContext *ctx)
{
    GError *error = NULL;
    MMPlugin *best_plugin;

    best_plugin = mm_plugin_manager_find_port_support_finish (plugin_manager,
                                                              result,
                                                              &error);
    if (!best_plugin) {
        MMBaseModem *existing;

        if (error) {
            mm_dbg ("(%s/%s): error checking support: '%s'",
                    g_udev_device_get_subsystem (ctx->device),
                    g_udev_device_get_name (ctx->device),
                    error->message);
            g_error_free (error);
        } else {
            mm_dbg ("(%s/%s): not supported by any plugin",
                    g_udev_device_get_subsystem (ctx->device),
                    g_udev_device_get_name (ctx->device));
        }

        /* So we couldn't get a plugin for this port, we should anyway check if
         * there is already an existing modem for the physical device, and if
         * so, check if it can already be exported. */
        existing = find_modem_for_device (
            ctx->manager,
            g_udev_device_get_sysfs_path (ctx->physical_device));
        if (existing)
            check_export_modem (ctx->manager, existing);
    } else {
        mm_dbg ("(%s/%s): found plugin '%s' giving best support",
                g_udev_device_get_subsystem (ctx->device),
                g_udev_device_get_name (ctx->device),
                mm_plugin_get_name ((MMPlugin *)best_plugin));

        grab_port (ctx->manager,
                   best_plugin,
                   ctx->device,
                   ctx->physical_device);
    }

    find_port_support_context_free (ctx);
}
static gboolean
try_open (gpointer user_data)
{
    MMPluginBaseSupportsTask *task = MM_PLUGIN_BASE_SUPPORTS_TASK (user_data);
    MMPluginBaseSupportsTaskPrivate *task_priv = MM_PLUGIN_BASE_SUPPORTS_TASK_GET_PRIVATE (task);
    GError *error = NULL;

    task_priv->open_id = 0;

    if (!mm_serial_port_open (MM_SERIAL_PORT (task_priv->probe_port), &error)) {
        if (++task_priv->open_tries > 4) {
            /* took too long to open the port; give up */
            g_warning ("(%s): failed to open after 4 tries.",
                       mm_port_get_device (MM_PORT (task_priv->probe_port)));
            probe_complete (task);
        } else if (g_error_matches (error,
                                    MM_SERIAL_ERROR,
                                    MM_SERIAL_ERROR_OPEN_FAILED_NO_DEVICE)) {
            /* this is nozomi being dumb; try again */
            task_priv->open_id = g_timeout_add_seconds (1, try_open, task);
        } else {
            /* some other hard error */
            probe_complete (task);
        }
        g_clear_error (&error);
    } else {
        /* success, start probing */
        GUdevDevice *port;

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

        task_priv->full_id = g_signal_connect (task_priv->probe_port, "buffer-full",
                                               G_CALLBACK (port_buffer_full), task);

        g_debug ("(%s): probe requested by plugin '%s'",
                 g_udev_device_get_name (port),
                 mm_plugin_get_name (MM_PLUGIN (task_priv->plugin)));
        mm_serial_port_flash (MM_SERIAL_PORT (task_priv->probe_port), 100, TRUE, flash_done, task);
    }

    return FALSE;
}
static gboolean
load_plugins (MMPluginManager *self,
              GError **error)
{
    GDir *dir = NULL;
    const gchar *fname;
    MMPlugin *generic_plugin = NULL;
    gchar *plugindir_display = NULL;

	if (!g_module_supported ()) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_UNSUPPORTED,
                     "GModules are not supported on your platform!");
        goto out;
	}

    /* Get printable UTF-8 string of the path */
    plugindir_display = g_filename_display_name (PLUGINDIR);

    mm_dbg ("Looking for plugins in '%s'", plugindir_display);
    dir = g_dir_open (PLUGINDIR, 0, NULL);
    if (!dir) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_NO_PLUGINS,
                     "Plugin directory '%s' not found",
                     plugindir_display);
        goto out;
    }

    while ((fname = g_dir_read_name (dir)) != NULL) {
        gchar *path;
        MMPlugin *plugin;

        if (!g_str_has_suffix (fname, G_MODULE_SUFFIX))
            continue;

        path = g_module_build_path (PLUGINDIR, fname);
        plugin = load_plugin (path);
        g_free (path);

        if (plugin) {
            if (g_str_equal (mm_plugin_get_name (plugin),
                             MM_PLUGIN_GENERIC_NAME))
                generic_plugin = plugin;
            else
                self->priv->plugins = g_slist_append (self->priv->plugins,
                                                      plugin);
        }
    }

    /* Sort last plugins that request it */
    self->priv->plugins = g_slist_sort (self->priv->plugins,
                                        (GCompareFunc)compare_plugins);

    /* Make sure the generic plugin is last */
    if (generic_plugin)
        self->priv->plugins = g_slist_append (self->priv->plugins,
                                              generic_plugin);

    /* Treat as error if we don't find any plugin */
    if (!self->priv->plugins) {
        g_set_error (error,
                     MM_CORE_ERROR,
                     MM_CORE_ERROR_NO_PLUGINS,
                     "No plugins found in plugin directory '%s'",
                     plugindir_display);
        goto out;
    }

    /* Now report about all the found plugins, in the same order they will be
     * used while checking support */
    g_slist_foreach (self->priv->plugins, (GFunc)found_plugin, NULL);

    mm_info ("Successfully loaded %u plugins",
             g_slist_length (self->priv->plugins));

out:
    if (dir)
        g_dir_close (dir);
    g_free (plugindir_display);

    return !!self->priv->plugins;
}
static void
found_plugin (MMPlugin *plugin)
{
    mm_info ("Loaded plugin '%s'", mm_plugin_get_name (plugin));
}
static void
supports_port_ready_cb (MMPlugin *plugin,
                        GAsyncResult *result,
                        SupportsInfo *info)
{
    MMPluginSupportsResult support_result;
    GError *error = NULL;

    /* Get supports check results */
    support_result = mm_plugin_supports_port_finish (plugin,
                                                     result,
                                                     &error);
    if (error) {
        mm_warn ("(%s): (%s) error when checking support: '%s'",
                 mm_plugin_get_name (plugin),
                 info->name,
                 error->message);
        g_error_free (error);
    }

    switch (support_result) {
    case MM_PLUGIN_SUPPORTS_PORT_SUPPORTED:
        /* Found a best plugin */
        info->best_plugin = plugin;

        if (info->suggested_plugin &&
            info->suggested_plugin != plugin) {
            /* The last plugin we tried said it supported this port, but it
             * doesn't correspond with the one we're being suggested. */
            g_warn_if_reached ();
        }

        mm_dbg ("(%s): (%s) found best plugin for port",
                mm_plugin_get_name (info->best_plugin),
                info->name);
        info->current = NULL;

        /* Schedule checking support, which will end the operation */
        info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle,
                                      info);
        break;

    case MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED:
        if (info->suggested_plugin) {
            if (info->suggested_plugin == plugin) {
                /* If the plugin that just completed the support check claims
                 * not to support this port, but this plugin is clearly the
                 * right plugin since it claimed this port's physical modem,
                 * just drop the port.
                 */
                mm_dbg ("(%s/%s): ignoring port unsupported by physical modem's plugin",
                        info->subsys,
                        info->name);
                info->best_plugin = NULL;
                info->current = NULL;
            } else {
                /* The last plugin we tried is NOT the one we got suggested, so
                 * directly check support with the suggested plugin. If we
                 * already checked its support, it won't be checked again. */
                info->current = g_slist_find (info->current,
                                              info->suggested_plugin);
            }
        } else {
            /* If the plugin knows it doesn't support the modem, just keep on
             * checking the next plugin.
             */
            info->current = g_slist_next (info->current);
        }
        info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle,
                                      info);
        break;

    case MM_PLUGIN_SUPPORTS_PORT_DEFER:
        /* Try with the suggested one after being deferred */
        if (info->suggested_plugin) {
            mm_dbg ("(%s): (%s) deferring support check, suggested: %s",
                    mm_plugin_get_name (MM_PLUGIN (info->current->data)),
                    info->name,
                    mm_plugin_get_name (MM_PLUGIN (info->suggested_plugin)));
            info->current = g_slist_find (info->current,
                                          info->suggested_plugin);
        } else {
            mm_dbg ("(%s): (%s) deferring support check",
                    mm_plugin_get_name (MM_PLUGIN (info->current->data)),
                    info->name);
        }
        /* Schedule checking support */
        info->source_id = g_timeout_add_seconds (SUPPORTS_DEFER_TIMEOUT_SECS,
                                                 (GSourceFunc)find_port_support_idle,
                                                 info);
        break;

    case MM_PLUGIN_SUPPORTS_PORT_DEFER_UNTIL_SUGGESTED:
        /* If we arrived here and we already have a plugin suggested, use it */
        if (info->suggested_plugin) {
            mm_dbg ("(%s): (%s) task completed, got suggested plugin",
                    mm_plugin_get_name (info->suggested_plugin),
                    info->name);
            /* Schedule checking support, which will end the operation */
            info->best_plugin = info->suggested_plugin;
            info->current = NULL;
            info->source_id = g_idle_add ((GSourceFunc)find_port_support_idle,
                                          info);
        } else {
            /* We are deferred until a suggested plugin is given. If last supports task
             * of a given device is finished without finding a best plugin, this task
             * will get finished reporting unsupported. */
            mm_dbg ("(%s) deferring support check until result suggested",
                    info->name);
            info->defer_until_suggested = TRUE;
        }
        break;
    }
}
Exemple #17
0
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *sysfs_path;
    guint32 caps;
    MMPortType ptype;
    MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE;
    guint16 vendor = 0, product = 0;

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

    /* Look for port type hints */
    if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_MODEM"))
        pflags = MM_AT_PORT_FLAG_PRIMARY;
    else if (g_udev_device_get_property_as_boolean (port, "ID_MM_ZTE_PORT_TYPE_AUX"))
        pflags = MM_AT_PORT_FLAG_SECONDARY;

    subsys = g_udev_device_get_subsystem (port);
    name = g_udev_device_get_name (port);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error (error, 0, 0, "Could not get modem product ID.");
        return NULL;
    }

    caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
    sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
    ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);
    if (!existing) {
        if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
            modem = mm_modem_zte_new (sysfs_path,
                                      mm_plugin_base_supports_task_get_driver (task),
                                      mm_plugin_get_name (MM_PLUGIN (base)),
                                      vendor,
                                      product);
        } else if (caps & CAP_CDMA) {
            modem = mm_generic_cdma_new (sysfs_path,
                                         mm_plugin_base_supports_task_get_driver (task),
                                         mm_plugin_get_name (MM_PLUGIN (base)),
                                         !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856),
                                         !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856_A),
                                         vendor,
                                         product);
        }

        if (modem) {
            if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) {
                g_object_unref (modem);
                return NULL;
            }
        }
    } else if (get_level_for_capabilities (caps) || (!strcmp (subsys, "net"))) {
        modem = existing;
        if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error))
            return NULL;
    }

    return modem;
}
Exemple #18
0
static MMBaseModem *
create_modem (MMPlugin *self,
              const gchar *sysfs_path,
              const gchar **drivers,
              guint16 vendor,
              guint16 product,
              GList *probes,
              GError **error)
{
    /* Note: at this point we don't make any difference between different
     * Dell-branded QMI or MBIM modems; they may come from Novatel, Ericsson or
     * Sierra. */

#if defined WITH_QMI
    if (mm_port_probe_list_has_qmi_port (probes)) {
        mm_dbg ("QMI-powered Dell-branded modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_qmi_new (sysfs_path,
                                                          drivers,
                                                          mm_plugin_get_name (self),
                                                          vendor,
                                                          product));
    }
#endif

#if defined WITH_MBIM
    if (mm_port_probe_list_has_mbim_port (probes)) {
        mm_dbg ("MBIM-powered Dell-branded modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_mbim_new (sysfs_path,
                                                           drivers,
                                                           mm_plugin_get_name (self),
                                                           vendor,
                                                           product));
    }
#endif

    if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_NOVATEL)) {
        mm_dbg ("Novatel-powered Dell-branded modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_novatel_new (sysfs_path,
                                                              drivers,
                                                              mm_plugin_get_name (self),
                                                              vendor,
                                                              product));
    }

    if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_SIERRA)) {
        mm_dbg ("Sierra-powered Dell-branded modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_sierra_new (sysfs_path,
                                                             drivers,
                                                             mm_plugin_get_name (self),
                                                             vendor,
                                                             product));
    }

    if (port_probe_list_has_manufacturer_port (probes, DELL_MANUFACTURER_TELIT)) {
        mm_dbg ("Telit-powered Dell-branded modem found...");
        return MM_BASE_MODEM (mm_broadband_modem_telit_new (sysfs_path,
                                                            drivers,
                                                            mm_plugin_get_name (self),
                                                            vendor,
                                                            product));
    }

    mm_dbg ("Dell-branded generic modem found...");
    return MM_BASE_MODEM (mm_broadband_modem_new (sysfs_path,
                                                  drivers,
                                                  mm_plugin_get_name (self),
                                                  vendor,
                                                  product));
}
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *devfile, *sysfs_path;
    guint32 caps;
    guint16 vendor = 0, product = 0;
    MMPortType ptype;
    int usbif;
    MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE;

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

    devfile = g_udev_device_get_device_file (port);
    if (!devfile) {
        g_set_error (error, 0, 0, "Could not get port's sysfs file.");
        return NULL;
    }

    subsys = g_udev_device_get_subsystem (port);
    name = g_udev_device_get_name (port);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error (error, 0, 0, "Could not get modem product ID.");
        return NULL;
    }

    usbif = g_udev_device_get_property_as_int (port, "ID_USB_INTERFACE_NUM");
    if (usbif < 0) {
        g_set_error (error, 0, 0, "Could not get USB device interface number.");
        return NULL;
    }

    caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
    ptype = mm_plugin_base_probed_capabilities_to_port_type (caps);

    if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (base), TAG_HUAWEI_PCUI_PORT)))
        pflags = MM_AT_PORT_FLAG_PRIMARY;
    else if (usbif + 1 == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (base), TAG_HUAWEI_MODEM_PORT)))
        pflags = MM_AT_PORT_FLAG_PPP;
    else if (!g_object_get_data (G_OBJECT (base), TAG_GETPORTMODE_SUPPORTED)) {
        /* If GETPORTMODE is not supported, we assume usbif 0 is the modem port */
        if ((usbif == 0) && (ptype == MM_PORT_TYPE_AT)) {
            pflags = MM_AT_PORT_FLAG_PPP;

            /* For CDMA modems we assume usbif0 is both primary and PPP, since
             * they don't have problems with talking on secondary ports.
             */
            if (caps & CAP_CDMA)
                pflags |= MM_AT_PORT_FLAG_PRIMARY;
        }
    }

    sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
    if (!existing) {
        if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
            modem = mm_modem_huawei_gsm_new (sysfs_path,
                                             mm_plugin_base_supports_task_get_driver (task),
                                             mm_plugin_get_name (MM_PLUGIN (base)),
                                             vendor,
                                             product);
        } else if (caps & CAP_CDMA) {
            modem = mm_modem_huawei_cdma_new (sysfs_path,
                                              mm_plugin_base_supports_task_get_driver (task),
                                              mm_plugin_get_name (MM_PLUGIN (base)),
                                              !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856),
                                              !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856_A),
                                              vendor,
                                              product);
        }

        if (modem) {
            if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error)) {
                g_object_unref (modem);
                return NULL;
            }
        }
    } else {
        modem = existing;
        if (!mm_modem_grab_port (modem, subsys, name, ptype, pflags, NULL, error))
            return NULL;
    }

    return modem;
}
static MMBaseModem *
grab_port (MMPluginBase *base,
           MMBaseModem *existing,
           MMPortProbe *probe,
           GError **error)
{
    MMBaseModem *modem = NULL;
    GUdevDevice *port;
    MMPortType ptype;
    const gchar *name, *subsys;
    guint16 vendor = 0, product = 0;
    MMAtPortFlag pflags = MM_AT_PORT_FLAG_NONE;

    /* The Simtech plugin cannot do anything with non-AT non-QCDM ports */
    if (!mm_port_probe_is_at (probe) &&
        !mm_port_probe_is_qcdm (probe)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_UNSUPPORTED,
                             "Ignoring non-AT non-QCDM port");
        return NULL;
    }

    port = mm_port_probe_get_port (probe); /* transfer none */
    subsys = mm_port_probe_get_port_subsys (probe);
    name = mm_port_probe_get_port_name (probe);

    if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
        g_set_error_literal (error,
                             MM_CORE_ERROR,
                             MM_CORE_ERROR_FAILED,
                             "Could not get modem product ID");
        return NULL;
    }

    /* Look for port type hints; just probing can't distinguish which port should
     * be the data/primary port on these devices.  We have to tag them based on
     * what the Windows .INF files say the port layout should be.
     */
    if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_MODEM"))
        pflags = MM_AT_PORT_FLAG_PRIMARY;
    else if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_AUX"))
        pflags = MM_AT_PORT_FLAG_SECONDARY;

    /* If the port was tagged by the udev rules but isn't a primary or secondary,
     * then ignore it to guard against race conditions if a device just happens
     * to show up with more than two AT-capable ports.
     */
    if (pflags == MM_AT_PORT_FLAG_NONE &&
        g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_TAGGED"))
        ptype = MM_PORT_TYPE_IGNORED;
    else
        ptype = mm_port_probe_get_port_type (probe);

    /* If this is the first port being grabbed, create a new modem object */
    if (!existing)
        modem = MM_BASE_MODEM (mm_broadband_modem_simtech_new (mm_port_probe_get_port_physdev (probe),
                                                               mm_port_probe_get_port_driver (probe),
                                                               mm_plugin_get_name (MM_PLUGIN (base)),
                                                               vendor,
                                                               product));

    if (!mm_base_modem_grab_port (existing ? existing : modem,
                                  subsys,
                                  name,
                                  ptype,
                                  pflags,
                                  error)) {
        if (modem)
            g_object_unref (modem);
        return NULL;
    }

    return existing ? existing : modem;
}
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *sysfs_path;
    guint32 caps;
    MMPortType ptype = MM_PORT_TYPE_UNKNOWN;

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

    /* Look for port type hints; just probing can't distinguish which port should
     * be the data/primary port on these devices.  We have to tag them based on
     * what the Windows .INF files say the port layout should be.
     */
    if (g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_PORT_TYPE_MODEM"))
        ptype = MM_PORT_TYPE_PRIMARY;
    else if (g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_PORT_TYPE_AUX"))
        ptype = MM_PORT_TYPE_SECONDARY;

    /* If the device was tagged by the udev rules, then ignore any other ports
     * to guard against race conditions if a device just happens to show up
     * with more than two AT-capable ports.
     */
    if (   (ptype == MM_PORT_TYPE_UNKNOWN)
        && g_udev_device_get_property_as_boolean (port, "ID_MM_LONGCHEER_TAGGED"))
        ptype = MM_PORT_TYPE_IGNORED;

    subsys = g_udev_device_get_subsystem (port);
    name = g_udev_device_get_name (port);

    caps = mm_plugin_base_supports_task_get_probed_capabilities (task);
    sysfs_path = mm_plugin_base_supports_task_get_physdev_path (task);
    if (!existing) {
        if (caps & MM_PLUGIN_BASE_PORT_CAP_GSM) {
            modem = mm_modem_longcheer_gsm_new (sysfs_path,
                                                mm_plugin_base_supports_task_get_driver (task),
                                                mm_plugin_get_name (MM_PLUGIN (base)));
        } else if (caps & CAP_CDMA) {
            modem = mm_generic_cdma_new (sysfs_path,
                                         mm_plugin_base_supports_task_get_driver (task),
                                         mm_plugin_get_name (MM_PLUGIN (base)),
                                         !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856),
                                         !!(caps & MM_PLUGIN_BASE_PORT_CAP_IS856_A));
        }

        if (modem) {
            if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error)) {
                g_object_unref (modem);
                return NULL;
            }
        }
    } else if (get_level_for_capabilities (caps)) {
        if (caps & MM_PLUGIN_BASE_PORT_CAP_QCDM)
            ptype = MM_PORT_TYPE_QCDM;

        modem = existing;
        if (!mm_modem_grab_port (modem, subsys, name, ptype, NULL, error))
            return NULL;
    }

    return modem;
}