Esempio n. 1
0
/**
 * 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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
/* 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))));
    }
}
Esempio n. 7
0
/* 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;
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}
Esempio n. 13
0
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");
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
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);
}
Esempio n. 16
0
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);
}
Esempio n. 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;
}
Esempio n. 18
0
/**
 * 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;
}
Esempio n. 19
0
/* 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;
}