How come GetDefaultCommConfig() Doesn't Work with Bluetooth SPP Devices? - winapi

I maintain an application that, amongst other things, provides a list to the user of available serial port devices on the host computer. This application makes use of the GetDefaultCommConfig() function in order to verify that devices in its list of serial port names are valid. I have received notice that my application does not work with Bluetooth serial ports. While debugging this issue today, I found that the GetDefaultCommConfig() function does not return a successful value when called with the bluetooth serial port name. The GetLastError() function returns 29 (invalid parameter) in these circumstances. Is there a workaround for this problem?

I've had a look at the serial ports on my machines with Bluetooth and can confirm that GetDefaultCommConfig() fails for virtual Serial Ports created by the Microsoft Bluetooth stack. It seems to work ok for Widcomm ports however. (I haven't tested BlueSoleil/Toshiba/etc.)
So it seems the best plan is not to use GetDefaultCommConfig() for the MSFT ports. To identify which ports are which stack, check the values under HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM, which lists the COM port name as the value. If the value name is "\Device\BtModemNNN" then it's the MSFT Bluetooth stack. (Widcomm has "\Device\BtPortNNN").
[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM]
"\\Device\\BtPort3"="COM19"
"\\Device\\BthModem2"="COM25"
Alan

This isn't a full answer.
I have found that my Windows 7 development machine quite correctly returns from GetDefaultCommConfig() for Bluetooth SPP COM ports even with using MSFT's stack (the ports show \Device\BthModem0 and \Device\BthModem1).
However, I do see GetDefaultCommConfig() failing in Windows 8.1 with a return code of 87 (returned by GetLastError()). This is identical in behaviour to COM ports that definitely don't exist.
The SPP COM ports do still work with a Hyperterminal type application but I do not know how the ports are scanned or opened in that application - I only know my application uses GetDefaultCommConfig() and its ilk from kernel32.dll and that this does not work.
Long shot and a half but I don't suppose anybody else has any input after 4 years?

Related

Simulate serial port device using stdin and stdout

Currently, I have a desktop app that I used to read and write data to a proprietary hardware device via a serial port interface. The app starts by listing the serial COM devices connected to the computer, and once a device is selected, one can interact with the app to communicate with the corresponding device. I no longer have such a device at hand, but I would still like to use the app nonetheless.
I have already developed a command-line utility that, given a binary message in stdin, emits the corresponding binary reply (the same reply that the proprietary hardware device would send via serial port) to stdout. Let's call this utility a simulator.
How do I set up a virtual serial port such that the app can detect it, and that whenever the app sends a message using the serial port protocol, such message is forwarded to the simulator, and the simulator's reply is returned back to the desktop app?
I'm on Mac OS 12 with an M1 CPU. I'm also open to solutions on Windows 10 (with less priority).
I have looked at previous questions on StackOverflow that might be similar to this one, but they were either incomplete or slightly different, with no obvious way to infer the solution for my actual problem.
Serial ports are unlike other channels. That's why separate system calls exist for them.
Normally, serial ports are created by physical devices (an old-fashioned serial port or a newer USB-based one) and the associated driver. Since writing a driver is quite difficult, a pragmatic and possibly unexpected approach would be to use hardware, specifically two USB-to-serial adapters. That way, a serial port is created by the drivers of the USB-to-serial adapter.
The two USB-to-serial adapters are wired to each other (RX to TX and vice versa). The will appear as two serial ports on macOS (/dev/cu.usb...).
The legacy application then connects to one of the serial ports. And your command line utility (acting as a device emulation) connects to the other serial port. All data send by the command line utility will go to the legacy application, and vice versa.
The remaining issue is how to connect your command line utility to the serial port. If you are lucky, you can use the screen command. But more likely, you will need to modify it to read and write from the serial port (instead of stdin and stdout).

Device interface over USB

I have an usb device (pole display), which i don't have driver for.
I installed generic usb driver and opened the port for sending(I use bulk transfer) data to device.
With usb monitoring software i see my data gets to device, but nothing much happens on device side.
The device commands(ESC/POS) work when transfered over (virtual) com port, but not over usb port.
Shouldn't device process commands the same way regardless connection type (com vs usb)?
How can i figure out what commands work with the device (for example, if i send some text, i want it to show on display)?
Any help is appreciated!
Look at the USB descriptors the device reports in order to determine its class. If it is a custom device and not a standard class then you'll likely not be able to work with it. There is a big difference between old RS-232 COM protocol and USB. USB devices can have multiple configurations and endpoints, each responding to data in different ways. Many classes exist and are pretty standard (CDC-ACM is typically used for virtual serial ports.) However, it's not uncommon for device manufacturers to include OEM specific configurations and endpoints which can be used for their own custom interfaces, firmware loading, etc.
Is there any initialization data transmitted through the COM port when connecting the device? The device surely can treat COM and USB different, but another possible thing that goes wrong is that the device needs to hear some sort of "I'm going to start sending commands"-signal from you first, and that signal may be different between COM and USB.
So what I would recommend is first (if you have not done that yet) see what data is sent to initialize the COM connection, and if that doesn't have an obvious USB counterpart, connect it to a PC where you do have drivers (assuming that is available somewhere and somehow, which is possible if e.g. you ask this due to OS incompatibility) and see how the connection is initialized there.
If the first doesn't work and the second is unavailable to you, then I'm afraid there's little I can do to help you, since it's usually not visible for you what commands the device wants to hear other than by guesswork, documentation, or comparing to similar devices where you do have that data available.

Do I need my own VID/PID USB identifiers when using virtual COM port through usbser.sys driver on Windows?

Do I need to buy VID/PID USB identifiers when using virtual COM port through usbser.sys driver on Windows or is the device being tied to a unique COM port sufficient?
The only real advantage to having your own VID and PID is that your device is more identifiable as your product, rather than something generic. Also, you can never guarantee you will be on a certain COM port, as something else may have taken that port number, no matter how obscure.
I would say that unless you are really bothered about your device coming up as something generic in device manager (and you have installed the drivers in a set-up program, so you don't get generic device installed messages on first plug-in) it's not worth bothering. The best bet to find your device is send a quick ID string down each port you can open (starting with your 'unique' one) to identify your COM port by the response.
There may even be some driver-signing woes to get involved with if you have your own PID and VID too (dependent on the USB-chipset vendor).

Communications between Visual C++ and Arduino:

I have a Arduino app that needs to talk to my PC across the USB (Serial) connection. I have this bit of code that I lifted from the Arduino Playground at
http://arduino.cc/playground/Interfacing/CPPWindows#VisualStudio2008
this->serialPort1->PortName = "COM5"; // Replace with your COM port!
this->serialPort1->Open();
this->serialPort1->Write( "7" ); // In the future, you'll expand on this
// to write your custom data to the board
this->serialPort1->Close();
My question is how does one determine what COM port the Arduino USB cable is attached to?
There are several ways you can approach this.
The most obvious is that you simply make your application configurable and tell it which serial port to use. The port name should never change, unless you have other processes on your machine allocating virtual COM ports such as Bluetooth drivers.
A second option is that you can do what the Arduino app does and scan the serial ports on the system looking for the hardware. Since you are using the CLR, System.IO.Ports.SerialPort.GetPortNames() will give you a list of all the serial ports on the system. (You can also get this from the registry.) Then you can enumerate through them and check the status of the pins to see which serial ports have devices attached. You should probably include in your sketch a way to query the Arduino so that you can send it a command and have it give a fixed response. This would allow you to discern your application from other serial devices such as modems.
There is a third option which would involve figuring out where the FTDI driver stores its configuration information in the system/registry and going from there. This is a bit more involved, so I can't give any information on if this approach is even viable.

Faking an RS232 Serial Port

I'm developing a project that has a number of hardware sensors connecting to the deployment machine through RS232 serial ports.
But ... I'm developing on a machine without an physical RS232 serial ports, but I would like to make fake serial ports that I can connect to and output data from with the aim of faking input from hardware sensors.
Does anyone know of a way to create a fake serial port and control it on Windows XP?
If you are developing for Windows, the com0com project might be, what you are looking for.
It provides pairs of virtual COM ports that are linked via a nullmodem connetion. You can then use your favorite terminal application or whatever you like to send data to one COM port and recieve from the other one.
EDIT:
As Thomas pointed out the project lacks of a signed driver, which is especially problematic on certain Windows version (e.g. Windows 7 x64).
There are a couple of unofficial com0com versions around that do contain a signed driver. One recent verion (3.0.0.0) can be downloaded e.g. from here.
I know this is an old post, but in case someone else happens upon this question, one good option is Virtual Serial Port Emulator (VSPE) from Eterlogic
It provides an API for creating kernel mode virtual comport devices, i.e. connectors, mappers, splitters etc.
However, some of the advertised capabilities were really not capabilities at all.
EDIT
A much better choice, Eltima. This product is fully baked. Good developer tech support. The product did all it claimed to do. Product options include both desktop applications, as well as software development kits with APIs.
Neither of these products are open source, or free. However, as other posts here have pointed out, there are other options. Here is a list of various serial utilities:
com0com (current)
com0com - With Signed Driver (old version)
Yet another place for com0com with Signed Driver (Pete's Blog)
Tactical Software
Termite
COM Port Serial Emulator
Kermit (obsolete, but still downloadable)
HWVSP3
HHD Software (free edition)
I use com0com - With Signed Driver, on windows 7 x64 to emulate COM3 AND COM4 as a pair.
Then i use COM Dataport Emulator to recieve from COM4.
Then i open COM3 with the app im developping (c#) and send data to COM3.
The data sent thru COM3 is received by COM4 and shown by 'COM Dataport Emulator' who can also send back a response (not automated).
So with this 2 great programs i managed to emulate Serial RS-232 comunication.
Hope it helps.
Both programs are free!!!!!
There's always the hardware route. Purchase two USB to serial converters, and connect them via a NULL modem.
Pro tips:
1) Windows may assign new COM ports to the adapters after every device sleep or reboot.
2) The market leaders in chips for USB to serial are Prolific and FTDI. Both companies are battling knockoffs, and may be blocked in future official Windows drivers. The Linux drivers however work fine with the clones.
Another alternative, even though the OP did not ask for it:
There exist usb-to-serial adapters.
Depending on the type of adapter, you may also need a nullmodem cable, too.
They are extremely easy to use under linux, work under windows, too, if you have got working drivers installed.
That way you can work directly with the sensors, and you do not have to try and emulate data.
That way you are maybe even save from building an anemic system.
(Due to your emulated data inputs not covering all cases, leading you to a brittle system.)
Its often better to work with the real stuff.
i used eltima make virtual serial port for my modbus application debug work. it is really very good application at development stage to check serial port program without connecting hardware.

Resources