如何使用/ dev / xxx路径中的C ++获取Ubuntu中设备的USB VID,PID和序列号

时间:2018-03-10 10:05:42

标签: c++ ubuntu

当USB摄像头插入Linux时,/ dev文件夹中会出现一个设备。例如,第一台摄像机将显示为video0。在我们正在构建的系统中,我们使用多个摄像头获得video0,video1和video2。

我的要求是使用C ++以编程方式读取USB摄像头的VendorID(VID),ProductID(PID)和序列号。

目前,我们使用UDEV规则将特定设备映射到/ dev / camera_one;但是我们想以编程方式读取序列号并检查设备是否未更改。

我们可以使用libudev枚举所有USB设备,因此我们知道我们可以从libudev(https://github.com/gavv/snippets/blob/master/udev/udev_monitor_usb.c)获取信息

但是我们如何使用libudev在/ dev / videoN路径下提取所需的VID,PID和序列号。

1 个答案:

答案 0 :(得分:0)

这是一个代码片段,它完全符合要求:

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

代码有两个重要方面。

首先,使用linux函数stat()获取/ dev文件的状态,此状态包含st_rdev,即device_ID。然后可以在UDEV函数udev_device_new_from_devnum()中使用它。

其次,udev_device_new_from_devnum()返回的设备是物理USB设备的“子”,它本身不知道序列号,供应商ID或产品ID。相反,您需要从设备的父级或父级的父级获取此信息。