Esempio n. 1
0
/**
 * gmw_probe_device_reset:
 **/
static gboolean
gmw_probe_device_reset (GmwProbeDevice *dev, GError **error)
{
	int fd;
	const gchar *devnode;

	/* just reset device */
	devnode = g_udev_device_get_device_file (dev->udev_device);
	g_debug ("Resetting %s", devnode);
	fd = g_open (devnode, O_WRONLY | O_NONBLOCK);
	if (fd < 0) {
		g_set_error (error,
			     GMW_ERROR,
			     GMW_ERROR_FAILED,
			     "Failed to open %s", devnode);
		return FALSE;
	}
	if (ioctl (fd, USBDEVFS_RESET) != 0) {
		g_set_error (error,
			     GMW_ERROR,
			     GMW_ERROR_FAILED,
			     "Failed to reset device");
		close (fd);
		return FALSE;
	}
	close (fd);
	return TRUE;
}
Esempio n. 2
0
/**
 * cd_sensor_client_add:
 **/
static gboolean
cd_sensor_client_add (CdSensorClient *sensor_client,
		      GUdevDevice *device)
{
	CdSensor *sensor = NULL;
	const gchar *device_file;
	const gchar *tmp;
	gboolean ret = FALSE;
	GError *error = NULL;

	/* interesting device? */
	tmp = g_udev_device_get_property (device, "COLORD_SENSOR_KIND");
	if (tmp == NULL)
		goto out;
	tmp = g_udev_device_get_property (device, "COLORD_IGNORE");
	if (tmp != NULL)
		goto out;

	/* actual device? */
	device_file = g_udev_device_get_device_file (device);
	if (device_file == NULL)
		goto out;

	/* get data */
	g_debug ("adding color management device: %s [%s]",
		 g_udev_device_get_sysfs_path (device),
		 device_file);
	sensor = cd_sensor_new ();
	ret = cd_sensor_set_from_device (sensor, device, &error);
	if (!ret) {
		g_warning ("CdSensorClient: failed to set CM sensor: %s",
			   error->message);
		g_error_free (error);
		goto out;
	}

	/* set the index */
	cd_sensor_set_index (sensor, sensor_client->priv->idx);

	/* load the sensor */
	ret = cd_sensor_load (sensor, &error);
	if (!ret) {
		/* not fatal, non-native devices are still useable */
		g_debug ("CdSensorClient: failed to load native sensor: %s",
			 error->message);
		g_clear_error (&error);
	}

	/* signal the addition */
	g_debug ("emit: added");
	g_signal_emit (sensor_client, signals[SIGNAL_SENSOR_ADDED], 0, sensor);
	sensor_client->priv->idx++;

	/* keep track so we can remove with the same device */
	g_ptr_array_add (sensor_client->priv->array_sensors, g_object_ref (sensor));
out:
	if (sensor != NULL)
		g_object_unref (sensor);
	return ret;
}
Esempio n. 3
0
static gboolean
input_accel_open (GUdevDevice        *device,
		  ReadingsUpdateFunc  callback_func,
		  gpointer            user_data)
{
	const gchar * const subsystems[] = { "input", NULL };
	const char *mount_matrix;

	drv_data = g_new0 (DrvData, 1);
	drv_data->dev = g_object_ref (device);
	drv_data->parent = g_udev_device_get_parent (drv_data->dev);
	drv_data->dev_path = g_udev_device_get_device_file (device);
	drv_data->name = g_udev_device_get_property (device, "NAME");
	drv_data->client = g_udev_client_new (subsystems);

	mount_matrix = g_udev_device_get_property (device, "ACCEL_MOUNT_MATRIX");
	if (!parse_mount_matrix (mount_matrix, &drv_data->mount_matrix)) {
		g_warning ("Invalid mount-matrix ('%s'), falling back to identity",
			   mount_matrix);
		parse_mount_matrix (NULL, &drv_data->mount_matrix);
	}

	drv_data->callback_func = callback_func;
	drv_data->user_data = user_data;

	g_signal_connect (drv_data->client, "uevent",
			  G_CALLBACK (uevent_received), NULL);

	g_idle_add (first_values, NULL);

	return TRUE;
}
static gboolean
iio_buffer_light_open (GUdevDevice        *device,
                       ReadingsUpdateFunc  callback_func,
                       gpointer            user_data)
{
	char *trigger_name;

	drv_data = g_new0 (DrvData, 1);

	/* Get the trigger name, and build the channels from that */
	trigger_name = get_trigger_name (device);
	if (!trigger_name) {
		g_clear_pointer (&drv_data, g_free);
		return FALSE;
	}
	drv_data->buffer_data = buffer_drv_data_new (device, trigger_name);
	g_free (trigger_name);

	if (!drv_data->buffer_data) {
		g_clear_pointer (&drv_data, g_free);
		return FALSE;
	}

	drv_data->dev = g_object_ref (device);
	drv_data->dev_path = g_udev_device_get_device_file (device);

	drv_data->callback_func = callback_func;
	drv_data->user_data = user_data;

	return TRUE;
}
Esempio n. 5
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 MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *devfile, *sysfs_path;
    guint32 caps;
    MMPortType ptype = MM_PORT_TYPE_UNKNOWN;

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

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

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

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

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

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

    return modem;
}
static gboolean
bcache_block_check (UDisksObject *object)
{
  UDisksLinuxDevice *device = NULL;
  gboolean rval = FALSE;

  g_return_val_if_fail (UDISKS_IS_LINUX_BLOCK_OBJECT (object), FALSE);

  /* Check device name */
  device = udisks_linux_block_object_get_device (UDISKS_LINUX_BLOCK_OBJECT (object));
  rval = g_str_has_prefix (g_udev_device_get_device_file (device->udev_device),
                            "/dev/bcache");
  g_object_unref(device);
  return rval;
}
Esempio n. 8
0
static gboolean
fu_altos_device_find_tty (FuAltosDevice *self, GError **error)
{
	GUsbDevice *usb_device = fu_usb_device_get_dev (FU_USB_DEVICE (self));
	g_autoptr(GList) devices = NULL;
	g_autoptr(GUdevClient) gudev_client = g_udev_client_new (NULL);

	/* find all tty devices */
	devices = g_udev_client_query_by_subsystem (gudev_client, "tty");
	for (GList *l = devices; l != NULL; l = l->next) {
		GUdevDevice *dev = G_UDEV_DEVICE (l->data);

		/* get the tty device */
		const gchar *dev_file = g_udev_device_get_device_file (dev);
		if (dev_file == NULL)
			continue;

		/* get grandparent */
		dev = g_udev_device_get_parent (dev);
		if (dev == NULL)
			continue;
		dev = g_udev_device_get_parent (dev);
		if (dev == NULL)
			continue;

		/* check correct device */
		if (g_udev_device_get_sysfs_attr_as_int (dev, "busnum") !=
		    g_usb_device_get_bus (usb_device))
			continue;
		if (g_udev_device_get_sysfs_attr_as_int (dev, "devnum") !=
		    g_usb_device_get_address (usb_device))
			continue;

		/* success */
		self->tty = g_strdup (dev_file);
		return TRUE;
	}

	/* failure */
	g_set_error (error,
		     FWUPD_ERROR,
		     FWUPD_ERROR_NOT_SUPPORTED,
		     "failed to find tty for %u:%u",
		     g_usb_device_get_bus (usb_device),
		     g_usb_device_get_address (usb_device));
	return FALSE;
}
Esempio n. 9
0
static gboolean
input_accel_discover (GUdevDevice *device)
{
	const char *path;

	if (g_strcmp0 (g_udev_device_get_property (device, "IIO_SENSOR_PROXY_TYPE"), "input-accel") != 0)
		return FALSE;

	path = g_udev_device_get_device_file (device);
	if (!path)
		return FALSE;
	if (strstr (path, "/event") == NULL)
		return FALSE;

	g_debug ("Found input accel at %s", g_udev_device_get_sysfs_path (device));
	return TRUE;
}
Esempio n. 10
0
static void dump_device_and_parent(GUdevDevice * device, guint indent)
{
	const gchar *const *list;
	const gchar *const *iter;
	GUdevDevice *parent;
	char propstr[500];
	guint32 namelen = 0, i;

	println(indent, "------------------------------------------------------");
	println(indent, "%-20s %s", _("Name:"), g_udev_device_get_name(device));
	println(indent, "%-20s %s", _("Type:"), g_udev_device_get_devtype(device));
	println(indent, "%-20s %s", _("Subsystem:"), g_udev_device_get_subsystem(device));
	println(indent, "%-20s %s", _("Number:"), g_udev_device_get_number(device));
	println(indent, "%-20s %s", _("Path:"), g_udev_device_get_sysfs_path(device));
	println(indent, "%-20s %s", _("Driver:"), g_udev_device_get_driver(device));
	println(indent, "%-20s %lld", _("Sequential Number:"), (long long int)g_udev_device_get_seqnum(device));
	println(indent, "%-20s %s", _("Device File:"), g_udev_device_get_device_file(device));

	println(indent, " ");
	println(indent, _("Properties:"));

	/* Get longest property name length for alignment */
	list = g_udev_device_get_property_keys(device);
	for (iter = list; iter && *iter; iter++) {
		if (strlen(*iter) > namelen)
			namelen = strlen(*iter);
	}
	namelen++;

	for (iter = list; iter && *iter; iter++) {
		strcpy(propstr, *iter);
		strcat(propstr, ":");
		for (i = 0; i < namelen - strlen(*iter); i++)
			strcat(propstr, " ");
		strcat(propstr, g_udev_device_get_property(device, *iter));
		println(indent + 2, "%s", propstr);
	}

	println(indent, " ");

	parent = g_udev_device_get_parent(device);
	if (parent) {
		dump_device_and_parent(parent, indent + 4);
		g_object_unref(parent);
	}
}
Esempio n. 11
0
static GMount *
find_mount_for_device (GUdevDevice *device)
{
	GMount *mount = NULL;
	const char *device_file;
	GVolumeMonitor *volmon;
	GList *mounts;
	GList *i;

	device_file = g_udev_device_get_device_file (device);
	if (device_file == NULL) {
		return NULL;
	}

	volmon = g_volume_monitor_get ();
	mounts = g_volume_monitor_get_mounts (volmon);
	g_object_unref (volmon);

	for (i = mounts; i != NULL; i = i->next) {
		GVolume *v;

		v = g_mount_get_volume (G_MOUNT (i->data));
		if (v != NULL) {
			char *devname = NULL;
			gboolean match;

			devname = g_volume_get_identifier (v, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
			g_object_unref (v);
			if (devname == NULL)
				continue;

			match = g_str_equal (devname, device_file);
			g_free (devname);

			if (match) {
				mount = G_MOUNT (i->data);
				g_object_ref (G_OBJECT (mount));
				break;
			}
		}
	}
	g_list_foreach (mounts, (GFunc)g_object_unref, NULL);
	g_list_free (mounts);
	return mount;
}
static gboolean
bcache_block_check (StoragedObject *object)
{
  const gchar *devname = NULL;
  StoragedLinuxDevice *device = NULL;
  gboolean rval = FALSE;

  g_return_val_if_fail (STORAGED_IS_LINUX_BLOCK_OBJECT (object), FALSE);

  /* Check device name */
  device = storaged_linux_block_object_get_device (STORAGED_LINUX_BLOCK_OBJECT (object));
  devname = g_strdup (g_udev_device_get_device_file (device->udev_device));

  rval = g_str_has_prefix (devname, "/dev/bcache");

  g_free ((gpointer) devname);

  return rval;
}
Esempio n. 13
0
/**
 * cd_sensor_client_remove:
 **/
static void
cd_sensor_client_remove (CdSensorClient *sensor_client,
			 GUdevDevice *device)
{
	CdSensor *sensor;
	const gchar *device_file;
	const gchar *device_path;
	const gchar *tmp;
	guint i;

	/* interesting device? */
	tmp = g_udev_device_get_property (device, "COLORD_SENSOR_KIND");
	if (tmp == NULL)
		goto out;

	/* actual device? */
	device_file = g_udev_device_get_device_file (device);
	if (device_file == NULL)
		goto out;

	/* get data */
	device_path = g_udev_device_get_sysfs_path (device);
	g_debug ("removing color management device: %s [%s]",
		 device_path, device_file);
	for (i = 0; i < sensor_client->priv->array_sensors->len; i++) {
		sensor = g_ptr_array_index (sensor_client->priv->array_sensors, i);
		if (g_strcmp0 (cd_sensor_get_device_path (sensor), device_path) == 0) {
			g_debug ("emit: removed");
			g_signal_emit (sensor_client, signals[SIGNAL_SENSOR_REMOVED], 0, sensor);
			g_ptr_array_remove_index_fast (sensor_client->priv->array_sensors, i);
			goto out;
		}
	}

	/* nothing found */
	g_warning ("removed CM sensor that was never added");
out:
	return;
}
Esempio n. 14
0
/**
 * cd_plugin_get_scanner_id_for_udev_device:
 **/
static gchar *
cd_plugin_get_scanner_id_for_udev_device (GUdevDevice *udev_device)
{
	GString *string;
	const gchar *tmp;

	/* get id */
	string = g_string_new ("sysfs");
	tmp = g_udev_device_get_property (udev_device, "ID_VENDOR");
	if (tmp != NULL)
		g_string_append_printf (string, "-%s", tmp);
	tmp = g_udev_device_get_property (udev_device, "ID_MODEL");
	if (tmp != NULL)
		g_string_append_printf (string, "-%s", tmp);

	/* fallback */
	if (string->len == 5) {
		tmp = g_udev_device_get_device_file (udev_device);
		g_string_append_printf (string, "-%s", tmp);
	}

	return g_string_free (string, FALSE);
}
/**
 * storaged_linux_block_object_reread_partition_table:
 * @object: A #StoragedLinuxBlockObject.
 *
 * Requests the kernel to re-read the partition table for @object.
 *
 * The events from any change this may cause will bubble up from the
 * kernel through the udev stack and will eventually be received by
 * the storaged daemon process itself. This method does not wait for the
 * event to be received.
 */
void
storaged_linux_block_object_reread_partition_table (StoragedLinuxBlockObject *object)
{
    const gchar *device_file;
    gint fd;

    g_return_if_fail (STORAGED_IS_LINUX_BLOCK_OBJECT (object));

    device_file = g_udev_device_get_device_file (object->device->udev_device);
    fd = open (device_file, O_RDONLY);
    if (fd == -1)
    {
        storaged_warning ("Error opening %s: %m", device_file);
    }
    else
    {
        if (ioctl (fd, BLKRRPART) != 0)
        {
            storaged_warning ("Error issuing BLKRRPART to %s: %m", device_file);
        }
        close (fd);
    }
}
Esempio n. 16
0
static MMBaseModem *
grab_port (MMPluginBase *base,
           MMBaseModem *existing,
           MMPortProbe *probe,
           GError **error)
{
    MMBaseModem *modem = NULL;
    GUdevDevice *port;
    const gchar *name, *subsys, *devfile;
    guint16 vendor = 0, product = 0;

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

    port = mm_port_probe_get_port (probe); /* transfer none */

    /* TODO: Why do we check for device file? */
    devfile = g_udev_device_get_device_file (port);
    if (!devfile) {
        g_set_error (error, 0, 0, "Could not get port's sysfs file.");
        return NULL;
    }

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

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

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

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

    return existing ? existing : modem;
}
static GstDevice *
gst_v4l2_device_provider_device_from_udev (GstV4l2DeviceProvider * provider,
    GUdevDevice * udev_device)
{
  GstV4l2Device *gstdev;
  const gchar *device_path = g_udev_device_get_device_file (udev_device);
  const gchar *device_name, *str;
  GstStructure *props;

  props = gst_structure_new ("v4l2deviceprovider", "udev-probed",
      G_TYPE_BOOLEAN, TRUE, NULL);

  str = g_udev_device_get_property (udev_device, "ID_PATH");
  if (!(str && *str)) {
    str = g_udev_device_get_sysfs_path (udev_device);
  }
  if (str && *str)
    gst_structure_set (props, "device.bus_path", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_sysfs_path (udev_device)) && *str)
    gst_structure_set (props, "sysfs.path", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_ID")) && *str)
    gst_structure_set (props, "udev.id", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_BUS")) && *str)
    gst_structure_set (props, "device.bus", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "SUBSYSTEM")) && *str)
    gst_structure_set (props, "device.subsystem", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_VENDOR_ID")) && *str)
    gst_structure_set (props, "device.vendor.id", G_TYPE_STRING, str, NULL);

  str = g_udev_device_get_property (udev_device, "ID_VENDOR_FROM_DATABASE");
  if (!(str && *str)) {
    str = g_udev_device_get_property (udev_device, "ID_VENDOR_ENC");
    if (!(str && *str)) {
      str = g_udev_device_get_property (udev_device, "ID_VENDOR");
    }
  }
  if (str && *str)
    gst_structure_set (props, "device.vendor.name", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_MODEL_ID")) && *str)
    gst_structure_set (props, "device.product.id", G_TYPE_STRING, str, NULL);

  device_name = g_udev_device_get_property (udev_device, "ID_V4L_PRODUCT");
  if (!(device_name && *device_name)) {
    device_name =
        g_udev_device_get_property (udev_device, "ID_MODEL_FROM_DATABASE");
    if (!(device_name && *device_name)) {
      device_name = g_udev_device_get_property (udev_device, "ID_MODEL_ENC");
      if (!(device_name && *device_name)) {
        device_name = g_udev_device_get_property (udev_device, "ID_MODEL");
      }
    }
  }
  if (device_name && *device_name)
    gst_structure_set (props, "device.product.name", G_TYPE_STRING, device_name,
        NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_SERIAL")) && *str)
    gst_structure_set (props, "device.serial", G_TYPE_STRING, str, NULL);

  if ((str = g_udev_device_get_property (udev_device, "ID_V4L_CAPABILITIES"))
      && *str)
    gst_structure_set (props, "device.capabilities", G_TYPE_STRING, str, NULL);

  gstdev = gst_v4l2_device_provider_probe_device (provider, device_path,
      device_name, props);

  if (gstdev)
    gstdev->syspath = g_strdup (g_udev_device_get_sysfs_path (udev_device));

  return GST_DEVICE (gstdev);
}
Esempio n. 18
0
static MMModem *
grab_port (MMPluginBase *base,
           MMModem *existing,
           MMPluginBaseSupportsTask *task,
           GError **error)
{
    GUdevDevice *port = NULL;
    MMModem *modem = NULL;
    const char *name, *subsys, *devfile, *sysfs_path;
    guint32 caps;
    guint16 vendor = 0, product = 0;
    MMPortType ptype;
    int usbif;
    MMAtPortFlags pflags = MM_AT_PORT_FLAG_NONE;

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

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

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

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

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

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

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

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

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

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

    return modem;
}
static void
empathy_camera_device_monitor_added (EmpathyCameraDeviceMonitor *monitor,
                                    GUdevDevice               *udevice)
{
  const char *device_file;
  const char *product_name;
  const char *vendor;
  const char *product;
  const char *bus;
  gint        vendor_id   = 0;
  gint        product_id  = 0;
  gint        v4l_version = 0;

  const gchar *devpath = g_udev_device_get_property (udevice, "DEVPATH");

  GST_INFO ("Checking udev device '%s'", devpath);

  bus = g_udev_device_get_property (udevice, "ID_BUS");
  if (g_strcmp0 (bus, "usb") == 0)
  {
    vendor = g_udev_device_get_property (udevice, "ID_VENDOR_ID");
    if (vendor != NULL)
      vendor_id = g_ascii_strtoll (vendor, NULL, 16);
    product = g_udev_device_get_property (udevice, "ID_MODEL_ID");
    if (product != NULL)
      product_id = g_ascii_strtoll (product, NULL, 16);
    if (vendor_id == 0 || product_id == 0)
    {
      GST_WARNING ("Error getting vendor and product id");
    }
    else
    {
      GST_INFO ("Found device %04x:%04x, getting capabilities...", vendor_id, product_id);
    }
  }
  else
  {
    GST_INFO ("Not an usb device, skipping vendor and model id retrieval");
  }

  device_file = g_udev_device_get_device_file (udevice);
  if (device_file == NULL)
  {
    GST_WARNING ("Error getting V4L device");
    return;
  }

  /* vbi devices support capture capability too, but cannot be used,
   * so detect them by device name */
  if (strstr (device_file, "vbi"))
  {
    GST_INFO ("Skipping vbi device: %s", device_file);
    return;
  }

  v4l_version = g_udev_device_get_property_as_int (udevice, "ID_V4L_VERSION");
  if (v4l_version == 2 || v4l_version == 1)
  {
    const char *caps;

    caps = g_udev_device_get_property (udevice, "ID_V4L_CAPABILITIES");
    if (caps == NULL || strstr (caps, ":capture:") == NULL)
    {
      GST_WARNING ("Device %s seems to not have the capture capability, (radio tuner?)"
                   "Removing it from device list.", device_file);
      return;
    }
    product_name = g_udev_device_get_property (udevice, "ID_V4L_PRODUCT");
  }
  else if (v4l_version == 0)
  {
    GST_ERROR ("Fix your udev installation to include v4l_id, ignoring %s", device_file);
    return;
  }
  else
  {
    g_assert_not_reached ();
  }

  g_signal_emit (monitor, monitor_signals[ADDED], 0,
                 devpath,
                 device_file,
                 product_name,
                 v4l_version);
}