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