Get /dev path of USB device from VID and PID in node.js - 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....
]

Related

libusb node usb get device instance path

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

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.

How the function works cdev_add()?

Do I understand correctly that when the structure is initialized
struct dev_t dev;
dev = MKDEV(major,minor_first);
I create only the device file, it's right to say - to the node. Next, should I indicate how I will work with this device? To do this, you need the function
cdev_add(&my_ch_dev, dev, minor_count);
after
cdev_init(&my_ch_dev ,&dev_fops);
So, I mean that my driver will work with the created node as a character device? Thanks in advance!
Here is the details how it works
dev = MKDEV(major,minor_first);
Still kernel doesn't know whether we selected major/minor number or not, so for this you need to register he device by calling register_chrdev_region()
register_chrdev_region(dev,minor_count,"AYRAT_DEVICE"); so till now number(major/minor) has reserved the name(dev) so that other driver will not get the same name. Next you need to register your driver with kernel.
register with cdev by calling cdev_init(&my_ch_dev ,&dev_fops); Next you need to inform to kernel that we filled all member of struct cdev, so for this use cdev_add().
cdev_add(&my_ch_dev, dev, minor_count);

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

How can I select an audio output device in directshow

I was wondering how I can select the output device for audio in directshow. I am able to get available audio output devices in directshow. But how can I make one of these to be audio output device. Its always going for the default audio device. I want to be able to output audio on my choice of device. I have been struggling through google but couldn't find anything useful. All I could get was this link but it doesn't really solve my problem.
Any help will be really helpful for me.
First off, if you're not using DirectShow .NET (DirectShowLib), get that here: It serves as a (very complete) interface between unmanaged DirectShow and C#
What follows is a pretty simple example of how to play an audio file, to the desired audio device
using DirectShowLib;
private IGraphBuilder m_objFilterGraph = null;
private IBasicAudio m_objBasicAudio = null;
private IMediaControl m_objMediaControl = null;
private void playAudioToDevice(string fName, int devIndex)
{
object source = null;
DsDevice[] devices;
devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory);
DsDevice device = (DsDevice)devices[devIndex];
Guid iid = typeof(IBaseFilter).GUID;
device.Mon.BindToObject(null, null, ref iid, out source);
m_objFilterGraph = (IGraphBuilder)new FilterGraph();
m_objFilterGraph.AddFilter((IBaseFilter)source, "Audio Render");
m_objFilterGraph.RenderFile(fName, "");
m_objBasicAudio = m_objFilterGraph as IBasicAudio;
m_objMediaControl = m_objFilterGraph as IMediaControl;
m_objMediaControl.Run();
}
It is up to user to manage audio devices and choose a primary device (such as via Control Panel applet). You can find ways to switch devices programmatically in Windows XP, however in Vista+ it is impossible without interactive user action by design.
See also Larry's answer here: How to change default sound playback device programmatically?
UPDATE: The mentioned above refers to modifying system configuration trying to alter default audio output device. An application is however not limited to default device only. Instead, it can enumerate available devices (see Using the System Device Enumerator + CLSID_AudioRendererCategory) and then create an instance of renderer for specific device with BindToObject call. From there on, it is a regular filter, just bound internally to device of interest.

Resources