Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I bridge two physical serial ports to each other in software (and log the data going across)?

Tags:

serial-port

Basically, I want to put my computer in the middle of a serial line and record the conversation going across it. I'm trying to reverse engineer this conversation and eventually emulate one end of the conversation.

Rough Diagram of what I'm trying to do:

Normally, I have this:

__________        __________  
|        |        |        |  
|Device 1|<======>|Device 2|  
|________|        |________|  

I want to do this:

__________     __________     __________  
|        |     |        |     |        |  
|Device 1|<===>|Computer|<===>|Device 2|  
|________|     |________|     |________|  

With the computer in the middle basically bridging the connection between the two devices and logging the data that goes across.

Answers using any programming language are probably useful. Preferably I would be able to do this on either Windows or Linux (or both if someone has a general solution to this problem).

like image 862
Justin T. Conroy Avatar asked Oct 27 '10 01:10

Justin T. Conroy


People also ask

Can you connect two terminal equipment serially?

If you connect two DTE's or two DCE's using a straight serial cable, then the TD pin on each device are connected to each other, and the RD pin on each device are connected to each other. Therefore, to connect two like devices, you must use a null modem cable.

What is a parallel serial port?

What Does Parallel Port Mean? A parallel port is an interface allowing a personal computer (PC) to transmit or receive data down multiple bundled cables to a peripheral device such as a printer. The most common parallel port is a printer port known as the Centronics port.

Can multiple applications use the same serial port?

Serial Port Splitter: What it is and how it worksSplitting a serial port means to share the interface with more than one application simultaneously. All attached applications get the same data flow from the serial port.


2 Answers

Well, a programmatic way to do it would be to just open the relevant devices, and start forwarding data between them, simultaneously saving to a file.

Most any language can do it. There are nice libraries for things like java and python.

Several implementations exist on the web, I found a python one called Telnet Serial Bridge (TSB) by googling, which would allow you to bridge connections together over ethernet, and log using telnet tools like putty.

Though in the past, I've used the java rxtx serial comm library from rxtx.qbang.org to do it myself, though I suspect there's an updated version now, or maybe something built into the JVM proper.

Adapted from an example on that site:

import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;

import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class TwoWaySerialComm
{
    void bridge( String portName1, String portName2 ) throws Exception
    {
        CommPortIdentifier portIdentifier1 = CommPortIdentifier.getPortIdentifier(portName1);
        CommPortIdentifier portIdentifier2 = CommPortIdentifier.getPortIdentifier(portName2);

        if ( portIdentifier1.isCurrentlyOwned() || portIdentifier2.isCurrentlyOwned())
        {
            System.out.println("Error: Port is currently in use");
        }
        else
        {
            CommPort commPort1 = portIdentifier1.open(this.getClass().getName(),2000);
            CommPort commPort2 = portIdentifier2.open(this.getClass().getName(),2000);

            if ( commPort instanceof SerialPort && commPort2 instanceof SerialPort )
            {
                SerialPort serialPort1 = (SerialPort) commPort1;
                serialPort1.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

                InputStream in1 = serialPort1.getInputStream();
                OutputStream out1 = serialPort1.getOutputStream();

                SerialPort serialPort2 = (SerialPort) commPort2;
                serialPort2.setSerialPortParams(57600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

                InputStream in2 = serialPort2.getInputStream();
                OutputStream out2 = serialPort2.getOutputStream();

                (new Thread(new SerialReader(in1, out2))).start();
                (new Thread(new SerialReader(in2, out1))).start();
            }
            else
            {
                System.out.println("Error: Only serial ports are handled by this example.");
            }
        }     
    }

    /** */
    public static class SerialReaderWriter implements Runnable 
    {
        InputStream in;
        OutputStream out;

        public SerialReader ( InputStream in, OutputStream out )
        {
            this.in = in;
            this.out = out;
        }

        public void run ()
        {
            byte[] buffer = new byte[1024];
            int len = -1;
            try
            {
                while ( ( len = this.in.read(buffer)) > -1 )
                {
                    out.write(buffer,0, len);
                    System.out.print(new String(buffer,0,len));
                }
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }            
        }
    }

    public static void main ( String[] args )
    {
        try
        {
            (new TwoWaySerialComm()).bridge("COM1", "COM3");
        }
        catch ( Exception e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
like image 82
davenpcj Avatar answered Sep 28 '22 08:09

davenpcj


This is a small python script to bridge between two physical ports` #!/usr/bin/python

import time, sys, serial
import collections
import re
from serial import SerialException
from termcolor import colored

SERIALPORT1 = "/dev/rfcomm0"  # the default com/serial port the receiver is connected to
BAUDRATE1 = 115200      # default baud rate we talk to Moteino

SERIALPORT2 = "/dev/ttyUSB0"  # the default com/serial port the receiver is connected to
BAUDRATE2 = 9600      # default baud rate we talk to Moteino


# MAIN()
if __name__ == "__main__":
    try:
        # open up the FTDI serial port to get data transmitted to Moteino
        ser1 = serial.Serial(SERIALPORT1, BAUDRATE1, timeout=1) #timeout=0 means nonblocking
        ser1.flushInput();
        print "\nCOM Port [", SERIALPORT1, "] found \n"
    except (IOError, SerialException) as e:
        print "\nCOM Port [", SERIALPORT1, "] not found, exiting...\n"
        exit(1)

    try:
        # open up the FTDI serial port to get data transmitted to Moteino
        ser2 = serial.Serial(SERIALPORT2, BAUDRATE2, timeout=1) #timeout=0 means nonblocking
        ser2.flushInput();
        print "\nCOM Port [", SERIALPORT2, "] found \n"
    except (IOError, SerialException) as e:
        print "\nCOM Port [", SERIALPORT2, "] not found, exiting...\n"
        exit(1)

    try:    

        while 1:
            ser1_waiting = ser1.inWaiting()
            if ser1_waiting > 0:
                #rx1 = ser1.read(ser1_waiting)
                rx1 = ser1.readline()
                ser2.write(rx1)
                print colored(rx1, 'red')
            ser2_waiting = ser2.inWaiting()
            if ser2_waiting > 0:
                #rx2 = ser2.read(ser2_waiting)
                rx2 = ser2.readline()
                ser1.write(rx2)
                print rx2       


    except IOError:
        print "Some IO Error found, exiting..." `
like image 40
dilraj N Avatar answered Sep 28 '22 07:09

dilraj N