I need to implement communication between two devices via serial ports on a Raspberry Pi (with the latest Raspbian on board). Both use the CP2102 controller and are connected to the Pi.

Terminal:
pi@pi ~ $ ls -l /dev/serial/by-id total 0 Silicon_Labs_CP2102_USB_to_UART_Bridge_Controller_0001-if00-port0 -> ../../ttyUSB2 pi@pi ~ $ ls -l /dev/serial/by-path total 0 platform-bcm2708_usb-usb-0:1.2.1:1.0-port0 -> ../../ttyUSB1 platform-bcm2708_usb-usb-0:1.2.4:1.0-port0 -> ../../ttyUSB2 platform-bcm2708_usb-usb-0:1.3:1.0-port0 -> ../../ttyUSB0
Usually, when I send a SERIAL A command, device A answers through SERIAL A and sends data through SERIAL B. After that I need to retransmit this data to device B (SERIAL C) and get a response from SERIAL C.
The problem is that SERIAL A appears on SERIAL B and SERIAL A appears SERIAL A.
I tried different languages ββand sequential libraries, but the result is the same. So the questions are: why does this happen when using raspberries? How can I implement this feature on Raspberry Pi?
PS Both devices are working correctly. My C # code works fine. I used the System.IO.Ports.SerialPort class for this implementation, and it looks like Pi4J and RXTX solutions.
PPS Some code that I tried to use on RPi:
Serial , C ++: (very bad piece of code)
Serial port("/dev/ttyUSB2", 115200U); Serial port1("/dev/ttyUSB1", 115200U); port1.setTimeout(Timeout::max(), 250, 0, 250, 0); port.setTimeout(Timeout::max(), 250, 0, 250, 0); cout << "Is the serial port open?"; if (port1.isOpen()) { cout << " Yes." << endl; uint8_t data[2] = { 0xAA, 0x00 }; port1.write(data, 2); data[1] = 0xFF; sleep(1); port1.write(data, 2); while (port.available() < 7); int av = port.available(); string ss; port.read(ss, av); for (int i = 0; i < av; i++){ cout << (uint)ss.at(i) << " "; } cout << "av: " + (uint)av << endl; }
RXTX, Java:
public class Bridge_rxtx { public static final int baudrate = 115200; protected SerialPort spDevB_Data; SerialReader devB_DataListener; protected SerialPort spDevA_Data; SerialReader DevA_DataListener; protected SerialPort spDevA_Control; SerialPortEventListener DevA_ControlListener; public Bridge_rxtx(String comDevB_Data, String comDevA_Data, String comDevA_Control) { try { spDevB_Data = setupPort(comDevB_Data); spDevA_Data = setupPort(comDevA_Data); spDevA_Control = setupPort(comDevA_Control); } catch (Exception ignored){ ignored.printStackTrace(); } try { devB_DataListener = new SerialReader(spDevB_Data.getInputStream(), spDevA_Data.getOutputStream(), "BA"); DevA_DataListener = new SerialReader(spDevA_Data.getInputStream(), spDevB_Data.getOutputStream(), "AB"); DevA_ControlListener = new SerialPortEventListener() { @Override public void serialEvent(SerialPortEvent spe) { throw new UnsupportedOperationException("Not supported yet."); } }; spDevB_Data.notifyOnDataAvailable(true); spDevA_Data.notifyOnDataAvailable(true); spDevA_Control.notifyOnDataAvailable(true); } catch (IOException ex) { Logger.getLogger(Bridge_rxtx.class.getName()).log(Level.SEVERE, null, ex); } } public void launchBridge(){ System.out.println("Starting..."); try { spDevA_Control.getOutputStream().write(new byte[] {(byte)0xAA, (byte) 0x00}, 0, 2); } catch (IOException ex) { Logger.getLogger(Bridge_rxtx.class.getName()).log(Level.SEVERE, null, ex); } try { Thread.sleep(200); } catch (InterruptedException ex) { Logger.getLogger(Bridge_rxtx.class.getName()).log(Level.SEVERE, null, ex); } try { spDevA_Control.getOutputStream().write(new byte[] {(byte)0xAA, (byte) 0xFF}, 0, 2); } catch (IOException ex) { Logger.getLogger(Bridge_rxtx.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("Started"); } SerialPort setupPort(String portName) throws Exception { SerialPort serialPort = null; CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName); if (portIdentifier.isCurrentlyOwned()) { System.out.println("Error: Port is currently in use"); } else { CommPort commPort = portIdentifier.open(this.getClass().getName(), 2000); if (commPort instanceof SerialPort) { serialPort = (SerialPort) commPort; serialPort.setSerialPortParams(baudrate, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); } else { System.out.println("Error: Only serial ports are handled by this code."); } } return serialPort; } public static void main(String[] args) { Bridge_rxtx bridge = new Bridge_rxtx("/dev/ttyUSB0", "/dev/ttyUSB2", "/dev/ttyUSB1"); bridge.launchBridge(); } }
Pi4J, Java:
public class Bridge { public static Bridge instance; public static final int baudrate = 115200; protected Serial spDevB_Data; SerialDataListener devB_DataListener; protected Serial spDevA_Data; SerialDataListener devA_DataListener; protected Serial spDevA_Control; SerialDataListener devA_ControlListener; private Bridge() { } public Bridge(String comDevB_Data, String comDevA_Data, String comDevA_Control) { instance = this; devA_ControlListener = new SerialDataListener() {