Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a serial port sniffer sniffing physical port using a python

I have a PC Software (OS: Win 64bit) that communicates with a machine via physical serial port RS232 and I want to make a sniffer for that port using a python. Please note that I am beginner to serial ports.

I've read multiple documents and questions posted online but most of them asks to just use 3rd-party software, but I cannot do this way because raw bytes have to be decoded into string message (I have my way own of decode/encode method).

Currently I have setup like this:

///////////////////       Physical COM1        /////////////
// (PC) Software // <------------------------> // Machine //
///////////////////                            /////////////

And I want a python to output any bytes that went through COM1.

Desired Behavior diagram (Virtual serial port has a question mark because I'm not sure if that is the right approach):

///////////////////       Physical COM1        /////////////
// (PC) Software // <------------------------> // Machine //
///////////////////            | Virtual       /////////////
                               | serial port?
                               v
                        //////////////////
                        // (PC) Sniffer // (Python)
                        //////////////////
                               | 
                               v
                         (output bytes)

Those of who knows Advanced Serial Port Monitor, its "spymode" functionality is exactly what I am trying to achieve using python.

I've tried to use com0com and PortMon but I can't find a way to configure com0com to sniff physical port (as far as my observation goes, com0com only makes virtual ports) and PortMon does not support Windows 64-bit.

I've been stuck at this for days... any comments/links/answers are appreciated. Thank you,

like image 303
Harry Cho Avatar asked Oct 07 '13 17:10

Harry Cho


1 Answers

We can use the code above without the need to go through threading to achieve a half duplex communication. we are going to use an infinite loop, and a variable which gonna specify in which port we are reading.

import serial
import time

baud_rate = 9600  # whatever baudrate you are listening to
com_port1 = '/dev/ttyUSB0'  # replace with your first com port path
com_port2 = '/dev/ttyUSB1'  # replace with your second com port path

ComRead_timeout = 0.1   # Read timeout to avoid waiting while there is no data on the buffer
ComWr_timeout = 0.1     # Write timeout to avoid waiting in case of write error on the serial port

log = open('log.txt', 'a+')     # Open our log file, to put read data

From_PC_To_Device = True    # this variable is used to specify which port we're gonna read from

listener = serial.Serial(port=com_port1, baudrate=baud_rate, timeout=ComRead_timeout,
                         write_timeout=ComWr_timeout)

forwarder = serial.Serial(port=com_port2, baudrate=baud_rate, timeout=ComRead_timeout,
                          write_timeout=ComWr_timeout)

while 1:
    while (listener.inWaiting()) and From_PC_To_Device:
        serial_out = listener.readline()
        localtime = time.asctime(time.localtime(time.time()))
        Msg = "PC " + localtime + " " + serial_out
        Msg += "\n"
        log.write(Msg)
        print(serial_out)  # or write it to a file
        forwarder.write(serial_out)
    else:
        From_PC_To_Device = False

    while (forwarder.inWaiting()) and not From_PC_To_Device:
        serial_out = forwarder.readline()
        localtime = time.asctime(time.localtime(time.time()))
        Msg = "DEVICE " + localtime + " " + serial_out + "\n"
        log.write(Msg)
        print(serial_out)  # or write it to a file
        listener.write(serial_out)
    else:
        From_PC_To_Device = True
like image 65
AbdoPro Avatar answered Oct 03 '22 15:10

AbdoPro