Match USB serial # to port name with Qt and libusb - c++

I have a device that acts as a serial port connected over USB. I have a class that interfaces with the device through a QSerialPort. Soon I will have multiple such devices and the program will need to reliably distinguish them to assign configured values to instances of the class.
Qt identifies serial devices by the portName field of the QSerialPortInfo helper object. This name is derived from the /dev/ path (e.g. /dev/tty.foo42 is port name "foo42") and this path does not remain associated with a particular device over reboots or deployment to a different machine. However, through libusb I can get a serial number, which is stable across reboots and different machines.
What I am still missing is a way to match the serial number, which can be identified in advance and recorded in a configuration file, to a port name, which can be used to open a QSerialPort. Currently deploying to MacOS, but in the future we may wish to deploy to Linux.
Searching existing questions mostly turns up ways to configure a Linux system to always assign a particular dev path to a particular device. A solution that involves configuring the operating system is acceptable, but something the application can do without that is preferable. A Mac specific solution is acceptable, but something that also works on Linux is preferable.

The documentation for QSerialPortInfo::serialNumber() (new in Qt 5.3) sounds like what you're after:
QString QSerialPortInfo::serialNumber() const
Returns the serial number string of the serial port, if available;
otherwise returns an empty string.
Note: The serial number may include letters.

Related

Finding out comm port settings of a running app

The situation is as follows: I have a piece of hardware connected to a, windows running, PC via a serial port. This custom hardware is used to interface other hardware through GPIB. Now, the software that is used to operate this setup on the PC side needs to be changed without touching the hardware in the middle. The problem is getting a hold of the proper serial comm. parameters used for communication - setting them (the timeouts in particular - baud rates and bits are fine) to arbitrary values in the new software leads to a lot of comm errors so I'd like to know them precisely. The function GetCommTimeouts() would do the job, however you need the handle to the comm. device aquired via call to CreateFile() - only the original software has access to it. So the question is if one can get a hold of these settings from outside of the running, old app?
Thanks,
drinker
I would suggest using a tool like Process Monitor. This tool can monitor the calls that are used to open and configure a serial port.

Returning Device GUIDs and Bios ID, C++, Linux

I am trying to write a function to return all the GUIDs of the devices attached to the machine, as well as returning the BIOS Id. How would I achieve this? I can only seem to find ways of doing it on a windows machine, but not a linux.
Linux does not assign a GUID to everything. Hardware is identified by hardware-native means, e.g. USB and PCI devices are identifies by vendor and device ID (and serial number).
You can see what data the kernel offers by browsing /sys. I'd also check the source of tools like lspci and lsusb to get an idea on how one retrieves data programmatically (i.e. without parsing files in /sys).
There is, by the way, also a tool called dmidecode, that does operate directly on DMI data.

Duplicate USB virtual serial ports being created - what might cause this?

I've got a strange problem with some code I inherited from another programmer who's left the company, and need some guidance on how to even begin to solve it.
The problem is this - on a semi-regular basis, we are finding that duplicate USB virtual comm ports are being created. For example, on my PC, when I view the Ports in Device Manager, and select "View Hidden Devices", I have two entries for the same device - one on COM6, and one on COM8.
Unfortunately, we cannot reliably re-create the problem. We suspect it may happen when someone quickly disconnects and reconnects the USB cable when our software is running, but that needs to be confirmed.
As far as I can tell, the code was written assuming that no one would ever unplug a cable. I see no logic whatsoever to detect this condition after the SW is started. And it fails when you re-plug the cable - silently generating read and write errors even after the cable is plugged back in. You have to restart the program before it will work again.
I have very little serial and USB experience, and am at a bit of a loss as to how to even get started on fixing this.
Can anyone suggest why this might be happening?
Misc. details, in case they might be relevant:
USB serial code is in a C++ DLL
VS2008
FTDIBUS USB/Serial drivers
Windows XP and Win7
Screen shot of duplicate Registry entries (note the value of the selected key!)
As explained on Raymond Chen's blog, the Old New Thing, here, and by commenters above:
https://blogs.msdn.com/b/oldnewthing/archive/2004/11/10/255047.aspx
To summarize:
Devices which are unplugged and plugged in again are tracked so they are not treated as a new device every time.
Usually this uses the device serial number to detect whether a device is the same one.
However not every device has a serial number. These devices are treated as the same device only if they have the same vendor ID and product ID and are plugged into the same port. If they are plugged into a different port they are treated as a different device.
Some manufacturers do not understand the word "Serial" in "Serial Number" and give all devices the same number instead of giving them numbers serially... To cope with this there is a registry setting which can be used to force these devices to be treated as if they have no serial number.
Therefore, if a device with no serial number or which is flagged in the Windows Registry as having duplicate serial numbers is plugged in to a serial port it has not been plugged into before, it will be treated as a new device rather than a reconnection of an old device. This will result in "Ghost" devices as you describe.
Some FTDI devices are specifically called out as having this problem by the manufacturer:
http://www.ftdichip.com/Support/Knowledgebase/index.html?ignorehardwareserialnumber.htm

Determine is a Serial Port exists, Linux C/C++

My development target is a Linux computer that has two physical serial ports located at /dev/ttyS0 and /dev/ttyS1. I also expect /dev/ttyS2 and /dev/ttyS3 to be defined.
Using stty -f /dev/ttyS0 and S1 reports the configuration of the two serial ports and reports something menaing "doesn't exist" for S2 and S3.
The hardware designers are talking about offering USB to Serial ports built onto the main board. They'll be DB9 connectors on the outside and just circuitry - no USB connectors on the inside. The number of USB-to-serial connections is not guaranteed and I know enough to design for "many" instead of one.
So, in setting up my port server daemon, I need to be able to determine which ttyS's and which ttyUSB's are "real" and which aren't. Will there ever be placeholdeer ttyUSB's? What if one were to be "unplugged" (say it was, indeed, a real USB coupler on the inside of the PC)?
Is there a better approach than popen()ing stty and examining its output to determine the status of the serial ports? Is there a C API for stty?
Thanks!
The "C-API" which stty uses is tcsetattr(3) and tcgetattr(3).
For finding TTYs without opening the device you may look at this question:
How to find all serial devices (ttyS, ttyUSB, ..) on Linux without opening them?

Testing Serial port application

I have a code to send data to serial port. I just want to make sure that it is sending the data properly. I checked the function's return value and the number of bytes written and it is success. Is there any other way to actually see the data whatever i am writing?
if(WriteFile(m_hSerialComm, pszBuf, dwSize, &dwNumberOfBytesWritten, NULL) != 0)
I tried to use "Advanced Terminal Port software"
but the data is not coming in that window.
There are several ways to test your software. If you have two serial ports then connect them with a cable and listen on the other port with a terminal application such as the one you mentioned. Otherwise, you could loop back on the same port by connecting pins 2 and 3 together. A hardware-free option would be to use virtual serial ports as provided by tools like com0com.
Assuming from your piece of code that you are developing on a Microsoft Windows operating system, I would recommend the Portmon for Windows "official" serial port monitoring utility. I have used it in in the past, and found it simple enough, and also quite useful specifically for its multiple filtering/search options (since sometimes the amount of data passed on your serial port is huge).
If all you want is a log of the data you have written to your own port, why not encapsulate your WriteFile (and maybe also your ReadFile) functions in some "utility" function(s) that reads/writes both on your serial port and in some log file? You could even add timestamps, and filter "whatever you are looking for" straight from your own code.
I found this last option really useful when remotely debugging applications with customers. You add a button in your application that toggles the logging on and off, then you simply have to ask your customer to hit the "log" button and to send you the results.