How to most properly use libusb to talk to connected USB devices? - c++

How do I most properly use libusb to talk to connected USB devices?
Specifically, how do I transfer data to the USB devices, receive information from the devices, find out the name of the connected device, if they have storage, etc.
More specifically, I will be running this on a Mac OS X machine, so I know I can't just use Windows header files.
If there is a good explanation on libusb and USB devices, that would be helpful too.

Here is a post on a similar question that might be useful to you. I include plenty of links.
But maybe you'd rather see it here. So in that case, here it goes!
Libusb allows you to enumerate devices and select the one you want based on a specific Vendor/Product id (V/P Id). If you don't know this and can't find it online with the product's description then you can easily find it.
If it is not online you will need to use an app similar to lsusb on Linux. (I don't believe it is on Mac.) When you run lsusb it lists connected devices and their V/P Ids. You can easily find your device by unplugging, running lsusb, and plugging the device back in and comparing. It's a piece of cake. Any usb list app on Mac will hopefully display the V/P ID like lsusb does.
Then once you have this V/P ID you will use libusb (if using 0.1) to enumerate all devices and find the device that matches that id. (I support using libusbx which happens to have a single find device function based on V/P id - in fact, libusbx is a whole lot more concise all around.)
After selecting your device you will send a packet using either Feature or Output Reports. This is the most complicated part because the packet you send is dependent on the individual device I believe. It is 8 bytes of data and only one of which is a single character you wish to send to the usb device. (If you wanted to send 8 characters, you would have to loop through an array of chars and send a feature or output report for each character.)
As an example feel free to reference a rather specific terminal example I wrote for controlling two LEDS. If it's helpful, great! It contains a libusbx and libusb-0.1 example.
I hope this helps!

The official site for libusb 1.0 (the newer and recommended version) is https://libusb.info/. The API documentation is at http://api.libusb.info. Click on the Modules section to walk through the different function areas. The source is at https://github.com/libusb/libusb and you can see some working examples at https://github.com/libusb/libusb/tree/master/examples. Hope that helps!
The article from #user2469202 is a good basic intro also.

The process that you can follow is:
Get the VID, PID for the device that you want to communicate using lsusb
Try to open the device and read the device descriptor
If you want name of the device use string descriptor to get that
Check if any kernel driver is attached. If it is, then detach it and do some raw data transfer
After getting the response again re-attach the driver.

Related

What is the correct way to read advertisement packets from a BLE sensor using bluez 5.43 and DBus

I am trying to implement a C++ code (using bluez 5.43 and dbus) to read advertisement packets from a BLE sensor. As per the bluez DBus docs, there is a StartDiscovery API that can be used to scan for nearby devices. However, I am unable to find any APIs to store/parse the advertisement packets from nearby BLE devices. The advertising-api.txt lists registeradvertisement API but as per my understanding, it can be used only for creating advertisement packets and not reading from an external device (or am I wrong?) Can someone please guide me on the correct way to get advertisement packets from nearby BLE devices using bluez and DBus?
Thanks for the suggestions everyone. I was finally able to get the manufacturer data by using Intel's tinyb library. It has an enable_manufacturer_data_notifications API which enables you to be notified whenever the manufacturer data changes.
The behavior you described in one your last comment is the right one (the advertising data is not beeing updated) : if I am correct a BLE device is not supposed to be up all the time, it can sleep or turn to low-power etc.
In this context, it is not weird that the data is in some way "cached". From my experience, when you perform a scan and discover a device (even if you don't Connect to it), the device information will be stored for some time.
In your case, that's problematic because you are passing data through the advertising. However there is a way to force bluez to remove all it's cached data about a device :
the adapter-api provides a RemoveDevice(object device) method. It takes the object path (eg "/org/bluez/hci0/dev_AA_BB_AA_BB_AA") as argument.
If you're looking for DBus bindings in C, I suggest GLib GDBus (you will find links at the bottom of this tutorial on freedesktop website : https://dbus.freedesktop.org/doc/dbus-tutorial.html).
If you are familiar with bluetoothctl (a tool to interact with bluez using commands), it was developped by the bluez guys using Glib GDbus and you can find the source code here (look at the bottom to find the command list) : https://git.kernel.org/cgit/bluetooth/bluez.git/tree/client/main.c
There are more straigthforward ways to use GDBus with bluez but bluetoothctl source code is a start and you'll find examples for pretty much anything that is possible to do with bluez =)

Easiest way to control USB TMC device on Windows/C++

I am developing C++/Qt application which interacts with Tektronix TDS2002 oscilloscope via USB. The oscilloscope appears as "USB Test and Measurement device (IVI)".
Currently I use TekVISA library supplied by the oscilloscope's vendor. It works, but it is huge, old, buggy and poorly maintained. Therefore I would like to bypass the library and interface the device directly.
So far I have found this simple library: https://github.com/xyphro/WinUsbTmc It is exactly what I am looking for, but it uses libusb which requires to install some device filter and in addition it is advised to be more development tool than customer solution. Do you have any experience on this?
What is the easiest way to interact with USB Test and Measurement device in Windows/C++/Qt?
Thank you for your suggestions :)
You need a USB driver. My oscilloscope works with the driver included in this VISA package (the driver can be extracted very easily): http://www.keysight.com/main/software.jspx?cc=CZ&lc=eng&nid=-11143.0.00&id=2504667&pageMode=CV I assume all USB TMC devices can use the same driver, but I have no possibility to check this.
USB driver can be accessed via standard Windows functions. Guys on this forum were really close:
https://forum.tek.com/viewtopic.php?f=568&t=137573 and also this document was very useful: http://www.ivifoundation.org/downloads/Class%20Specifications/Ivi-6%202_USBTMC_2010-03-23.doc
You cannot write commands to OSC directly - data you send and receive have certain header which has to be in the correct format, otherwise the oscilloscope ignores the message. See reading and writting implementation in this simple library: https://github.com/xyphro/WinUsbTmc I didn't use this library because it uses libusb library which uses some kind of device filter and I personally do not like this concept (and in addition I have genuine working driver).
Data you read have also a simple header. To ensure you fit the header structure on input data well, you should first flush the input buffer. Then you issue reading request (using write command - see WinUsbTmc library above) and finally you receive the data and fit the header on its beginning.
I hope this will help to somebody :)
With regards
klasyc

How to find what device is connected to USB port (HID or Disk drive) in C++

I have managed to enumerate all the connected USB ports using SetupDi calls. Sample code is available at this link.
Please could any one tell me how can I find what device is connected to USB port like whether it is any HID device or any Disk drive?
Thanks.
I would recommend looking at the USBView sample in the WDK. If you are unfamiliar with this, simply run it - this tool walks the entire USB tree on the system and prints out information and descriptor listings for each device.
In your case, I'd start at the RefreshTree() function in this sample, you can then follow the code to see how it enumerates the host controllers, hubs and finally devices. For each device that you find you can look at the bInterfaceClass in the interface descriptors to find out what types of interfaces it is advertising (in your case 0x03 for HID Interface Class and 0x08 for Mass Storage Class).
The easiest way to get the source to this sample is to install the 7.1.0 WDK which is currently available here:
http://www.microsoft.com/en-us/download/details.aspx?id=11800

Do I even need libusb?

I have a feature request on a project I work on, it is to integrate with a Paylife CC handheld, which has a USB connector to connect with the computer. I have the docs, and am reading up on it.
When I searched on google how to read/write to a usb device on linux, it said, use libusb.
I was wondering, is there another possibility? Can't I just open it like a file and write a stream to it, and read a stream from it?
I don't actually need to do anything fancy. I just need to write a string of control codes to the device, and it would be mildly nice to read back the ACK and Error codes. But since those are already displayed on the device screen, I don't have to do much with it, just deliver the total required for payment.
So my question is, what are my options?
The connected computer is a regular ol ubuntu linux box.
It is definitely possible when the device complies with one of the USB device classes -- drivers for them are universal.
If that's not the case, then you may stick with a manufacturer-provided or a third-party driver, given there is one and you possess enough of it's documentation.
If that's also not the case, libusb-1.0 is your resort, unless you want to write a kernel driver youself :)

API to detect usb device

Can some one please point to any API or links where i can detect a USB device and other interfaces to transfer data into it.I am trying to do this on linux
Take a look at libusb - it's cross-platform.
Can you see your device in the command output lsusb? If yes, then you must check the vendor Id and Product Id of the same.
Probably in Linux there is already a driver available to make bulk data transfer from concerned USB device (your USB device).
You can check this (http://www.linux-usb.org/usb.ids) to verify whether a driver is available or not.
To make your own program and API's, as stated above libusb is a place to start, if you don't want to write a driver for your device.