libusb node usb get device instance path - node.js

Using Device Manager in windows on a USB device I get this in the device instance path property:
USB\VID_0403&PID_E868\02302692
I'm trying to get this info from the Node USB library which is based on libusb. When I query I get these values:
idVendor: 1027,
idProduct: 59496,
bcdDevice: 1536,
iSerialNumber: 3,
Which when converted are those values in the device manager.
//E868 = 59496
//1027 = 403
//1536 = 600
HOWEVER, I can't seem to find the \02302692. When I run lsusb -v that value is also not there.
Where is Windows getting the \02302692. If using libusb what is the property that retrieves that value? I thought it was the iSerialNumber??
To get what I have I'm calling
var lxdevice = usb.findByIds(1027, 59496);
console.log(lxdevice.deviceDescriptor);
in the node usb library. https://github.com/tessel/node-usb

Related

libudev udev_device_get_sysattr_value() return NULL for idVendor/idProduct when device is removed

I'm trying to implement USB monitor service/daemon to detect specfic PID/VID device only. I can easily detect device 'add' action attrib by filtering PID/VID but when I remove ANY USB device from port then as part of 'remove' action attrib, I try to filter PID/VID same like in 'add' action ... by using
const char* vendor = udev_device_get_sysattr_value(dev, "idVendor");
const char* product = udev_device_get_sysattr_value(dev, "idProduct");
but in above two char ptr I always get NULL.
Due to this my remove action will execute for all USB device which will remove from port
Is their any other way in libudev API to detect specific device remove only ?
Once the USB device is at the "remove" action, udev_device_get_sysattr_value(dev) will return NULL in my experience. Even the prior "unbind" action is too late.
One way to detect the removal of a specific device is to store its dev node when it is inserted.
First, find the udev_device* you want to monitor by enumerating the devices (struct udev_enumerate*)(device already plugged in) and monitoring the "add" or "bind" action.
In those states, the udev_device_get_sysattr_value will return the correct strings as you have already seen. If the values match the ones for the device you want to monitor, retrieve its current dev node by calling udev_device_get_devnode(dev). Store that dev node value (strdup to make a copy of it).
In the "unbind" or "remove" action, udev_device_get_devnode(dev) will still return the proper value as opposed to udev_device_get_sysattr_value(dev, prop_name). Match the dev_node with the previously stored dev node to identify that the action applies to the device you are monitoring.
Note that the dev node will likely change every time the device is inserted.

Get /dev path of USB device from VID and PID in node.js

I'm writing a node.js JavaScript app to run on a Mac (macOS server) that will communicate with USB devices that are plugged in. The library I need to use to interact with the device takes a path in the form /dev/pathToDevice - e.g. lib.connect('/dev/pathToDevice'); - whereas the only way I have to identify the USB device from within my code is by the vendorId (VID) and productId (PID) obtained via the usb-detection library from NPM on insertion.
How can I, in JavaScript, identify or derive the path to the device from the VID and PID of the inserted USB device, so I can pass that to the library?
You could write a small C++ program that uses libusbp_generic_interface_get_os_filename function from libusbp. You would then call the C program from node.js. Let me know if you need help writing the C++ program. I would probably start with the port_name example form libusbp's source tree.
Or, you could use the lsusb example from libusbp as is. It returns a path like /sys/devices/pci0000:00/0000:00:06.0/usb1/1-1 for each device. That is a directory with a bunch of special files; one of them is busnum and one of them is devnum, which are the two numbers you need to construct a path like /dev/bus/usb/DEVNUM/BUSNUM.
If that works, you might prefer to write a binding for libusbp from node.js instead of using a C executable.
Try drivelist , It gives you the mountpaths and its cross platform and you can combine this with usb-detection easily.
var drivelist = require("drivelist")
drivelist.list((error, devices)=> { console.log(devices) })
//Output
[ {
//stuff...
device: '/dev/disk0',
raw: '/dev/rdisk0',
mountpoints: [
{"path":"/","label":"Macintosh HD"},
{"path":"/private/var/vm","label":"VM"}
],
isRemovable: false,
//stuff....
]

ftdi_usb_open() returns -8 on Linux, but the same code is working on Mac

I am using FT2232H in SYNC FIFO FT245 mode and I can't get it working on Linux, my code is perfectly working on Mac OS X, but it doesn't on Linux.
I have installed both libftdi1 and libftdi-dev packages.
Relevant parts of code:
#define PID 0x6010
.
.
.
if(vftdic == NULL)
{
this->ftdic = static_cast<struct ftdi_context*>(malloc(sizeof(struct ftdi_context)));
}
else
{
this->ftdic = vftdic;
}
int f;
// Init 1. channel
if (ftdi_init(ftdic) < 0)
{
throw DeviceException("ftdi_init failure\n", FTDI_ERROR);
}
ftdi_set_interface(ftdic, INTERFACE_A);
f = ftdi_usb_open(ftdic, 0x0403, PID);
if (f < 0 && (f != -5))
{
//here f is equal to -8 only on Linux
throw DeviceException("Unable to open FTDI device, channel A\n", FTDI_ERROR);
}
Here is listing from lsusb:
Bus 001 Device 005: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
All hardware used is the same (MacBook Pro 2010 + my usb device with ft2232h).
Does the user account you're using have permissions to access the raw USB bus? Check permissions of the device file corresponding to your FTDI located somewhere below /dev/bus/usb – most like you don't have permissions to access it.
In that case add some UDev rules to place the device file in the ownership of some dedicated group and and add yourself to the members of this group.
In addition to making sure you have permission to the device node, you must verify that no other driver (such as a USB serial driver which normally ships with a linux distribution) has claimed the interface.

win32_USBDevice is missging from Win32 Classes

I am trying to retrieve PID and VID of a connected USB device. Starting with this line of C# code:
System.Management.ManagementClass USBClass = new ManagementClass("Win32_USBDevice");
Then I got exception "ManagementException not found", Later I run into this link:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394084(v=vs.85).aspx
It turned out Win32_USBDevice was not on the list at all. Tried Win32_USBController but didn't get what I wanted. Could anyone let me know if there is any substitute class on the list to extract PID and VID of a connected USB device?
Thanks in advance!
Try this:
System.Management.ManagementClass USBClass = new ManagementClass("Win32_USBHub");
Use Win32_PnPEntity. You can get the both the PID and VID of connected USB devices from Win32_PnPEntity by parsing the "PNPDeviceID".
Start with this example: Get List of connected USB Devices

linux / libusb get usb device path

I use libusb to enumerate over a few usb-devices. Now i like to get the "device-path". I think it's not called usb device-path, because i was not successful with google.
If i connect a usb-device with linux, i get a message in dmesg, here are a few examples for such a "device-path" with an usb temperature sensor (something like this):
Directly to a usb port:
[68448.099682] generic-usb 0003:0C45:7401.0056: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.0-1/input0 => 12.0-1
Directly to another port:
[68560.853108] generic-usb 0003:0C45:7401.0058: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:13.0-1/input0 => 13.0-1
To a usb hub on the first used port:
[68600.245809] generic-usb 0003:0C45:7401.005A: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.4/input0 => 12.2-1.4
To another port on the same usb hub:
[68647.925092] generic-usb 0003:0C45:7401.005C: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.3/input0 => 12.2-1.3
An now to a usb hub on the usb hub used before:
[68740.715518] generic-usb 0003:0C45:7401.005E: input,hidraw1: USB HID v1.10 Keyboard [RDing TEMPer1V1.2] on usb-0000:00:12.2-1.4.4/input0 => 12.2-1.4.4
Long story short:
The kernel message always contains a unique path for the physical usb device location (see the bold text before). Is it possible to get this "path" in the user space via libusb? I tried many things with struct usb_bus and struct usb_device, but i always was unsuccessfully.
I need this to identify multiple of these usb thermometers, because they don't have a unique serial number and sometimes they just "reconnect" at runtime, so they get different usb id's. So i think the only way to identify them is via the physical location.
Thanks for the help,
Best Regards
Kevin M.
-edit-
Currently i use the following code to search my usb device:
usb_dev_handle *find_lvr_winusb() {
struct usb_bus *bus;
struct usb_device *dev;
for (bus = usb_busses; bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
if (dev->descriptor.idVendor == VENDOR_ID &&
dev->descriptor.idProduct == PRODUCT_ID ) {
usb_dev_handle *handle;
if(debug) {
printf("lvr_winusb with Vendor Id: %x and Product Id: %x found.\n", VENDOR_ID, PRODUCT_ID);
printf("INFO: %d\n", dev->bus->location);
printf("INFO: %d %s\n", bus->location, bus->dirname);
}
if (!(handle = usb_open(dev))) {
printf("Could not open USB device\n");
return NULL;
}
return handle;
}
}
}
return NULL;
}
But with this code i cannot get a unique physical position id. The bus->location returns an integer (bus->dirname contains the same, but as string), which is not unique. I know usb has a hierarchy and in the dmesg i can see this hierarchys path.
With libusb i only can get the bus-id (?) and some device id's. But they don't help me, because i need to identify two or more of these temperature sensors. The device-id always changes when the temperature sensor reset's the connection (every 5 to 60 seconds) and the bus id is not unique. Unfortunately the temperature sensor has no unique serial id.
So i think the physical path is the only way to identify the device.
Best regards
Kevin M.
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.
Overall summery of the sysfs structure path:
1-1.3:1.0
|_usb root hub - bus number - 1
|_ port number - 1 of root hub
|_port number - 3 of intermediate hub
|_current configuration number - 1
|_ current interface number - 0
More information here
It's possible, like here.
Just scan all USB devices at all busses. When you find needed VID/PID — that's your device.
Or you can do simpler: write an udev-rule which would create symlink like /dev/thermoX when you attach you device. All you need after is to open needed /dev/thermoX.

Resources