# create pty and connect it to a serial port /dev/ttyUSB0

Problem:

I have two Linux machines connected with a serial interface. I use ppp to communicate between them (I have to since it is a project requirement). Communication speed is at 9600 bits/s. I need to measure bandwidth used, bits/s, live, i.e. while the system is running. Initially I thought I would use ifstat -btwTWS -i ppp0, since this is what the tools was designed for. However the value that was displayed was way more than 9600 bits/s. It hovered around 12.09 Kbits/s. I did ask why this happening, and the response was that it could be because of a compression. This does make sense. What I need, however, is actual bits/s after compression and before decompression happens.

My initial approach to solve this problem:

Initially I thought to use some sort of a serial traffic sniffer with a capability to display a data rate. I've tried several, but whenever I try to connect to /dev/ttyUSB0 I'm getting a resource busy error. This is happening because PPP is taking over the device.

My second approach to solve this problem:

I want to create a pseudo serial port, connect it to a real serial port. Then PPP will take over pseudo serial port and I will sniff the traffic on a real serial port. Here is the diagram:

--------------------         -------------------------
|                  |         |                       |
|      PPP         |         |        sniffer        |
|  -------------   |         |   ------------------  |
|  | /dev/pty0 |---|---------|---|  /dev/ttyUSB0  |  |
|  -------------   |         |   ------------------  |
|                  |         |                       |
--------------------         -------------------------


My understanding is that socat can do that. I've been reading up on this, but I coulnd't find any options that allow me to do that.

So here is my question:

How do I create a pseudoterminal with socat and connect to a real serial port? Is that even possible?

• I wonder why you don't just disable the compression in pppd? (novj, nobsdcomp, noccp, nodeflate, etc). – mosvy Jan 12 at 18:34

You should be able to use socat in a simple command like

socat pty,link=$HOME/myserial,rawer /dev/ttyUSB0,rawer 2>&1  This creates a symbolic link ~/myserial to the pty, and any i/o to the pty is copied to/from the serial port. Going one step further, you can add options -v to get the i/o copied to stderr, and -x to have it printed in hex with header lines of the form: < 2019/01/12 18:16:36.528942 length=12 from=310 to=321  where the first character is the direction < or >, and the length is the number of bytes copied. The use of hex ensures the header line is not confused with the raw data. Here's a possible awk script to parse this. Approximately every 10 seconds it writes out the current number of bytes/second in a direction. socat -v -x pty,link=$HOME/myserial,rawer /dev/ttyUSB0,rawer 2>&1  |
awk '
/^[><]/{ split($3,x,":"); tod = (x[1]*60+x[2])*60+x[3]; split($4,x,"="); len = x[2]+0;
dir = \$1=="<" ? "rx" : "tx";
if(tod-lasttod[dir]>=10){
printf "%s %f\n",dir,(len+tot[dir])/(tod-lasttod[dir])
lasttod[dir] = tod
tot[dir] = 0
}else tot[dir] += len
}'


To keep it simple, each direction is handled separately, and you will need to fix time going through midnight. Typical output might be

tx 2.398754
rx 0.000425
tx 2.398772
rx 61.768501