/** * udisks_daemon_util_block_get_size: * @device: A #GUdevDevice for a top-level block device. * @out_media_available: (out): Return location for whether media is available or %NULL. * @out_media_change_detected: (out): Return location for whether media change is detected or %NULL. * * Gets the size of the @device top-level block device, checking for media in the process * * Returns: The size of @device or 0 if no media is available or if unknown. */ guint64 udisks_daemon_util_block_get_size (GUdevDevice *device, gboolean *out_media_available, gboolean *out_media_change_detected) { gboolean media_available = FALSE; gboolean media_change_detected = TRUE; guint64 size = 0; /* figuring out if media is available is a bit tricky */ if (g_udev_device_get_sysfs_attr_as_boolean (device, "removable")) { /* never try to open optical drives (might cause the door to close) or * floppy drives (makes noise) */ if (g_udev_device_get_property_as_boolean (device, "ID_DRIVE_FLOPPY")) { /* assume media available */ media_available = TRUE; media_change_detected = FALSE; } else if (g_udev_device_get_property_as_boolean (device, "ID_CDROM")) { /* Rely on (careful) work already done by udev's cdrom_id prober */ if (g_udev_device_get_property_as_boolean (device, "ID_CDROM_MEDIA")) media_available = TRUE; } else { gint fd; /* For the general case, just rely on open(2) failing with * ENOMEDIUM if no medium is inserted */ fd = open (g_udev_device_get_device_file (device), O_RDONLY); if (fd >= 0) { media_available = TRUE; close (fd); } } } else { /* not removable, so media is implicitly available */ media_available = TRUE; } if (media_available && size == 0 && media_change_detected) size = g_udev_device_get_sysfs_attr_as_uint64 (device, "size") * 512; if (out_media_available != NULL) *out_media_available = media_available; if (out_media_change_detected != NULL) *out_media_change_detected = media_change_detected; return size; }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; GUdevDevice *port; MMPortType port_type; port_type = mm_port_probe_get_port_type (probe); port = mm_port_probe_peek_port (probe); if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_AT_PORT")) { mm_dbg ("(%s/%s)' Port flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_MODEM_PORT")) { mm_dbg ("(%s/%s) Port flagged as PPP", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PPP; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_GPS_PORT")) { mm_dbg ("(%s/%s) Port flagged as GPS", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); port_type = MM_PORT_TYPE_GPS; } else { gchar *str; pflags = (MMPortSerialAtFlag) GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (probe), TAG_AT_PORT_FLAGS)); str = mm_port_serial_at_flag_build_string_from_mask (pflags); mm_dbg ("(%s/%s) Port will have AT flags '%s'", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), str); g_free (str); } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), port_type, pflags, error); }
static void telit_custom_init (MMPortProbe *probe, MMPortSerialAt *port, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { MMDevice *device; GUdevDevice *udevDevice; TelitCustomInitContext *ctx; device = mm_port_probe_peek_device (probe); udevDevice = mm_port_probe_peek_port (probe); ctx = g_slice_new (TelitCustomInitContext); ctx->result = g_simple_async_result_new (G_OBJECT (probe), callback, user_data, telit_custom_init); ctx->probe = g_object_ref (probe); ctx->port = g_object_ref (port); ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; ctx->getportcfg_done = FALSE; ctx->getportcfg_retries = 3; /* If the device is tagged for supporting #PORTCFG do the custom init */ if (g_udev_device_get_property_as_boolean (udevDevice, "ID_MM_TELIT_PORTS_TAGGED")) { telit_custom_init_step (ctx); return; } g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); telit_custom_init_context_complete_and_free (ctx); }
static void dell_custom_init (MMPortProbe *probe, MMPortSerialAt *port, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { CustomInitContext *ctx; GUdevDevice *udevDevice; udevDevice = mm_port_probe_peek_port (probe); ctx = g_slice_new0 (CustomInitContext); ctx->result = g_simple_async_result_new (G_OBJECT (probe), callback, user_data, dell_custom_init); ctx->probe = g_object_ref (probe); ctx->port = g_object_ref (port); ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; ctx->gmi_retries = 3; ctx->cgmi_retries = 3; ctx->ati_retries = 3; /* Dell-branded Telit modems always answer to +GMI * Avoid +CGMI and ATI sending for minimizing port probing time */ if (g_udev_device_get_property_as_boolean (udevDevice, "ID_MM_TELIT_PORTS_TAGGED")) { ctx->cgmi_retries = 0; ctx->ati_retries = 0; } custom_init_step (ctx); }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { GUdevDevice *port; MMPortType ptype; MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; port = mm_port_probe_peek_port (probe); ptype = mm_port_probe_get_port_type (probe); if (mm_port_probe_is_at (probe)) { /* 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")) { mm_dbg ("Simtech: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_PORT_TYPE_AUX")) { mm_dbg ("Simtech: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_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_PORT_SERIAL_AT_FLAG_NONE && g_udev_device_get_property_as_boolean (port, "ID_MM_SIMTECH_TAGGED")) ptype = MM_PORT_TYPE_IGNORED; } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), ptype, pflags, error); }
/* called with lock held */ static void handle_block_uevent (UDisksLinuxProvider *provider, const gchar *action, UDisksLinuxDevice *device) { /* We use the sysfs block device for all of * * - UDisksLinuxDriveObject * - UDisksLinuxMDRaidObject * - UDisksLinuxBlockObject * * objects. Ensure that drive and mdraid objects are added before * and removed after block objects. */ if (g_strcmp0 (action, "remove") == 0) { handle_block_uevent_for_block (provider, action, device); handle_block_uevent_for_drive (provider, action, device); handle_block_uevent_for_mdraid (provider, action, device); } else { if (g_udev_device_get_property_as_boolean (device->udev_device, "DM_UDEV_DISABLE_OTHER_RULES_FLAG")) { /* Ignore the uevent if the device-mapper layer requests * that other rules ignore this uevent * * It's somewhat nasty to do this but it avoids all kinds of * race-conditions caused by the design of device-mapper * (such as temporary-cryptsetup nodes and cleartext devices * without ID_FS properties properly set). */ } else { handle_block_uevent_for_mdraid (provider, action, device); handle_block_uevent_for_drive (provider, action, device); handle_block_uevent_for_block (provider, action, device); } } if (g_strcmp0 (action, "add") != 0) { /* Possibly need to clean up */ udisks_state_check (udisks_daemon_get_state (udisks_provider_get_daemon (UDISKS_PROVIDER (provider)))); } }
/* Overriding SUBSYSTEM isn't allowed in udev (works sometimes, but not * always). For evemu devices we need to set custom properties to make them * detected by libwacom. */ static char * get_uinput_subsystem (GUdevDevice *device) { const char *bus_str; GUdevDevice *parent; bus_str = NULL; parent = g_object_ref (device); while (parent && !g_udev_device_get_property_as_boolean (parent, "UINPUT_DEVICE")) { GUdevDevice *old_parent = parent; parent = g_udev_device_get_parent (old_parent); g_object_unref (old_parent); } if (parent) { bus_str = g_udev_device_get_property (parent, "UINPUT_SUBSYSTEM"); g_object_unref (parent); } return bus_str ? g_strdup (bus_str) : NULL; }
static void device_added (MMBaseManager *manager, GUdevDevice *port, gboolean hotplugged, gboolean manual_scan) { MMDevice *device; const char *subsys, *name, *physdev_path, *physdev_subsys; gboolean is_candidate; GUdevDevice *physdev = NULL; g_return_if_fail (port != NULL); subsys = g_udev_device_get_subsystem (port); name = g_udev_device_get_name (port); /* ignore VTs */ if (strncmp (name, "tty", 3) == 0 && isdigit (name[3])) return; /* Ignore devices that aren't completely configured by udev yet. If * ModemManager is started in parallel with udev, explicitly requesting * devices may return devices for which not all udev rules have yet been * applied (a bug in udev/gudev). Since we often need those rules to match * the device to a specific ModemManager driver, we need to ensure that all * rules have been processed before handling a device. */ is_candidate = g_udev_device_get_property_as_boolean (port, "ID_MM_CANDIDATE"); if (!is_candidate) { /* This could mean that device changed, loosing its ID_MM_CANDIDATE * flags (such as Bluetooth RFCOMM devices upon disconnect. * Try to forget it. */ if (hotplugged && !manual_scan) device_removed (manager, port); return; } if (find_device_by_port (manager, port)) return; /* Find the port's physical device's sysfs path. This is the kernel device * that "owns" all the ports of the device, like the USB device or the PCI * device the provides each tty or network port. */ physdev = find_physical_device (port); if (!physdev) { /* Warn about it, but filter out some common ports that we know don't have * anything to do with mobile broadband. */ if ( strcmp (name, "console") && strcmp (name, "ptmx") && strcmp (name, "lo") && strcmp (name, "tty") && !strstr (name, "virbr")) mm_dbg ("(%s/%s): could not get port's parent device", subsys, name); goto out; } /* Is the device blacklisted? */ if (g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_IGNORE")) { mm_dbg ("(%s/%s): port's parent device is blacklisted", subsys, name); goto out; } /* Is the device in the manual-only greylist? If so, return if this is an * automatic scan. */ if (!manual_scan && g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_MANUAL_SCAN_ONLY")) { mm_dbg ("(%s/%s): port probed only in manual scan", subsys, name); goto out; } /* If the physdev is a 'platform' or 'pnp' device that's not whitelisted, ignore it */ physdev_subsys = g_udev_device_get_subsystem (physdev); if ( physdev_subsys && ( g_str_equal (physdev_subsys, "platform") || g_str_equal (physdev_subsys, "pnp")) && !g_udev_device_get_property_as_boolean (physdev, "ID_MM_PLATFORM_DRIVER_PROBE")) { mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); goto out; } physdev_path = g_udev_device_get_sysfs_path (physdev); if (!physdev_path) { mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name); goto out; } /* See if we already created an object to handle ports in this device */ device = find_device_by_sysfs_path (manager, physdev_path); if (!device) { FindDeviceSupportContext *ctx; /* Keep the device listed in the Manager */ device = mm_device_new (physdev, hotplugged); g_hash_table_insert (manager->priv->devices, g_strdup (physdev_path), device); /* Launch device support check */ ctx = g_slice_new (FindDeviceSupportContext); ctx->self = g_object_ref (manager); ctx->device = g_object_ref (device); mm_plugin_manager_device_support_check ( manager->priv->plugin_manager, device, (GAsyncReadyCallback) device_support_check_ready, ctx); } /* Grab the port in the existing device. */ mm_device_grab_port (device, port); out: if (physdev) g_object_unref (physdev); }
void tvm_usb_device_added (TvmContext *context) { const gchar *icon; const gchar *summary; const gchar *message; const gchar *driver; const gchar *enabled_property = NULL; const gchar *command_property = NULL; gboolean enabled; gboolean is_camera; gchar *command; g_return_if_fail (context != NULL); /* collect device information */ driver = g_udev_device_get_property (context->device, "DRIVER"); is_camera = g_udev_device_get_property_as_boolean (context->device, "ID_GPHOTO2"); if (is_camera) { enabled_property = "/autophoto/enabled"; command_property = "/autophoto/command"; icon = "camera-photo"; summary = _("Camera detected"); message = _("A photo camera was detected"); } else if (g_strcmp0 (driver, "usblp") == 0) { enabled_property = "/autoprinter/enabled"; command_property = "/autoprinter/command"; icon = "printer"; summary = _("Printer detected"); message = _("A USB printer was detected"); } /* check if we have a device that we support */ if (enabled_property != NULL && command_property != NULL) { /* check whether handling the printer or whatever is enabled */ enabled = xfconf_channel_get_bool (context->channel, enabled_property, FALSE); if (enabled) { #ifdef HAVE_LIBNOTIFY /* display a detection notification */ tvm_notify (icon, summary, message); #endif /* fetch the command for the input device type and try to run it */ command = xfconf_channel_get_string (context->channel, command_property, NULL); if (command != NULL && *command != '\0') { tvm_run_command (context, NULL, command, context->error); } g_free (command); } } else { /* return an error because we cannot handle the usb device */ g_set_error (context->error, G_FILE_ERROR, G_FILE_ERROR_FAILED, _("Unsupported USB device type \"%s\""), driver); } /* finish processing the device */ tvm_device_handler_finished (context); }
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; }
static gboolean grab_port (MMPlugin *self, MMBaseModem *modem, MMPortProbe *probe, GError **error) { GUdevDevice *port; MMDevice *device; MMPortType ptype; MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; port = mm_port_probe_peek_port (probe); ptype = mm_port_probe_get_port_type (probe); device = mm_port_probe_peek_device (probe); /* 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 no udev rules are found, AT#PORTCFG (if supported) can be used for * identifying the port layout */ if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_MODEM_PORT)) { mm_dbg ("telit: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_AUX_PORT)) { mm_dbg ("telit: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; } else if (g_udev_device_get_property_as_boolean (port, TAG_TELIT_NMEA_PORT)) { mm_dbg ("telit: port '%s/%s' flagged as NMEA", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); ptype = MM_PORT_TYPE_GPS; } else if (g_object_get_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED) != NULL) { if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT)) == 0) { mm_dbg ("telit: AT port '%s/%s' flagged as primary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; } else if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_AUX_PORT)) == 0) { mm_dbg ("telit: AT port '%s/%s' flagged as secondary", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; } else if (g_strcmp0 (g_udev_device_get_property (port, "ID_USB_INTERFACE_NUM"), g_object_get_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT)) == 0) { mm_dbg ("telit: port '%s/%s' flagged as NMEA", mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); ptype = MM_PORT_TYPE_GPS; } else ptype = MM_PORT_TYPE_IGNORED; } else { /* 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. */ ptype = MM_PORT_TYPE_IGNORED; } return mm_base_modem_grab_port (modem, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe), mm_port_probe_get_parent_path (probe), ptype, pflags, error); }
static gboolean is_tablet_or_touchpad (GUdevDevice *device) { return g_udev_device_get_property_as_boolean (device, "ID_INPUT_TABLET") || g_udev_device_get_property_as_boolean (device, "ID_INPUT_TOUCHPAD"); }
static RBSource * create_source_device_cb (RBRemovableMediaManager *rmm, GObject *device_obj, RBMtpPlugin *plugin) { GUdevDevice *device = G_UDEV_DEVICE (device_obj); LIBMTP_device_entry_t *device_list; int numdevs; int vendor; int model; int busnum; int devnum; int i; /* check subsystem == usb? */ if (g_strcmp0 (g_udev_device_get_subsystem (device), "usb") != 0) { rb_debug ("device %s is not a USB device", g_udev_device_get_name (device)); return NULL; } /* check that it's not an iPhone or iPod Touch */ if (g_udev_device_get_property_as_boolean (device, "USBMUX_SUPPORTED")) { rb_debug ("device %s is supported through AFC, ignore", g_udev_device_get_name (device)); return NULL; } /* get device info */ vendor = get_property_as_int (device, "ID_VENDOR_ID", 16); model = get_property_as_int (device, "ID_MODEL_ID", 16); busnum = get_property_as_int (device, "BUSNUM", 10); devnum = get_property_as_int (device, "DEVNUM", 10); if (vendor == 0 || model == 0) { rb_debug ("couldn't get vendor or model ID for device (%x:%x)", vendor, model); return NULL; } rb_debug ("matching device %x:%x against libmtp device list", vendor, model); LIBMTP_Get_Supported_Devices_List(&device_list, &numdevs); for (i = 0; i < numdevs; i++) { if (device_list[i].vendor_id == vendor && device_list[i].product_id == model) { LIBMTP_raw_device_t rawdevice; RBSource *source; RBShell *shell; rb_debug ("found libmtp device list entry (model: %s, vendor: %s)", device_list[i].vendor, device_list[i].product); rawdevice.device_entry = device_list[i]; rawdevice.bus_location = busnum; rawdevice.devnum = devnum; g_object_get (plugin, "object", &shell, NULL); source = rb_mtp_source_new (shell, G_OBJECT (plugin), device, &rawdevice); plugin->mtp_sources = g_list_prepend (plugin->mtp_sources, source); g_signal_connect_object (G_OBJECT (source), "deleted", G_CALLBACK (source_deleted_cb), plugin, 0); g_object_unref (shell); return source; } } rb_debug ("device didn't match anything"); return NULL; }
static void device_added (MMManager *manager, GUdevDevice *device) { const char *subsys, *name, *physdev_path, *physdev_subsys; gboolean is_candidate; GUdevDevice *physdev = NULL; MMPlugin *plugin; MMBaseModem *existing; g_return_if_fail (device != NULL); subsys = g_udev_device_get_subsystem (device); name = g_udev_device_get_name (device); /* ignore VTs */ if (strncmp (name, "tty", 3) == 0 && isdigit (name[3])) return; /* Ignore devices that aren't completely configured by udev yet. If * ModemManager is started in parallel with udev, explicitly requesting * devices may return devices for which not all udev rules have yet been * applied (a bug in udev/gudev). Since we often need those rules to match * the device to a specific ModemManager driver, we need to ensure that all * rules have been processed before handling a device. */ is_candidate = g_udev_device_get_property_as_boolean (device, "ID_MM_CANDIDATE"); if (!is_candidate) return; if (find_modem_for_port (manager, subsys, name)) return; /* Find the port's physical device's sysfs path. This is the kernel device * that "owns" all the ports of the device, like the USB device or the PCI * device the provides each tty or network port. */ physdev = find_physical_device (device); if (!physdev) { /* Warn about it, but filter out some common ports that we know don't have * anything to do with mobile broadband. */ if ( strcmp (name, "console") && strcmp (name, "ptmx") && strcmp (name, "lo") && strcmp (name, "tty") && !strstr (name, "virbr")) mm_dbg ("(%s/%s): could not get port's parent device", subsys, name); goto out; } /* Is the device blacklisted? */ if (g_udev_device_get_property_as_boolean (physdev, "ID_MM_DEVICE_IGNORE")) { mm_dbg ("(%s/%s): port's parent device is blacklisted", subsys, name); goto out; } /* If the physdev is a 'platform' device that's not whitelisted, ignore it */ physdev_subsys = g_udev_device_get_subsystem (physdev); if ( physdev_subsys && !strcmp (physdev_subsys, "platform") && !g_udev_device_get_property_as_boolean (physdev, "ID_MM_PLATFORM_DRIVER_PROBE")) { mm_dbg ("(%s/%s): port's parent platform driver is not whitelisted", subsys, name); goto out; } physdev_path = g_udev_device_get_sysfs_path (physdev); if (!physdev_path) { mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name); goto out; } /* Already launched the same port support check? */ if (mm_plugin_manager_is_finding_port_support (manager->priv->plugin_manager, subsys, name, physdev_path)) { mm_dbg ("(%s/%s): support check already requested in port", subsys, name); goto out; } /* If this port's physical modem is already owned by a plugin, don't bother * asking all plugins whether they support this port, just let the owning * plugin check if it supports the port. */ existing = find_modem_for_device (manager, physdev_path); plugin = (existing ? MM_PLUGIN (g_object_get_data (G_OBJECT (existing), MANAGER_PLUGIN_TAG)) : NULL); /* Launch supports check in the Plugin Manager */ mm_plugin_manager_find_port_support ( manager->priv->plugin_manager, subsys, name, physdev_path, plugin, existing, (GAsyncReadyCallback)find_port_support_ready_cb, find_port_support_context_new (manager, device, physdev)); out: if (physdev) g_object_unref (physdev); }
static void huawei_custom_init_step (HuaweiCustomInitContext *ctx) { FirstInterfaceContext *fi_ctx; GUdevDevice *port; /* If cancelled, end */ if (g_cancellable_is_cancelled (ctx->cancellable)) { mm_dbg ("(Huawei) no need to keep on running custom init in (%s)", mm_port_get_device (MM_PORT (ctx->port))); g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); huawei_custom_init_context_complete_and_free (ctx); return; } if (!ctx->curc_done) { if (ctx->curc_retries == 0) { /* All retries consumed, probably not an AT port */ mm_port_probe_set_result_at (ctx->probe, FALSE); g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); /* Try with next */ try_next_usbif (mm_port_probe_peek_device (ctx->probe)); huawei_custom_init_context_complete_and_free (ctx); return; } ctx->curc_retries--; /* Turn off unsolicited messages on secondary ports until needed */ mm_port_serial_at_command ( ctx->port, "AT^CURC=0", 3, FALSE, /* raw */ FALSE, /* allow_cached */ ctx->cancellable, (GAsyncReadyCallback)curc_ready, ctx); return; } /* Try to get a port map from the modem */ port = mm_port_probe_peek_port (ctx->probe); if (!ctx->getportmode_done && !g_udev_device_get_property_as_boolean (port, "ID_MM_HUAWEI_DISABLE_GETPORTMODE")) { if (ctx->getportmode_retries == 0) { g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); huawei_custom_init_context_complete_and_free (ctx); return; } ctx->getportmode_retries--; mm_port_serial_at_command ( ctx->port, "AT^GETPORTMODE", 3, FALSE, /* raw */ FALSE, /* allow_cached */ ctx->cancellable, (GAsyncReadyCallback)getportmode_ready, ctx); return; } /* All done it seems */ fi_ctx = g_object_get_data (G_OBJECT (mm_port_probe_peek_device (ctx->probe)), TAG_FIRST_INTERFACE_CONTEXT); g_assert (fi_ctx != NULL); fi_ctx->custom_init_run = TRUE; g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); huawei_custom_init_context_complete_and_free (ctx); }
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; }
/** * cd_sensor_set_from_device: **/ gboolean cd_sensor_set_from_device (CdSensor *sensor, GUdevDevice *device, GError **error) { CdSensorCap cap; CdSensorPrivate *priv = sensor->priv; const gchar *images[] = { "attach", "calibrate", "screen", NULL }; const gchar *images_md[] = { CD_SENSOR_METADATA_IMAGE_ATTACH, CD_SENSOR_METADATA_IMAGE_CALIBRATE, CD_SENSOR_METADATA_IMAGE_SCREEN, NULL }; const gchar *kind_str; const gchar *model_tmp = NULL; const gchar *vendor_tmp = NULL; const gchar * const *caps_str; gboolean ret; gboolean use_database; gchar *tmp; guint i; /* only use the database if we found both the VID and the PID */ use_database = g_udev_device_has_property (device, "ID_VENDOR_FROM_DATABASE") && g_udev_device_has_property (device, "ID_MODEL_FROM_DATABASE"); /* vendor */ if (use_database) vendor_tmp = g_udev_device_get_property (device, "ID_VENDOR_FROM_DATABASE"); if (vendor_tmp == NULL) vendor_tmp = g_udev_device_get_property (device, "ID_VENDOR"); if (vendor_tmp == NULL) vendor_tmp = g_udev_device_get_sysfs_attr (device, "manufacturer"); if (vendor_tmp == NULL) vendor_tmp = "unknown"; priv->vendor = g_strdup (vendor_tmp); /* make name sane */ g_strdelimit (priv->vendor, "_", ' '); /* model */ if (use_database) model_tmp = g_udev_device_get_property (device, "ID_MODEL_FROM_DATABASE"); if (model_tmp == NULL) model_tmp = g_udev_device_get_property (device, "ID_MODEL"); if (model_tmp == NULL) model_tmp = g_udev_device_get_sysfs_attr (device, "product"); if (model_tmp == NULL) model_tmp = "Unknown"; cd_sensor_set_model (sensor, model_tmp); /* make name sane */ g_strdelimit (priv->model, "_", ' '); /* try to get type */ kind_str = g_udev_device_get_property (device, "COLORD_SENSOR_KIND"); priv->kind = cd_sensor_kind_from_string (kind_str); if (priv->kind == CD_SENSOR_KIND_UNKNOWN) { ret = FALSE; g_set_error (error, 1, 0, "failed to recognize color device: %s - %s", vendor_tmp, model_tmp); goto out; } /* get caps */ caps_str = g_udev_device_get_property_as_strv (device, "COLORD_SENSOR_CAPS"); if (caps_str != NULL) { for (i = 0; caps_str[i] != NULL; i++) { cap = cd_sensor_cap_from_string (caps_str[i]); if (cap != CD_SENSOR_CAP_UNKNOWN) { cd_bitfield_add (priv->caps, cap); } else { g_warning ("Unknown sensor cap %s on %s", caps_str[i], kind_str); } } } /* is the sensor embeded, e.g. on the W700? */ ret = g_udev_device_get_property_as_boolean (device, "COLORD_SENSOR_EMBEDDED"); if (ret) priv->embedded = TRUE; /* add image metadata if the files exist */ for (i = 0; images[i] != NULL; i++) { tmp = g_strdup_printf ("%s/colord/icons/%s-%s.svg", DATADIR, kind_str, images[i]); if (g_file_test (tmp, G_FILE_TEST_EXISTS)) { g_debug ("helper image %s found", tmp); g_hash_table_insert (priv->metadata, g_strdup (images_md[i]), tmp); } else { g_debug ("helper image %s not found", tmp); g_free (tmp); } } /* some properties might not be valid in the GUdevDevice if the * device changes as this is only a snapshot */ priv->device = g_object_ref (device); /* success */ ret = TRUE; out: return ret; }
/* Returns TRUE if the support check request was filtered out */ static gboolean apply_pre_probing_filters (MMPlugin *self, MMDevice *device, GUdevDevice *port, gboolean *need_vendor_probing, gboolean *need_product_probing) { guint16 vendor; guint16 product; gboolean product_filtered = FALSE; gboolean vendor_filtered = FALSE; guint i; *need_vendor_probing = FALSE; *need_product_probing = FALSE; /* The plugin may specify that only some subsystems are supported. If that * is the case, filter by subsystem */ if (apply_subsystem_filter (self, port)) { mm_dbg ("(%s) [%s] filtered by subsystem", self->priv->name, g_udev_device_get_name (port)); return TRUE; } /* The plugin may specify that only some drivers are supported, or that some * drivers are not supported. If that is the case, filter by driver */ if (self->priv->drivers || self->priv->forbidden_drivers) { static const gchar *virtual_drivers [] = { "virtual", NULL }; const gchar **drivers; /* Detect any modems accessible through the list of virtual ports */ drivers = (is_virtual_port (g_udev_device_get_name (port)) ? virtual_drivers : mm_device_get_drivers (device)); /* If error retrieving driver: unsupported */ if (!drivers) { mm_dbg ("(%s) [%s] filtered as couldn't retrieve drivers", self->priv->name, g_udev_device_get_name (port)); return TRUE; } /* Filtering by allowed drivers */ if (self->priv->drivers) { gboolean found = FALSE; for (i = 0; self->priv->drivers[i] && !found; i++) { guint j; for (j = 0; drivers[j] && !found; j++) { if (g_str_equal (drivers[j], self->priv->drivers[i])) found = TRUE; } } /* If we didn't match any driver: unsupported */ if (!found) { mm_dbg ("(%s) [%s] filtered by drivers", self->priv->name, g_udev_device_get_name (port)); return TRUE; } } /* Filtering by forbidden drivers */ else { for (i = 0; self->priv->forbidden_drivers[i]; i++) { guint j; for (j = 0; drivers[j]; j++) { /* If we match a forbidden driver: unsupported */ if (g_str_equal (drivers[j], self->priv->forbidden_drivers[i])) { mm_dbg ("(%s) [%s] filtered by forbidden drivers", self->priv->name, g_udev_device_get_name (port)); return TRUE; } } } } } vendor = mm_device_get_vendor (device); product = mm_device_get_product (device); /* The plugin may specify that only some vendor IDs are supported. If that * is the case, filter by vendor ID. */ if (self->priv->vendor_ids) { /* If we didn't get any vendor: filtered */ if (!vendor) vendor_filtered = TRUE; else { for (i = 0; self->priv->vendor_ids[i]; i++) if (vendor == self->priv->vendor_ids[i]) break; /* If we didn't match any vendor: filtered */ if (!self->priv->vendor_ids[i]) vendor_filtered = TRUE; } } /* The plugin may specify that only some product IDs are supported. If * that is the case, filter by vendor+product ID pair */ if (self->priv->product_ids) { /* If we didn't get any product: filtered */ if (!product || !vendor) product_filtered = TRUE; else { for (i = 0; self->priv->product_ids[i].l; i++) if (vendor == self->priv->product_ids[i].l && product == self->priv->product_ids[i].r) break; /* If we didn't match any product: filtered */ if (!self->priv->product_ids[i].l) product_filtered = TRUE; } } /* If we got filtered by vendor or product IDs and we do not have vendor * or product strings to compare with: unsupported */ if ((vendor_filtered || product_filtered) && !self->priv->vendor_strings && !self->priv->product_strings && !self->priv->forbidden_product_strings) { mm_dbg ("(%s) [%s] filtered by vendor/product IDs", self->priv->name, g_udev_device_get_name (port)); return TRUE; } /* The plugin may specify that some product IDs are not supported. If * that is the case, filter by forbidden vendor+product ID pair */ if (self->priv->forbidden_product_ids && product && vendor) { for (i = 0; self->priv->forbidden_product_ids[i].l; i++) { if (vendor == self->priv->forbidden_product_ids[i].l && product == self->priv->forbidden_product_ids[i].r) { mm_dbg ("(%s) [%s] filtered by forbidden vendor/product IDs", self->priv->name, g_udev_device_get_name (port)); return TRUE; } } } /* Check if we need vendor/product string probing * Only require these probings if the corresponding filters are given, and: * 1) if there was no vendor/product ID probing * 2) if there was vendor/product ID probing but we got filtered * * In other words, don't require vendor/product string probing if the plugin * already had vendor/product ID filters and we actually passed those. */ if ((!self->priv->vendor_ids && !self->priv->product_ids) || vendor_filtered || product_filtered) { /* If product strings related filters around, we need to probe for both * vendor and product strings */ if (self->priv->product_strings || self->priv->forbidden_product_strings) { *need_vendor_probing = TRUE; *need_product_probing = TRUE; } /* If only vendor string filter is needed, only probe for vendor string */ else if (self->priv->vendor_strings) *need_vendor_probing = TRUE; } /* The plugin may specify that only ports with some given udev tags are * supported. If that is the case, filter by udev tag */ if (self->priv->udev_tags) { for (i = 0; self->priv->udev_tags[i]; i++) { /* Check if the port was tagged */ if (g_udev_device_get_property_as_boolean (port, self->priv->udev_tags[i])) break; } /* If we didn't match any udev tag: unsupported */ if (!self->priv->udev_tags[i]) { mm_dbg ("(%s) [%s] filtered by udev tags", self->priv->name, g_udev_device_get_name (port)); return TRUE; } } return FALSE; }