4

I'm currently trying to access data on both directions of a serial port connected to an an app.
What i'm trying to do is:
ttymxc0 <-----> socat sniff <------> ttyV0 <------> Application
ttymxc0 is the real port and ttyV0 is the virtual one.

I found that socat command that worked on Ubuntu 16.04: http://www.iheartrobotics.com/2010/02/debugginng-serial-interfaces.html

But when i use it on an embedded system using buildroot, i obtain this error:

socat -d /dev/ttymxc0,raw,echo=0 SYSTEM:'tee input.txt | socat - "PTY,link=/tmp/ttyV0,raw,echo=0,waitslave" | tee output.txt'
 socat[3167.1996369920] E address "GOPEN..." in intermediate context, leftdirs=4, rightdirs=7, with 1 parameter(s) is not available
 socat[3167.1996369920] W cannot restore terminal settings on fd 3: Bad file descriptor

I tried to look on the access properties of my files without success. It works when you don't ask to print input and output, but that's not useful for my usage

Any ideas of what could be different between buildroot and Ubuntu in this case?

Adraub
  • 41
  • 1
  • 3
  • 3
    Solved using that command: socat -x /dev/ttymxc0,raw,echo=0,crnl PTY,link=/dev/ttyV1,raw,echo=0,crnl , that outputs directly content to the terminal – Adraub Aug 10 '16 at 10:23

2 Answers2

6

You already answered your own question, but this a slightly modernized answer is:

$ socat -x -v /dev/ttyUSB0,rawer,b115200,crnl PTY,link=ttyV1,rawer,crnl
< 2022/01/12 15:34:47.845709  length=11 from=0 to=10
 65 63 68 6f 20 48 65 6c 6c 6f 0a                 echo Hello.
--
> 2022/01/12 15:34:47.847937  length=12 from=0 to=11
 65 63 68 6f 20 48 65 6c 6c 6f 0d 0a              echo Hello..
--
> 2022/01/12 15:34:47.876068  length=7 from=12 to=18
 48 65 6c 6c 6f 0d 0a                             Hello..
--
> 2022/01/12 15:34:47.905274  length=1 from=19 to=19
 24                                               $
--

From the socat manual:

  1. -v "Writes the transferred data not only to their target streams, but also to stderr. The output format is text with some conversions for readability, and prefixed with "> " or "< " indicating flow directions."
  2. raw is obsolete and rawer "makes terminal rawer than raw option. This option implicitly turns off echo."
  3. b115200 "sets the serial line speed to 115200 baud" which is a quite common settings. Of course set the correct one for your case.
Diego
  • 5,326
  • 1
  • 35
  • 32
  • WTF? Zero votes? You have NO idea how long I could have used this! Ever debug a kernel via gdb over serial and then have it panic kgdb and reboot, but you can't see the message because gdb was trying to interpret it via the serial remote protocol!? gdb doesn't have a feature to log it. – Daniel Santos Mar 19 '22 at 18:14
  • i tested in macos, it worked well enough. – Muthukumar Anbalagan May 01 '22 at 06:38
1

Diego's answer is great if you're fine with socat's -v output format. However, if you'd prefer creating a separate device that's just a read-only version of the original device like myself - say, so that you can open minicom on the read-only device and let other software interact with the read-write device normally - I just came up with the following that works nicely.

socat /dev/ttyUSB0,rawer SYSTEM:'tee >(socat - "PTY,link=/tmp/foobar-ro,rawer" >%-) | socat - "PTY,link=/tmp/foobar-rw,rawer,wait-slave"'

That's complicated, so I'll break it down a bit. Logically it's this:

socat /dev/ttyUSB3,rawer SYSTEM:'tee [READ-ONLY PTY] | [READ-WRITE PTY]'

And it works roughly like so:

  1. The first socat command sets up a bidirectional pipe between the first address (/dev/ttyUSB0) and second (the SYSTEM command).
  2. Inside the SYSTEM command now, tee duplicates its stdin (i.e. the output of /dev/ttyUSB0) to both [READ-ONLY PTY] and to its own stdout, which we then pipe to [READ-WRITE PTY].
  3. [READ-ONLY PTY] is created with a 2nd socat command where the first address is - (shorthand for socat's STDIO address type) and the second is a new PTY. We also make sure to close this 2nd socat command's stdout with >%-; this is what makes it read-only.
    • For a reason I don't quite understand, unless the 2nd socat's stdout is closed, tee seems to include the output from the process substitution in its own output. I'm not sure why tee would be reading from its arguments at all.
  4. Finally, [READ-WRITE PTY] is created with a 3rd socat command similar to the 2nd. This 3rd socat's stdout becomes the output of the SYSTEM address in the 1st socat and is fed to the original device's input, completing the loop.
Bryan Henry
  • 8,348
  • 3
  • 34
  • 30
  • Thanks for the command. In my setup the full command was not working, but I split it to two scripts: #!/usr/bin/env bash tee >(socat - "PTY,link=$HOME/console-ro,rawer" >%-) | socat - "PTY,link=$HOME/console-rw,rawer" and the command: socat ,rawer SYSTEM: – Andrei Emeltchenko Apr 06 '23 at 10:23