I've got some bar code scanner devices that can handle a variety of USB interfaces (COMM Emulation, HID Keyboard, HID POS, etc.) The problem is that, while I can tell if the device is in a HID mode, I need to be able to determine if it's HID Keyboard or HID POS.
Is there a way to determine this using Win32 C++, preferably with the built in windows HID library (hidsdi.h)?
You can use HidD_GetHidGuid to get the unique GUID for the device. Device interface guids are defined by each device/application software vendor, Microsoft or third party as they see fit. In some cases the guids are published and public knowledge and are standard interfaces, in some cases they are not.
You can also use the USBView utility from Microsoft which will let you browse the USB tree or you can look in the registry and see if you can find the GUID for your device. You may still have to query your device to determine device type if the config data is not present or it does not reveal itself other than a generic device, if your device supports this.
There are two types of GUIDs: Device Class and Device Interface. A device can only be a part of one class. Unfortunately, the Device Class and Device Interface GUIDs are sometimes the same, thus confusing developers. In the WinXP DDK, standards were created to try and make the definition of GUIDs less confusing.
See also this previous SO question: Use RegisterDeviceNotification() for ALL USB devices.
Here is a list of possible HID Guids: http://msdn.microsoft.com/en-us/library/ms791134.aspx and use HidD_GetHidGuid as Roboto suggested
You'll need to use the HidP_ functions to check the hid report capabilities. Find out what capabilities (usages) are presented by the HIDPOS device, and check if those usages are present using HidD_GetPreparsedData(), HidP_GetCaps() and then HidP_GetValueCaps(and/or ..ButtonCaps, etc). A good place to look for examples is Jan Axelson's page. If the usages are present, then you've got the POS device. If not, then it must be the keyboard (assuming you've confirmed the device is attached.)
Related
I am writing a C++ Linux userspace driver for a USB device using the C library libusb. I have two copies of the same device (same vendor ID and product ID) and would like to know how to handle this case.
Here are the possibilities I can think of:
libusb_get_device_list() returns only devices that are not currently in use
I can differentiate the used vs. unused devices using information of the device descriptor, using libusb_get_device_descriptor()
libusb_open() on the currently in-use device will fail, by returning either LIBUSB_ERROR_ACCESS or LIBUSB_ERROR
How should I deal with this? Which of the preceding options, if any, is the behaviour of libusb when dealing with many of the same devices? How can I differentiate between the in-use device and the idle one?
As #fiscblog said in his answer, "Identification is done via the device descriptor (use the serialnumber which should always be unique)". My problem here is that, in order to do so, the two drivers should communicate to know which instance is handling which device (using, for instance, a file), and I would like to avoid this. I also would like to avoid having to introduce multithreading and manage two devices with one driver, as I don't have the skills to do so in an efficient and well-controlled way (nasty race conditions ... !)
The correct handling is:
enumerate all devices (get device list)
identify the requested device and open it
Identification is done via the device descriptor (use the serialnumber which should always be unique), as you discovered yourself.
How to know if a device is in use?
If a device is open, the endpoints will be bound and configured for I/O. Therefore you cannot open it again but will get the error codes you mentioned.
According to the documentation on libusb_claim_interface():
Interface claiming is used to instruct the underlying operating system that your application wishes to take ownership of the interface.
so you should be able to call libusb_claim_interface() on each device and it should only succeed on the unclaimed one:
It is legal to attempt to claim an already-claimed interface, in which case libusb just returns 0 without doing anything.
libusb is written in C and follows the same basic general guidelines for accessing devices, file descriptors, streams, etc.
1 - Connect to de device
2 - Check the connection, if there's an error, inform and return
3 - There's no error!! Interact
Following this basic flow, the solution in your case IMHO is as simple as:
Identify the devices
Iterate througth them trying to connect until one throws no failure
do something
close
I am looking for a piece of software, or assistance with where to start for coding, that will let you select a USB device and convert its output signals (when buttons are pressed on the device) into keystrokes or configurable macros.
In more detail, I have this remote control (more accurately, a USB handset/phone) that sends USB signals depending on which button is pressed and the software I currently use converts those signals into keystrokes or macros. The software I currently use however is extremely limited, non-configurable and obsolete. The software which I retrieved from the CD that the device came in is simply named 'USBPhone 5 in 1' however there is no mention of this anywhere on the internet.
The device is unfortunately unbranded and also has very little visibility on the internet so I cannot see if there's any updated software or even any way to edit it.
Any help is greatly appreciated!
I think you need to start by getting basic understanding of the USB standard and device classes. Then you need to find out if your device implements a specific device class or some proprietary interfaces. Then you will either need to use a driver for the device class or implement a proprietary driver.
While USB is abbreviation from Universal Serial Bus, it is not transferring some random analogue data but well defined digital packets. The standard defines Audio Class for audio devices, Video class for video devices etc. Most devices implement one or more of those classes. For keyboards and mouse it defines HID class, which is most likely what your device implements. You can find HID device class related specifications here. It is not the most simple one to begin with, but it should work when you just plug the device to your PC and open e.g. notepad and start writing. USB device class codes are listed here.
In order to find out what device class your device implements, you need to read it's descriptors. In Windows one of the easier ways is to use usbview. You can read more about USB decriptors from here.
You do not mention what is your USB host (Windows or Linux PC, Mac or something else), so I am not going to go into actual USB driver implementation, but hopefully I was able to give you some information on what could be needed. In any case, if the device has some proprietary implementation, you will either need to have specification for it, or reverse engineer it by monitoring the USB packets. There are lots of expensive hardware solutions on the market for analyzing the USB traffic, but there are also some free SW solutions that might be good enough for your purpose. Quick Googling brought up this.
You can try joyToKey, this software do exactly what you want but with gamedpad. I don't know if it will work well with your USB controller.
http://joytokey.net/en/
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
I'm trying to write a program that sends COM port information to devices that may get unplugged and end up with a different COM port number. Using SetupDi, I know it's possible to list all the COM ports on a computer by number, but given that the number might change I'm trying to find a better way to access the COM ports.
The COM devices I'm using are FTDI serial-to-com adapters that let me program the device model. I'd love to be able to choose a COM port based on the device model. I've tried (almost) all of the properties that I can get to using SetupDi, but no dice. It looks like there's a difference between the device list SetupDi lets me access, and the devices that show up under Devices and Printers (where the model name does show up). Is there any way to get devices in the Devices and Printers window programmatically and map them to COM port using Windows APIs?
The link below is a great (if not the only) comprehensive overview on how to enumerate COM ports on Windows and extract extra information in various ways:
http://www.naughter.com/enumser.html
What we use in our own software (Docklight) is according to what the "UsingSetupAPI1" way from the enumser.cpp file shows (SetupAPI - GUID_DEVINTERFACE_COMPORT). The UsingSetupAPI1 example demonstrates how to extract the device name as shown in the Windows Device Manager, along with the COM number. This is called "friendlyNames" in the enumser.cpp code.
Another way to identify and communicating to your device could be not asking Windows in the first place, but the FTDI D2XX API:
http://www.ftdichip.com/Support/SoftwareExamples/CodeExamples.htm
We use the D2XX API for communication when we know it is always a FTDI device. Identification is simpler and we have much better performance / less latency than using Windows Communications API via "virtual COM port".
If we need to correlate between COM port numbers and a FTDI device ID, we use the FTDI D2XX API's ListDevices and GetComPortNumber functions.
I would be using a USB hub to connect multiple devices. I want to fix a specific USB device to a particular slot. Then check if it is done properly.
The way I am planning to achieve this is to get the complete USB path like
PCIROOT(0)#PCI(1D00)#USBROOT(0)#USB(1)#USB(2)#USB(3)#USB(3)
I can get this particular string in w7 via device property but the same is not available in wXP.
You can build this path by using the SetupAPI.
The device manager is built with this.
You start with CM_Locate_DevNode and enumerate children with CM_Get_Child.
I strongly advise you against what you're planning to do. AFAIK a USB device MUST function regardless on the USB port it's plugged in. If you'll creating such a device, forget e.g. about the "Certified for Windows" logo.
Just handle WM_DEVICECHANGE message, then use e.g. WMI to search for the USB device you're interested in. Here's my article about it: that time I coded C# language, however WMI has C++ API as well.