WaitCommEvent compatible with pipes? - c++

I am working with legacy C++/MFC/Win32 code. The project multiplexes various serial protocols over separate physical serial ports, one per client system, to a common front end data repository.
Since the program was originally designed to communicate over serial ports there are many assumptions in the code as far as setup and management of serial events go: ACK/NAK transport verification, inner-byte delay checks, etc…
The existing architecture leverages overlapped reads and writes with event notification via WaitCommEvent.
I have been tasked to add another client interface, using a single client pipe server; which, like the serial ports, will support one client per “file”.
In reading the docs for WaitCommEvent it looks like it was designed to work with OS abstracted physical communications devices; like serial ports.
The simple question, can I leverage the existing serial skewed “wait” model to work with a pipe, or should I go ahead and virtualize it so that it can be overridden it with specific pipe logic?
Thanks to those (the minority for sure) of developers who know what I am asking.

I can't find a good reference right now, but it is my understanding that WaitCommEvent only works with communications resources and that a pipe is not defined to be a communications resource in the same sense as e.g. a serial port. WaitCommEvent waits for the underlying driver to set certain bit-flags, like when new characters arrive, and I don't believe pipes (or files) work that way internally.

Related

Many-to-one two-way communication of separate programs

I'm trying to make two-way many-to-one communication between programs in Linux.
My plan is the following: One program called "driver" that talks with the hardware needs to communicate with an unknown number of applications in Linux.
I read that one of the most common ways for inter process communication is "named pipes".
The question I haven't found yet is: How new programs should notify the driver that a new program is running so that one more connection (named pipe) between the new program and the driver enstablished?
All programs will be written in C++
In essence, what you've described is a server/client relationship between programs; what each program does on either side of the communications bridge is probably irrelevant.
Even though these processes appear from the question to be intended to be on the same machine, networking is still available to you via localhost.
If you're not wedded to pipes, why not use a port for the driver (server) known to each program (client), to which the server listens?
That's pretty much the underlying philosophy of X-Windows, I believe.
Plus, there should be lots of reliable code out there to get you started.
I also think sockets may be a better solution, but if you really want named pipes, I'd do it this way:
The server opens a pipe named channel_request for reading. Any new client opens it for writing and writes a unique ID. (PID should work). The server reads this id and creates a named pipe called channel_[id]. The client then opens channel_[id] for reading and can start receiving data.
Note that linux pipes are unidirectional, so if you want two-way communications as shown in your diagram, you will need to open both a channel_[id]_out and a channel_[id]_in.

Create virtual serial port in Qt/C++

I would like to create a linux app which appears as a serial port (eg /dev/ttyTEST). This app will listen for commands sent to the port, and respond back.
Is this possible using Qt/C++ ? I haven't done kernel programming so I'm hoping this is possible in user space.
Everything depends on what the application using such device expects.
If /dev/ttyTEST is to behave like a real serial device and respond properly to all ioctl's that set its speed etc., then this can't be done from userspace. It wouldn't be too hard to implement in the kernel space, though.
If /dev/ttyTEST only needs to be a tty, then provide a pseudo tty.
If /dev/ttyTEST is merely to be something another application can write to and read from then socketpair() does it.
If you have control over the application's code, then you can have it check whether the device is a socket pair or a real character device, and ignore the failures of the serial-port-specific APIs on a socket.

How to retrieve a data from a directory by sending a request through the serial port?

I have a controller which has a serial port and ethernet. I want to retrieve an event and the data associated with this event from the event directory through the serial or ethernet port of the controller. I do have a packet format (request packet data) for the specified event to be retrieved. Can anyone tell me how to retrieve the data by sending a request through the serial port? I am beginner and not that much well-versed in programming.
You will need to have some kind of a program running on your embedded platform, listening to the serial port and answering requests. This kind of program is usually called a "daemon" (pronounced the same as "demon"; just like "Caesar" rhymes with "sea star").
If you already have a daemon, you will need to figure out what format it uses. Since I have no idea what you might have I cannot even guess.
If you will be writing your own daemon, you will need to choose some sort of protocol. Personally I like the JSON format for a serial protocol; it is simple enough that you can extract data just using sscanf() from the C library if there is not a better library available, and of course it's easy to build JSON strings just using sprintf().
http://json.org/
What you want is the Serial Programming Guide for POSIX Operating Systems. If you are bound to Windows for some reason, you get POSIX through installing Cygwin. Expect to become familiar with man pages like termios and fcntl since you'll first have to set the serial port parameters to work with your device, though they're likely to be the standard 8-N-1 at some rate. Then it's a matter of reading and writing bytes to the port's file descriptor. You're more likely to be using the low level open(), close(), read(), and write(), which are a level below the stdio (printf, fopen, stdout) you're more likely to be used to as a newer programmer.
Computers these days often lack the RS232 serial port, so if you need one you can find a cheap USB adapter. Be aware that USB adapters don't necessarily implement some of the ancillary signals (RTS,CTS,etc.) in my experience.
Also look into libraries for your specific needs and situation.
You should specify the controller for more useful answers.
Your controller should support any data exchange protocol. You can find this info in documenttion. May be, it supports MODBUS or MODBUS TCP. In this case you can use any modbus compatible software.

Can I write Ethernet based network programs in C++?

I would like to write a program and run it on two machines, and send some data from one machine to another in an Ethernet frame.
Typically application data is at layer 7 of the OSI model, is there anything like a kernel restriction or API restriction, that would stop me from writing a program in which I can specify a destination MAC address and have some data sent to that MAC as the Ethernet payload? Then write a program to listen for incoming frames and grab the frames from a specified source MAC address, extracting the payload of data from the frame?
(So I don't want any other overhead like IP or TCP/UDP headers, I don't want to go higher than layer 2).
Can this be done in C++, or must all communication happen at the IP layer, and can this be done on Ubuntu? Extra love for pointing or providing examples! :D
My problem is obviously I'm new to network programming in c++ and as far as I know, if I want to communicate across a network I have to use a socket() call or similar, which works at an IP layer, so can I write a c++ program to work at OSI layer 2, are there APIs for this, does the Linux kernel even allow this?
As you already mentioned sockets, probably you would just like to use a raw socket. Maybe this page with C example code is of some help.
In case you are looking for an idea for a program only using Ethernet while still being useful:
Wake on LAN in it's original form is quite simple. Note however that most current implementations actually send UDP packets (exploiting that the receiver does not parse for packet headers etc. but just a string in the packet's payload).
Also the use of raw sockets is usually restricted to privileged users. You might need to either
call your program as root
or have it owned by root and setuid bit set
or set the capability for creating raw socket using setcap CAP_NET_RAW+ep /path/to/your/program-file
The last option gives more fine grained privileges (just raw sockets, not write access to your whole file system etc.) than the other two. It is still less widely known however, since it is "only" supported from kernel 2.6.24 on (which came with Ubuntu 8.04).
Yes, actually linux has a very nice feature that makes it easy to deal with layer 2 packets. You can use a TAP device, which allows your userspace program to read/write ethernet traffic through the kernel.
http://www.kernel.org/pub/linux/kernel/people/marcelo/linux-2.4/Documentation/networking/tuntap.txt
http://en.wikipedia.org/wiki/TUN/TAP

C++ network multi application protocols

I am programming a Client/Server application for my project in C++. The whole application protocol was given or discussed by the working group. The main idea is that we have 3 protocols.
Text-protocol: send and receive some information in string format between client and server.
Binary-protocol: client sends continiously some status data to server.
Binary-protocol: client sends continiously some data like sound/video/images/text
All Protocols should run on different ports.
I implemented a Socket-Class, which is responsible to create and listen socket, accept the connection from the client. Also there is a function to receive/send string-based data and receive/send binary-based data.
In the next step I wanted to define 3 Classes. Each of them should be responsible for creating one socket in new Thread and responsible for the protocol, which was defined for that port (s. 1-3). So at the end I will get 3 Sockets (1 Socket for one Port).
My question is, if I think in right direction? Maybe you can recommend my some design patterns for using different application protocols. It would be great if you can recommend me some projects or code, which can be similar with my project.
Thank you.
You should decouple your socket class from the 3 protocol handlers - don't have methods for both text and binary data handling on the Socket or you unintentionally encourage people to mix and match data types over the same socket, which is clearly not what you want.
Your socket should provide simple connect/disconnect, data transmission and receipt functionality, and the decoding and encoding of sent/received data is then done in a different object, likely picked from 3 new classes (one per protocol).
On a general note, I question the use of text data. It's inefficient compared to virtually any serialization library you could name. You could be trading a little extra debuggability for a lot of hard-written data parsing and error checking code, and concomitant CPU cycle wastage. If the text data is fairly simple (not actually structured like XML, say) then this is less of a concern.
Protocol 2. might be implementable using UDP rather than TCP, if the status info is not mission-critical. That's one less connection you'd have to manage.
You might consider using enet. It does reliable and unreliable UDP communications and will do most of the heavy lifting of the communications for you.