Пример #1
0
/* add or remove a ACL for a given uid from all matching devices */
static void apply_acl_to_devices(uid_t uid, int add)
{
	struct udev *udev;
	struct udev_enumerate *enumerate;
	struct udev_list_entry *list_entry;

	/* iterate over all devices tagged with ACL_SET */
	udev = udev_new();
	enumerate = udev_enumerate_new(udev);
	udev_enumerate_add_match_tag(enumerate, "udev-acl");
	udev_enumerate_scan_devices(enumerate);
	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
		struct udev_device *device;
		const char *node;

		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
						      udev_list_entry_get_name(list_entry));
		if (device == NULL)
			continue;
		node = udev_device_get_devnode(device);
		if (node == NULL)
			continue;
		set_facl(node, uid, add);
		udev_device_unref(device);
	}
	udev_enumerate_unref(enumerate);
	udev_unref(udev);
}
Пример #2
0
/////////////////////////////////////////////////////////////////////////////
/// enumerate existing devices
void DeviceMonitor::enumDevices_( ) {
	assert( dev_context_ );
	
	// create udev enumeration interface
	std::tr1::shared_ptr< udev_enumerate > dev_enum( udev_enumerate_new( dev_context_ ), &udev_enumerate_unref );
	
	// only interested in scsi_device's
	udev_enumerate_add_match_subsystem( dev_enum.get(), "block" );
	udev_enumerate_add_match_property( dev_enum.get(), "ID_BUS", "ata" );
	udev_enumerate_scan_devices( dev_enum.get() ); // start
	
	//- enumerate list
	udev_list_entry* list_entry = udev_enumerate_get_list_entry( dev_enum.get() );
	for ( ; list_entry; list_entry = udev_list_entry_get_next( list_entry ) ) {
		// retrieve device
		std::tr1::shared_ptr< udev_device > device(
			udev_device_new_from_syspath(
				udev_enumerate_get_udev( dev_enum.get() ),
				udev_list_entry_get_name( list_entry )
			), &udev_device_unref
		);
                if ( !device ) continue;

		if (!acceptDevice_(device.get())) continue;

		int led_idx = scsiHostIndex_(device.get());
		if (led_idx < 0) continue;
		if (debug || verbose > 1) std::cout << " device: " << udev_device_get_syspath(device.get()) << "\n led: " << led_idx << "\n";

		leds_idx_[num_disks_] = led_idx;

                stats_files_[num_disks_] = std::string( udev_device_get_syspath(device.get()) );
                stats_files_[num_disks_].append( "/stat" );

                // make sure it's there and we can open it
                std::ifstream stats;
                stats.open( stats_files_[num_disks_].c_str() );
                if( !stats )
                {
                    std::cout << " Couldn't open stats " << stats_files_[num_disks_] << "\n";
                    continue;
                }
                else
                    stats.close();

                ++num_disks_;

		deviceAdded_( device.get() );
	}
}
Пример #3
0
int Storage::enumerate_mmcblk_devices(struct udev *udev)
{
    struct udev_enumerate *udev_enumerate;

    qDebug() << Q_FUNC_INFO << ": enumerate 'block' devices";
    udev_enumerate = udev_enumerate_new(udev);
    if (udev_enumerate == NULL)
        return -1;
    udev_enumerate_add_match_subsystem(udev_enumerate,"block");
    udev_enumerate_scan_devices(udev_enumerate);
    struct udev_list_entry *list_entry;

    udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate))
    {
        struct udev_device *device;

        device = udev_device_new_from_syspath(udev_enumerate_get_udev(udev_enumerate),
                                      udev_list_entry_get_name(list_entry));
        if (device != NULL) {
            QString sysname("/dev/");
            sysname += QString(udev_device_get_sysname(device));
            if (sysname.contains(QRegExp("mmcblk[1-9]\\d*"))  || sysname.contains(QRegExp("mmcblk[1-9]")))
            {
                QString path = udev_device_get_devpath(device);
                QString parent = udev_device_get_devpath( udev_device_get_parent (device));
                QString action = "add";
                QString devtype = udev_device_get_devtype(device);

                qDebug() << "Enumerate device " << path << ":" << action;
                qDebug() << "    Got Device";
                qDebug() << "    Node: " <<  udev_device_get_devnode(device);
                qDebug() << "    Subsystem: "<< udev_device_get_subsystem(device);
                qDebug() << "    Devtype: " << devtype;
                qDebug() << "    Action: " << action;
                qDebug() << "    Sysname: " << sysname;
                qDebug() << "    sysnum: " << udev_device_get_sysnum (device);
                qDebug() << "    parent: " << parent;

                processRemovableUdevEvents(devtype, path, sysname, action);
            }

            udev_device_unref(device);
        }
    }

    udev_enumerate_unref(udev_enumerate);
    return 0;
}
Пример #4
0
static void exec_list(struct udev_enumerate *udev_enumerate, const char *action)
{
	struct udev *udev = udev_enumerate_get_udev(udev_enumerate);
	struct udev_list_entry *entry;

	udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) {
		char filename[UTIL_PATH_SIZE];
		int fd;

		if (verbose)
			printf("%s\n", udev_list_entry_get_name(entry));
		if (dry_run)
			continue;
		util_strscpyl(filename, sizeof(filename), udev_list_entry_get_name(entry), "/uevent", NULL);
		fd = open(filename, O_WRONLY);
		if (fd < 0) {
			dbg(udev, "error on opening %s: %m\n", filename);
			continue;
		}
		if (write(fd, action, strlen(action)) < 0)
			info(udev, "error writing '%s' to '%s': %m\n", action, filename);
		close(fd);
	}
Пример #5
0
static int usb_dongle_probe_print_list(struct udev_enumerate *enumerate)
{
	struct udev_list_entry *list_entry;
	unsigned int vid, pid;
	int ret = -1;

	udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) {
		struct udev_device *device;

		device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate),
				udev_list_entry_get_name(list_entry));
		if (device != NULL) {
			mylog_info("device: '%s' (%s)\n",
					udev_device_get_syspath(device),
					udev_device_get_subsystem(device));
			get_vid_pid(device, &vid, &pid);
			ret = wlan_driver_match(vid, pid, wlan_driver_add_callback);
			udev_device_unref(device);
			if (!ret)
				break;
		}
	}
	return ret;
}
jobjectArray getusb_firmware_version(JNIEnv *env, jint usbvid_to_match, jint usbpid_to_match, jstring serial_number) {

	int x = 0;
	int vid = 0;
	int pid = 0;
	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;
	char buffer[128];
	const char* serial = NULL;
	const char *prop_val;
	struct jstrarray_list list = {0};
	jstring usb_dev_info;
	jclass strClass = NULL;
	jobjectArray usbDevicesFwVerFound = NULL;

	if(serial_number != NULL) {
		serial = (*env)->GetStringUTFChars(env, serial_number, NULL);
		if((serial == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
			throw_serialcom_exception(env, 3, 0, E_GETSTRUTFCHARSTR);
			return NULL;
		}
	}

	init_jstrarraylist(&list, 10);

	/* 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) {

			/* match vid */
			sysattr_val = udev_device_get_sysattr_value(udev_device, "idVendor");
			if(sysattr_val != NULL) {
				vid = 0x0000FFFF & (int)strtol(sysattr_val, &endptr, 16);
				if(vid != usbvid_to_match) {
					udev_device_unref(udev_device);
					continue;
				}
			}else {
				udev_device_unref(udev_device);
				continue;
			}

			/* match pid */
			sysattr_val = udev_device_get_sysattr_value(udev_device, "idProduct");
			if(sysattr_val != NULL) {
				pid = 0x0000FFFF & (int)strtol(sysattr_val, &endptr, 16);
				if(pid != usbpid_to_match) {
					udev_device_unref(udev_device);
					continue;
				}
			}else {
				udev_device_unref(udev_device);
				continue;
			}

			/* match serial number if requested by application */
			if (serial != NULL) {
				sysattr_val = udev_device_get_sysattr_value(udev_device, "serial");
				if(sysattr_val != NULL) {
					if(strcasecmp(sysattr_val, serial) != 0) {
						udev_device_unref(udev_device);
						continue;
					}
				}else {
					udev_device_unref(udev_device);
					continue;
				}
			}

			/* reaching here means that this is the device whose firmware version application need to know. */
			prop_val = udev_device_get_property_value(udev_device, "ID_REVISION");
			memset(buffer, '\0', sizeof(buffer));
			snprintf(buffer, 128, "%d", (0x0000FFFF & (int)strtol(prop_val, &endptr, 16)));
			usb_dev_info = (*env)->NewStringUTF(env, buffer);
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				free_jstrarraylist(&list);
				udev_device_unref(udev_device);
				udev_enumerate_unref(enumerator);
				udev_unref(udev_ctx);
				throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
				return NULL;
			}
			insert_jstrarraylist(&list, usb_dev_info);
		}
		udev_device_unref(udev_device);
	}
/*
 * 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 (6 informations
 * per USB device). If a particular USB attribute is not set in descriptor or can not be
 * obtained "---" is placed in its place.
 *
 * Return array of USB device's information found, empty array if no USB device is found,
 * NULL if an error occurs (additionally throws exception).
 */
jobjectArray list_usb_devices(JNIEnv *env, jint vendor_to_match) {
	int x = 0;
	struct jstrarray_list list = {0};
	jstring usb_dev_info;
	jclass strClass = NULL;
	jobjectArray usbDevicesFound = NULL;

	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;

	init_jstrarraylist(&list, 100);

	/* 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) {
			/* USB-IF vendor ID */
			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, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

			/* USB product ID */
			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, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

			/* SERIAL NUMBER */
			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, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

			/* PRODUCT */
			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, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

			/* MANUFACTURER */
			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, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

			/* LOCATION (constructed) TODO*/
			sysattr_val = udev_device_get_sysattr_value(udev_device, "busnum");
			if(sysattr_val != NULL) {
				usb_dev_info = (*env)->NewStringUTF(env, sysattr_val);
			}else {
				usb_dev_info = (*env)->NewStringUTF(env, "---");
			}
			if((usb_dev_info == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
				return linux_listusb_clean_throw_exp(env, 1, NULL, &list, udev_device, enumerator, udev_ctx);
			}
			insert_jstrarraylist(&list, usb_dev_info);

		}
		udev_device_unref(udev_device);
	}
Пример #8
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 things mounted on /tmp
    if (strstr(mountpoint, "/tmp"))
    {
      udev_device_unref(device);
      continue;
    }

    // look for usb devices on the usb bus, or mounted on /media/usbX (sdcards) or cdroms
    const char *bus = udev_device_get_property_value(device, "ID_BUS");
    const char *cdrom = udev_device_get_property_value(device, "ID_CDROM");
    if (removable  &&
      ((bus        && strstr(bus, "usb")) ||
       (cdrom      && strstr(cdrom,"1"))  ||
       (mountpoint && strstr(mountpoint, "/media/"))))
    {
      const char *label = udev_device_get_property_value(device, "ID_FS_LABEL");
      if (!label)
        label = URIUtils::GetFileName(mountpoint);

      CMediaSource share;
      share.strName  = label;
      share.strPath  = mountpoint;
      share.m_ignore = true;
      share.m_iDriveType = CMediaSource::SOURCE_TYPE_REMOVABLE;
      AddOrReplace(disks, share);
    }
    udev_device_unref(device);
  }
  udev_enumerate_unref(u_enum);
}
/*
 * Find the name of the driver which is currently associated with the given HID device.
 *
 * A HID device can be on usb, bluetooth or pseudo. For Linux we walk down the
 * sysfs tree until a driver is found for the given device node.
 */
jstring linux_find_driver_for_given_hiddevice(JNIEnv *env, jstring hidDevNode) {

	const char* hid_name_to_match = NULL;
	jstring driver_name = NULL;
	int check_for_parent = -1;
	struct udev *udev_ctx;
	struct udev_enumerate *enumerator;
	struct udev_list_entry *devices, *dev_list_entry;
	const char *prop_val_driver_name;
	const char *device_node;
	const char *path;
	struct udev_device *udev_device;
	struct udev_device *parent_device;

	hid_name_to_match = (*env)->GetStringUTFChars(env, hidDevNode, NULL);
	if((hid_name_to_match == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		throw_serialcom_exception(env, 3, 0, E_GETSTRUTFCHARSTR);
		return NULL;
	}

	udev_ctx = udev_new();
	enumerator = udev_enumerate_new(udev_ctx);
	udev_enumerate_add_match_subsystem(enumerator, "hidraw");
	udev_enumerate_scan_devices(enumerator);
	devices = udev_enumerate_get_list_entry(enumerator);

	udev_list_entry_foreach(dev_list_entry, devices) {

		/* from the sysfs filename create a udev_device object representing it. */
		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;
		}

		/* get the device node for this udev device. */
		device_node = udev_device_get_devnode(udev_device);

		/* If the device node name matches what we are looking for get driver for it.
		 * if we fail to get driver name than return empty string (prop_val_driver_name
		 * will be NULL when control reaches at the end of this function). */
		if(device_node != NULL) {
			if(strcmp(hid_name_to_match, device_node) == 0) {
				prop_val_driver_name = udev_device_get_driver(udev_device);
				if(prop_val_driver_name != NULL) {
					driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
					if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
						(*env)->ExceptionClear(env);
						udev_device_unref(udev_device);
						udev_enumerate_unref(enumerator);
						udev_unref(udev_ctx);
						(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
						throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
						return NULL;
					}
					check_for_parent = -1;
				}else {
					check_for_parent = 1;
				}

				if(check_for_parent == 1) {
					parent_device = udev_device_get_parent(udev_device);
					if(parent_device != NULL) {
						prop_val_driver_name = udev_device_get_driver(parent_device);
						if(prop_val_driver_name != NULL) {
							driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
							if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
								(*env)->ExceptionClear(env);
								udev_device_unref(udev_device);
								udev_enumerate_unref(enumerator);
								udev_unref(udev_ctx);
								(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
								throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
								return NULL;
							}else {
								/* if both the parent and driver found, return driver name to caller. */
								check_for_parent = -1;
							}
						}else {
							/* if the parent is found but driver not found then analyze next parent device. */
							check_for_parent = 1;
						}
					}else {
						/* if the parent does not exist, make no more attempts to analyze parent devices further down the tree. */
						check_for_parent = -1;
					}
				}

				if(check_for_parent == 1) {
					parent_device = udev_device_get_parent(parent_device );
					if(parent_device != NULL) {
						prop_val_driver_name = udev_device_get_driver(parent_device);
						if(prop_val_driver_name != NULL) {
							driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
							if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
								(*env)->ExceptionClear(env);
								udev_device_unref(udev_device);
								udev_enumerate_unref(enumerator);
								udev_unref(udev_ctx);
								(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
								throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
								return NULL;
							}else {
								check_for_parent = -1;
							}
						}else {
							check_for_parent = 1;
						}
					}else {
						check_for_parent = -1;
					}
				}

				if(check_for_parent == 1) {
					parent_device = udev_device_get_parent(parent_device);
					if(parent_device != NULL) {
						prop_val_driver_name = udev_device_get_driver(parent_device);
						if(prop_val_driver_name != NULL) {
							driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
							if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
								(*env)->ExceptionClear(env);
								udev_device_unref(udev_device);
								udev_enumerate_unref(enumerator);
								udev_unref(udev_ctx);
								(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
								throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
								return NULL;
							}else {
								check_for_parent = -1;
							}
						}else {
							check_for_parent = 1;
						}
					}else {
						check_for_parent = -1;
					}
				}

				if(check_for_parent == 1) {
					parent_device = udev_device_get_parent(udev_device);
					if(parent_device != NULL) {
						prop_val_driver_name = udev_device_get_driver(parent_device );
						if(prop_val_driver_name != NULL) {
							driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
							if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
								(*env)->ExceptionClear(env);
								udev_device_unref(udev_device);
								udev_enumerate_unref(enumerator);
								udev_unref(udev_ctx);
								(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
								throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
								return NULL;
							}else {
								check_for_parent = -1;
							}
						}else {
							check_for_parent = 1;
						}
					}else {
						check_for_parent = -1;
					}
				}

				if(check_for_parent == 1) {
					parent_device = udev_device_get_parent(parent_device);
					if(parent_device != NULL) {
						prop_val_driver_name = udev_device_get_driver(parent_device);
						if(prop_val_driver_name != NULL) {
							driver_name = (*env)->NewStringUTF(env, prop_val_driver_name);
							if((driver_name == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
								(*env)->ExceptionClear(env);
								udev_device_unref(udev_device);
								udev_enumerate_unref(enumerator);
								udev_unref(udev_ctx);
								(*env)->ReleaseStringUTFChars(env, hidDevNode, hid_name_to_match);
								throw_serialcom_exception(env, 3, 0, E_NEWSTRUTFSTR);
								return NULL;
							}
						}
					}
				}

				/* whether prop_val_driver_name is NULL (return empty string) or not
				 * (return driver name found), no more iteration is needed. */
				udev_device_unref(udev_device);
				break;
			}
		}

		/* released only after desired property value has been saved to some
		 * other memory region like one got from NewStringUTF(). */
		udev_device_unref(udev_device);
	}
/*
 * get the current latency timer value for ftdi devices.
 * return value read on success or -1 if any error occurs.
 */
jint get_latency_timer_value(JNIEnv *env, jstring comPortName) {

	struct udev *udev_ctx;
	struct udev_enumerate *enumerator;
	struct udev_list_entry *devices, *dev_list_entry;
	const char *device_path;
	const char *device_node;
	const char *path;
	struct udev_device *udev_device;
	const char *com_port_to_match = NULL;
	char buffer[512];
	int fd = 0;
	int ret = 0;
	char *endptr;
	jint timer_value = 0;

	udev_ctx = udev_new();
	enumerator = udev_enumerate_new(udev_ctx);
	udev_enumerate_add_match_subsystem(enumerator, "tty");
	udev_enumerate_scan_devices(enumerator);
	devices = udev_enumerate_get_list_entry(enumerator);

	com_port_to_match = (*env)->GetStringUTFChars(env, comPortName, NULL);
	if((com_port_to_match == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
		throw_serialcom_exception(env, 3, 0, E_GETSTRUTFCHARSTR);
		return -1;
	}

	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;
		}

		/* match the device node, if matched get device path, and create absolute path to
		 * latency file and read its value */
		device_node = udev_device_get_devnode(udev_device);
		if(device_node != NULL) {
			if(strcmp(device_node, com_port_to_match) == 0) {

				device_path = udev_device_get_devpath(udev_device);
				if(device_path != NULL) {
					memset(buffer, '\0', sizeof(buffer));
					snprintf(buffer, 512, "/sys%s/device/latency_timer", device_path);

					errno = 0;
					fd = open(buffer, O_RDONLY);
					if(fd < 0) {
						(*env)->ReleaseStringUTFChars(env, comPortName, com_port_to_match);
						throw_serialcom_exception(env, 1, errno, NULL);
						return -1;
					}

					memset(buffer, '\0', sizeof(buffer));
					errno = 0;
					ret = read(fd, buffer, 512);
					if(ret < 0) {
						(*env)->ReleaseStringUTFChars(env, comPortName, com_port_to_match);
						throw_serialcom_exception(env, 1, errno, NULL);
						return -1;
					}
					close(fd);

					timer_value = (jint) strtol(buffer, &endptr, 10);
					(*env)->ReleaseStringUTFChars(env, comPortName, com_port_to_match);
					udev_device_unref(udev_device);
					udev_enumerate_unref(enumerator);
					udev_unref(udev_ctx);
					return timer_value;
				}
			}
		}

		udev_device_unref(udev_device);
	}
/*
 * Find device nodes (like COMxx, ttyUSBxx etc) assigned by operating system to the USB-UART bridge/converter(s)
 * from the USB device attributes.
 *
 * The USB strings are Unicode, UCS2 encoded, but the strings returned from udev_device_get_sysattr_value() are UTF-8 encoded.
 * GetStringUTFChars() returns in modified UTF-8 encoding.
 */
jobjectArray vcp_node_from_usb_attributes(JNIEnv *env, jobject obj, jint usbvid_to_match, jint usbpid_to_match, jstring serial_num, jobject status) {
	int x = 0;
	struct jstrarray_list list = {0};
	jclass strClass = NULL;
	jobjectArray vcpPortsFound = NULL;
	const char* serial_to_match = NULL;
	jstring vcp_node;

#if defined (__linux__)
	struct udev *udev_ctx;
	struct udev_enumerate *enumerator;
	struct udev_list_entry *devices, *dev_list_entry;
	const char *prop_val;
	const char *path;
	struct udev_device *udev_device;
	int usb_vid;
	int usb_pid;
	char *endptr;
	int matched;
#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, 50);
	if(serial_num != NULL) {
		serial_to_match = (*env)->GetStringUTFChars(env, serial_num, NULL);
		if(serial_to_match == NULL) {
			/* handle error */
		}
	}

#if defined (__linux__)
	udev_ctx = udev_new();
	enumerator = udev_enumerate_new(udev_ctx);
	udev_enumerate_add_match_subsystem(enumerator, "tty");
	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;
		}

		matched = 0;
		prop_val = udev_device_get_property_value(udev_device, "ID_VENDOR_ID");
		if(prop_val != NULL) {
			usb_vid = 0x0000FFFF & (int) strtol(prop_val, &endptr, 16);
			if(usb_vid == usbvid_to_match) {
				matched = 1;
			}
		}
		if(matched == 0) {
			udev_device_unref(udev_device);
			continue;
		}

		matched = 0;
		prop_val = udev_device_get_property_value(udev_device, "ID_MODEL_ID");
		if(prop_val != NULL) {
			usb_pid = 0x0000FFFF & (int) strtol(prop_val, &endptr, 16);
			if(usb_pid == usbpid_to_match) {
				matched = 1;
			}
		}
		if(matched == 0) {
			udev_device_unref(udev_device);
			continue;
		}

		if(serial_to_match != NULL) {
			matched = 0;
			prop_val = udev_device_get_property_value(udev_device, "ID_SERIAL_SHORT");
			if(prop_val != NULL) {
				if(!strcasecmp(prop_val, serial_to_match)) {
					matched = 1;
				}
			}
		}

		if(matched == 1) {
			/* this device met all criteria, get dev node for this */
			prop_val = udev_device_get_property_value(udev_device, "DEVNAME");
			if(prop_val != NULL) {
				vcp_node = (*env)->NewStringUTF(env, prop_val);
				if(vcp_node != NULL) {
					insert_jstrarraylist(&list, vcp_node);
				}
			}
		}

		udev_device_unref(udev_device);
	}
/*
 * 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);
	}
Пример #13
0
io_device_iterator::io_device_iterator(udev_enumerate* uenum)
	: m_uenum(uenum)
{
	m_udev = udev_enumerate_get_udev(m_uenum);
	reset();
}
Пример #14
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);
}
/*
 * Finds if a USB device whose VID, PID and serial number is given is connected to system
 * or not using platform specific APIs.
 *
 * Returns 1 if device is connected, returns 0 if not connected, -1 if an error occurs.
 */
jint is_usb_dev_connected(JNIEnv *env, jint usbvid_to_match, jint usbpid_to_match, jstring serial_number) {

	int vid = 0;
	int pid = 0;
	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;
	const char* serial = NULL;

	if(serial_number != NULL) {
		serial = (*env)->GetStringUTFChars(env, serial_number, NULL);
		if((serial == NULL) || ((*env)->ExceptionOccurred(env) != NULL)) {
			throw_serialcom_exception(env, 3, 0, E_GETSTRUTFCHARSTR);
			return -1;
		}
	}

	/* 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) {

			/* match vid */
			sysattr_val = udev_device_get_sysattr_value(udev_device, "idVendor");
			if(sysattr_val != NULL) {
				vid = 0x0000FFFF & (int)strtol(sysattr_val, &endptr, 16);
				if(vid != usbvid_to_match) {
					udev_device_unref(udev_device);
					continue;
				}
			}else {
				udev_device_unref(udev_device);
				continue;
			}

			/* match pid */
			sysattr_val = udev_device_get_sysattr_value(udev_device, "idProduct");
			if(sysattr_val != NULL) {
				pid = 0x0000FFFF & (int)strtol(sysattr_val, &endptr, 16);
				if(pid != usbpid_to_match) {
					udev_device_unref(udev_device);
					continue;
				}
			}else {
				udev_device_unref(udev_device);
				continue;
			}

			/* match serial number if requested by application */
			if (serial != NULL) {
				sysattr_val = udev_device_get_sysattr_value(udev_device, "serial");
				if(sysattr_val != NULL) {
					if(strcasecmp(sysattr_val, serial) != 0) {
						udev_device_unref(udev_device);
						continue;
					}
				}else {
					udev_device_unref(udev_device);
					continue;
				}
			}

			/* reaching here means device is connected to system at present which matches given criteria. */
			udev_device_unref(udev_device);
			udev_enumerate_unref(enumerator);
			udev_unref(udev_ctx);
			return 1;
		}
		udev_device_unref(udev_device);
	}