static gboolean
handle_set_profile (MmGdbusTest *skeleton,
                    GDBusMethodInvocation *invocation,
                    const gchar *id,
                    const gchar *plugin_name,
                    const gchar *const *ports,
                    MMBaseManager *self)
{
    MMPlugin *plugin;
    MMDevice *device;
    gchar *physdev;
    GError *error = NULL;

    mm_info ("Test profile set to: '%s'", id);

    /* Create device and keep it listed in the Manager */
    physdev = g_strdup_printf ("/virtual/%s", id);
    device = mm_device_virtual_new (physdev, TRUE);
    g_hash_table_insert (self->priv->devices, physdev, device);

    /* Grab virtual ports */
    mm_device_virtual_grab_ports (device, (const gchar **)ports);

    /* Set plugin to use */
    plugin = mm_plugin_manager_peek_plugin (self->priv->plugin_manager, plugin_name);
    if (!plugin) {
        error = g_error_new (MM_CORE_ERROR,
                             MM_CORE_ERROR_NOT_FOUND,
                             "Requested plugin '%s' not found",
                             plugin_name);
        mm_warn ("Couldn't set plugin for virtual device at '%s': %s",
                 mm_device_get_path (device),
                 error->message);
        goto out;
    }
    mm_device_set_plugin (device, G_OBJECT (plugin));

    /* Create modem */
    if (!mm_device_create_modem (device, self->priv->object_manager, &error)) {
        mm_warn ("Couldn't create modem for virtual device at '%s': %s",
                 mm_device_get_path (device),
                 error->message);
        goto out;
    }

    mm_info ("Modem for virtual device at '%s' successfully created",
             mm_device_get_path (device));

out:

    if (error) {
        mm_device_remove_modem (device);
        g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
        g_dbus_method_invocation_return_gerror (invocation, error);
        g_error_free (error);
    } else
        mm_gdbus_test_complete_set_profile (skeleton, invocation);

    return TRUE;
}
static void
device_support_check_ready (MMPluginManager          *plugin_manager,
                            GAsyncResult             *res,
                            FindDeviceSupportContext *ctx)
{
    GError   *error = NULL;
    MMPlugin *plugin;

    /* Receive plugin result from the plugin manager */
    plugin = mm_plugin_manager_device_support_check_finish (plugin_manager, res, &error);
    if (!plugin) {
        mm_info ("Couldn't check support for device at '%s': %s",
                 mm_device_get_path (ctx->device), error->message);
        g_error_free (error);
        find_device_support_context_free (ctx);
        return;
    }

    /* Set the plugin as the one expected in the device */
    mm_device_set_plugin (ctx->device, G_OBJECT (plugin));
    g_object_unref (plugin);

    if (!mm_device_create_modem (ctx->device, ctx->self->priv->object_manager, &error)) {
        mm_warn ("Couldn't create modem for device at '%s': %s",
                 mm_device_get_path (ctx->device), error->message);
        g_error_free (error);
        find_device_support_context_free (ctx);
        return;
    }

    /* Modem now created */
    mm_info ("Modem for device at '%s' successfully created",
             mm_device_get_path (ctx->device));
    find_device_support_context_free (ctx);
}
static void
device_removed (MMBaseManager *self,
                GUdevDevice *udev_device)
{
    MMDevice *device;
    const gchar *subsys;
    const gchar *name;

    g_return_if_fail (udev_device != NULL);

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

    if (!g_str_has_prefix (subsys, "usb") ||
        (name && g_str_has_prefix (name, "cdc-wdm"))) {
        /* Handle tty/net/wdm port removal */
        device = find_device_by_port (self, udev_device);
        if (device) {
            mm_info ("(%s/%s): released by modem %s",
                     subsys,
                     name,
                     g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
            mm_device_release_port (device, udev_device);

            /* If port probe list gets empty, remove the device object iself */
            if (!mm_device_peek_port_probe_list (device)) {
                mm_dbg ("Removing empty device '%s'", mm_device_get_path (device));
                if (mm_plugin_manager_device_support_check_cancel (self->priv->plugin_manager, device))
                    mm_dbg ("Device support check has been cancelled");
                mm_device_remove_modem (device);
                g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
            }
        }

        return;
    }

    /* This case is designed to handle the case where, at least with kernel 2.6.31, unplugging
     * an in-use ttyACMx device results in udev generating remove events for the usb, but the
     * ttyACMx device (subsystem tty) is not removed, since it was in-use.  So if we have not
     * found a modem for the port (above), we're going to look here to see if we have a modem
     * associated with the newly removed device.  If so, we'll remove the modem, since the
     * device has been removed.  That way, if the device is reinserted later, we'll go through
     * the process of exporting it.
     */
    device = find_device_by_udev_device (self, udev_device);
    if (device) {
        mm_dbg ("Removing device '%s'", mm_device_get_path (device));
        mm_device_remove_modem (device);
        g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
        return;
    }

    /* Maybe a plugin is checking whether or not the port is supported.
     * TODO: Cancel every possible supports check in this port. */
}
Exemple #4
0
static void
find_device_support_ready (MMPluginManager *plugin_manager,
                           GAsyncResult *result,
                           FindDeviceSupportContext *ctx)
{
    GError *error = NULL;

    if (!mm_plugin_manager_find_device_support_finish (plugin_manager, result, &error)) {
        mm_warn ("Couldn't find support for device at '%s': %s",
                 mm_device_get_path (ctx->device),
                 error->message);
        g_error_free (error);
    } else if (!mm_device_create_modem (ctx->device, ctx->self->priv->object_manager, &error)) {
        mm_warn ("Couldn't create modem for device at '%s': %s",
                 mm_device_get_path (ctx->device),
                 error->message);
        g_error_free (error);
    } else {
        mm_info ("Modem for device at '%s' successfully created",
                 mm_device_get_path (ctx->device));
    }

    find_device_support_context_free (ctx);
}
Exemple #5
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;
}