Get Device Path Based on Usb Vid:Pid in Linux

Get device path based on USB VID:PID in Linux

libusb can't get it actually. So look at this file instead: /proc/bus/input/devices

Example line from the file:

I: Bus=0003 Vendor=1a2c Product=0c23 Version=0110
N: Name="USB USB Keyboard"
P: Phys=usb-0000:00:14.0-3/input0
S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0/0003:1A2C:0C23.0015/input/input30
U: Uniq=
H: Handlers=sysrq kbd event10 leds
B: PROP=0
B: EV=120013
B: KEY=1000000000007 ff800000000007ff febeffdff3cfffff fffffffffffffffe
B: MSC=10
B: LED=7

This function gets the event number from the device with the matching VID:PID:

#include <string>
#include <iostream>
#include <fstream>

void open_device (std::string device_vid, std::string device_pid)
{
try
{
std::ifstream file_input;
std::size_t pos;
std::string device_path, current_line, search_str, event_str;
std::string device_list_file = "/proc/bus/input/devices";
bool vid_pid_found = false;
int fd = 0;
bool debug = true;

// 1. open device list file
file_input.open(device_list_file.c_str());
if (!file_input.is_open())
{
std::cerr << "file_input.open >> " << std::strerror(errno) << std::endl;
throw -2;
}

// 2. search for first VID:PID and get event number
search_str = "Vendor=" + device_vid + " Product=" + device_pid;
while (getline(file_input, current_line))
{
if (!vid_pid_found)
{
pos = current_line.find(search_str, 0);
if (pos != std::string::npos)
{
vid_pid_found = true;
search_str = "event";
}
}
else
{
pos = current_line.find(search_str, 0);
if (pos != std::string::npos)
{
event_str = current_line.substr(pos);
// find space and substring event##
pos = event_str.find(' ', 0);
event_str = event_str.substr(0, pos);
break;
}
}
}

// 3. build device path
device_path = "/dev/input/" + event_str;
if (debug) std::cout << "device_path = " << device_path << std::endl;

// 4. connect to device
fd = open (device_path.c_str(), O_RDONLY);
if (fd < 0)
{
std::cerr << "open >> errno = " << std::strerror(errno) << std::endl;
throw -3;
}
}
catch (const std::exception &e)
{
std::cerr << "e.what() = " << e.what() << std::endl;
throw -1;
}

return;
}

Find /dev entry with VID/PID of USB device

you can use udevadm for this

in the output of udevadm info -q property -n /dev/sd* the VID is in the ID_VENDOR_ID field and the PID is in the ID_MODEL_ID field

you can extract this using grep / sed...

How to determine sysfs devpath from USB device VID and PID in Python?

You might try using the sysfs path for usb devices, /sys/bus/usb/devices/, and globbing for the idProduct and idVendor files

/sys/bus/usb/devices/*/idProduct
/sys/bus/usb/devices/*/idVendor

How to get the USB VID, PID and serial number of a device in Ubuntu using C++ from /dev/xxx path

Here is a code snippet the does exactly what is being asked:

void ReadUsbIdentifiers(std::string dev_path){
auto udev = udev_new();
if (!udev) { return; }

struct stat statbuf;
if (stat(dev_path.c_str(), &statbuf) < 0) { return; }
auto type = S_ISBLK(statbuf.st_mode) ? 'b' : S_ISCHR(statbuf.st_mode) ? 'c' : 0;

auto opened_dev = udev_device_new_from_devnum(udev, type, statbuf.st_rdev);
auto dev = opened_dev;

while (dev != nullptr)
{
auto serial = udev_device_get_sysattr_value(dev, "serial");
if (nullptr == serial)
{
dev = udev_device_get_parent(dev);
}
else
{
std::cout << "VID: " << udev_device_get_sysattr_value(dev, "idVendor") << std::endl;
std::cout << "PID: " << udev_device_get_sysattr_value(dev, "idProduct") << std::endl;
std::cout << "Serial Number: " << serial << std::endl;
}
}
if (opened_dev) { udev_device_unref(opened_dev); }
udev_unref(udev);
}

There are two significant aspects to the code.

Firstly, you use the linux function stat() to get the /dev file’s status, and this status contains the st_rdev which is the device_ID. This can then be used in the UDEV function udev_device_new_from_devnum().

Secondly, the device returned by udev_device_new_from_devnum() is a ‘child’ of the physical USB device, and it does not itself know the serial number, vendor Id or product Id. Instead you need to get this information from the parent of the device, or the parent’s parent.

linux / libusb get usb device path

Since libusb 1.0.12, they have introduced libusb_get_port_path(), and in 1.0.16 replaced it with libusb_get_port_numbers() which allows you to query the bus topology.



Related Topics



Leave a reply



Submit