Beispiel #1
0
void HPMPrivate::run()
{
    udev *udev_ctx = udev_new();
    Q_ASSERT(udev_ctx != NULL);

    udev_monitor *mon = udev_monitor_new_from_netlink(udev_ctx, UDEV_NETLINK_SOURCE);
    Q_ASSERT(mon != NULL);

    if (udev_monitor_filter_add_match_subsystem_devtype(mon, USB_SUBSYSTEM, USB_DEVICE_TYPE) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to add match for USB devices";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    if (udev_monitor_enable_receiving(mon) < 0)
    {
        qWarning() << Q_FUNC_INFO << "Unable to enable udev uevent reception";
        udev_monitor_unref(mon);
        udev_unref(udev_ctx);
        return;
    }

    int fd = udev_monitor_get_fd(mon);
    fd_set readfs;
    FD_ZERO(&readfs);

    m_run = true;
    while (m_run == true)
    {
        struct timeval tv;
        tv.tv_sec = 1;
        tv.tv_usec = 0;

        FD_SET(fd, &readfs);
        int retval = select(fd + 1, &readfs, NULL, NULL, &tv);
        if (retval == -1)
        {
            qWarning() << Q_FUNC_INFO << strerror(errno);
            m_run = false;
        }
        else if (retval > 0 && FD_ISSET(fd, &readfs))
        {
            udev_device *dev = udev_monitor_receive_device(mon);
            if (dev != NULL)
            {
                QString action = QString(udev_device_get_action(dev));
                QString vendor = QString(udev_device_get_property_value(dev, PROPERTY_VID));
                QString product = QString(udev_device_get_property_value(dev, PROPERTY_PID));

                // fallback to composite PRODUCT property VID/PID/REV
                if (vendor.isEmpty() && product.isEmpty())
                {
                    QString compProduct = QString(udev_device_get_property_value(dev, PROPERTY_PRODUCT));
                    QStringList tokens = compProduct.split("/");
                    if (tokens.count() >= 2)
                    {
                        vendor = tokens.at(0);
                        product = tokens.at(1);
                    }
                }
                if (action.isEmpty() || vendor.isEmpty() || product.isEmpty())
                {
                    qWarning() << Q_FUNC_INFO << "Unable to get device properties"
                               << (void*) dev << "Action:" << QString(action);
                }
                else if (action == QString(DEVICE_ACTION_ADD))
                {
                    uint vid = vendor.toUInt(0, 16);
                    uint pid = product.toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceAdded(vid, pid);
                }
                else if (action == QString(DEVICE_ACTION_REMOVE))
                {
                    uint vid = vendor.toUInt(0, 16);
                    uint pid = product.toUInt(0, 16);
                    HotPlugMonitor* hpm = qobject_cast<HotPlugMonitor*> (parent());
                    Q_ASSERT(hpm != NULL);
                    hpm->emitDeviceRemoved(vid, pid);
                }
                else
                {
                    qWarning() << Q_FUNC_INFO << "Unhandled udev action:" << action;
                }

                udev_device_unref(dev);
            }
        }
    }

    udev_monitor_unref(mon);
    udev_unref(udev_ctx);
}
Beispiel #2
0
static void dev_kmsg_record(Server *s, char *p, size_t l) {
        struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
        char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL;
        int priority, r;
        unsigned n = 0, z = 0, j;
        unsigned long long usec;
        char *identifier = NULL, *pid = NULL, *e, *f, *k;
        uint64_t serial;
        size_t pl;
        char *kernel_device = NULL;

        assert(s);
        assert(p);

        if (l <= 0)
                return;

        e = memchr(p, ',', l);
        if (!e)
                return;
        *e = 0;

        r = safe_atoi(p, &priority);
        if (r < 0 || priority < 0 || priority > 999)
                return;

        if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN)
                return;

        l -= (e - p) + 1;
        p = e + 1;
        e = memchr(p, ',', l);
        if (!e)
                return;
        *e = 0;

        r = safe_atou64(p, &serial);
        if (r < 0)
                return;

        if (s->kernel_seqnum) {
                /* We already read this one? */
                if (serial < *s->kernel_seqnum)
                        return;

                /* Did we lose any? */
                if (serial > *s->kernel_seqnum)
                        server_driver_message(s, SD_MESSAGE_JOURNAL_MISSED, "Missed %"PRIu64" kernel messages",
                                              serial - *s->kernel_seqnum);

                /* Make sure we never read this one again. Note that
                 * we always store the next message serial we expect
                 * here, simply because this makes handling the first
                 * message with serial 0 easy. */
                *s->kernel_seqnum = serial + 1;
        }

        l -= (e - p) + 1;
        p = e + 1;
        f = memchr(p, ';', l);
        if (!f)
                return;
        /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */
        e = memchr(p, ',', l);
        if (!e || f < e)
                e = f;
        *e = 0;

        r = safe_atollu(p, &usec);
        if (r < 0)
                return;

        l -= (f - p) + 1;
        p = f + 1;
        e = memchr(p, '\n', l);
        if (!e)
                return;
        *e = 0;

        pl = e - p;
        l -= (e - p) + 1;
        k = e + 1;

        for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) {
                char *m;
                /* Meta data fields attached */

                if (*k != ' ')
                        break;

                k ++, l --;

                e = memchr(k, '\n', l);
                if (!e)
                        return;

                *e = 0;

                m = cunescape_length_with_prefix(k, e - k, "_KERNEL_");
                if (!m)
                        break;

                if (startswith(m, "_KERNEL_DEVICE="))
                        kernel_device = m + 15;

                IOVEC_SET_STRING(iovec[n++], m);
                z++;

                l -= (e - k) + 1;
                k = e + 1;
        }

        if (kernel_device) {
                struct udev_device *ud;

                ud = udev_device_new_from_device_id(s->udev, kernel_device);
                if (ud) {
                        const char *g;
                        struct udev_list_entry *ll;
                        char *b;

                        g = udev_device_get_devnode(ud);
                        if (g) {
                                b = strappend("_UDEV_DEVNODE=", g);
                                if (b) {
                                        IOVEC_SET_STRING(iovec[n++], b);
                                        z++;
                                }
                        }

                        g = udev_device_get_sysname(ud);
                        if (g) {
                                b = strappend("_UDEV_SYSNAME=", g);
                                if (b) {
                                        IOVEC_SET_STRING(iovec[n++], b);
                                        z++;
                                }
                        }

                        j = 0;
                        ll = udev_device_get_devlinks_list_entry(ud);
                        udev_list_entry_foreach(ll, ll) {

                                if (j > N_IOVEC_UDEV_FIELDS)
                                        break;

                                g = udev_list_entry_get_name(ll);
                                if (g) {
                                        b = strappend("_UDEV_DEVLINK=", g);
                                        if (b) {
                                                IOVEC_SET_STRING(iovec[n++], b);
                                                z++;
                                        }
                                }

                                j++;
                        }

                        udev_device_unref(ud);
                }
        }

        if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0)
                IOVEC_SET_STRING(iovec[n++], source_time);

        IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=kernel");

        if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
                IOVEC_SET_STRING(iovec[n++], syslog_priority);

        if ((priority & LOG_FACMASK) == LOG_KERN)
                IOVEC_SET_STRING(iovec[n++], "SYSLOG_IDENTIFIER=kernel");
        else {
                pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid);

                /* Avoid any messages we generated ourselves via
                 * log_info() and friends. */
                if (pid && is_us(pid))
                        goto finish;

                if (identifier) {
                        syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier);
                        if (syslog_identifier)
                                IOVEC_SET_STRING(iovec[n++], syslog_identifier);
                }

                if (pid) {
                        syslog_pid = strappend("SYSLOG_PID=", pid);
                        if (syslog_pid)
                                IOVEC_SET_STRING(iovec[n++], syslog_pid);
                }

                if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
                        IOVEC_SET_STRING(iovec[n++], syslog_facility);
        }

        message = cunescape_length_with_prefix(p, pl, "MESSAGE=");
        if (message)
                IOVEC_SET_STRING(iovec[n++], message);

        server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, NULL, 0, NULL, priority, 0);

finish:
        for (j = 0; j < z; j++)
                free(iovec[j].iov_base);

        free(message);
        free(syslog_priority);
        free(syslog_identifier);
        free(syslog_pid);
        free(syslog_facility);
        free(source_time);
        free(identifier);
        free(pid);
}
Beispiel #3
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;

	struct hid_device_info *root = NULL; /* return object */
	struct hid_device_info *cur_dev = NULL;
	struct hid_device_info *prev_dev = NULL; /* previous device */

	hid_init();

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		return NULL;
	}

	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item, see if it matches the vid/pid, and if so
	   create a udev_device record for it */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *sysfs_path;
		const char *dev_path;
		const char *str;
		struct udev_device *raw_dev; /* The device's hidraw udev node. */
		struct udev_device *hid_dev; /* The device's HID udev node. */
		struct udev_device *usb_dev; /* The device's USB udev node. */
		struct udev_device *intf_dev; /* The device's interface (in the USB sense). */
		unsigned short dev_vid;
		unsigned short dev_pid;
		char *serial_number_utf8 = NULL;
		char *product_name_utf8 = NULL;
		int bus_type;
		int result;

		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		sysfs_path = udev_list_entry_get_name(dev_list_entry);
		raw_dev = udev_device_new_from_syspath(udev, sysfs_path);
		dev_path = udev_device_get_devnode(raw_dev);

		hid_dev = udev_device_get_parent_with_subsystem_devtype(
			raw_dev,
			"hid",
			NULL);

		if (!hid_dev) {
			/* Unable to find parent hid device. */
			goto next;
		}

		result = parse_uevent_info(
			udev_device_get_sysattr_value(hid_dev, "uevent"),
			&bus_type,
			&dev_vid,
			&dev_pid,
			&serial_number_utf8,
			&product_name_utf8);

		if (!result) {
			/* parse_uevent_info() failed for at least one field. */
			goto next;
		}

		if (bus_type != BUS_USB && bus_type != BUS_BLUETOOTH) {
			/* We only know how to handle USB and BT devices. */
			goto next;
		}

		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
		    (product_id == 0x0 || product_id == dev_pid)) {
			struct hid_device_info *tmp;

			/* VID/PID match. Create the record. */
			tmp = malloc(sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			prev_dev = cur_dev;
			cur_dev = tmp;

			/* Fill out the record */
			cur_dev->next = NULL;
			cur_dev->path = dev_path? strdup(dev_path): NULL;

			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;

			/* Serial Number */
			cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8);

			/* Release Number */
			cur_dev->release_number = 0x0;

			/* Interface Number */
			cur_dev->interface_number = -1;

			switch (bus_type) {
				case BUS_USB:
					/* The device pointed to by raw_dev contains information about
					   the hidraw device. In order to get information about the
					   USB device, get the parent device with the
					   subsystem/devtype pair of "usb"/"usb_device". This will
					   be several levels up the tree, but the function will find
					   it. */
					usb_dev = udev_device_get_parent_with_subsystem_devtype(
							raw_dev,
							"usb",
							"usb_device");

					if (!usb_dev) {
						/* Free this device */
						free(cur_dev->serial_number);
						free(cur_dev->path);
						free(cur_dev);

						/* Take it off the device list. */
						if (prev_dev) {
							prev_dev->next = NULL;
							cur_dev = prev_dev;
						}
						else {
							cur_dev = root = NULL;
						}

						goto next;
					}

					/* Manufacturer and Product strings */
					cur_dev->manufacturer_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_MANUFACTURER]);
					cur_dev->product_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_PRODUCT]);

					/* Release Number */
					str = udev_device_get_sysattr_value(usb_dev, "bcdDevice");
					cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;

					/* Get a handle to the interface's udev node. */
					intf_dev = udev_device_get_parent_with_subsystem_devtype(
							raw_dev,
							"usb",
							"usb_interface");
					if (intf_dev) {
						str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
						cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
					}

					break;

				case BUS_BLUETOOTH:
					/* Manufacturer and Product strings */
					cur_dev->manufacturer_string = wcsdup(L"");
					cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);

					break;

				default:
					/* Unknown device type - this should never happen, as we
					 * check for USB and Bluetooth devices above */
					break;
			}
		}

	next:
		free(serial_number_utf8);
		free(product_name_utf8);
		udev_device_unref(raw_dev);
		/* hid_dev, usb_dev and intf_dev don't need to be (and can't be)
		   unref()d.  It will cause a double-free() error.  I'm not
		   sure why.  */
	}
	/* Free the enumerator and udev objects. */
	udev_enumerate_unref(enumerate);
	udev_unref(udev);

	return root;
}
/*
 * Finds information about USB devices using operating system specific facilities and API.
 * The sequence of entries in array must match with what java layer expect. If a particular USB attribute
 * is not set in descriptor or can not be obtained "---" is placed in its place.
 */
jobjectArray list_usb_devices(JNIEnv *env, jobject obj, jobject status, jint vendor_to_match) {
	int x = 0;
	struct jstrarray_list list = {0};
	jstring usb_dev_info;
	jclass strClass = NULL;
	jobjectArray usbDevicesFound = NULL;

#if defined (__linux__)
	struct udev *udev_ctx;
	struct udev_enumerate *enumerator;
	struct udev_list_entry *devices, *dev_list_entry;
	const char *sysattr_val;
	const char *path;
	struct udev_device *udev_device;
	char *endptr;
#endif
#if defined (__APPLE__)
	kern_return_t kr;
	CFDictionaryRef matching_dictionary = NULL;
	io_iterator_t iterator = 0;
	io_service_t usb_dev_obj;
	CFNumberRef num_ref;
	CFStringRef str_ref;
	int result;
	char hexcharbuffer[5];

	/* For storing USB descriptor attributes string like manufacturer, product, serial number etc.
	 * in any encoding 1024 is sufficient. We prevented malloc() every time for every new attribute. */
	char charbuffer[1024];
#endif

	init_jstrarraylist(&list, 100);

#if defined (__linux__)
	/* libudev is reference counted. Memory is freed when counts reach to zero. */
	udev_ctx = udev_new();
	enumerator = udev_enumerate_new(udev_ctx);
	udev_enumerate_add_match_subsystem(enumerator, "usb");
	udev_enumerate_scan_devices(enumerator);
	devices = udev_enumerate_get_list_entry(enumerator);

	udev_list_entry_foreach(dev_list_entry, devices) {
		path = udev_list_entry_get_name(dev_list_entry);
		udev_device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerator), path);
		if(udev_device == NULL) {
			continue;
		}

		if(strcmp("usb_device", udev_device_get_devtype(udev_device)) == 0) {
			sysattr_val = udev_device_get_sysattr_value(udev_device, "idVendor");
			if(sysattr_val != NULL) {
				if(vendor_to_match != 0) {
					/* we need to apply filter for identify specific vendor */
					if(vendor_to_match != (0x0000FFFF & (int)strtol(sysattr_val, &endptr, 16))) {
						udev_device_unref(udev_device);
						continue;
					}
				}
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			insert_jstrarraylist(&list, usb_dev_info);

			sysattr_val = udev_device_get_sysattr_value(udev_device, "idProduct");
			if(sysattr_val != NULL) {
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			insert_jstrarraylist(&list, usb_dev_info);

			sysattr_val = udev_device_get_sysattr_value(udev_device, "serial");
			if(sysattr_val != NULL) {
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			insert_jstrarraylist(&list, usb_dev_info);

			sysattr_val = udev_device_get_sysattr_value(udev_device, "product");
			if(sysattr_val != NULL) {
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			insert_jstrarraylist(&list, usb_dev_info);

			sysattr_val = udev_device_get_sysattr_value(udev_device, "manufacturer");
			if(sysattr_val != NULL) {
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			insert_jstrarraylist(&list, usb_dev_info);
		}
		udev_device_unref(udev_device);
	}
int main (void)
{
  struct udev *udev;
  struct udev_enumerate *enumerate;
  struct udev_list_entry *devices, *dev_list_entry;
  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);
  }
  /* Set up a monitor to monitor hidraw devices */
  mon = udev_monitor_new_from_netlink(udev, "udev");
  udev_monitor_filter_add_match_subsystem_devtype(mon, "hidraw", NULL);
  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);

  /* 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 (1) {
    /* 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 = 0;

    ret = select(fd+1, &fds, NULL, NULL, NULL);

    /* Check if our file descriptor has received data. */
    if (ret > 0 && FD_ISSET(fd, &fds)) {
      printf("\nselect() says there should be data\n");

      /* Make the call to receive the device.
	 select() ensured that this will not block. */
      dev = udev_monitor_receive_device(mon);
      if (dev) {
	printf("Got Device\n");
	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));
	udev_device_unref(dev);
      }
      else {
	printf("No Device from receive_device(). An error occured.\n");
      }
    }
    usleep(250*1000);
    printf(".");
    fflush(stdout);
  }

  udev_unref(udev);

  return 0;
}
Beispiel #6
0
/**
 * Probes and initializes.
 */
static int Open (vlc_object_t *obj, const struct subsys *subsys)
{
    services_discovery_t *sd = (services_discovery_t *)obj;
    services_discovery_sys_t *p_sys = malloc (sizeof (*p_sys));

    if (p_sys == NULL)
        return VLC_ENOMEM;
    sd->p_sys = p_sys;
    p_sys->subsys = subsys;
    p_sys->root = NULL;

    struct udev_monitor *mon = NULL;
    struct udev *udev = udev_new ();
    if (udev == NULL)
        goto error;

    mon = udev_monitor_new_from_netlink (udev, "udev");
    if (mon == NULL
     || udev_monitor_filter_add_match_subsystem_devtype (mon, subsys->name,
                                                         NULL))
        goto error;
    p_sys->monitor = mon;

    /* Enumerate existing devices */
    struct udev_enumerate *devenum = udev_enumerate_new (udev);
    if (devenum == NULL)
        goto error;
    if (udev_enumerate_add_match_subsystem (devenum, subsys->name))
    {
        udev_enumerate_unref (devenum);
        goto error;
    }

    udev_monitor_enable_receiving (mon);
    /* Note that we enumerate _after_ monitoring is enabled so that we do not
     * loose device events occuring while we are enumerating. We could still
     * loose events if the Netlink socket receive buffer overflows. */
    udev_enumerate_scan_devices (devenum);
    struct udev_list_entry *devlist = udev_enumerate_get_list_entry (devenum);
    struct udev_list_entry *deventry;
    udev_list_entry_foreach (deventry, devlist)
    {
        const char *path = udev_list_entry_get_name (deventry);
        struct udev_device *dev = udev_device_new_from_syspath (udev, path);
        AddDevice (sd, dev);
        udev_device_unref (dev);
    }
    udev_enumerate_unref (devenum);

    if (vlc_clone (&p_sys->thread, Run, sd, VLC_THREAD_PRIORITY_LOW))
    {   /* Fallback without thread */
        udev_monitor_unref (mon);
        udev_unref (udev);
        p_sys->monitor = NULL;
    }
    return VLC_SUCCESS;

error:
    if (mon != NULL)
        udev_monitor_unref (mon);
    if (udev != NULL)
        udev_unref (udev);
    free (p_sys);
    return VLC_EGENERIC;
}
Beispiel #7
0
 void operator()(struct udev_device* dev) const {
     udev_device_unref(dev);
 }
static int adm_monitor(struct udev *udev, int argc, char *argv[])
{
        struct sigaction act;
        sigset_t mask;
        int option;
        bool prop = false;
        bool print_kernel = false;
        bool print_udev = false;
        struct udev_list subsystem_match_list;
        struct udev_list tag_match_list;
        struct udev_monitor *udev_monitor = NULL;
        struct udev_monitor *kernel_monitor = NULL;
        int fd_ep = -1;
        int fd_kernel = -1, fd_udev = -1;
        struct epoll_event ep_kernel, ep_udev;
        int rc = 0;

        static const struct option options[] = {
                { "property", no_argument, NULL, 'p' },
                { "environment", no_argument, NULL, 'e' },
                { "kernel", no_argument, NULL, 'k' },
                { "udev", no_argument, NULL, 'u' },
                { "subsystem-match", required_argument, NULL, 's' },
                { "tag-match", required_argument, NULL, 't' },
                { "help", no_argument, NULL, 'h' },
                {}
        };

        udev_list_init(udev, &subsystem_match_list, true);
        udev_list_init(udev, &tag_match_list, true);

        for (;;) {
                option = getopt_long(argc, argv, "pekus:t:h", options, NULL);
                if (option == -1)
                        break;

                switch (option) {
                case 'p':
                case 'e':
                        prop = true;
                        break;
                case 'k':
                        print_kernel = true;
                        break;
                case 'u':
                        print_udev = true;
                        break;
                case 's':
                        {
                                char subsys[UTIL_NAME_SIZE];
                                char *devtype;

                                strscpy(subsys, sizeof(subsys), optarg);
                                devtype = strchr(subsys, '/');
                                if (devtype != NULL) {
                                        devtype[0] = '\0';
                                        devtype++;
                                }
                                udev_list_entry_add(&subsystem_match_list, subsys, devtype);
                                break;
                        }
                case 't':
                        udev_list_entry_add(&tag_match_list, optarg, NULL);
                        break;
                case 'h':
                        printf("Usage: udevadm monitor [--property] [--kernel] [--udev] [--help]\n"
                               "  --property                              print the event properties\n"
                               "  --kernel                                print kernel uevents\n"
                               "  --udev                                  print udev events\n"
                               "  --subsystem-match=<subsystem[/devtype]> filter events by subsystem\n"
                               "  --tag-match=<tag>                       filter events by tag\n"
                               "  --help\n\n");
                        goto out;
                default:
                        rc = 1;
                        goto out;
                }
        }

        if (!print_kernel && !print_udev) {
                print_kernel = true;
                print_udev = true;
        }

        /* set signal handlers */
        memset(&act, 0x00, sizeof(struct sigaction));
        act.sa_handler = sig_handler;
        sigemptyset(&act.sa_mask);
        act.sa_flags = SA_RESTART;
        sigaction(SIGINT, &act, NULL);
        sigaction(SIGTERM, &act, NULL);
        sigemptyset(&mask);
        sigaddset(&mask, SIGINT);
        sigaddset(&mask, SIGTERM);
        sigprocmask(SIG_UNBLOCK, &mask, NULL);

        fd_ep = epoll_create1(EPOLL_CLOEXEC);
        if (fd_ep < 0) {
                log_error("error creating epoll fd: %m\n");
                goto out;
        }

        printf("monitor will print the received events for:\n");
        if (print_udev) {
                struct udev_list_entry *entry;

                udev_monitor = udev_monitor_new_from_netlink(udev, "udev");
                if (udev_monitor == NULL) {
                        fprintf(stderr, "error: unable to create netlink socket\n");
                        rc = 1;
                        goto out;
                }
                udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024);
                fd_udev = udev_monitor_get_fd(udev_monitor);

                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
                        const char *subsys = udev_list_entry_get_name(entry);
                        const char *devtype = udev_list_entry_get_value(entry);

                        if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsys, devtype) < 0)
                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
                }

                udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) {
                        const char *tag = udev_list_entry_get_name(entry);

                        if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0)
                                fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag);
                }

                if (udev_monitor_enable_receiving(udev_monitor) < 0) {
                        fprintf(stderr, "error: unable to subscribe to udev events\n");
                        rc = 2;
                        goto out;
                }

                memset(&ep_udev, 0, sizeof(struct epoll_event));
                ep_udev.events = EPOLLIN;
                ep_udev.data.fd = fd_udev;
                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) {
                        log_error("fail to add fd to epoll: %m\n");
                        goto out;
                }

                printf("UDEV - the event which udev sends out after rule processing\n");
        }

        if (print_kernel) {
                struct udev_list_entry *entry;

                kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel");
                if (kernel_monitor == NULL) {
                        fprintf(stderr, "error: unable to create netlink socket\n");
                        rc = 3;
                        goto out;
                }
                udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024);
                fd_kernel = udev_monitor_get_fd(kernel_monitor);

                udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) {
                        const char *subsys = udev_list_entry_get_name(entry);

                        if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, subsys, NULL) < 0)
                                fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys);
                }

                if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
                        fprintf(stderr, "error: unable to subscribe to kernel events\n");
                        rc = 4;
                        goto out;
                }

                memset(&ep_kernel, 0, sizeof(struct epoll_event));
                ep_kernel.events = EPOLLIN;
                ep_kernel.data.fd = fd_kernel;
                if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) {
                        log_error("fail to add fd to epoll: %m\n");
                        goto out;
                }

                printf("KERNEL - the kernel uevent\n");
        }
        printf("\n");

        while (!udev_exit) {
                int fdcount;
                struct epoll_event ev[4];
                int i;

                fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1);
                if (fdcount < 0) {
                        if (errno != EINTR)
                                fprintf(stderr, "error receiving uevent message: %m\n");
                        continue;
                }

                for (i = 0; i < fdcount; i++) {
                        if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) {
                                struct udev_device *device;

                                device = udev_monitor_receive_device(kernel_monitor);
                                if (device == NULL)
                                        continue;
                                print_device(device, "KERNEL", prop);
                                udev_device_unref(device);
                        } else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
                                struct udev_device *device;

                                device = udev_monitor_receive_device(udev_monitor);
                                if (device == NULL)
                                        continue;
                                print_device(device, "UDEV", prop);
                                udev_device_unref(device);
                        }
                }
        }
out:
        if (fd_ep >= 0)
                close(fd_ep);
        udev_monitor_unref(udev_monitor);
        udev_monitor_unref(kernel_monitor);
        udev_list_cleanup(&subsystem_match_list);
        udev_list_cleanup(&tag_match_list);
        return rc;
}
Beispiel #9
0
void CUDevProvider::GetDisks(VECSOURCES& disks, bool removable)
{
  // enumerate existing block devices
  struct udev_enumerate *u_enum = udev_enumerate_new(m_udev);
  if (u_enum == NULL)
  {
    fprintf(stderr, "Error: udev_enumerate_new(udev)\n");
    return;
  }

  udev_enumerate_add_match_subsystem(u_enum, "block");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "disk");
  udev_enumerate_add_match_property(u_enum, "DEVTYPE", "partition");
  udev_enumerate_scan_devices(u_enum);

  struct udev_list_entry *u_list_ent;
  struct udev_list_entry *u_first_list_ent;
  u_first_list_ent = udev_enumerate_get_list_entry(u_enum);
  udev_list_entry_foreach(u_list_ent, u_first_list_ent)
  {
    const char *name = udev_list_entry_get_name(u_list_ent);
    struct udev *context = udev_enumerate_get_udev(u_enum);
    struct udev_device *device = udev_device_new_from_syspath(context, name);
    if (device == NULL)
      continue;

    // filter out devices that are not mounted
    const char *mountpoint = get_mountpoint(udev_device_get_devnode(device));
    if (!mountpoint)
    {
      udev_device_unref(device);
      continue;
    }

    // filter out root partition
    if (strcmp(mountpoint, "/") == 0)
    {
      udev_device_unref(device);
      continue;
    }

    // filter out things mounted on /tmp
    if (strstr(mountpoint, "/tmp"))
    {
      udev_device_unref(device);
      continue;
    }

    // look for devices on the usb bus, or mounted on */media/ (sdcards), or optical devices
    const char *bus = udev_device_get_property_value(device, "ID_BUS");
    const char *optical = udev_device_get_property_value(device, "ID_CDROM"); // matches also DVD, Blu-ray
    bool isRemovable = ((bus        && strstr(bus, "usb")) ||
                        (optical    && strstr(optical,"1"))  ||
                        (mountpoint && strstr(mountpoint, "/media/")));

    // filter according to requested device type
    if (removable != isRemovable)
    {
      udev_device_unref(device);
      continue;
    }

    const char *udev_label = udev_device_get_property_value(device, "ID_FS_LABEL");
    std::string label;
    if (udev_label)
      label = udev_label;
    else
      label = URIUtils::GetFileName(mountpoint);

    CMediaSource share;
    share.strName  = label;
    share.strPath  = mountpoint;
    share.m_ignore = true;
    if (isRemovable)
    {
      if (optical)
        share.m_iDriveType = CMediaSource::SOURCE_TYPE_DVD;
      else
        share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
    }
    else
      share.m_iDriveType = CMediaSource::SOURCE_TYPE_LOCAL;

    disks.push_back(share);
    udev_device_unref(device);
  }
  udev_enumerate_unref(u_enum);
}
Beispiel #10
0
int main(int argc, char *argv[])
{
	struct udev *udev;
	struct udev_event *event;
	struct udev_device *dev;
	struct udev_rules *rules;
	char syspath[UTIL_PATH_SIZE];
	const char *devpath;
	const char *action;
	const char *subsystem;
	struct sigaction act;
	int err = -EINVAL;

	udev = udev_new();
	if (udev == NULL)
		exit(1);
	info(udev, "version %s\n", VERSION);
	udev_selinux_init(udev);

	/* set signal handlers */
	memset(&act, 0x00, sizeof(act));
	act.sa_handler = (void (*)(int)) sig_handler;
	sigemptyset (&act.sa_mask);
	act.sa_flags = 0;
	sigaction(SIGALRM, &act, NULL);
	sigaction(SIGINT, &act, NULL);
	sigaction(SIGTERM, &act, NULL);

	/* trigger timeout to prevent hanging processes */
	alarm(UDEV_EVENT_TIMEOUT);

	action = getenv("ACTION");
	devpath = getenv("DEVPATH");
	subsystem = getenv("SUBSYSTEM");

	if (action == NULL || subsystem == NULL || devpath == NULL) {
		err(udev, "action, subsystem or devpath missing\n");
		goto exit;
	}

	rules = udev_rules_new(udev, 1);

	util_strlcpy(syspath, udev_get_sys_path(udev), sizeof(syspath));
	util_strlcat(syspath, devpath, sizeof(syspath));
	dev = udev_device_new_from_syspath(udev, syspath);
	if (dev == NULL) {
		info(udev, "unknown device '%s'\n", devpath);
		goto fail;
	}

	/* skip reading of db, but read kernel parameters */
	udev_device_set_info_loaded(dev);
	udev_device_read_uevent_file(dev);

	udev_device_set_action(dev, action);
	event = udev_event_new(dev);
	err = udev_event_execute_rules(event, rules);

	/* rules may change/disable the timeout */
	if (udev_device_get_event_timeout(dev) >= 0)
		alarm(udev_device_get_event_timeout(dev));

	if (err == 0 && !event->ignore_device && udev_get_run(udev))
		udev_event_execute_run(event);

	udev_event_unref(event);
	udev_device_unref(dev);
fail:
	udev_rules_unref(rules);
exit:
	udev_selinux_exit(udev);
	udev_unref(udev);
	if (err != 0)
		return 1;
	return 0;
}
static int get_js_number(struct udev_device *udevice)
{
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_enumerate *enumerate;
	struct udev_device *hid_parent;
	const char *hidraw_node;
	const char *hid_id;
	int number = 0;

	hid_parent = udev_device_get_parent_with_subsystem_devtype(udevice,
								"hid", NULL);

	/*
	 * Look for HID_UNIQ first for the correct behavior via BT, if
	 * HID_UNIQ is not available it means the USB bus is being used and we
	 * can rely on HID_PHYS.
	 */
	hid_id = udev_device_get_property_value(hid_parent, "HID_UNIQ");
	if (!hid_id)
		hid_id = udev_device_get_property_value(hid_parent,
							"HID_PHYS");

	hidraw_node = udev_device_get_devnode(udevice);
	if (!hid_id || !hidraw_node)
		return 0;

	enumerate = udev_enumerate_new(udev_device_get_udev(udevice));
	udev_enumerate_add_match_sysname(enumerate, "js*");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);

	udev_list_entry_foreach(dev_list_entry, devices) {
		struct udev_device *input_parent;
		struct udev_device *js_dev;
		const char *input_id;
		const char *devname;

		devname = udev_list_entry_get_name(dev_list_entry);
		js_dev = udev_device_new_from_syspath(
						udev_device_get_udev(udevice),
						devname);

		input_parent = udev_device_get_parent_with_subsystem_devtype(
							js_dev, "input", NULL);
		if (!input_parent)
			goto next;

		/* check if this is the joystick relative to the hidraw device
		 * above */
		input_id = udev_device_get_sysattr_value(input_parent, "uniq");

		/*
		 * A strlen() check is needed because input device over USB
		 * have the UNIQ attribute defined but with an empty value.
		 */
		if (!input_id || strlen(input_id) == 0)
			input_id = udev_device_get_sysattr_value(input_parent,
								 "phys");

		if (!input_id)
			goto next;

		if (!strcmp(input_id, hid_id)) {
			number = atoi(udev_device_get_sysnum(js_dev));

			/* joystick numbers start from 0, leds from 1 */
			number++;

			udev_device_unref(js_dev);
			break;
		}
next:
		udev_device_unref(js_dev);
	}

	udev_enumerate_unref(enumerate);

	return number;
}
Beispiel #12
0
static void
udev_monitor_watcher (struct udev_monitor *udev_monitor,
		      NihIoWatch *         watch,
		      NihIoEvents          events)
{
	struct udev_device *    udev_device;
	nih_local char *        subsystem = NULL;
	nih_local char *        action = NULL;
	nih_local char *        kernel = NULL;
	nih_local char *        devpath = NULL;
	nih_local char *        devname = NULL;
	nih_local char *        name = NULL;
	nih_local char **       env = NULL;
	const char *            value = NULL;
	size_t                  env_len = 0;
	DBusPendingCall *       pending_call;
	char                 *(*copy_string)(const void *, const char *) = NULL;


	udev_device = udev_monitor_receive_device (udev_monitor);
	if (! udev_device)
		return;

	copy_string = no_strip_udev_data ? nih_strdup : make_safe_string;

	value = udev_device_get_subsystem (udev_device);
	subsystem = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_action (udev_device);
	action = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_sysname (udev_device);
	kernel = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_devpath (udev_device);
	devpath = value ? copy_string (NULL, value) : NULL;

	value = udev_device_get_devnode (udev_device);
	devname = value ? copy_string (NULL, value) : NULL;

	/* Protect against the "impossible" */
	if (! action)
		goto out;

	if (! strcmp (action, "add")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-added",
					      subsystem));
	} else if (! strcmp (action, "change")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-changed",
					      subsystem));
	} else if (! strcmp (action, "remove")) {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-removed",
					      subsystem));
	} else {
		name = NIH_MUST (nih_sprintf (NULL, "%s-device-%s",
					      subsystem, action));
	}

	env = NIH_MUST (nih_str_array_new (NULL));

	if (kernel) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "KERNEL=%s", kernel));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (devpath) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "DEVPATH=%s", devpath));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (devname) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "DEVNAME=%s", devname));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (subsystem) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "SUBSYSTEM=%s", subsystem));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	if (action) {
		nih_local char *var = NULL;

		var = NIH_MUST (nih_sprintf (NULL, "ACTION=%s", action));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	for (struct udev_list_entry *list_entry = udev_device_get_properties_list_entry (udev_device);
	     list_entry != NULL;
	     list_entry = udev_list_entry_get_next (list_entry)) {
		nih_local char *udev_name = NULL;
		nih_local char *udev_value = NULL;
		nih_local char *var = NULL;

		udev_name = copy_string (NULL, udev_list_entry_get_name (list_entry));

		if (! strcmp (udev_name, "DEVPATH"))
			continue;
		if (! strcmp (udev_name, "DEVNAME"))
			continue;
		if (! strcmp (udev_name, "SUBSYSTEM"))
			continue;
		if (! strcmp (udev_name, "ACTION"))
			continue;

		udev_value = copy_string (NULL, udev_list_entry_get_value (list_entry));

		var = NIH_MUST (nih_sprintf (NULL, "%s=%s", udev_name, udev_value));
		NIH_MUST (nih_str_array_addp (&env, NULL, &env_len, var));
	}

	nih_debug ("%s %s", name, devname ? devname : "");

	pending_call = upstart_emit_event (upstart,
			name, env, FALSE,
			NULL, emit_event_error, NULL,
			NIH_DBUS_TIMEOUT_NEVER);

	if (! pending_call) {
		NihError *err;
		int saved = errno;

		err = nih_error_get ();
		nih_warn ("%s", err->message);

		if (saved != ENOMEM && subsystem)
			nih_warn ("Likely that udev '%s' event contains binary garbage", subsystem);

		nih_free (err);
	}

	dbus_pending_call_unref (pending_call);

out:
	udev_device_unref (udev_device);
}
/// Checks which key events the keypad offers. If it offers the QWERTY key
/// events, sets kbPresent to true, otherwise, to false.
void KbSliderPlugin::readKbPresent()
{
    static bool read = false;
    if (read)
        return;
    read = true;

    struct udev* udev = udev_new();
    if (udev == NULL) {
        return;
    }

    QString sysPath = QString("/sys/%1")
        .arg(findKeypadDevice());

    struct udev_device* originalDev = udev_device_new_from_syspath(udev,
                                                           sysPath.toAscii().constData());
    struct udev_device* dev = originalDev;

    const char* capabilities = 0;
    QStringList split;
    unsigned long lowBits[1] = {0};
    bool ok = false;

    if (dev == NULL) {
        goto out_udev;
    }

    // Walk to the parent until we get a device with "capabilities/key". E.g.,
    // this device is /devices/platform/something/input/inputX/eventX but we
    // need to go to the parent /devices/platform/something/input/inputX
    while (dev != NULL && udev_device_get_sysattr_value(dev, "capabilities/key") == NULL) {
        dev = udev_device_get_parent_with_subsystem_devtype(dev, "input", NULL);
        // We don't need to decrement the ref count, since the returned device
        // is not referenced, and will be cleaned up when the child device is
        // cleaned up.
    }

    // We can assume that the input device in question has events of type
    // KEY. The only thing to check is which key events are supported.

    // Get the key bitmask. The returned string contains hexadecimal numbers
    // separated by spaces. The actual key bitmask is these numbers in reverse
    // order. We're only interested in the low bits, so we check only the last
    // number.
    capabilities = udev_device_get_sysattr_value(dev, "capabilities/key");
    if (capabilities == 0)
        goto out_device;

    split = QString(capabilities).split(' ', QString::SkipEmptyParts);
    if (split.isEmpty())
        goto out_device;

    lowBits[0] = split.last().toULong(&ok, 16);
    if (!ok)
        goto out_device;

    // Check the bits KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T and KEY_Y.
    kbPresent = test_bit(KEY_Q, lowBits) && test_bit(KEY_W, lowBits) &&
        test_bit(KEY_E, lowBits) && test_bit(KEY_R, lowBits) &&
        test_bit(KEY_T, lowBits) && test_bit(KEY_Y, lowBits);

out_device:
    udev_device_unref(originalDev);
out_udev:
    udev_unref(udev);
}
LDevices *enum_devices( gchar *videodevice, struct udev *udev, int debug)
{
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices, *dev_list_entry;
    struct udev_device *dev;
    
    int num_dev = 0;
    int fd = 0;
    struct v4l2_capability v4l2_cap;
    
    if (!udev) 
    {
        /*use fall through method (sysfs)*/
        g_printf("Can't create udev...using sysfs method\n");
        return(list_devices(videodevice));
    }
    
    LDevices *listDevices = NULL;
    listDevices = g_new0( LDevices, 1);
    listDevices->listVidDevices = NULL;
    
    /* Create a list of the devices in the 'v4l2' subsystem. */
    enumerate = udev_enumerate_new(udev);
    udev_enumerate_add_match_subsystem(enumerate, "video4linux");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);
    /* For each item enumerated, print out its information.
        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);

        /* usb_device_get_devnode() returns the path to the device node
            itself in /dev. */
        const gchar *v4l2_device = udev_device_get_devnode(dev);
        if (debug) 
            g_printf("Device Node Path: %s\n", v4l2_device);
        
        /* open the device and query the capabilities */
        if ((fd = v4l2_open(v4l2_device, O_RDWR | O_NONBLOCK, 0)) < 0) 
        {
            g_printerr("ERROR opening V4L2 interface for %s\n", v4l2_device);
            v4l2_close(fd);
            continue; /*next dir entry*/
        }

        if (xioctl(fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0) 
        {
            perror("VIDIOC_QUERYCAP error");
            g_printerr("   couldn't query device %s\n", v4l2_device);
            v4l2_close(fd);
            continue; /*next dir entry*/
        }
        v4l2_close(fd);
        
        num_dev++;
        /* Update the device list*/
        listDevices->listVidDevices = g_renew(VidDevice, 
            listDevices->listVidDevices, 
            num_dev);
        listDevices->listVidDevices[num_dev-1].device = g_strdup(v4l2_device);
        listDevices->listVidDevices[num_dev-1].name = g_strdup((gchar *) v4l2_cap.card);
        listDevices->listVidDevices[num_dev-1].driver = g_strdup((gchar *) v4l2_cap.driver);
        listDevices->listVidDevices[num_dev-1].location = g_strdup((gchar *) v4l2_cap.bus_info);
        listDevices->listVidDevices[num_dev-1].valid = 1;
        if(g_strcmp0(videodevice,listDevices->listVidDevices[num_dev-1].device)==0) 
        {
            listDevices->listVidDevices[num_dev-1].current = 1;
            listDevices->current_device = num_dev-1;
        }
        else
            listDevices->listVidDevices[num_dev-1].current = 0;
        
        /* The device pointed to by dev contains information about
            the v4l2 device. In order to get information about the
            USB device, get the parent device with the
            subsystem/devtype pair of "usb"/"usb_device". This will
            be several levels up the tree, but the function will find
            it.*/
        dev = udev_device_get_parent_with_subsystem_devtype(
                dev,
                "usb",
                "usb_device");
        if (!dev) 
        {
            printf("Unable to find parent usb device.");
            continue;
        }
        
        /* From here, we can call get_sysattr_value() for each file
            in the device's /sys entry. The strings passed into these
            functions (idProduct, idVendor, serial, etc.) correspond
            directly to the files in the directory which represents
            the USB device. Note that USB strings are Unicode, UCS2
            encoded, but the strings returned from
            udev_device_get_sysattr_value() are UTF-8 encoded. */
        if (debug) 
        {
            g_printf("  VID/PID: %s %s\n",
                udev_device_get_sysattr_value(dev,"idVendor"),
                udev_device_get_sysattr_value(dev, "idProduct"));
            g_printf("  %s\n  %s\n",
                udev_device_get_sysattr_value(dev,"manufacturer"),
                udev_device_get_sysattr_value(dev,"product"));
            g_printf("  serial: %s\n",
                udev_device_get_sysattr_value(dev, "serial"));
        }
        
        listDevices->listVidDevices[num_dev-1].vendor = g_ascii_strtoull(udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16);
        listDevices->listVidDevices[num_dev-1].product = g_ascii_strtoull(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16);
        
        udev_device_unref(dev);
    }
    /* Free the enumerator object */
    udev_enumerate_unref(enumerate);
    
    listDevices->num_devices = num_dev;
    return(listDevices);

}
static void HPRescanUsbBus(struct udev *udev)
{
	int i, j;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;

	/* all reader are marked absent */
	for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
		readerTracker[i].status = READER_ABSENT;

	/* Create a list of the devices in the 'usb' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "usb");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);

	/* For each item enumerated */
	udev_list_entry_foreach(dev_list_entry, devices)
	{
		const char *devpath;
		struct udev_device *dev, *parent;
		struct _driverTracker *driver, *classdriver;
		int newreader;
		int bInterfaceNumber;
		const char *interface;

		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		devpath = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, devpath);

		/* The device pointed to by dev contains information about
		   the interface. In order to get information about the USB
		   device, get the parent device with the subsystem/devtype pair
		   of "usb"/"usb_device". This will be several levels up the
		   tree, but the function will find it.*/
		parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb",
			"usb_device");
		if (!parent)
			continue;

		devpath = udev_device_get_devnode(parent);
		if (!devpath)
		{
			/* the device disapeared? */
			Log1(PCSC_LOG_ERROR, "udev_device_get_devnode() failed");
			continue;
		}

		driver = get_driver(parent, devpath, &classdriver);
		if (NULL == driver)
			/* no driver known for this device */
			continue;

#ifdef DEBUG_HOTPLUG
		Log2(PCSC_LOG_DEBUG, "Found matching USB device: %s", devpath);
#endif

		newreader = TRUE;
		bInterfaceNumber = 0;
		interface = udev_device_get_sysattr_value(dev, "bInterfaceNumber");
		if (interface)
			bInterfaceNumber = atoi(interface);

		/* Check if the reader is a new one */
		for (j=0; j<PCSCLITE_MAX_READERS_CONTEXTS; j++)
		{
			if (readerTracker[j].devpath
				&& (strcmp(readerTracker[j].devpath, devpath) == 0)
				&& (bInterfaceNumber == readerTracker[j].bInterfaceNumber))
			{
				/* The reader is already known */
				readerTracker[j].status = READER_PRESENT;
				newreader = FALSE;
#ifdef DEBUG_HOTPLUG
				Log2(PCSC_LOG_DEBUG, "Refresh USB device: %s", devpath);
#endif
				break;
			}
		}

		/* New reader found */
		if (newreader)
			HPAddDevice(dev, parent, devpath);

		/* free device */
		udev_device_unref(dev);
	}

	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	pthread_mutex_lock(&usbNotifierMutex);
	/* check if all the previously found readers are still present */
	for (i=0; i<PCSCLITE_MAX_READERS_CONTEXTS; i++)
	{
		if ((READER_ABSENT == readerTracker[i].status)
			&& (readerTracker[i].fullName != NULL))
		{
			Log4(PCSC_LOG_INFO, "Removing USB device[%d]: %s at %s", i,
				readerTracker[i].fullName, readerTracker[i].devpath);

			RFRemoveReader(readerTracker[i].fullName,
				PCSCLITE_HP_BASE_PORT + i);

			readerTracker[i].status = READER_ABSENT;
			free(readerTracker[i].devpath);
			readerTracker[i].devpath = NULL;
			free(readerTracker[i].fullName);
			readerTracker[i].fullName = NULL;

		}
	}
	pthread_mutex_unlock(&usbNotifierMutex);
}
Beispiel #16
0
bool CUDevProvider::PumpDriveChangeEvents(IStorageEventsCallback *callback)
{
  bool changed = false;

  fd_set readfds;
  FD_ZERO(&readfds);
  FD_SET(udev_monitor_get_fd(m_udevMon), &readfds);

  // non-blocking, check the file descriptor for received data
  struct timeval tv = {0};
  int count = select(udev_monitor_get_fd(m_udevMon) + 1, &readfds, NULL, NULL, &tv);
  if (count < 0)
    return false;

  if (FD_ISSET(udev_monitor_get_fd(m_udevMon), &readfds))
  {
		struct udev_device *dev = udev_monitor_receive_device(m_udevMon);
    if (!dev)
      return false;

    const char *action  = udev_device_get_action(dev);
    if (action)
    {
      std::string label;
      const char *udev_label = udev_device_get_property_value(dev, "ID_FS_LABEL");
      const char *mountpoint = get_mountpoint(udev_device_get_devnode(dev));
      if (udev_label)
        label = udev_label;
      else if (mountpoint)
        label = URIUtils::GetFileName(mountpoint);

      const char *fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE");
      if (mountpoint && strcmp(action, "add") == 0 && (fs_usage && strcmp(fs_usage, "filesystem") == 0))
      {
        CLog::Log(LOGNOTICE, "UDev: Added %s", mountpoint);
        if (callback)
          callback->OnStorageAdded(label, mountpoint);
        changed = true;
      }
      if (strcmp(action, "remove") == 0 && (fs_usage && strcmp(fs_usage, "filesystem") == 0))
      {
        if (callback)
          callback->OnStorageSafelyRemoved(label);
        changed = true;
      }
      if (strcmp(action, "change") == 0)
      {
        if (mountpoint)
        {
          CLog::Log(LOGNOTICE, "UDev: Changed / Added %s", mountpoint);
          if (callback)
            callback->OnStorageAdded(label, mountpoint);
          changed = true;
        }
        const char *eject_request = udev_device_get_property_value(dev, "DISK_EJECT_REQUEST");
        if (eject_request && strcmp(eject_request, "1") == 0)
        {
          if (callback)
            callback->OnStorageSafelyRemoved(label);
          changed = true;
        }
      }
    }
    udev_device_unref(dev);
  }

  return changed;
}
static void HPEstablishUSBNotifications(struct udev *udev)
{
	struct udev_monitor *udev_monitor;
	int r, i;
	int fd;
	fd_set fds;

	udev_monitor = udev_monitor_new_from_netlink(udev, "udev");

	/* filter only the interfaces */
	r = udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, "usb",
		"usb_interface");
	if (r)
	{
		Log2(PCSC_LOG_ERROR, "udev_monitor_filter_add_match_subsystem_devtype() error: %d\n", r);
		return;
	}

	r = udev_monitor_enable_receiving(udev_monitor);
	if (r)
	{
		Log2(PCSC_LOG_ERROR, "udev_monitor_enable_receiving() error: %d\n", r);
		return;
	}

	/* udev monitor file descriptor */
	fd = udev_monitor_get_fd(udev_monitor);

	while (!AraKiriHotPlug)
	{
		struct udev_device *dev, *parent;
		const char *action, *devpath;

#ifdef DEBUG_HOTPLUG
		Log0(PCSC_LOG_INFO);
#endif

		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		/* wait for a udev event */
		r = select(fd+1, &fds, NULL, NULL, NULL);
		if (r < 0)
		{
			Log2(PCSC_LOG_ERROR, "select(): %s", strerror(errno));
			return;
		}

		dev = udev_monitor_receive_device(udev_monitor);
		if (!dev)
		{
			Log1(PCSC_LOG_ERROR, "udev_monitor_receive_device() error\n");
			return;
		}

		action = udev_device_get_action(dev);
		if (0 == strcmp("remove", action))
		{
			Log1(PCSC_LOG_INFO, "Device removed");
			HPRescanUsbBus(udev);
			continue;
		}

		if (strcmp("add", action))
			continue;

		parent = udev_device_get_parent_with_subsystem_devtype(dev, "usb",
			"usb_device");
		devpath = udev_device_get_devnode(parent);
		if (!devpath)
		{
			/* the device disapeared? */
			Log1(PCSC_LOG_ERROR, "udev_device_get_devnode() failed");
			continue;
		}

		HPAddDevice(dev, parent, devpath);

		/* free device */
		udev_device_unref(dev);

	}

	for (i=0; i<driverSize; i++)
	{
		/* free strings allocated by strdup() */
		free(driverTracker[i].bundleName);
		free(driverTracker[i].libraryPath);
		free(driverTracker[i].readerName);
	}
	free(driverTracker);

	Log1(PCSC_LOG_INFO, "Hotplug stopped");
} /* HPEstablishUSBNotifications */
Beispiel #18
0
/*
 * check for new devices
 * args:
 *   vd - pointer to device data (can be null)
 *
 * asserts:
 *   my_device_list.udev is not null
 *   my_device_list.udev_fd is valid (> 0)
 *   my_device_list.udev_mon is not null
 *
 * returns: true(1) if device list was updated, false(0) otherwise
 */
int check_device_list_events(v4l2_dev_t *vd)
{
	/*assertions*/
	assert(my_device_list.udev != NULL);
	assert(my_device_list.udev_fd > 0);
	assert(my_device_list.udev_mon != NULL);

    fd_set fds;
    struct timeval tv;
    int ret = 0;

    FD_ZERO(&fds);
    FD_SET(my_device_list.udev_fd, &fds);
    tv.tv_sec = 0;
    tv.tv_usec = 0;

    ret = select(my_device_list.udev_fd+1, &fds, NULL, NULL, &tv);

    /* Check if our file descriptor has received data. */
    if (ret > 0 && FD_ISSET(my_device_list.udev_fd, &fds))
    {
        /*
         * Make the call to receive the device.
         *   select() ensured that this will not block.
         */
        struct udev_device *dev = udev_monitor_receive_device(my_device_list.udev_mon);
        if (dev)
        {
            if (verbosity > 0)
            {
                printf("V4L2_CORE: Got Device event\n");
                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));
            }

            /*update device list*/
            if(my_device_list.list_devices != NULL)
				free_device_list();
            enum_v4l2_devices();
            
            /*update the current device index*/
            if(vd)
            {
				vd->this_device = v4l2core_get_device_index(vd->videodevice);
				if(vd->this_device < 0)
					vd->this_device = 0;
	
				if(my_device_list.list_devices)
					my_device_list.list_devices[vd->this_device].current = 1;
			}
			
            udev_device_unref(dev);

            return(1);
        }
        else
            fprintf(stderr, "V4L2_CORE: No Device from receive_device(). An error occured.\n");
    }

    return(0);
}
Beispiel #19
0
bool udev_initial_probe(udev_probe_device_f_t probe_device)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;
	
	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		ERROR("can't create udev");
		return false;
	}
	
	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "input");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item enumerated, print out its information.
	   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);

		/* usb_device_get_devnode() returns the path to the device node
		   itself in /dev. */
		DEBUG("Device Node Path: %s", udev_device_get_devnode(dev));

		/* From here, we can call get_sysattr_value() for each file
		   in the device's /sys entry. The strings passed into these
		   functions (idProduct, idVendor, serial, etc.) correspond
		   directly to the files in the directory which represents
		   the USB device. Note that USB strings are Unicode, UCS2
		   encoded, but the strings returned from
		   udev_device_get_sysattr_value() are UTF-8 encoded. */
		DEBUG("  VID/PID: %s %s",
		        udev_device_get_sysattr_value(dev,"idVendor"),
		        udev_device_get_sysattr_value(dev, "idProduct"));
		DEBUG("  %s\n  %s",
		        udev_device_get_sysattr_value(dev,"manufacturer"),
		        udev_device_get_sysattr_value(dev,"product"));
		DEBUG("  serial: %s",
		         udev_device_get_sysattr_value(dev, "serial"));

		probe_device(dev);

		udev_device_unref(dev);
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	udev_unref(udev);
	return true;
}
Beispiel #20
0
/*
 * enumerate available v4l2 devices
 * and creates list in vd->list_devices
 * args:
 *   none
 *
 * asserts:
 *   my_device_list.udev is not null
 *   my_device_list.list_devices is null
 *
 * returns: error code
 */
int enum_v4l2_devices()
{
    struct udev_enumerate *enumerate;
    struct udev_list_entry *devices;
    struct udev_list_entry *dev_list_entry;

    int num_dev = 0;
    struct v4l2_capability v4l2_cap;

    my_device_list.list_devices = calloc(1, sizeof(v4l2_dev_sys_data_t));
    if(my_device_list.list_devices == NULL)
	{
		fprintf(stderr, "V4L2_CORE: FATAL memory allocation failure (enum_v4l2_devices): %s\n", strerror(errno));
		exit(-1);
	}

    /* Create a list of the devices in the 'v4l2' subsystem. */
    enumerate = udev_enumerate_new(my_device_list.udev);
    udev_enumerate_add_match_subsystem(enumerate, "video4linux");
    udev_enumerate_scan_devices(enumerate);
    devices = udev_enumerate_get_list_entry(enumerate);
    /*
     * For each item enumerated, print out its information.
     * 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);
        struct udev_device *dev = udev_device_new_from_syspath(my_device_list.udev, path);

        /* usb_device_get_devnode() returns the path to the device node
            itself in /dev. */
        const char *v4l2_device = udev_device_get_devnode(dev);
        if (verbosity > 0)
            printf("V4L2_CORE: Device Node Path: %s\n", v4l2_device);

		int fd = 0;
        /* open the device and query the capabilities */
        if ((fd = v4l2_open(v4l2_device, O_RDWR | O_NONBLOCK, 0)) < 0)
        {
            fprintf(stderr, "V4L2_CORE: ERROR opening V4L2 interface for %s\n", v4l2_device);
            v4l2_close(fd);
            continue; /*next dir entry*/
        }

        if (xioctl(fd, VIDIOC_QUERYCAP, &v4l2_cap) < 0)
        {
            fprintf(stderr, "V4L2_CORE: VIDIOC_QUERYCAP error: %s\n", strerror(errno));
            fprintf(stderr, "V4L2_CORE: couldn't query device %s\n", v4l2_device);
            v4l2_close(fd);
            continue; /*next dir entry*/
        }
        v4l2_close(fd);

        num_dev++;
        /* Update the device list*/
        my_device_list.list_devices = realloc(my_device_list.list_devices, num_dev * sizeof(v4l2_dev_sys_data_t));
        if(my_device_list.list_devices == NULL)
		{
			fprintf(stderr, "V4L2_CORE: FATAL memory allocation failure (enum_v4l2_devices): %s\n", strerror(errno));
			exit(-1);
		}
        my_device_list.list_devices[num_dev-1].device = strdup(v4l2_device);
        my_device_list.list_devices[num_dev-1].name = strdup((char *) v4l2_cap.card);
        my_device_list.list_devices[num_dev-1].driver = strdup((char *) v4l2_cap.driver);
        my_device_list.list_devices[num_dev-1].location = strdup((char *) v4l2_cap.bus_info);
        my_device_list.list_devices[num_dev-1].valid = 1;
        my_device_list.list_devices[num_dev-1].current = 0;
				
        /* The device pointed to by dev contains information about
            the v4l2 device. In order to get information about the
            USB device, get the parent device with the
            subsystem/devtype pair of "usb"/"usb_device". This will
            be several levels up the tree, but the function will find
            it.*/
        dev = udev_device_get_parent_with_subsystem_devtype(
                dev,
                "usb",
                "usb_device");
        if (!dev)
        {
            fprintf(stderr, "V4L2_CORE: Unable to find parent usb device.");
            continue;
        }

        /* From here, we can call get_sysattr_value() for each file
            in the device's /sys entry. The strings passed into these
            functions (idProduct, idVendor, serial, etc.) correspond
            directly to the files in the directory which represents
            the USB device. Note that USB strings are Unicode, UCS2
            encoded, but the strings returned from
            udev_device_get_sysattr_value() are UTF-8 encoded. */
        if (verbosity > 0)
        {
            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"));
            printf("  serial: %s\n",
                udev_device_get_sysattr_value(dev, "serial"));
            printf("  busnum: %s\n",
                udev_device_get_sysattr_value(dev, "busnum"));
            printf("  devnum: %s\n",
                udev_device_get_sysattr_value(dev, "devnum"));
        }

        my_device_list.list_devices[num_dev-1].vendor = strtoull(udev_device_get_sysattr_value(dev,"idVendor"), NULL, 16);
        my_device_list.list_devices[num_dev-1].product = strtoull(udev_device_get_sysattr_value(dev, "idProduct"), NULL, 16);
        my_device_list.list_devices[num_dev-1].busnum = strtoull(udev_device_get_sysattr_value(dev, "busnum"), NULL, 10);
		my_device_list.list_devices[num_dev-1].devnum = strtoull(udev_device_get_sysattr_value(dev, "devnum"), NULL, 10);

        udev_device_unref(dev);
    }
    /* Free the enumerator object */
    udev_enumerate_unref(enumerate);

    my_device_list.num_devices = num_dev;

    return(E_OK);
}
Beispiel #21
0
void get_seecam(char cpath[]) {
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	struct udev_device *dev;

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		exit(1);
	}

	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item enumerated, print out its information.
	   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);

		/* usb_device_get_devnode() returns the path to the device node
		   itself in /dev. */
		const char * node = udev_device_get_devnode(dev);
		#if DEBUG
		printf("Device Node Path: %s\n", node);
		#endif

		/* The device pointed to by dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       dev,
		       "usb",
		       "usb_device");
		if (!dev) {
			printf("Unable to find parent usb device.");
			exit(1);
		}

		/* From here, we can call get_sysattr_value() for each file
		   in the device's /sys entry. The strings passed into these
		   functions (idProduct, idVendor, serial, etc.) correspond
		   directly to the files in the directory which represents
		   the USB device. Note that USB strings are Unicode, UCS2
		   encoded, but the strings returned from
		   udev_device_get_sysattr_value() are UTF-8 encoded. */
		if(strcmp(udev_device_get_sysattr_value(dev, "idVendor"), CAMERA_VID) == 0 &&
			strcmp(udev_device_get_sysattr_value(dev, "idProduct"), CAMERA_PID) == 0) {
			strcpy(cpath,node);
		}

		#if DEBUG
		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"));
		printf("  serial: %s\n",
		         udev_device_get_sysattr_value(dev, "serial"));
		#endif
		udev_device_unref(dev);
	}
	/* Free the enumerator object */
	udev_enumerate_unref(enumerate);

	udev_unref(udev);

	return;
}
Beispiel #22
0
/**
 * get_dmi_info:
 **/
DmiInfo *
get_dmi_info ()
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices;
	struct udev_list_entry *dev_list_entry;
	struct udev_device *dev;
	DmiInfo *info = NULL;

	udev = udev_new ();
	if (!udev) {
		g_warning ("Cannot create udev");
		return NULL;
	}

	info = g_new0 (DmiInfo, 1);

	enumerate = udev_enumerate_new (udev);
	udev_enumerate_add_match_subsystem (enumerate, "dmi");
	udev_enumerate_scan_devices (enumerate);
	devices = udev_enumerate_get_list_entry (enumerate);

	udev_list_entry_foreach (dev_list_entry, devices) {
		const char *path;
		const char *attribute;
		path = udev_list_entry_get_name (dev_list_entry);
		dev = udev_device_new_from_syspath (udev, path);

		attribute = udev_device_get_sysattr_value (dev, "sys_vendor");
		if (attribute)
			info->sys_vendor = g_strdup (attribute);

		attribute = udev_device_get_sysattr_value (dev, "bios_date");
		if (attribute)
			info->bios_date = g_strdup (attribute);

		attribute = udev_device_get_sysattr_value (dev, "bios_vendor");
		if (attribute)
			info->bios_vendor = g_strdup (attribute);

		attribute = udev_device_get_sysattr_value (dev, "bios_version");
		if (attribute)
			info->bios_version = g_strdup (attribute);

		attribute = udev_device_get_sysattr_value (dev, "product_name");
		if (attribute)
			info->product_name = g_strdup (attribute);

		attribute = udev_device_get_sysattr_value (dev, "product_version");
		if (attribute)
			info->product_version = g_strdup (attribute);

		udev_device_unref (dev);
	}

	udev_enumerate_unref (enumerate);
	udev_unref (udev);

	return info;
}
Beispiel #23
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	
	setlocale(LC_ALL,"");

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		return NULL;
	}

	/* Create a list of the devices in the 'hidraw' subsystem. */
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
	udev_enumerate_scan_devices(enumerate);
	devices = udev_enumerate_get_list_entry(enumerate);
	/* For each item, see if it matches the vid/pid, and if so
	   create a udev_device record for it */
	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *sysfs_path;
		const char *dev_path;
		const char *str;
		struct udev_device *hid_dev; // The device's HID udev node.
		struct udev_device *dev; // The actual hardware device.
		struct udev_device *intf_dev; // The device's interface (in the USB sense).
		unsigned short dev_vid;
		unsigned short dev_pid;
		
		/* Get the filename of the /sys entry for the device
		   and create a udev_device object (dev) representing it */
		sysfs_path = udev_list_entry_get_name(dev_list_entry);
		hid_dev = udev_device_new_from_syspath(udev, sysfs_path);
		dev_path = udev_device_get_devnode(hid_dev);
		
		/* The device pointed to by hid_dev contains information about
		   the hidraw device. In order to get information about the
		   USB device, get the parent device with the
		   subsystem/devtype pair of "usb"/"usb_device". This will
		   be several levels up the tree, but the function will find
		   it.*/
		dev = udev_device_get_parent_with_subsystem_devtype(
		       hid_dev,
		       "usb",
		       "usb_device");
		if (!dev) {
			/* Unable to find parent usb device. */
			goto next;
		}

		/* Get the VID/PID of the device */
		str = udev_device_get_sysattr_value(dev,"idVendor");
		dev_vid = (str)? strtol(str, NULL, 16): 0x0;
		str = udev_device_get_sysattr_value(dev, "idProduct");
		dev_pid = (str)? strtol(str, NULL, 16): 0x0;

		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 && product_id == 0x0) ||
		    (vendor_id == dev_vid && product_id == dev_pid)) {
			struct hid_device_info *tmp;
			size_t len;

		    	/* VID/PID match. Create the record. */
			tmp = malloc(sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;
			
			/* Fill out the record */
			cur_dev->next = NULL;
			str = dev_path;
			if (str) {
				len = strlen(str);
				cur_dev->path = calloc(len+1, sizeof(char));
				strncpy(cur_dev->path, str, len+1);
				cur_dev->path[len] = '\0';
			}
			else
				cur_dev->path = NULL;
			
			/* Serial Number */
			cur_dev->serial_number
				= copy_udev_string(dev, "serial");

			/* Manufacturer and Product strings */
			cur_dev->manufacturer_string
				= copy_udev_string(dev, "manufacturer");
			cur_dev->product_string
				= copy_udev_string(dev, "product");
			
			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;

			/* Release Number */
			str = udev_device_get_sysattr_value(dev, "bcdDevice");
			cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
			
			/* Interface Number */
			cur_dev->interface_number = -1;
			/* Get a handle to the interface's udev node. */
			intf_dev = udev_device_get_parent_with_subsystem_devtype(
				   hid_dev,
				   "usb",
				   "usb_interface");
			if (intf_dev) {
				str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
				cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
			}
		}
		else
			goto next;

	next:
		udev_device_unref(hid_dev);
		/* dev and intf_dev don't need to be (and can't be)
		   unref()d.  It will cause a double-free() error.  I'm not
		   sure why.  */
	}
	/* Free the enumerator and udev objects. */
	udev_enumerate_unref(enumerate);
	udev_unref(udev);
	
	return root;
}
Beispiel #24
0
libusbp_error * libusbp_serial_port_create(
    const libusbp_device * device,
    uint8_t interface_number,
    bool composite,
    libusbp_serial_port ** port)
{
    LIBUSBP_UNUSED(composite);

    if (port == NULL)
    {
        return error_create("Serial port output pointer is null.");
    }

    *port = NULL;

    if (device == NULL)
    {
        return error_create("Device is null.");
    }

    libusbp_error * error = NULL;

    libusbp_serial_port * new_port = NULL;
    if (error == NULL)
    {
        new_port = calloc(1, sizeof(libusbp_serial_port));
        if (new_port == NULL)
        {
            error = &error_no_memory;
        }
    }

    // Get the syspath of the physical device.
    char * new_device_syspath = NULL;
    if (error == NULL)
    {
        error = libusbp_device_get_os_id(device, &new_device_syspath);
    }

    // Get a udev context.
    struct udev * new_udev = NULL;
    if (error == NULL)
    {
        error = udevw_create_context(&new_udev);
    }

    // Get the USB interface device.
    struct udev_device * new_interface_dev = NULL;
    if (error == NULL)
    {
        error = udevw_get_interface(new_udev, new_device_syspath,
            interface_number, &new_interface_dev);
    }

    // Get the tty device.
    struct udev_device * new_tty_dev = NULL;
    if (error == NULL)
    {
        error = udevw_get_tty(new_udev, new_interface_dev, &new_tty_dev);
    }

    // Get the syspath of the tty device.
    if (error == NULL)
    {
        error = udevw_get_syspath_copy(new_tty_dev, &new_port->syspath);
    }

    // Get the port name (e.g. /dev/ttyACM0)
    const char * port_name = NULL;
    if (error == NULL)
    {
        port_name = udev_device_get_property_value(new_tty_dev, "DEVNAME");
        if (port_name == NULL)
        {
            error = error_create("The DEVNAME property does not exist.");
        }
    }

    // Copy the port name to the new serial port object.
    if (error == NULL)
    {
        error = string_copy(port_name, &new_port->port_name);
    }

    // Pass the new object to the caller.
    if (error == NULL)
    {
        *port = new_port;
        new_port = NULL;
    }

    if (new_tty_dev != NULL) { udev_device_unref(new_tty_dev); }
    if (new_interface_dev != NULL) { udev_device_unref(new_interface_dev); }
    if (new_udev != NULL) { udev_unref(new_udev); }
    libusbp_string_free(new_device_syspath);
    libusbp_serial_port_free(new_port);

    return error;
}
int main (int argc, char ** argv) {
	struct udev * udev;
	struct udev_device * dev;
	char * device = NULL;
   	struct udev_monitor * mon = NULL;
	fd_set readfds;
	int fdcount, devnum, errcount = 0;
	unsigned short int i, major, minor;
	short int * maxminor;

	char * notification = NULL;
	char * icon = NULL;
        NotifyNotification * netlink;
        NotifyNotification *** netlinkref;

	blkid_cache cache = NULL;
	char *read = NULL;
	blkid_tag_iterate iter;
	const char *type, *value, *devname;
	blkid_dev blkdev;

	GError * error = NULL;

	printf("%s: %s v%s (compiled: %s)\n", argv[0], PROGNAME, VERSION, DATE);

	if(!notify_init("Udev-Block-Notification")) {
		fprintf(stderr, "%s: Can't create notify.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	udev = udev_new();
	if(!udev) {
		fprintf(stderr, "%s: Can't create udev.\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	mon = udev_monitor_new_from_netlink(udev, "udev");
	udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
	udev_monitor_enable_receiving(mon);

	netlinkref = malloc(256 * sizeof(size_t));
	for(i = 0; i < 256; i++)
		netlinkref[i] = NULL;
	maxminor = malloc(256 * sizeof(short int));
	for(i = 0; i < 256; i++)
		maxminor[i] = -1;

	while (1) {
                FD_ZERO(&readfds);
                if (mon != NULL)
                        FD_SET(udev_monitor_get_fd(mon), &readfds);

                fdcount = select(udev_monitor_get_fd(mon) + 1, &readfds, NULL, NULL, NULL);

                if ((mon != NULL) && FD_ISSET(udev_monitor_get_fd(mon), &readfds)) {
			dev = udev_monitor_receive_device(mon);
			if(dev) {
				device = (char *) udev_device_get_sysname(dev);
				devnum = udev_device_get_devnum(dev);
				major = devnum / 256;
				minor = devnum - (major * 256);

				switch(udev_device_get_action(dev)[0]) {
					case 'a':
						// a: add
						notification = (char *) malloc(strlen(TEXT_ADD) + strlen(device));
						sprintf(notification, TEXT_ADD, device, major, minor);
						icon = ICON_ADD;
						break;
					case 'r':
						// r: remove
						notification = (char *) malloc(strlen(TEXT_REMOVE) + strlen(device));
						sprintf(notification, TEXT_REMOVE, device, major, minor);
						icon = ICON_REMOVE;
						break;
					case 'm':
						// m: move
						notification = (char *) malloc(strlen(TEXT_MOVE) + strlen(device));
						sprintf(notification, TEXT_MOVE, device, major, minor);
						icon = ICON_MOVE;
						break;
					case 'c':
						// c: change
						notification = (char *) malloc(strlen(TEXT_CHANGE) + strlen(device));
						sprintf(notification, TEXT_CHANGE, device, major, minor);
						icon = ICON_CHANGE;
						break;
					default:
						// we should never get here I think...
						notification = (char *) malloc(strlen(TEXT_DEFAULT) + strlen(device));
						sprintf(notification, TEXT_CHANGE, device, major, minor);
						icon = ICON_DEFAULT;
				}

				blkid_get_cache(&cache, read);
				blkdev = blkid_get_dev(cache, udev_device_get_devnode(dev), BLKID_DEV_NORMAL);
			
				if (blkdev) {
					iter = blkid_tag_iterate_begin(blkdev);
			
					while (blkid_tag_next(iter, &type, &value) == 0) {
						notification = (char *) realloc(notification, strlen(TEXT_TAG) + strlen(notification) + strlen(type) + strlen(value));
						sprintf(notification, TEXT_TAG, notification, type, value);
					}

					blkid_tag_iterate_end(iter);
					blkid_put_cache(cache);
				}

				printf("%s: %s\n", argv[0], notification);

				if (maxminor[major] < minor) {
					netlinkref[major] = realloc(netlinkref[major], (minor + 1) * sizeof(size_t));
			                while(maxminor[major] < minor)
			                        netlinkref[major][++maxminor[major]] = NULL;
			        }
					
				if (netlinkref[major][minor] == NULL) {
					netlink = notify_notification_new("Udev-Block", notification, icon);
					netlinkref[major][minor] = netlink;
				} else {
					netlink = netlinkref[major][minor];
					notify_notification_update(netlink, "Udev-Block", notification, icon);
				}

			        notify_notification_set_timeout(netlink, NOTIFICATION_TIMEOUT);
				notify_notification_set_category(netlink, "Udev-Block");
				notify_notification_set_urgency (netlink, NOTIFY_URGENCY_NORMAL);
	
				while(!notify_notification_show(netlink, &error)) {
					if (errcount > 1) {
						fprintf(stderr, "%s: Looks like we can not reconnect to notification daemon... Exiting.\n", argv[0]);
						exit(EXIT_FAILURE);
					} else {
						g_printerr("%s: Error \"%s\" while trying to show notification. Trying to reconnect.\n", argv[0], error->message);
						errcount++;

						g_error_free(error);
						error = NULL;
	
						notify_uninit();

						usleep(500 * 1000);

						if(!notify_init("Udev-Block-Notification")) {
							fprintf(stderr, "%s: Can't create notify.\n", argv[0]);
							exit(EXIT_FAILURE);
						}
					}
				}
				errcount = 0;
	
				free(notification);
				udev_device_unref(dev);
			}
	
			// This is not really needed... But we want to make shure not to eat 100% CPU if anything breaks. ;)
			usleep(500 * 1000);
		}
	}

	udev_unref(udev);
	return EXIT_SUCCESS;
}
QList<QextPortInfo> QextSerialEnumeratorPrivate::getPorts_sys()
{
    QList<QextPortInfo> infoList;
#ifndef QESP_NO_UDEV
    struct udev *ud = udev_new();
    if (!ud) {
        qCritical() << "Unable to enumerate ports because udev is not initialized.";
        return infoList;
    }

    struct udev_enumerate *enumerate = udev_enumerate_new(ud);
    udev_enumerate_add_match_subsystem(enumerate, "tty");
    udev_enumerate_scan_devices(enumerate);
    struct udev_list_entry *list = udev_enumerate_get_list_entry(enumerate);
    struct udev_list_entry *entry;
    udev_list_entry_foreach(entry, list) {
        const char *path;
        struct udev_device *dev;

        // Have to grab the actual udev device here...
        path = udev_list_entry_get_name(entry);
        dev = udev_device_new_from_syspath(ud, path);

        infoList.append(portInfoFromDevice(dev));

        // Done with this device
        udev_device_unref(dev);
    }
    // Done with the list and this udev
    udev_enumerate_unref(enumerate);
    udev_unref(ud);
#else
    QStringList portNamePrefixes, portNameList;
    portNamePrefixes << QLatin1String("ttyS*"); // list normal serial ports first

    QDir dir(QLatin1String("/dev"));
    portNameList = dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name);

    // remove the values which are not serial ports for e.g.  /dev/ttysa
    for (int i = 0; i < portNameList.size(); i++) {
        bool ok;
        QString current = portNameList.at(i);
        // remove the ttyS part, and check, if the other part is a number
        current.remove(0,4).toInt(&ok, 10);
        if (!ok) {
            portNameList.removeAt(i);
            i--;
        }
    }

    // get the non standard serial ports names
    // (USB-serial, bluetooth-serial, 18F PICs, and so on)
    // if you know an other name prefix for serial ports please let us know
    portNamePrefixes.clear();
    portNamePrefixes << QLatin1String("ttyACM*") << QLatin1String("ttyUSB*") << QLatin1String("rfcomm*");
    portNameList += dir.entryList(portNamePrefixes, (QDir::System | QDir::Files), QDir::Name);

    foreach (QString str , portNameList) {
        QextPortInfo inf;
        inf.physName = QLatin1String("/dev/")+str;
        inf.portName = str;

        if (str.contains(QLatin1String("ttyS"))) {
            inf.friendName = QLatin1String("Serial port ")+str.remove(0, 4);
        }
        else if (str.contains(QLatin1String("ttyUSB"))) {
            inf.friendName = QLatin1String("USB-serial adapter ")+str.remove(0, 6);
        }
        else if (str.contains(QLatin1String("rfcomm"))) {
            inf.friendName = QLatin1String("Bluetooth-serial adapter ")+str.remove(0, 6);
        }
        inf.enumName = QLatin1String("/dev"); // is there a more helpful name for this?
        infoList.append(inf);
    }
Beispiel #27
0
static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t *string, size_t maxlen)
{
	struct udev *udev;
	struct udev_device *udev_dev, *parent, *hid_dev;
	struct stat s;
	int ret = -1;
        char *serial_number_utf8 = NULL;
        char *product_name_utf8 = NULL;

	/* Create the udev object */
	udev = udev_new();
	if (!udev) {
		printf("Can't create udev\n");
		return -1;
	}

	/* Get the dev_t (major/minor numbers) from the file handle. */
	fstat(dev->device_handle, &s);
	/* Open a udev device from the dev_t. 'c' means character device. */
	udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
	if (udev_dev) {
		hid_dev = udev_device_get_parent_with_subsystem_devtype(
			udev_dev,
			"hid",
			NULL);
		if (hid_dev) {
			unsigned short dev_vid;
			unsigned short dev_pid;
			int bus_type;
			size_t retm;

			ret = parse_uevent_info(
			           udev_device_get_sysattr_value(hid_dev, "uevent"),
			           &bus_type,
			           &dev_vid,
			           &dev_pid,
			           &serial_number_utf8,
			           &product_name_utf8);

			if (bus_type == BUS_BLUETOOTH) {
				switch (key) {
					case DEVICE_STRING_MANUFACTURER:
						wcsncpy(string, L"", maxlen);
						ret = 0;
						break;
					case DEVICE_STRING_PRODUCT:
						retm = mbstowcs(string, product_name_utf8, maxlen);
						ret = (retm == (size_t)-1)? -1: 0;
						break;
					case DEVICE_STRING_SERIAL:
						retm = mbstowcs(string, serial_number_utf8, maxlen);
						ret = (retm == (size_t)-1)? -1: 0;
						break;
					case DEVICE_STRING_COUNT:
					default:
						ret = -1;
						break;
				}
			}
			else {
				/* This is a USB device. Find its parent USB Device node. */
				parent = udev_device_get_parent_with_subsystem_devtype(
					   udev_dev,
					   "usb",
					   "usb_device");
				if (parent) {
					const char *str;
					const char *key_str = NULL;

					if (key >= 0 && key < DEVICE_STRING_COUNT) {
						key_str = device_string_names[key];
					} else {
						ret = -1;
						goto end;
					}

					str = udev_device_get_sysattr_value(parent, key_str);
					if (str) {
						/* Convert the string from UTF-8 to wchar_t */
						retm = mbstowcs(string, str, maxlen);
						ret = (retm == (size_t)-1)? -1: 0;
						goto end;
					}
				}
			}
		}
	}

end:
        free(serial_number_utf8);
        free(product_name_utf8);

	udev_device_unref(udev_dev);
	/* parent and hid_dev don't need to be (and can't be) unref'd.
	   I'm not sure why, but they'll throw double-free() errors. */
	udev_unref(udev);

	return ret;
}
Beispiel #28
0
/* move any old watches directory out of the way, and then restore
 * the watches
 */
void udev_watch_restore(struct udev *udev)
{
    char filename[UTIL_PATH_SIZE], oldname[UTIL_PATH_SIZE];

    if (inotify_fd < 0)
        return;

    util_strlcpy(oldname, udev_get_dev_path(udev), sizeof(oldname));
    util_strlcat(oldname, "/.udev/watch.old", sizeof(oldname));

    util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
    util_strlcat(filename, "/.udev/watch", sizeof(filename));

    if (rename(filename, oldname) == 0) {
        DIR *dir;
        struct dirent *ent;

        dir = opendir(oldname);
        if (dir == NULL) {
            err(udev, "unable to open old watches dir '%s', old watches will not be restored: %m", oldname);
            return;
        }

        while ((ent = readdir(dir)) != NULL) {
            char path[UTIL_PATH_SIZE];
            char buf[UTIL_PATH_SIZE];
            ssize_t syslen;
            ssize_t len;
            struct udev_device *dev;

            if (ent->d_name[0] < '0' || ent->d_name[0] > '9')
                continue;

            util_strlcpy(path, oldname, sizeof(path));
            util_strlcat(path, "/", sizeof(path));
            util_strlcat(path, ent->d_name, sizeof(path));

            syslen = util_strlcpy(buf, udev_get_sys_path(udev), sizeof(buf));
            len = readlink(path, &buf[syslen], sizeof(buf)-syslen);
            if (len <= 0 || len >= (ssize_t)(sizeof(buf)-syslen)) {
                unlink(path);
                continue;
            }
            buf[syslen + len] = '\0';
            dbg(udev, "old watch to '%s' found\n", buf);
            dev = udev_device_new_from_syspath(udev, buf);
            if (dev == NULL) {
                unlink(path);
                continue;
            }

            info(udev, "restoring old watch on '%s'\n", udev_device_get_devnode(dev));
            udev_watch_begin(udev, dev);

            udev_device_unref(dev);
            unlink(path);
        }

        closedir(dir);
        rmdir(oldname);

    } else if (errno != ENOENT) {
        err(udev, "unable to move watches dir '%s', old watches will not be restored: %m", filename);
    }
}
static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
        struct udev *udev = udev_device_get_udev(names->pcidev);
        unsigned domain, bus, slot, func, dev_port = 0;
        size_t l;
        char *s;
        const char *attr;
        struct udev_device *pci = NULL;
        char slots[256], str[256];
        _cleanup_closedir_ DIR *dir = NULL;
        struct dirent *dent;
        int hotplug_slot = 0, err = 0;

        if (sscanf(udev_device_get_sysname(names->pcidev), "%x:%x:%x.%u", &domain, &bus, &slot, &func) != 4)
                return -ENOENT;

        /* kernel provided port index for multiple ports on a single PCI function */
        attr = udev_device_get_sysattr_value(dev, "dev_port");
        if (attr)
                dev_port = strtol(attr, NULL, 10);

        /* compose a name based on the raw kernel's PCI bus, slot numbers */
        s = names->pci_path;
        l = sizeof(names->pci_path);
        if (domain > 0)
                l = strpcpyf(&s, l, "P%u", domain);
        l = strpcpyf(&s, l, "p%us%u", bus, slot);
        if (func > 0 || is_pci_multifunction(names->pcidev))
                l = strpcpyf(&s, l, "f%u", func);
        if (dev_port > 0)
                l = strpcpyf(&s, l, "d%u", dev_port);
        if (l == 0)
                names->pci_path[0] = '\0';

        /* ACPI _SUN  -- slot user number */
        pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
        if (!pci) {
                err = -ENOENT;
                goto out;
        }
        snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
        dir = opendir(slots);
        if (!dir) {
                err = -errno;
                goto out;
        }

        for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
                int i;
                char *rest;
                char *address;

                if (dent->d_name[0] == '.')
                        continue;
                i = strtol(dent->d_name, &rest, 10);
                if (rest[0] != '\0')
                        continue;
                if (i < 1)
                        continue;
                snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
                if (read_one_line_file(str, &address) >= 0) {
                        /* match slot address with device by stripping the function */
                        if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
                                hotplug_slot = i;
                        free(address);
                }

                if (hotplug_slot > 0)
                        break;
        }

        if (hotplug_slot > 0) {
                s = names->pci_slot;
                l = sizeof(names->pci_slot);
                if (domain > 0)
                        l = strpcpyf(&s, l, "P%d", domain);
                l = strpcpyf(&s, l, "s%d", hotplug_slot);
                if (func > 0 || is_pci_multifunction(names->pcidev))
                        l = strpcpyf(&s, l, "f%d", func);
                if (dev_port > 0)
                        l = strpcpyf(&s, l, "d%d", dev_port);
                if (l == 0)
                        names->pci_slot[0] = '\0';
        }
out:
        udev_device_unref(pci);
        return err;
}
Beispiel #30
0
static char *map_block_to_usb_dev(const char *block_dev)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *devices, *dev_list_entry;
	char *usb_dev_path = NULL;

	udev = udev_new();
	if (!udev)
		err(errno, "Can't create udev");

	/* XXX Avoid the enumeration using udev_device_new_from_devnum(). */
	enumerate = udev_enumerate_new(udev);
	assert(enumerate);
	assert(!udev_enumerate_add_match_subsystem(enumerate, "block"));
	assert(!udev_enumerate_scan_devices(enumerate));
	devices = udev_enumerate_get_list_entry(enumerate);
	assert(devices);

	udev_list_entry_foreach(dev_list_entry, devices) {
		const char *sys_path, *dev_path;
		struct udev_device *dev, *parent_dev;

		/* Get the filename of the /sys entry for the device,
		 * and create a udev_device object (dev) representing it.
		 */
		sys_path = udev_list_entry_get_name(dev_list_entry);
		dev = udev_device_new_from_syspath(udev, sys_path);

		/* usb_device_get_devnode() returns the path to
		 * the device node itself in /dev.
		 */
		dev_path = udev_device_get_devnode(dev);
		if (strcmp(block_dev, dev_path)) {
			assert(!udev_device_unref(dev));
			continue;
		}

		/* The device pointed to by dev contains information about
		 * the USB device.
		 * In order to get information about the USB device,
		 * get the parent device with the subsystem/devtype pair of
		 * "usb"/"usb_device".
		 * This will be several levels up the tree,
		 * but the function will find it.
		 */
		parent_dev = udev_device_get_parent_with_subsystem_devtype(
			dev, "usb", "usb_device");
		if (!parent_dev)
			err(errno, "Unable to find parent usb device of `%s'",
				block_dev);

		usb_dev_path = strdup(udev_device_get_devnode(parent_dev));
		/* @parent_dev is not referenced, and will be freed when
		 * the child (i.e. @dev) is freed.
		 * See udev_device_get_parent_with_subsystem_devtype() for
		 * details.
		 */
		assert(!udev_device_unref(dev));
		break;
	}
	/* Free the enumerator object. */
	assert(!udev_enumerate_unref(enumerate));

	assert(!udev_unref(udev));
	return usb_dev_path;
}