Trace a binary stream from a device file

binarypipetail

I'm debugging a binary stream that is coming from a device file.
I would like to have the output printed out in real time as hex values.

So far I've used tail -f /dev/ttyAPP2 | hexdump -C but after I started missing some bytes in the output I understood that this could be a bad choice because it doesn't flush the data until a newline character is found.

There is an unofficial binary tail but I currently can't use that approach and am looking for a suggestion how to achieve this with other means?

Example

First the tty is set to raw mode.

stty -F /dev/ttyAPP2 raw

Here is what I get when listening to the device (this is real output)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54 

However, the expected package should be (this isn't a real output):

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54  
00000020  52 4c 00 00 00 00 00 8b  

The other part of the package gets printed out on arrival of the second package (this is real output)

root@Vdevice:/dev# hexdump -C < /dev/ttyAPP2
00000000  55 00 21 00 02 26 00 02  0b 00 09 02 06 01 00 01  
00000010  99 0c ec 45 4f 01 03 47  41 54 45 57 41 59 43 54
00000020  52 4c 00 00 00 00 00 8b  55 00 21 00 02 26 00 02
00000030  0b 00 09 02 06 01 00 01  99 0c ec 45 4f 01 03 47
00000040  41 54 45 57 41 59 43 54  52 4c 00 00 00 00 00 8b

Best Answer

You don't need to tail -f a tty. If it's sending you EOF, or, if it is line-buffering, then you need to configure it.

stty -F/dev/ttyAPP2 raw

Now you can...

cat /dev/ttyAPP2

...as needed...

You might try...

</dev/ttyAPP2 \
dd bs=16 conv=sync | od -vtx1

...which will sync out every successful read() from your device into 16-byte, null-padded blocks, and so will write line-buffered output (such as to your terminal) in real-time regardless of throughput, though any trailing nulls might distort your stream.

With GNU stdbuf and a dynamically linked od:

stdbuf -o0 od -vtx1 </dev/ttyAPP2

...would write output in real-time regardless.

You might also buffer to a temp file like...

f=$(mktemp)
exec 3<>"$f"; rm -- "$f"
while   dd >&3 of=/dev/fd/1 bs=4k count=1
        [ -s /dev/fd/3 ]
do      od -An -vtx1 /dev/fd/3
        echo
done    </dev/ttyAPP2 2>/dev/null

...which, though likely not nearly as efficient as the other recommendations, might be worth considering if you wanted to delimit reads from your device by EOF. I find the technique useful sometimes when working with ttys, anyway.

It is also possible to force hexdump to print out less bytes by using the custom print format. The example below will print every time there are 4 bytes available:

hexdump -e '4/1 "%02x " "\n"' < /dev/ttyAPP2

Related Question