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

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.

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

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....
]

On Linux, what's a good way to to use HID reports over USB?

On macOS, I use IOKit to get and set HID reports over a USB connection (for the curious, this is a controller for a standing desk that allows you to raise and lower the desk programmatically). I can get a list of devices using an IOHIDManager:
_manager = IOHIDManagerCreate(NULL, 0);
NSDictionary *deviceQuery = #{#kIOHIDVendorIDKey: #0x12D3, #kIOHIDProductIDKey: #0x0002};
IOHIDManagerSetDeviceMatching(_manager, (__bridge CFDictionaryRef)deviceQuery);
IOHIDManagerOpen(_manager, kIOHIDManagerOptionNone);
CFSetRef devices = IOHIDManagerCopyDevices(_manager);
// pick a device from the set and you eventually get a...
IOHIDDeviceRef myDevice = foo;
I then build up request buffers and make requests using:
int8_t *_buffer = ...;
IOHIDDeviceSetReport(myDevice, kIOHIDReportTypeFeature, *_buffer & 0xff, (const uint8_t *)_buffer, REQ_BUFFER_SIZE);
… and read responses using:
IOHIDDeviceGetReport(myDevice, kIOHIDReportTypeFeature, *_buffer & 0xff, (uint8_t *)_buffer, RES_BUFFER_SIZE);
What is an analogous way to do this on Linux? I've never worked with USB on Linux before (nor HID devices), and I'm open to pretty much any stack as long as it'll run on a Raspberry Pi.
to list all devices, capturing interfaces,... on linux libsub is used, see this http://www.microchip.com/forums/m340898.aspx
for the HID reports you can use usbhid-dump http://www.pkill.info/linux/man/8-usbhid-dump/ https://github.com/DIGImend/usbhid-dump or hidraw for low-level

UWP Unpaired Paired Bluetooth devices

I am developing in Visual Studio 2015 in C# for
a Raspberry PI 2 device running Windows IoT Core.
For my application I need to pair and unpair Bluetooth devices.
Can I get a list with paired / unpaired / all Bluetooth devices?
Like what can be seen on the Bluetooth page of the
built-in management website (http://[deviceip]:8080/bluetooth.htm)
I found a example (https://github.com/Microsoft/Windows-universal-samples),
but this is to much for me!
For now I just want to get a list with paired / unpaired Bluetooth devices
In order to find devices (Bluetooth or otherwise) you need a selector
which can be used to tell the DeviceWatcher the type of device to search for.
These selectors are basically strings identifying the type of device,
and the UWP framework provides some of them through methods on various classes.
//Gets all paired Bluetooth devices
var selector = BluetoothDevice.GetDeviceSelector();
//Gets all paired Bluetooth devices (same as above as far as I can tell)
var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(true);
//Gets all unpaired Bluetooth devices
var selector = BluetoothDevice.GetDeviceSelectorFromPairingState(false);
From the samples on GitHub:
Currently Bluetooth APIs don't provide a selector to get ALL devices
that are both paired and non-paired. Typically you wouldn't need this
for common scenarios, but it's convenient to demonstrate the
various sample scenarios.
Why we wouldn't typically need this is beyond me, but they do provide
a selector which can be used to find both paired and unpaired devices:
var selector =
"System.Devices.Aep.ProtocolId:=\"{e0cbf06c-cd8b-4647-bb8a-263b43f0f974}\"";
Once you have this selector you need to create an instance
of the DeviceWatcher class using a method on the DeviceInformation class:
var deviceWatcher = DeviceInformation.CreateWatcher(selector,
null, DeviceInformationKind.AssociationEndpoint);
Finally you have to hook up the events so you get notified of changes:
deviceWatcher.Added += (s, i) => { //Handle the new device };
deviceWatcher.Updated += (s, i) => { //Handle the updated device };
deviceWatcher.Removed += (s, i) => { //Handle the removed device };
deviceWatcher.Completed += (s, a) => { s.Stop(); };
deviceWatcher.Stopped += (s, a) => { //Handle here };
Notice that in the Completed handler I stopped the DeviceWatcher
so it enters the Stopped state and can be started again.
Once you have the DeviceInformation you can pair as follows:
var pairingResult =
await i.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
As for unpairing, you need to make sure your project targets Build 10586
or any later version in the project properties windows:
Then you'll be able to call UnPairAsync:
await i.Pairing.UnpairAsync();
Older builds do not support UnpairAsync.

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