示例#1
0
/**
 * Search udev for usb device with specified idVendor and idProduct
 */
const char* get_usb_device_syspath(const char* idVendor, const char* idProduct, char* buf) {
    struct udev* udev;
    struct udev_enumerate* en;
    struct udev_list_entry* dev_list_entry;

    udev = udev_new();
    if (udev<0) {
        return 0;
    }

    en = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(en, "usb");
    udev_enumerate_add_match_sysattr(en, "idVendor",idVendor);
    udev_enumerate_add_match_sysattr(en, "idProduct",idProduct);
    udev_enumerate_scan_devices(en);

    dev_list_entry = udev_enumerate_get_list_entry(en);
    if (dev_list_entry == 0 ) {
        return 0;
    }

    sprintf(buf, udev_list_entry_get_name(dev_list_entry));
    udev_enumerate_unref(en);
    udev_unref(udev);
    return buf;
}
示例#2
0
int get_usbinfo(int bus, int dev, usbinfo_t *ui)
{
  struct udev *udev;
  struct udev_enumerate *enumerate;
  struct udev_list_entry *devices, *dev_list_entry;
  struct udev_device *udev_dev;
  char bus_str[16], dev_str[16];
  int found = 0;

  memset(ui, 0, sizeof(usbinfo_t));

  /* construct xenstore dev id */
  if (dev > 0xFFF) {
    xd_log(LOG_ERR, "bad device id %d", dev);
    return -EINVAL;
  }

  ui->usb_virtid = bus << 12 | (dev & 0xFFF);
  ui->usb_bus = bus;
  ui->usb_device = dev;

  /* udev scan */
  udev = udev_new();
  if (!udev) {
    xd_log(LOG_ERR, "Can't create udev");
    return -ENOMEM;
  }
  enumerate = udev_enumerate_new(udev);
  if (!enumerate) {
    xd_log(LOG_ERR, "Can't create enumeration");
    return -ENOMEM;
  }

  snprintf(bus_str, sizeof(bus_str), "%d", bus);
  snprintf(dev_str, sizeof(dev_str), "%d", dev);

  udev_enumerate_add_match_subsystem(enumerate, "usb");
  udev_enumerate_add_match_sysattr(enumerate, "busnum", bus_str);
  udev_enumerate_add_match_sysattr(enumerate, "devnum", dev_str);
  udev_enumerate_scan_devices(enumerate);
  devices = udev_enumerate_get_list_entry(enumerate);
  udev_list_entry_foreach(dev_list_entry, devices) {
    const char *path;
    path = udev_list_entry_get_name(dev_list_entry);
    udev_dev = udev_device_new_from_syspath(udev, path);
    sscanf(udev_device_get_sysattr_value(udev_dev, "idVendor"), "%x", &ui->usb_vendor);
    sscanf(udev_device_get_sysattr_value(udev_dev, "idProduct"), "%x", &ui->usb_product);
    udev_device_unref(udev_dev);
    udev_enumerate_unref(enumerate);
    udev_unref(udev);
    return 0;
  }
  udev_enumerate_unref(enumerate);
  udev_unref(udev);
  return -ENOENT;
}
示例#3
0
void udevenum(){
    struct udev_enumerate* enumerator = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerator, "usb");
    udev_enumerate_add_match_sysattr(enumerator, "idVendor", V_CORSAIR_STR);
    udev_enumerate_scan_devices(enumerator);
    struct udev_list_entry* devices, *dev_list_entry;
    devices = udev_enumerate_get_list_entry(enumerator);

    udev_list_entry_foreach(dev_list_entry, devices){
        const char* path = udev_list_entry_get_name(dev_list_entry);
        struct udev_device* dev = udev_device_new_from_syspath(udev, path);
        // If the device matches a recognized device ID, open it
        const char* product = udev_device_get_sysattr_value(dev, "idProduct");
        if(!strcmp(product, P_K70_STR)){
            pthread_mutex_lock(&kblistmutex);
            openusb(dev, 70);
            pthread_mutex_unlock(&kblistmutex);
            continue;
        }
        if(!strcmp(product, P_K95_STR)){
            pthread_mutex_lock(&kblistmutex);
            openusb(dev, 95);
            pthread_mutex_unlock(&kblistmutex);
            continue;
        }
        // Free the device if it wasn't used
        udev_device_unref(dev);
    }
    udev_enumerate_unref(enumerator);
}
示例#4
0
文件: umount.c 项目: nazgul77/systemd
static int loopback_list_get(MountPoint **head) {
        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
        struct udev_list_entry *item = NULL, *first = NULL;
        _cleanup_udev_unref_ struct udev *udev = NULL;
        int r;

        assert(head);

        udev = udev_new();
        if (!udev)
                return -ENOMEM;

        e = udev_enumerate_new(udev);
        if (!e)
                return -ENOMEM;

        r = udev_enumerate_add_match_subsystem(e, "block");
        if (r < 0)
                return r;

        r = udev_enumerate_add_match_sysname(e, "loop*");
        if (r < 0)
                return r;

        r = udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL);
        if (r < 0)
                return r;

        r = udev_enumerate_scan_devices(e);
        if (r < 0)
                return r;

        first = udev_enumerate_get_list_entry(e);
        udev_list_entry_foreach(item, first) {
                MountPoint *lb;
                _cleanup_udev_device_unref_ struct udev_device *d;
                char *loop;
                const char *dn;

                d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
                if (!d)
                        return -ENOMEM;

                dn = udev_device_get_devnode(d);
                if (!dn)
                        continue;

                loop = strdup(dn);
                if (!loop)
                        return -ENOMEM;

                lb = new0(MountPoint, 1);
                if (!lb) {
                        free(loop);
                        return -ENOMEM;
                }

                lb->path = loop;
                LIST_PREPEND(mount_point, *head, lb);
        }
示例#5
0
static virInterfacePtr
udevInterfaceLookupByMACString(virConnectPtr conn, const char *macstr)
{
    struct udev_iface_driver *driverState = conn->interfacePrivateData;
    struct udev *udev = udev_ref(driverState->udev);
    struct udev_enumerate *enumerate = NULL;
    struct udev_list_entry *dev_entry;
    struct udev_device *dev;
    const char *name;
    virInterfacePtr ret = NULL;

    enumerate = udevGetDevices(udev, VIR_UDEV_IFACE_ALL);

    if (!enumerate) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to lookup interface with MAC address '%s'"),
                       macstr);
        goto err;
    }

    /* Match on MAC */
    udev_enumerate_add_match_sysattr(enumerate, "address", macstr);

    /* Do the scan to load up the enumeration */
    udev_enumerate_scan_devices(enumerate);

    /* Get a list we can walk */
    dev_entry = udev_enumerate_get_list_entry(enumerate);

    /* Check that we got something back */
    if (!dev_entry) {
        virReportError(VIR_ERR_NO_INTERFACE,
                       _("couldn't find interface with MAC address '%s'"),
                       macstr);
        goto err;
    }

    /* Check that we didn't get multiple items back */
    if (udev_list_entry_get_next(dev_entry)) {
        virReportError(VIR_ERR_MULTIPLE_INTERFACES,
                       _("the MAC address '%s' matches multiple interfaces"),
                       macstr);
        goto err;
    }

    dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(dev_entry));
    name = udev_device_get_sysname(dev);
    ret = virGetInterface(conn, name, macstr);
    udev_device_unref(dev);

err:
    if (enumerate)
        udev_enumerate_unref(enumerate);
    udev_unref(udev);

    return ret;
}
示例#6
0
udevGetDevices(struct udev *udev, virUdevStatus status)
{
    struct udev_enumerate *enumerate;

    /* Create a new enumeration to create a list */
    enumerate = udev_enumerate_new(udev);

    if (!enumerate)
        return NULL;

    /* Enumerate all network subsystem devices */
    udev_enumerate_add_match_subsystem(enumerate, "net");

    /* Ignore devices that are part of a bridge */
    udev_enumerate_add_nomatch_sysattr(enumerate, "brport/state", NULL);

    /* State of the device */
    switch (status) {
        case VIR_UDEV_IFACE_ACTIVE:
            udev_enumerate_add_match_sysattr(enumerate, "operstate", "up");
            break;

        case VIR_UDEV_IFACE_INACTIVE:
            udev_enumerate_add_match_sysattr(enumerate, "operstate", "down");
            break;

        case VIR_UDEV_IFACE_ALL:
            break;
    }

    /* We don't want to see the TUN devices that QEMU creates for other guests
     * running on this machine. By saying nomatch NULL, we just are getting
     * devices without the tun_flags sysattr.
     */
    udev_enumerate_add_nomatch_sysattr(enumerate, "tun_flags", NULL);

    return enumerate;
}
示例#7
0
static int
get_usbinfo(int bus, int dev, usbinfo_t *ui)
{
  struct udev_enumerate *enumerate;
  struct udev_list_entry *devices, *dev_list_entry;
  struct udev_device *udev_dev;
  char bus_str[16], dev_str[16];
  int vendor, product;

  enumerate = udev_enumerate_new(udev_handle);
  if (!enumerate) {
    xd_log(LOG_ERR, "Can't create enumeration");
    return -ENOMEM;
  }

  snprintf(bus_str, sizeof(bus_str), "%d", bus);
  snprintf(dev_str, sizeof(dev_str), "%d", dev);

  udev_enumerate_add_match_subsystem(enumerate, "usb");
  udev_enumerate_add_match_sysattr(enumerate, "busnum", bus_str);
  udev_enumerate_add_match_sysattr(enumerate, "devnum", dev_str);
  udev_enumerate_scan_devices(enumerate);
  devices = udev_enumerate_get_list_entry(enumerate);
  udev_list_entry_foreach(dev_list_entry, devices) {
    const char *path;

    path = udev_list_entry_get_name(dev_list_entry);
    udev_dev = udev_device_new_from_syspath(udev_handle, path);
    sscanf(udev_device_get_sysattr_value(udev_dev, "idVendor"), "%x", &vendor);
    sscanf(udev_device_get_sysattr_value(udev_dev, "idProduct"), "%x", &product);
    udev_device_unref(udev_dev);
    udev_enumerate_unref(enumerate);
    return usbowls_build_usbinfo(bus, dev, vendor, product, ui);
  }
  udev_enumerate_unref(enumerate);
  return -ENOENT;
}
示例#8
0
static void udev_enum(){
    struct udev_enumerate* enumerator = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerator, "usb");
    udev_enumerate_add_match_sysattr(enumerator, "idVendor", V_CORSAIR_STR);
    udev_enumerate_scan_devices(enumerator);
    struct udev_list_entry* devices, *dev_list_entry;
    devices = udev_enumerate_get_list_entry(enumerator);

    udev_list_entry_foreach(dev_list_entry, devices){
        const char* path = udev_list_entry_get_name(dev_list_entry);
        if(!path)
            continue;
        struct udev_device* dev = udev_device_new_from_syspath(udev, path);
        if(!dev)
            continue;
        // If the device matches a recognized device ID, open it
        if(usb_add_device(dev))
            // Release device if not
            udev_device_unref(dev);
    }
    udev_enumerate_unref(enumerator);
}
示例#9
0
XN_THREAD_PROC xnUSBUDEVEventsThread(XN_THREAD_PARAM pThreadParam)
{
	struct udev *udev;
	struct udev_device *dev;
   	struct udev_monitor *mon;
	int fd;
	
	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}

	/* This section sets up a monitor which will report events when
	   devices attached to the system change.  Events include "add",
	   "remove", "change", "online", and "offline".
	   
	   This section sets up and starts the monitoring. Events are
	   polled for (and delivered) later on.
	   
	   It is important that the monitor be set up before the call to
	   udev_enumerate_scan_devices() so that events (and devices) are
	   not missed.  For example, if enumeration happened first, there
	   would be no event generated for a device which was attached after
	   enumeration but before monitoring began.
	   
	   Note that a filter is added so that we only get events for
	   "usb/usb_device" devices. */
	
	/* Set up a monitor to monitor "usb_device" devices */
	mon = udev_monitor_new_from_netlink(udev, "udev");
	udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_device");
	udev_monitor_enable_receiving(mon);
	/* Get the file descriptor (fd) for the monitor.
	   This fd will get passed to select() */
	fd = udev_monitor_get_fd(mon);
	
	//////////////////////////////////////////////////////////////////////////

	/* Enumerate the currently connected devices and store them, 
	   so we can notify of their disconnection */

	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;


	enumerate = udev_enumerate_new(udev);
	/* Create a list of the devices.
	   Note that it's not possible to match by "devtype="usb_device"",
	   as in monitor filter, but this filter combination seems to do the job... */
	udev_enumerate_add_match_subsystem(enumerate, "usb");
	udev_enumerate_add_match_sysattr(enumerate, "idVendor", NULL);
	udev_enumerate_add_match_sysattr(enumerate, "idProduct", NULL);
	udev_enumerate_add_match_sysattr(enumerate, "busnum", NULL);
	udev_enumerate_add_match_sysattr(enumerate, "devnum", NULL);

	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* udev_list_entry_foreach is a macro which expands to
	   a loop. The loop will be executed for each member in
	   devices, setting dev_list_entry to a list entry
	   which contains the device's path in /sys. */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *path;
		
		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, path);

		/* Notify as if it was just connected */
		// note - it's better that connectivity events register AFTER this point,
		//        so they don't get notified of already connected devices.
		xnUSBDeviceConnected(dev);
	
		udev_device_unref(dev);
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	//////////////////////////////////////////////////////////////////////////

	/* Begin polling for udev events. Events occur when devices
	   attached to the system are added, removed, or change state. 
	   udev_monitor_receive_device() will return a device
	   object representing the device which changed and what type of
	   change occured.

	   The select() system call is used to ensure that the call to
	   udev_monitor_receive_device() will not block.
	   
	   The monitor was set up earler in this file, and monitoring is
	   already underway.
	   
	   This section will run continuously, calling usleep() at the end
	   of each pass. This is to demonstrate how to use a udev_monitor
	   in a non-blocking way. */
	while (g_bShouldRunUDEVThread)
	{
		/* Set up the call to select(). In this case, select() will
		   only operate on a single file descriptor, the one
		   associated with our udev_monitor. Note that the timeval
		   object is set to 0, which will cause select() to not
		   block. */
		fd_set fds;
		struct timeval tv;
		int ret;
		
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		tv.tv_sec = 0;
		tv.tv_usec = 250 * 1000;
		
		ret = select(fd+1, &fds, NULL, NULL, &tv);
		
		/* Check if our file descriptor has received data. */
		if (ret > 0 && FD_ISSET(fd, &fds)) {
			/* Make the call to receive the device.
			   select() ensured that this will not block. */
			dev = udev_monitor_receive_device(mon);
			if (dev) {
			/*
				printf("   Node: %s\n", udev_device_get_devnode(dev));
				printf("   Subsystem: %s\n", udev_device_get_subsystem(dev));
				printf("   Devtype: %s\n", udev_device_get_devtype(dev));
				printf("   Action: %s\n", udev_device_get_action(dev));

				printf("  VID/PID: %s %s\n",
						udev_device_get_sysattr_value(dev,"idVendor"),
						udev_device_get_sysattr_value(dev,"idProduct"));
				printf("  %s\n  %s\n",
						udev_device_get_sysattr_value(dev,"manufacturer"),
						udev_device_get_sysattr_value(dev,"product"));
				fflush(stdout);
			*/
				const XnChar *action = udev_device_get_action(dev);

				if (!xnOSStrCmp(action, "add"))
				{
					xnUSBDeviceConnected(dev);
				}
				else if (!xnOSStrCmp(action, "remove"))
				{
					xnUSBDeviceDisconnected(dev);
				}
				//note - handle the other events? "change" event might be useful...

				// now release dev
				udev_device_unref(dev);
			}
			else {
				xnLogWarning(XN_MASK_USB, "No Device from udev_monitor_receive_device(). An error occured.");
			}					
		}
	}
	udev_monitor_unref(mon);
	udev_unref(udev);

	XN_THREAD_PROC_RETURN(XN_STATUS_OK);
}