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. */ }
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); }
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; }