views:

1878

answers:

3

I"m working on a C++ Win32 application for which I'm trying to essentially "auto detect" if a device has been plugged into one of the RS232 ports and then if it has been disconnected.

The checking for a connected device is easy enough because my use case allows me to assume that this particular thread will be the first to try to initiate communication with the port. I'm able to scan the available ports every minute or so and once I've found a port with the device on it I flag that port has having a device, close the port, then set an event so that the process that actually will use the device knows it can now connect on that port.

The disconnect detect is where I run into trouble. When I'm scanning for connected devices I can actually send data to the port to be sure that, if there is a device, it's the specific device I'm looking for. But once it's connected, that port will already be open by the other process and I can no longer open that port from the detect thread. So I am looking for a way to either open the port in a "listen mode" or something like that so I can just see if the device is still there.

I briefly came across something about watching the DSR or DTR line or something...but couldn't find any more or how to actually do it.

Any suggestions?

Edit: Looks like I need to clarify a little more... For detecting the disconnect, I cannot send data to the RS232 port in any way. Also, I cannot assume that another application actually has the port open. The device may be physically connected, but without and open connection...but I still can't risk sending data to it. I was hoping there was a way to just check that there was still power on that port or something like that.

+1  A: 

Sounds like it might be a good idea to have that process that will give notification of connected and disconnected events also relay the data to the other process. Have your app work in layers such that there is a process that takes control of the RS232 connection and sends your upper layer app events: connected, disconnected, data available, etc.

ThePosey
Unfortunately, that is not an option. The process that actually uses the connection must have complete control over the connection...long story, but that's just how it's been designed.
Adam Haile
is there any way you can wrap the connection in your own class that will do the monitoring and provide all the functions that the process calls?
ThePosey
no...unfortunately it needs to be completely non-intrusive
Adam Haile
A: 

I have done applications like this and its not really a language specific problem (unless you have no serial port access in your language).

My preferred solution has always been to have one thread per port, according to your configuration and the thread maintains a state which is accessible from some sort of controller.

The default condition is that the thread polls the port every few seconds and while there is no answer assume there is no device connected. Once a device seems to respond, change the state to indicate this is so.

I designed an application that had a number of queues: One with disconnected threads, one with connected, but idle threads and another with connected and busy threads. The controller moved threads between queues as they changed state.

quamrana
+3  A: 

It depends on the connected hardware whether there will be a change in the modem state registers when you disconnect the hardware, but if there is then you could check the state of for example the CTS or DSR line using the GetCommModemStatus() function.

There is however the problem that you need a file handle to the COM port to call any API function, and this is exclusive as the documentation of CreateFile() states:

The CreateFile function can create a handle to a communications resource, such as the serial port COM1. For communications resources, the dwCreationDisposition parameter must be OPEN_EXISTING, the dwShareMode parameter must be zero (exclusive access)

So you can not open the COM port to watch the line state while another process has the port opened for communication.

There are ways to do this, but they involve a driver. SysInternals has the Portmon tool, and a Google search will turn up some companies selling software for sharing COM port access between applications, but AFAIK simultaneous access is impossible using the standard API.

mghie
Great Explanation, Thank You. Unfortunately I can't access at the driver level...but I may be able to at least get a handle to the port that's already open, so I can check.
Adam Haile
One more thought... is there a way to try to connect to the port where it will fail if there's already a connection? That way if it fails with a previous connection, or just plain connects, I know it's still there.
Adam Haile
Sure, just try to open the port, and check the result of GetLastError() if it fails. That will tell you whether the port is open. It doesn't tell you whether the device is still connected. You need to have some periodical data exchange for that, or use GetCommModemStatus() in your other process too.
mghie