import serial
import threading
import os
import pty
import subprocess
import time

# Configuration
real_serial_port = "/dev/ttyAMA3"
baud_rate = 115200

# Desired names for the virtual ports
named_read_port = "/dev/ttyUNIVERSAL" 
named_write_port = "/dev/ttyNMEA"

# Create two virtual serial ports
master1, slave1 = pty.openpty()  # For data read from /dev/ttyAMA3
master2, slave2 = pty.openpty()  # For data sent to /dev/ttyAMA3

# Get the dynamically generated port names
virtual_read_port = os.ttyname(slave1)
virtual_write_port = os.ttyname(slave2)

# Create symbolic links with desired names
subprocess.run(["ln", "-sf", virtual_read_port, named_read_port], check=True)
subprocess.run(["ln", "-sf", virtual_write_port, named_write_port], check=True)

print(f"Virtual read port (linked): {named_read_port} -> {virtual_read_port}")
print(f"Virtual write port (linked): {named_write_port} -> {virtual_write_port}")

# Open the real serial port
try:
    real_port = serial.Serial(real_serial_port, baud_rate)
except serial.SerialException as e:
    print(f"Error opening serial port {real_serial_port}: {e}")
    exit(1)

def forward_to_virtual():
    """Forward data read from /dev/ttyAMA3 to the virtual read port."""
    while True:
        data = real_port.read(real_port.in_waiting or 1)
        os.write(master1, data)

def forward_to_real():
    """Forward data written to the virtual write port to /dev/ttyAMA3."""
    while True:
        data = os.read(master2, 1024)
        real_port.write(data)

# Start the threads for bidirectional communication
threading.Thread(target=forward_to_virtual, daemon=True).start()
threading.Thread(target=forward_to_real, daemon=True).start()

# Keep the program running
try:
    while True:
        time.sleep(1)  # Keeps the main thread alive
except KeyboardInterrupt:
    print("\nExiting...")
