From 255137345f98130ddfa5301d190051651fde223d Mon Sep 17 00:00:00 2001 From: Torsten Harenberg Date: Sun, 2 Feb 2025 19:19:16 +0100 Subject: [PATCH] first commit in new repo --- README.md | 124 ++++++ TODO.txt | 15 + fifo.go | 241 ++++++++++++ go.mod | 23 ++ main.go | 192 +++++++++ pics/Screenshot.png | Bin 0 -> 76947 bytes pics/ptb.png | Bin 0 -> 62836 bytes ptc.go | 937 ++++++++++++++++++++++++++++++++++++++++++++ tcpserver.go | 320 +++++++++++++++ tui.go | 157 ++++++++ 10 files changed, 2009 insertions(+) create mode 100644 README.md create mode 100644 TODO.txt create mode 100644 fifo.go create mode 100644 go.mod create mode 100644 main.go create mode 100644 pics/Screenshot.png create mode 100644 pics/ptb.png create mode 100644 ptc.go create mode 100644 tcpserver.go create mode 100644 tui.go diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c33493 --- /dev/null +++ b/README.md @@ -0,0 +1,124 @@ +# The PACTOR-TCP-BRIDGE + +logo +by Torsten Harenberg (DL1THM) + +## What is the PACTOR-TCP-BRIDGE (ptb) + +It's a tool that + +- talks via a serial line (USB or Bluetooth) to [PACTOR modems](https://scs-ptc.com/modems.html) made by [SCS](https://scs-ptc.com) using the extended WA8DED hostmode [(see the manual, chapter 10)](https://www.p4dragon.com/download/SCS_Manual_PTC-IIIusb_4.1.pdf) protocol these modems offer +- offers two TCP sockets which can be used by [Pat](https://getpat.io/) (and other tools) + +## What it is used for + +The main purpose is to build a connection between Pat and PACTOR modems. In order to establish a "listen" mode for PACTOR in Pat, +the modem needs to be kept in the WA8DED hostmode. I found it easiest to create a separate program +for that - in the same way, the VARA modem is a separate program. + +On the long run, this tool will replace the current PACTOR driver in Pat. + +## How to use it + +In order to use this tool, you'll need to configure it. + +If you start it for the first time, it will create a default configuration file and will tell you its location: + +```bash + % ./ptb +new Config file /Users/harenber/.config/dl1thm.pactortcpbridge/Config.yaml created. Please edit the Config file and restart the application +``` + +Now edit the file and configure it accordingly: + +```yaml +device: /tmp/ttyUSB0 +baudrate: 9600 +mycall: N0CALL +server_address: 127.0.0.1:8300 +data_address: 127.0.0.1:8301 +cmdline_init: "" +vara_mode: false +``` + +| Variable | Meaning | +|-------------------|-----------------------------------------------------------------------------------------------------------------------------| +| `device` | Path to the serial device where the modem is connected | +| `baudrate` | baud rate of the modem | +| `mycall` | The callsign to be used on HF | +| `server_address` | server socket address for the **commands** | +| `data_address` | server socket address for the **data** | +| `cmdline_init` | extra commands sent to the modem before going into hostmode, separated by semicolons, Ex: `DISP BR 1;DISP A 1;DISP DIMMOFF` | +| `vara_mode` | see the chapter about the VARA mode | + +If you plan to you Pat with the VARA driver, data `data_address` you **must** use a port number one number higher than the `server_address`. + +A matching Pat config using VARA for the example above would look like: + +```yaml +"varahf": { +"addr": "localhost:8300", +"bandwidth": 2300, +"rig": "", +"ptt_ctrl": false +} +``` + +Using PACTOR, the PTT is triggered through the modem, so you need to set `ptt_ctrl` to `false`! If you configure a `rig`, it +needs to be connected in a way that `rigctl` can configure it. Configure your rig through the PACTOR modem +is **not** supported in VARA mode. + +## VARA mode + +The VARA mode translate WA8DED commands into VARA commands and vice versa. See the VARA homepage for the "VARA TNC Commands" +doumentation. + +If enabledm software which is written to interact with the VARA software TNC to work +with PACTOR as well. It was used by the author to use the [VARA driver for Pat](https://github.com/n8jja/Pat-Vara) +with the PACTOR-TCP-Bridge. + +## How to run + +As a rule of thumb, you have to start the PACTOR-TCP-bridge before you want to use +Pat and stop it after you finished using Pat. + +So a typical session works like this + +1. start the PACTOR-TCP-Bridge +2. wait for it to finish configure your modem +3. use Pat (or any other software) +4. quit Pat +5. stop the PACTOR-TCP-Bridge + +The software supports command line options: + +```bash + % ./ptb --help +Usage of ptb - the PACTOR-IP-Bridge: + -c, --configfile string Name of config file (default "Config.yaml") + -d, --daemon Daemon mode (no TUI) + -l, --logfile string Path to the log file (default "/tmp/pactortcpbridge.log") +``` + +which should be rather self-explaining. + +A typical session (without using the daemon mode, see below) looks like this: + +![Screenshot showing a terminal with a session](pics/Screenshot.png) + +- on the upper left you will see all **payload** from and to the PACTOR modem +- on the lower left the **commands** (with VARA translations, if switched on) to and **answers** from the modem +- on the right hand side you'll see a clock, then a mode indicator (showing `VARA` or `TCP`). Furthermore, you'll see two indicator (`TCP CMD` and `TCP DATA`) which will turn green when a client is connected. The 4 counters below show the usage of the buffers. + + +## "Daemon"-mode + +The "daemon"-mode will omit the terminal UI ("TUI") and might be useful if you have no full terminal (or to run the tool with systemd). + +Instead of the UI, you will only see a message saying that you may quit with CTRL-C. + +## Keys + +- **CTRL-C**
Quits the program +- **CTRL-V**
swtiches between the VARA and normal mode + diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..b71c638 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,15 @@ +--Kein leeren Befehl senden-- +-- Keine leere Antwort durch parsen -- +-- VARA Tests -- +-- CLI -- +-- Debug handling -- +-- Muell vom Input ausschliessen? -- +-- kommen error Mmeldungen durch? -> ja -- +stophostmodem(): Timeouts beim lesen vom Modem... (scheint weg zu sein?) +-- Was mache ich mit dem initfile -- +Log sollte auch auf stdout schreiben +-- VARA Mode beim starten -- +-- Goconcurrentqueue los werden -- +-- "daemon" mode: Achtung.. Daten fuer den Screen werden wahrscheinlich noch geschickt. ERLEDIGT -- +-- Vielleicht flags umstellen auf Standard-Flags mit short forms wie hier beschrieben https://www.antoniojgutierrez.com/posts/2021-05-14-short-and-long-options-in-go-flags-pkg/ -- + diff --git a/fifo.go b/fifo.go new file mode 100644 index 0000000..bdc4b1e --- /dev/null +++ b/fifo.go @@ -0,0 +1,241 @@ +package main + +import ( + "context" + "errors" + "sync" +) + +type ByteFIFO struct { + buffer []byte // The underlying byte slice + mutex sync.Mutex // Mutex for thread safety + cond *sync.Cond // Condition variable for signaling + cap int // Capacity of the buffer +} + +// NewByteFIFO creates a new ByteFIFO with the given capacity. +func NewByteFIFO(capacity int) *ByteFIFO { + fifo := &ByteFIFO{ + buffer: make([]byte, 0, capacity), + cap: capacity, + } + fifo.cond = sync.NewCond(&fifo.mutex) // Initialize condition variable + return fifo +} + +// Enqueue adds bytes to the end of the buffer. Returns an error if the buffer is full. +func (f *ByteFIFO) Enqueue(data []byte) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.buffer)+len(data) > f.cap { + return errors.New("buffer overflow") + } + + f.buffer = append(f.buffer, data...) + f.cond.Signal() // Notify waiting goroutines that data is available + return nil +} + +// Dequeue removes and returns the first `n` bytes from the buffer (or what's left if n>len(f.buffer)). +// Returns an error if nothing is in the queue +func (f *ByteFIFO) Dequeue(n int) ([]byte, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.buffer) == 0 { + return nil, errors.New("buffer is empty") + } + if n > len(f.buffer) { + n = len(f.buffer) + } + + data := f.buffer[:n] + f.buffer = f.buffer[n:] + return data, nil +} + +// DequeueOrWait removes and returns the first `n` bytes, waiting if the buffer is empty until data is available. +func (f *ByteFIFO) DequeueOrWait(n int) ([]byte, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + // Wait until enough data is available + for len(f.buffer) < n { + f.cond.Wait() + } + + data := f.buffer[:n] + f.buffer = f.buffer[n:] + return data, nil +} + +// DequeueOrWaitContext removes and returns the first `n` bytes, waiting if necessary until data is available or the context is canceled. +func (f *ByteFIFO) DequeueOrWaitContext(ctx context.Context, n int) ([]byte, error) { + done := make(chan struct{}) + var data []byte + var err error + + go func() { + f.mutex.Lock() + defer f.mutex.Unlock() + defer close(done) + + // Wait until enough data is available + for len(f.buffer) < n { + select { + case <-ctx.Done(): + err = ctx.Err() + return + default: + f.cond.Wait() + } + } + + data = f.buffer[:n] + f.buffer = f.buffer[n:] + }() + + select { + case <-done: + return data, err + case <-ctx.Done(): + return nil, ctx.Err() + } +} + +// Peek returns the first `n` bytes without removing them from the buffer. Returns an error if there are not enough bytes. +func (f *ByteFIFO) Peek(n int) ([]byte, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if n > len(f.buffer) { + return nil, errors.New("not enough data in buffer") + } + + return f.buffer[:n], nil +} + +// Size returns the current number of bytes in the buffer. +func (f *ByteFIFO) GetLen() int { + f.mutex.Lock() + defer f.mutex.Unlock() + + return len(f.buffer) +} + +// Capacity returns the maximum capacity of the buffer. +func (f *ByteFIFO) Capacity() int { + return f.cap +} + +// ***** + +type StringFIFO struct { + buffer []string // The underlying byte slice + mutex sync.Mutex // Mutex for thread safety + cond *sync.Cond // Condition variable for signaling +} + +// NewByteFIFO creates a new ByteFIFO with the given capacity. +func NewStringFIFO() *StringFIFO { + fifo := &StringFIFO{ + buffer: make([]string, 0), + } + fifo.cond = sync.NewCond(&fifo.mutex) // Initialize condition variable + return fifo +} + +// Enqueue adds a string to the end of the buffer. Returns an error if the buffer is full. +func (f *StringFIFO) Enqueue(data string) error { + f.mutex.Lock() + defer f.mutex.Unlock() + + f.buffer = append(f.buffer, data) + f.cond.Signal() // Notify waiting goroutines that data is available + return nil +} + +// Dequeue removes and returns the first `n` bytes from the buffer (or what's left if n>len(f.buffer)). +// Returns an error if nothing is in the queue +func (f *StringFIFO) Dequeue() (string, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.buffer) == 0 { + return "", errors.New("buffer is empty") + } + + data := f.buffer[0] + f.buffer = f.buffer[1:] + return data, nil +} + +// DequeueOrWait removes and returns the first `n` bytes, waiting if the buffer is empty until data is available. +func (f *StringFIFO) DequeueOrWait() (string, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + // Wait until enough data is available + for len(f.buffer) == 0 { + f.cond.Wait() + } + + data := f.buffer[0] + f.buffer = f.buffer[1:] + return data, nil +} + +// DequeueOrWaitContext removes and returns the first `n` bytes, waiting if necessary until data is available or the context is canceled. +func (f *StringFIFO) DequeueOrWaitContext(ctx context.Context) (string, error) { + done := make(chan struct{}) + var data string + var err error + + go func() { + f.mutex.Lock() + defer f.mutex.Unlock() + defer close(done) + + // Wait until enough data is available + for len(f.buffer) == 0 { + select { + case <-ctx.Done(): + err = ctx.Err() + return + default: + f.cond.Wait() + } + } + + data = f.buffer[0] + f.buffer = f.buffer[1:] + }() + + select { + case <-done: + return data, err + case <-ctx.Done(): + return "", ctx.Err() + } +} + +// Peek returns the first `n` bytes without removing them from the buffer. Returns an error if there are not enough bytes. +func (f *StringFIFO) Peek() (string, error) { + f.mutex.Lock() + defer f.mutex.Unlock() + + if len(f.buffer) == 0 { + return "", errors.New("not enough data in buffer") + } + + return f.buffer[0], nil +} + +// GetLen returns the current number of bytes in the buffer. +func (f *StringFIFO) GetLen() int { + f.mutex.Lock() + defer f.mutex.Unlock() + + return len(f.buffer) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ad1cfb4 --- /dev/null +++ b/go.mod @@ -0,0 +1,23 @@ +module gotests/pactorjarabridge + +go 1.23 + +require ( + github.com/TwiN/go-color v1.4.1 + github.com/albenik/go-serial/v2 v2.6.1 + github.com/howeyc/crc16 v0.0.0-20171223171357-2b2a61e366a6 + github.com/jroimartin/gocui v0.5.0 + github.com/karanveersp/store v0.0.0-20230714152426-8bd691c2bad8 + gopkg.in/yaml.v2 v2.4.0 +) + +require ( + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/creack/goselect v0.1.2 // indirect + github.com/kr/pretty v0.3.1 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/nsf/termbox-go v1.1.1 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/sys v0.20.0 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..3ba0003 --- /dev/null +++ b/main.go @@ -0,0 +1,192 @@ +package main + +import ( + "errors" + "flag" + "fmt" + "path/filepath" + + //log "github.com/fangdingjun/go-log" + "log" + "os" + "os/signal" + "syscall" + + "github.com/jroimartin/gocui" + "github.com/karanveersp/store" + "gopkg.in/yaml.v2" +) + +const usage = `Usage of ptb - the PACTOR-IP-Bridge: + -c, --configfile string Name of config file (default "Config.yaml") + -d, --daemon Daemon mode (no TUI) + -l, --logfile string Path to the log file +` + +const ( + StatusTCPCmdActive uint8 = 1 << iota //00000001 + StatusTCPDataActive //00000010 +) + +type TCPServer struct { + Protocol chan string + ToPactor *ByteFIFO + FromPactor *ByteFIFO + VARAMode bool + DaemonMode bool + Status uint8 + Command struct { + Cmd *StringFIFO + Response *StringFIFO + } + Data struct { + Data *ByteFIFO + Response *ByteFIFO + } +} + +func NewTCPServer(varamode bool, daemonmode bool) *TCPServer { + return &TCPServer{ + Protocol: make(chan string, 1024), + ToPactor: NewByteFIFO(1024), + FromPactor: NewByteFIFO(1024), + VARAMode: varamode, + DaemonMode: daemonmode, + Status: 0, + Command: struct { + Cmd *StringFIFO + Response *StringFIFO + }{Cmd: NewStringFIFO(), Response: NewStringFIFO()}, + Data: struct { + Data *ByteFIFO + Response *ByteFIFO + }{Data: NewByteFIFO(10240), Response: NewByteFIFO(10240)}, + } +} + +type Userconfig struct { + Device string `yaml:"device"` + Baudrate int `yaml:"baudrate"` + Mycall string `yaml:"mycall"` + ServerAddress string `yaml:"server_address"` + DataAddress string `yaml:"data_address"` + CmdLineInit string `yaml:"cmdline_init"` + StartwithVaraMode bool `yaml:"vara_mode"` +} + +func configmanage(Config *Userconfig, path string) error { + cf := store.GetApplicationDirPath() + string(os.PathSeparator) + path + + _, err := os.Stat(cf) + if err != nil { + log.Println("loadConfig error:", err) + log.Println("Config file not found. Creating new one") + Config = &Userconfig{Device: "/tmp/ttyUSB0", + Baudrate: 9600, + Mycall: "N0CALL", + ServerAddress: "127.0.0.1:8300", + DataAddress: "127.0.0.1:8301", + CmdLineInit: "", + StartwithVaraMode: false} + + if err := store.Save("Config.yaml", Config); err != nil { + log.Println("failed to save the Config file: ", err) + return err + } + return errors.New(fmt.Sprintf("new Config file %s created. Please edit the Config file and restart the application", cf)) + + } + if err := store.Load(path, Config); err != nil { + return err + } + + if Config.Device != "" { + //log.Println("Config loaded:", Config) + return nil + } + return errors.New(fmt.Sprintf("Empty device name in Config file. Please edit the Config file %s and restart the application", cf)) +} + +func init() { + store.Init("dl1thm.pactortcpbridge") + store.Register("ini", yaml.Marshal, yaml.Unmarshal) +} + +var s *TCPServer // s is a pointer to TCPServer, managing communication via channels and FIFO queues for command and data handling. + +func main() { + + tmpfile := filepath.FromSlash(os.TempDir() + "/ptb.log") + + // read command line arguments -- the standard flag module unfortunately doesn't know shorthands + var configfile string + flag.StringVar(&configfile, "configfile", "Config.yaml", "Name of config file") + flag.StringVar(&configfile, "c", "Config.yaml", "Name of config file") + var logfile string + flag.StringVar(&logfile, "logfile", tmpfile, "Name of log file") + flag.StringVar(&logfile, "l", tmpfile, "Name of log file") + var daemonMode bool + flag.BoolVar(&daemonMode, "daemon", false, "Daemon mode (no TUI)") + flag.BoolVar(&daemonMode, "d", false, "Daemon mode (no TUI)") + flag.Usage = func() { fmt.Print(usage) } + + flag.Parse() + + f, err := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + defer f.Close() + + log.SetOutput(f) + fmt.Println("logging to " + logfile) + + // read config + var Config Userconfig + //c := store.GetApplicationDirPath() + err = configmanage(&Config, configfile) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + s = NewTCPServer(Config.StartwithVaraMode, daemonMode) + fmt.Println("Initializing PACTOR modem, please wait...") + m, err := OpenModem(Config.Device, Config.Baudrate, Config.Mycall, "", Config.CmdLineInit) + if err != nil { + log.Panicln(err) + } + defer m.Close() + + go tcpCmdServer(&Config) + go tcpDataServer(&Config) + + if !daemonMode { + // Initialize the gocui GUI + g, err := gocui.NewGui(gocui.OutputNormal) + if err != nil { + log.Panicln(err) + } + defer g.Close() + + g.SetManagerFunc(layout) + go protocolUpdate(g) + go pactorUpdate(g) + go statusUpdate(g) + + // Set keybindings + if err := keybindings(g); err != nil { + log.Panicln(err) + } + // Start the main TUI loop + if err := g.MainLoop(); err != nil && err != gocui.ErrQuit { + log.Panicln(err) + } + } else { + // daemon mode: just print a message and wait for CTRL-C + done := make(chan os.Signal, 1) + signal.Notify(done, syscall.SIGINT, syscall.SIGTERM) + fmt.Println("pactortcpbridge running, press ctrl+c to end the process...") + <-done + } +} diff --git a/pics/Screenshot.png b/pics/Screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..75414e0f1d00ba275c7ee3a32af26edbde83bb6a GIT binary patch literal 76947 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 z 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�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 level { + _, file, no, ok := runtime.Caller(1) + if ok { + log.Println(file + "#" + strconv.Itoa(no) + ": " + message) + } else { + log.Println(message) + } + } + return +} + +// OpenModem: Initialise the pactor modem and all variables. Switch the modem into hostmode. +// +// Will abort if modem reports failed link setup, Close() is called or timeout +// has occured (90 seconds) +func OpenModem(path string, baudRate int, myCall string, initfile string, cmdlineinit string) (p *Modem, err error) { + writeDebug("Trying to open "+path+" with "+strconv.Itoa(baudRate)+" baud.", 0) + p = &Modem{ + // Initialise variables + devicePath: path, + + localAddr: myCall, + remoteAddr: "", + + state: Closed, + + device: nil, + flags: pflags{ + exit: false, + stopmodem: false, + connected: make(chan struct{}, 1), + closeWaiting: make(chan struct{}, 1)}, + goodChunks: 0, + // cmdBuf: make(chan string, 0), + cmdlineinit: cmdlineinit, + initfile: initfile, + } + + writeDebug("Initialising pactor modem", 1) + if err := p.checkSerialDevice(); err != nil { + writeDebug(err.Error(), 1) + return nil, err + } + + //Setup serial device + if p.device, err = serial.Open(p.devicePath, serial.WithBaudrate(baudRate), serial.WithReadTimeout(SerialTimeout)); err != nil { + writeDebug(err.Error(), 1) + return nil, err + } + + err = p.init() + if err != nil { + return nil, err + } + // run modem thread + + time.Sleep(3 * time.Second) // give the device a moment to settle, so no commands get lost + return p, nil +} + +func (p *Modem) setState(state State) { + writeDebug("Setting state to: "+strconv.FormatUint(uint64(state), 10), 1) + p.state = state +} + +func (p *Modem) IsClosed() bool { + if p == nil { + return true + } + return p.state == Closed +} + +func (p *Modem) init() (err error) { + writeDebug("Entering PACTOR init", 1) + // Get modem out of CRC hostmode if it is still in it while starting. + //p.stophostmode() + //p._write(string([]byte{0xaa, 0xaa, 0x00, 0x01, 0x05, 0x4a, 0x48, 0x4f, 0x53, 0x54, 0x30, 0xfb, 0x3d})) + //time.Sleep(100 * time.Millisecond) + //_, _, _ = p._read(100) + + if _, _, err = p.writeAndGetResponse("", -1, false, 10240); err != nil { + return err + } + + // Make sure, modem is in main menu. Will respose with "ERROR:" when already in it -> Just discard answer! + _, ans, err := p.writeAndGetResponse("Quit", -1, false, 1024) + if err != nil { + return err + } + + if len(ans) < 2 { + return errors.New("Modem does not react to Quit command. Please re-power your modem") + } + + // Check if we can determine the modem's type + _, ver, err := p.writeAndGetResponse("ver ##", -1, false, 1024) + if err != nil { + return err + } + re, err := regexp.Compile(`\w#1`) + if err != nil { + return errors.New("Cannot read SCS modem version string, did you configure the correct serial device? Error: " + err.Error()) + } + version := strings.ReplaceAll(string(re.Find([]byte(ver))), "#1", "") + modem, exists := SCSversion[version] + + if !exists { + return errors.New("Found a modem type: " + ver + " which this driver doesn't support. Please contact the author.") + } + writeDebug("Found a "+modem+" modem at "+p.devicePath, 0) + writeDebug("Running init commands", 1) + ct := time.Now() + commands := []string{"DD", "RESTART", "MYcall " + p.localAddr, "PTCH " + strconv.Itoa(PactorChannel), + "MAXE 35", "REM 0", "CHOB 0", "PD 1", + "ADDLF 0", "ARX 0", "BELL 0", "BC 0", "BKCHR 25", "CMSG 0", "LFIGNORE 0", "LISTEN 0", "MAIL 0", "REMOTE 0", + "PDTIMER 5", "STATUS 1", + "TONES 4", "MARK 1600", "SPACE 1400", "CWID 0", "CONType 3", "MODE 0", + "DATE " + ct.Format("020106"), "TIME " + ct.Format("150405")} + + //run additional commands provided on the command line with "init" + if p.cmdlineinit != "" { + for _, command := range strings.Split(strings.TrimSuffix(p.cmdlineinit, "\n"), ";") { + commands = append(commands, command) + } + } + + for _, cmd := range commands { + var res string + writeDebug("Sending command to modem: "+cmd, 0) + _, res, err = p.writeAndGetResponse(cmd, -1, false, 1024) + if err != nil { + return err + } + if strings.Contains(res, "ERROR") { + log.Print(`Command "` + cmd + `" not accepted: ` + res) + return fmt.Errorf(`Command "` + cmd + `" not accepted: ` + res) + } else { + l := fmt.Sprintf("%s --> "+color.InGreen("OK\n"), cmd) // print some output + log.Println(l) + fmt.Println(l) + } + } + + // run additional commands stored in the init script file + if p.initfile != "" { + if err = p.runInitScript(p.initfile); err != nil { + return err + } + } + p.flags.stopmodem = false + p.setState(Ready) + go p.modemThread() + //p.flags.exit = false + return nil +} + +// Send additional initialisation command stored in the InitScript +// +// Each command has to be on a new line +func (p *Modem) runInitScript(initScript string) error { + if _, err := os.Stat(initScript); os.IsNotExist(err) { + return fmt.Errorf("ERROR: PTC init script defined but not existent: %s", initScript) + } + + file, err := os.Open(initScript) + if err != nil { + return err + } + defer file.Close() + + scanner := bufio.NewScanner(file) + for scanner.Scan() { + writeDebug("Sending command to modem: "+scanner.Text(), 0) + if _, _, err = p.writeAndGetResponse(scanner.Text(), -1, false, 1024); err != nil { + return err + } + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + +func (p *Modem) modemThread() { + writeDebug("start modem thread", 1) + + _, _, _ = p.read(1024) + _, _, _ = p.writeAndGetResponse("JHOST4", -1, false, 1024) + _, _, _ = p.read(1024) + // need to wait a second for WA8DED mode to "settle" + time.Sleep(time.Second) + const chunkSize = 1024 + p.wg.Add(1) + for !p.flags.stopmodem { + + // TX data + if p.getNumFramesNotTransmitted() < MaxFrameNotTX { + // data := p.getSendData() + data, err := s.Data.Data.Dequeue(256) + if err == nil { + //data := []byte(d.(string)) + writeDebug("Write data ("+strconv.Itoa(len(data))+"): "+hex.EncodeToString(data), 2) + // TODO: Catch errors! + _, _, _ = p.writeAndGetResponse(string(data), PactorChannel, false, chunkSize) + time.Sleep(1000 * time.Millisecond) // wait for the data to be filled into the buffer + + if s.VARAMode { + s.Command.Response.Enqueue(fmt.Sprintf("BUFFER %d", s.Data.Data.GetLen())) + } + + } + } + + // TX commands + cmd, err := s.Command.Cmd.Dequeue() + if err == nil { + writeDebug("Write command ("+strconv.Itoa(len(cmd))+"): "+cmd, 1) + _, ans, err := p.writeAndGetResponse(cmd, PactorChannel, true, chunkSize) + if err != nil { + writeDebug("Error when sending Command: "+err.Error(), 0) + } + if strings.HasPrefix(cmd, "C ") || strings.HasPrefix(cmd, "c ") { + + // in VARA mode we need to know if the connection is outgoing or incoming so mark outgoing connects + p.setState(Connecting) + } + if len(ans) > 2 { + if !s.VARAMode { + s.Command.Response.Enqueue(ans[2:]) + } + } + writeDebug("Answer from modem: "+ans, 1) + // TODO: Catch errors! + } + + // RX + var res []byte + + if channels, err := p.getChannelsWithOutput(); err == nil { + for _, c := range channels { + _, data, _ := p.writeAndGetResponse("G", c, true, chunkSize) + if _, res, err = p.checkResponse(data, c); err != nil { + writeDebug("checkResponse returned: "+err.Error(), 1) + } else { + if res != nil { + writeDebug("response: "+string(res)+"\n"+hex.Dump(res), 3) + switch c { + case PactorChannel: + s.Data.Response.Enqueue(res) + writeDebug("Written to sendbuf", 3) + case 254: //Status update + p.chanbusy = int(res[0])&112 == 112 // See PTC-IIIusb manual "STATUS" command + writeDebug("PACTOR state: "+strconv.FormatInt(int64(res[0]), 2), 2) + default: + writeDebug("Channel "+strconv.Itoa(c)+": "+string(res), 1) + } + } + } + } + } + } + time.Sleep(100 * time.Millisecond) + + _, _, err := p.writeAndGetResponse("JHOST0", PactorChannel, true, chunkSize) + if err != nil { + writeDebug("PACTOR ERROR Could not get modem out of the WA8DED mode: "+err.Error(), 0) + } + + writeDebug("Modemthread is about to end", 1) + + time.Sleep(100 * time.Millisecond) + p.wg.Done() + //p.ModemClose() + writeDebug("exit modem thread", 1) +} + +func (p *Modem) Close() error { + _, file, no, ok := runtime.Caller(1) + if ok { + writeDebug("PACTOR Close called from "+file+"#"+strconv.Itoa(no), 1) + } else { + writeDebug("PACTOR Close called", 1) + } + + var err error + p.closeOnce.Do(func() { err = p.close() }) + return err +} + +func (p *Modem) stophostmode() { + writeDebug("Stopping WA8DED hostmode", 0) + var ok bool + var err error + + // Send JHOST0 in CRC-enhanced WA8DED mode syntax + + for ok == false { + buff := make([]byte, 100) + p.device.Write([]byte{0xaa, 0xaa, 0x00, 0x01, 0x05, 0x4a, 0x48, 0x4f, 0x53, 0x54, 0x30, 0xfb, 0x3d}) + time.Sleep(100 * time.Millisecond) + for { + n, err := p.device.Read(buff) + if err != nil { + log.Fatal(err) + break + } + if n == 0 { + break + } + //fmt.Printf("%v", string(buff[:n])) + } + p.device.Write([]byte("\rRESTART\r")) + time.Sleep(1000 * time.Millisecond) + for { + n, err := p.device.Read(buff) + if err != nil { + log.Fatal(err) + break + } + if n == 0 { + break + } + //fmt.Printf("%v", string(buff[:n])) + } + ok, err = regexp.Match("cmd:", buff) + if err != nil { + writeDebug("Error in stophostmode: "+err.Error(), 0) + } + } +} + +// Wait for transmission to be finished +// +// BLOCKING until either all frames are transmitted and acknowledged or timeouts +// occurs +func (p *Modem) waitTransmissionFinish(t time.Duration) error { + timeout := time.After(t) + tick := time.Tick(500 * time.Millisecond) + for { + notAck := p.getNumFrameNotAck() + notTrans := p.getNumFramesNotTransmitted() + select { + case <-timeout: + if notAck != 0 && notTrans != 0 { + return errors.New("Timeout: " + strconv.Itoa(notAck) + "frames not ack and " + strconv.Itoa(notTrans) + " frames not transmitted") + } else if notAck != 0 { + return errors.New("Timeout: " + strconv.Itoa(notAck) + "frames not ack") + } else { + return errors.New("Timeout: " + strconv.Itoa(notTrans) + " frames not transmitted") + } + + case <-tick: + if notAck == 0 && notTrans == 0 { + return nil + } + } + } +} + +// Close current serial connection. Stop all threads and close all channels. +func (p *Modem) close() (err error) { + + _, file, no, ok := runtime.Caller(1) + if ok { + writeDebug("PACTOR close called from "+file+"#"+strconv.Itoa(no), 1) + } else { + writeDebug("PACTOR close called", 1) + } + + //p.disconnect() + writeDebug("signal modem thread to stop", 1) + p.flags.stopmodem = true + writeDebug("waiting for all threads to exit", 1) + p.wg.Wait() + writeDebug("modem thread stopped", 1) + + //p.hostmodeQuit() + // will not close the serial port as we reuse it + //p.device.Close() + p.stophostmode() + p.setState(Closed) + writeDebug("PACTOR close() finished", 1) + return nil +} + +// Set specified flag (channel) +func setFlag(flag chan struct{}) { + flag <- struct{}{} +} + +// Get number of frames not yet transmitted by the modem +func (p *Modem) getNumFramesNotTransmitted() int { + //return p.channelState.c + return 0 +} + +// Get number of frames not acknowledged by the remote station +func (p *Modem) getNumFrameNotAck() int { + //return p.channelState.d + return 0 +} + +// Check if serial device is still available (e.g still connected) +func (p *Modem) checkSerialDevice() (err error) { + if _, err := os.Stat(p.devicePath); os.IsNotExist(err) { + return fmt.Errorf("ERROR: Device %s does not exist", p.devicePath) + } + return nil +} + +// Poll channel 255 with "G" command to find what channels have output. +// Write them into the channels list. +func (p *Modem) getChannelsWithOutput() (channels []int, err error) { + //Poll Channel 255 to find what channels have output + n, chs, err := p.writeAndGetResponse("G", 255, true, 1024) + if err != nil { + return nil, err + } + + channels = make([]int, 0) + + for i, ch := range []byte(chs)[:n-1] { + if (i == 0 && ch == 255) || (i == 1 && ch == 1) { + continue + } + channels = append(channels, int(ch)-1) + } + + writeDebug("Channels with output: "+fmt.Sprintf("%#v", channels), 2) + + return +} + +// Do some checks on the returned data. +// +// Currently, only connection information (payload) messages are passed on +func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err error) { + if len(resp) < 3 { + return 0, nil, fmt.Errorf("No data") + } + + head := []byte(resp[:3]) + payload := []byte(resp[3:]) + length := int(head[2]) + 1 + pl := len(payload) + if int(head[0]) != ch { + writeDebug("WARNING: Returned data does not match polled channel\n"+hex.Dump([]byte(resp)), 1) + return 0, nil, fmt.Errorf("Channel missmatch") + } + if int(head[1]) == 1 { //sucess,message follows + writeDebug("*** SUCCESS: "+string(payload), 0) + } + if int(head[1]) == 2 { + writeDebug("*** ERROR: "+string(payload), 0) + } + if int(head[1]) != 7 && int(head[1]) != 3 { + if !s.VARAMode { + s.Command.Response.Enqueue(fmt.Sprintf("%s\n", payload)) + } + writeDebug("Message from Modem: "+string(payload), 0) + return 0, nil, fmt.Errorf("Not a data response") + } + if int(head[1]) == 3 { //Link status + if !s.VARAMode { + s.Command.Response.Enqueue(fmt.Sprintf("%s\n", payload)) + } + writeDebug("*** LINK STATUS: "+string(payload), 0) + // there is no way to get the remote callsign from the WA8DED data, so we have to parse the link status :( + re, err := regexp.Compile(` CONNECTED to \w{2,16}`) + if err != nil { + writeDebug("Cannot convert connect message to callsign: "+string(payload), 1) + } else { + ans := strings.ReplaceAll(string(re.Find(payload)), " CONNECTED to ", "") + if len(ans) > 2 { //callsign consists of 3+ characters + p.remoteAddr = ans + writeDebug("PACTOR connection to: "+ans, 0) + if s.VARAMode { + if p.state == Connecting { //outgoing connection + s.Command.Response.Enqueue(fmt.Sprintf("CONNECTED %s %s BW", p.localAddr, ans)) + } else { //incoming connection + s.Command.Response.Enqueue(fmt.Sprintf("CONNECTED %s %s BW", ans, p.localAddr)) + } + } + p.setState(Conntected) + return 0, nil, nil + } + } + if strings.Contains(string(payload), "DISCONNECTED") { + writeDebug("PACTOR DISCONNECTED", 0) + p.setState(Ready) + if s.VARAMode { + s.Command.Response.Enqueue("DISCONNECTED") + } + // } + //p.channelState.f = 0 + return 0, nil, nil + } + return 0, nil, fmt.Errorf("Link data") + } + if length != pl { + writeDebug("WARNING: Data length "+strconv.Itoa(pl)+" does not match stated amount "+strconv.Itoa(length)+". After "+strconv.Itoa(p.goodChunks)+" good chunks.", 1) + p.goodChunks = 0 + if pl < length { + // TODO: search for propper go function + for i := 0; i < (length - pl); i++ { + payload = append(payload, 0x00) + } + } else { + payload = payload[:length] + } + } else { + p.goodChunks += 1 + writeDebug("Good chunk", 2) + } + return length, payload, nil +} + +// Write and read response from pactor modem +// +// Can be used in both, normal and hostmode. If used in hostmode, provide +// channel (>=0). If used in normal mode, set channel to -1, isCommand is +// ignored. +func (p *Modem) writeAndGetResponse(msg string, ch int, isCommand bool, chunkSize int) (int, string, error) { + writeDebug("wagr: Channel: "+strconv.Itoa(ch)+"; isCommand: "+strconv.FormatBool(isCommand)+"\n"+hex.Dump([]byte(msg)), 3) + var err error + + var n int + var str string + if ch < 0 { + err = p._write(msg + "\r") + if err != nil { + return 0, "", err + } + time.Sleep(500 * time.Millisecond) + i := 0 + var tmp []byte + for { + n, tmp, err = p._read(chunkSize) + str = string(tmp) + if err == nil { + break + } + i += 1 + if i > 9 { + writeDebug("No successful read after 10 times!", 1) + return 0, "", err + } + } + writeDebug(fmt.Sprintf("response: %s\n%s", str, hex.Dump(tmp)), 2) + return n, str, err + } else { + err = p.writeChannel(msg, ch, isCommand) + if err != nil { + return 0, "", err + } + if msg == "JHOST0" { //looks like the SCS modems do not answer to JHOST0, although the standard defines it + return 0, "", nil + } + time.Sleep(50 * time.Millisecond) + writeDebug("Decode WA8DED", 4) + buf := []byte{} + valid := false + + for valid == false { + if bytes.Compare(buf, []byte{170, 170, 170, 85}) == 0 { // check for re-request #170#170#170#85 + // packet was re-requested!! + writeDebug("Re-Request magic received", 3) + buf = []byte{} //delete the re-request packet + err = p.writeChannel(msg, ch, isCommand) // write command again + if err != nil { + return 0, "", err + } + } + br, b, err := p._read(1) + if err != nil { + writeDebug("ERROR at _read: "+error.Error(err), 1) + } + writeDebug("Len: "+strconv.Itoa(len(buf))+"State: "+string(hex.Dump(buf)+"\n"), 4) + if br > 0 { + //we got some data + buf = append(buf, b...) + if len(buf) > 5 { // otherwise it's no enh. WA8DED: 2 magic bytes, 2 header bytes, 2 CRC bytes + //unstuff (from 3rd byte on) + t := bytes.Replace(buf[2:], []byte{170, 0}, []byte{170}, -1) + buf = append([]byte{0xaa, 0xaa}, t...) + if checkcrc(buf) { + n = len(t) - 2 + str = string(t[:n]) + valid = true + } else { + writeDebug("(still) Invalid checksum", 4) + } + + } + } + } + + } + + p.packetcounter = !(p.packetcounter) + writeDebug("wagr: returning \n"+hex.Dump([]byte(str)), 3) + return n, str, err +} + +// Flush waits for the last frames to be transmitted. +// +// Will throw error if remaining frames could not bet sent within 120s +func (p *Modem) Flush() (err error) { + writeDebug("Flush called", 2) + if err = p.waitTransmissionFinish(120 * time.Second); err != nil { + writeDebug(err.Error(), 2) + } + return +} + +// TxBufferLen returns the number of bytes in the out sendbuf queue. +func (p *Modem) TxBufferLen() int { + writeDebug("TxBufferLen called ("+strconv.Itoa(s.Data.Data.GetLen())+" bytes remaining in sendbuf)", 2) + return s.Data.Data.GetLen() + (p.getNumFramesNotTransmitted() * MaxSendData) +} + +func (p *Modem) Busy() bool { + return p.chanbusy +} + +// Write to serial connection (thread safe) +// +// No other read/write operation allowed during this time +func (p *Modem) write(cmd string) error { + p.mux.pactor.Lock() + defer p.mux.pactor.Unlock() + return p._write(cmd) +} + +// Write to serial connection (NOT thread safe) +// +// If used, make shure to lock/unlock p.mux.pactor mutex! +func (p *Modem) _write(cmd string) error { + if err := p.checkSerialDevice(); err != nil { + writeDebug(err.Error(), 1) + return err + } + + writeDebug("write: \n"+hex.Dump([]byte(cmd)), 3) + + p.mux.device.Lock() + defer p.mux.device.Unlock() + out := cmd + "\r" + for { + status, err := p.device.GetModemStatusBits() + if err != nil { + writeDebug("GetModemStatusBits failed. cmd: "+cmd+" Error: "+err.Error(), 1) + return err + } + if status.CTS { + for { + sent, err := p.device.Write([]byte(out)) + if err == nil { + break + } else { + // log.Errorf("ERROR while sending serial command: %s\n", out) + writeDebug(err.Error(), 2) + out = out[sent:] + } + } + break + } + } + + return nil +} + +// *** Helper functions for the CRC hostmode +// Although these functions are small, I prefer to keep their functionality +// separate. They follow the steps in the SCS documentation + +// helper function: de-hexlify and write to debug channel +func printhex(s string) { + t, _ := hex.DecodeString(s) + writeDebug(string(t), 3) +} + +// helper function: "unstuff" a string +func unstuff(s string) string { + //Expect: the string contains aa aa at the beginning, that should NOT be + //stuffed + n, _ := hex.DecodeString(s[4:]) + n = bytes.Replace(n, []byte{170, 0}, []byte{170}, -1) + var r []byte + r = append([]byte{0xaa, 0xaa}, n...) + re := hex.EncodeToString(r) + return re +} + +// helper function: "stuff" a string: replaces every #170 with #170#0 +func stuff(s string) string { + //Expect: the string contains aa aa at the beginning, that should NOT be + //stuffed + n, err := hex.DecodeString(s[4:]) + if err != nil { + writeDebug("ERROR in Stuff: "+err.Error()+"\n"+string(hex.Dump([]byte(s))), 1) + } + + n = bytes.Replace(n, []byte{170}, []byte{170, 0}, -1) + var r []byte + r = append([]byte{0xaa, 0xaa}, n...) + re := hex.EncodeToString(r) + return re +} + +// helper function: calculates the CCITT-CRC16 checksum +func checksum(s string) uint16 { + tochecksum, _ := hex.DecodeString(s[4:]) + chksum := bits.ReverseBytes16(crc16.ChecksumCCITT([]byte(tochecksum))) + return chksum +} + +// helper fuction: check the checksum by comparing +func checkcrc(s []byte) bool { + tochecksum := s[2 : len(s)-2] + chksum := bits.ReverseBytes16(crc16.ChecksumCCITT(tochecksum)) + pksum := s[len(s)-2:] + return (binary.BigEndian.Uint16(pksum) == chksum) +} + +// super helper fuction: convert an ordinary WA8DED message into a CRC-Hostmode message +func docrc(msg string) string { + // step 1: add a #170170 + msg = fmt.Sprintf("%02x%02x%s", 170, 170, msg) + // step 2: calculate and add the checksum + chksum := checksum(msg) + msg = fmt.Sprintf("%s%04x", msg, chksum) + // step 3: add "stuff" bytes + msg = stuff(msg) + return msg + +} + +// Write channel to serial connection (NOT thread safe) +// +// If used, make shure to lock/unlock p.mux.pactor mutex! +func (p *Modem) writeChannel(msg string, ch int, isCommand bool) error { + if err := p.checkSerialDevice(); err != nil { + writeDebug(err.Error(), 1) + return err + } + + var d byte + switch { + case !p.packetcounter && !isCommand: + d = byte(0x00) + case !p.packetcounter && isCommand: + d = byte(0x01) + case p.packetcounter && !isCommand: + d = byte(0x80) + case p.packetcounter && isCommand: + d = byte(0x81) + } + + var o []byte = []byte{170, 170, byte(ch), byte(d), byte((len(msg) - 1))} + o = append(o, []byte(msg)...) + cksum := bits.ReverseBytes16(crc16.ChecksumCCITT(o[2:])) + cksumb := make([]byte, 2) + binary.BigEndian.PutUint16(cksumb, cksum) + o = append(o, cksumb...) + tostuff := o[2:] + tostuff = bytes.Replace(tostuff, []byte{170}, []byte{170, 0}, -1) + o = append([]byte{170, 170}, tostuff...) + /* + msg = fmt.Sprintf("%02x%02x%s", 170, 170, msg) + // step 2: calculate and add the checksum + chksum := checksum(msg) + msg = fmt.Sprintf("%s%04x", msg, chksum) + // step 3: add "stuff" bytes + msg = stuff(msg) + */ + /*c := fmt.Sprintf("%02x", ch) + l := fmt.Sprintf("%02x", (len(msg) - 1)) + s := hex.EncodeToString([]byte(msg)) + // add crc hostmode addons + bs, _ := hex.DecodeString(docrc(fmt.Sprintf("%s%s%s%s", c, d, l, s)))*/ + writeDebug("write channel: \n"+hex.Dump(o), 2) + + if err := p.write(string(o)); err != nil { + writeDebug(err.Error(), 2) + return err + } + /*if !isCommand { + p.cmdBuf <- "%Q" + }*/ + return nil +} + +// Read from serial connection (thread safe) +// +// No other read/write operation allowed during this time +func (p *Modem) read(chunkSize int) (int, []byte, error) { + p.mux.pactor.Lock() + defer p.mux.pactor.Unlock() + return p._read(chunkSize) +} + +// Read from serial connection (NOT thread safe) +// +// If used, make shure to lock/unlock p.mux.pactor mutex! +func (p *Modem) _read(chunkSize int) (int, []byte, error) { + if err := p.checkSerialDevice(); err != nil { + writeDebug(err.Error(), 1) + return 0, []byte{}, err + } + + buf := make([]byte, chunkSize) + + p.mux.device.Lock() + defer p.mux.device.Unlock() + n, err := p.device.Read(buf) + if err != nil { + writeDebug("Error received during read: "+err.Error(), 1) + return 0, []byte{}, err + } + + return n, buf[0:n], nil +} diff --git a/tcpserver.go b/tcpserver.go new file mode 100644 index 0000000..963974f --- /dev/null +++ b/tcpserver.go @@ -0,0 +1,320 @@ +package main + +import ( + "bufio" + "context" + "errors" + "fmt" + "github.com/TwiN/go-color" + "log" + "net" + "regexp" + "strings" + "time" +) + +// Chunks splits a string into chunks of chunkSize length +// by topskip taken from https://stackoverflow.com/questions/18556693/slice-string-into-letters +func Chunks(s string, chunkSize int) []string { + if len(s) == 0 { + return nil + } + if chunkSize >= len(s) { + return []string{s} + } + var chunks []string = make([]string, 0, (len(s)-1)/chunkSize+1) + currentLen := 0 + currentStart := 0 + for i := range s { + if currentLen == chunkSize { + chunks = append(chunks, s[currentStart:i]) + currentLen = 0 + currentStart = i + } + currentLen++ + } + chunks = append(chunks, s[currentStart:]) + return chunks +} + +// HandleConnection processes incoming connections +func handleTCPCmdConnection(conn net.Conn) { + defer func() { + s.Status &^= StatusTCPCmdActive + conn.Close() + }() + + s.Status |= StatusTCPCmdActive + // Sending "IAMLIVE" every 60 seconds + alivectx, alivecancel := context.WithCancel(context.Background()) + go func(conn net.Conn, ctx context.Context) { + for ctx.Err() == nil { + if s.VARAMode { + s.Command.Response.Enqueue("IAMALIVE") + } + time.Sleep(60 * time.Second) + } + }(conn, alivectx) + defer alivecancel() + + /* + bufferctx, buffercancel := context.WithCancel(context.Background()) + go func(conn net.Conn, ctx context.Context) { + for ctx.Err() == nil { + if s.VARAMode { + s.Command.Response.Enqueue(fmt.Sprintf("BUFFER %d", s.Data.Data.GetLen())) + } + time.Sleep(10 * time.Second) + } + }(conn, bufferctx) + defer buffercancel() + */ + + s.Protocol <- fmt.Sprintf(color.InGreen("TCP Cmd Connection established with %s\n"), conn.RemoteAddr()) + + s.Status |= StatusTCPCmdActive + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func(ctx context.Context) { + for ctx.Err() == nil { + msg, err := s.Command.Response.DequeueOrWaitContext(ctx) + if err != nil { + s.Protocol <- fmt.Sprintf(color.InRed("End of Cmd Data Connection %s\n"), conn.RemoteAddr()) + return + } else { + s.Protocol <- fmt.Sprintf(color.InCyan("Response: %s\n"), msg) + conn.Write([]byte(fmt.Sprintf("%s\r", msg))) + } + } + }(ctx) + + reader := bufio.NewReader(conn) + for { + // Read incoming message + message, err := reader.ReadString('\r') + if err != nil { + //s.Protocol <- fmt.Sprintf(color.InRed("Connection closed by %s\n"), conn.RemoteAddr()) + s.Status &^= StatusTCPCmdActive + alivecancel() + //buffercancel() + cancel() + conn.Close() + break + } + + message = strings.TrimSpace(message) + re := regexp.MustCompile("[[:^ascii:]]") + message = re.ReplaceAllLiteralString(message, "") // prevent any non-ASCII from being sent + + if message == "" { // do not send an empty message to the controller + continue + } + // Process the VARA TNC protocol commands + if s.VARAMode { + translatedmsg, predefanswer, err := processVARACommand(message) + if err != nil { + s.Protocol <- color.InRed(fmt.Sprintf("Error translating VARA command %s: %s\n", message, err.Error())) + log.Println(fmt.Sprintf("Error translating VARA command %s: %s\n", message, err.Error())) + s.Command.Response.Enqueue("WRONG") + } else { + if translatedmsg != "" { + s.Protocol <- fmt.Sprintf(color.InPurple("(V) Got: %s Sending: %s\n"), message, translatedmsg) + s.Command.Cmd.Enqueue(translatedmsg) + } + if predefanswer != "" { + s.Command.Response.Enqueue(predefanswer) + } else { + s.Command.Response.Enqueue("OK") + } + } + } else { // TCP Mode == passthrough + s.Protocol <- fmt.Sprintf(color.InPurple("(T) Sending: %s\n"), message) + s.Command.Cmd.Enqueue(message) + } + + } +} + +func handleTCPDataConnection(conn net.Conn) { + defer func() { + s.Status &^= StatusTCPDataActive + conn.Close() + }() + + s.Protocol <- fmt.Sprintf(color.InGreen("TCP Data Connection established with %s\n"), conn.RemoteAddr()) + s.Status |= StatusTCPDataActive + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go func() { + for { + msg, err := s.Data.Response.DequeueOrWaitContext(ctx, 1) + if err != nil { + s.Protocol <- fmt.Sprintf(color.InRed("End of TCP Data Connection %s\n"), conn.RemoteAddr()) + return + } else { + //TODO: VARA + if !s.DaemonMode { + s.FromPactor.Enqueue(msg) + } + conn.Write(msg) + } + } + }() + reader := bufio.NewReader(conn) + for { + var temp []byte + buf := make([]byte, 1024) + n, err := reader.Read(buf) + if n > 0 { + temp = append(temp, buf[:n]...) + } + if err != nil { + s.Status &^= StatusTCPDataActive + cancel() + conn.Close() + return + } + //TODO: muss das nicht weg? + /* if temp == 0x04 { + break + } + */ + if !s.DaemonMode { + s.ToPactor.Enqueue(temp) + } + if n > 255 { + // we can dump at max 255 bytes into + for _, ck := range Chunks(string(temp), 255) { + s.Data.Data.Enqueue([]byte(ck)) + } + } else { + s.Data.Data.Enqueue(temp) + } + } +} + +// Process VARA commands and return appropriate WA8DED command and a pre-defined answer +func processVARACommand(command string) (string, string, error) { + switch { + case strings.HasPrefix(command, "CONNECT"): + re, err := regexp.MatchString(`CONNECT \w+ \w+`, command) + if err != nil || !re { + return "", "", errors.New("Error matching regex") + } + c := strings.Split(command, " ") + return fmt.Sprintf("C %s", c[2]), "", nil + + case strings.HasPrefix(command, "DISCONNECT"): + return "D", "", nil + + case strings.HasPrefix(command, "ABORT"): + return "DD", "", nil + // case strings.HasPrefix(command, "VERSION"): + // return "", nil + + case strings.HasPrefix(command, "LISTEN"): + // Handle listen + if strings.HasSuffix(command, "ON") { + return "%L 1", "", nil + } + if strings.HasSuffix(command, "OFF") { + return "%L 0", "", nil + } + return "", "", errors.New("Neither ON nor OFF after LISTEN") + + case strings.HasPrefix(command, "MYCALL"): + m := "" + // Handle MYCALL + s := strings.Split(command, " ") + if len(s) > 1 { + // send own callsign to PACTOR controller + m = s[1] + } else { + return "", "", errors.New("Invalid MYCALL command") + } + return fmt.Sprintf("%s%s", "I ", m), "", nil + + case strings.HasPrefix(command, "COMPRESSION"): + // Handle COMPRESSION + return "", "", nil + + case strings.HasPrefix(command, "BW"): + // Has no meaning for PACTOR + return "", "", nil + + case strings.HasPrefix(command, "CHAT"): + // Has no meaning for PACTOR + return "", "", nil + + case strings.HasPrefix(command, "WINLINK SESSION"): + // Has no meaning for PACTOR, just return "OK" + return "", "", nil + + case strings.HasPrefix(command, "P2P SESSION"): + // Has no meaning for PACTOR, just return "OK" + return "", "", nil + + case strings.HasPrefix(command, "CWID"): + // Has no meaning for PACTOR, just return "OK" + return "", "", nil + + case strings.HasPrefix(command, "PUBLIC"): + // Has no meaning for PACTOR, just return "OK" + return "", "", nil + + case strings.HasPrefix(command, "VERSION"): + return "", "VERSION 1.0.0", nil + + default: + // Handle unrecognized commands + return "", "", errors.New("Unknown command") + } +} + +func tcpCmdServer(Config *Userconfig) { + // Start listening for connections + listener, err := net.Listen("tcp", Config.ServerAddress) + if err != nil { + s.Protocol <- fmt.Sprintf(color.InWhiteOverRed("Error starting server: %v\n"), err) + log.Println(err) + return + } + defer listener.Close() + + s.Protocol <- fmt.Sprintf("TCP Protocol Server listening on %s\n", Config.ServerAddress) + + for { + // Accept incoming connection + conn, err := listener.Accept() + if err != nil { + s.Protocol <- fmt.Sprintf("Error accepting connection: %v\n", err) + continue + } + + // Handle connection in a separate goroutine + go handleTCPCmdConnection(conn) + } +} + +func tcpDataServer(Config *Userconfig) { + listener, err := net.Listen("tcp", Config.DataAddress) + if err != nil { + s.Protocol <- fmt.Sprintf(color.InWhiteOverRed("Error starting server: %v\n"), err) + log.Println(err) + return + } + defer listener.Close() + + s.Protocol <- fmt.Sprintf("TCP Data Server listening on %s\n", Config.DataAddress) + for { + // Accept incoming connection + conn, err := listener.Accept() + if err != nil { + s.Protocol <- fmt.Sprintf("Error accepting connection: %v\n", err) + continue + } + + // Handle connection in a separate goroutine + go handleTCPDataConnection(conn) + } +} diff --git a/tui.go b/tui.go new file mode 100644 index 0000000..e285050 --- /dev/null +++ b/tui.go @@ -0,0 +1,157 @@ +package main + +import ( + "fmt" + "github.com/TwiN/go-color" + "github.com/jroimartin/gocui" + "log" + "strings" + "time" + "unicode" +) + +func printable(r rune) rune { + if r == rune('\u000d') || r == rune('\u000a') { // ctrl-r or ctrl-n + return rune('\u000a') //ctrl-n + } + if unicode.IsGraphic(r) { + return r + } + return rune('\u002e') // dot +} + +func Ternary(condition bool, valueIfTrue, valueIfFalse interface{}) interface{} { + if condition { + return valueIfTrue + } + return valueIfFalse +} + +func layout(g *gocui.Gui) error { + maxX, maxY := g.Size() + lwX := int(float32(maxX) * 0.8) + + // "data" view: Top-left large view + if v, err := g.SetView("data", 0, 0, lwX-1, maxY/2-1); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = "Data" + v.Wrap = true + v.Autoscroll = true + } + + // "protocol" view: Bottom-left large view + if v, err := g.SetView("protocol", 0, maxY/2, lwX-1, maxY-1); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = "Protocol" + v.Wrap = true + v.Autoscroll = true + } + + // "status" view: Smaller view on the right + if v, err := g.SetView("status", lwX, 0, maxX-1, maxY-1); err != nil { + if err != gocui.ErrUnknownView { + return err + } + v.Title = "Status" + } + + return nil +} + +func keybindings(g *gocui.Gui) error { + // Quit the application with Ctrl+C + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + return err + } + if err := g.SetKeybinding("", gocui.KeyCtrlT, gocui.ModNone, toggleMode); err != nil { + return err + } + return nil +} + +func protocolUpdate(g *gocui.Gui) { + for { + msg := <-s.Protocol + g.Update(func(g *gocui.Gui) error { + v, err := g.View("protocol") + if err != nil { + log.Println(err.Error()) + return err + } + fmt.Fprint(v, msg) + return nil + }) + } +} + +func pactorUpdate(g *gocui.Gui) { + for { + if s.ToPactor.GetLen() > 0 { + msg, err := s.ToPactor.Dequeue(256) + if err != nil { + log.Println(err.Error()) + continue + } + g.Update(func(g *gocui.Gui) error { + v, err := g.View("data") + if err != nil { + log.Println(err.Error()) + return err + } + fmt.Fprint(v, strings.Map(printable, string(msg))) + return nil + }) + } + if s.FromPactor.GetLen() > 0 { + msg, err := s.FromPactor.Dequeue(256) + if err != nil { + log.Println(err.Error()) + continue + } + g.Update(func(g *gocui.Gui) error { + v, err := g.View("data") + if err != nil { + log.Println(err.Error()) + return err + } + fmt.Fprint(v, color.InRed(strings.Map(printable, string(msg)))) + return nil + }) + } + time.Sleep(3 * time.Second) + } +} + +func statusUpdate(g *gocui.Gui) { + for { + time.Sleep(1 * time.Second) + g.Update(func(g *gocui.Gui) error { + v, err := g.View("status") + if err != nil { + log.Println(err.Error()) + } else { + v.Clear() + fmt.Fprintln(v, time.Now().Format("15:04:05")) + fmt.Fprintln(v, Ternary(s.VARAMode, "VARA", "TCP")) + fmt.Fprintln(v, Ternary(s.Status&StatusTCPCmdActive != 0, color.InGreen("TCP CMD"), color.InRed("TCP CMD"))) + fmt.Fprintln(v, Ternary(s.Status&StatusTCPDataActive != 0, color.InGreen("TCP DATA"), color.InRed("TCP DATA"))) + fmt.Fprintln(v, fmt.Sprintf("\nCMD S: %d\nCMD R: %d\nDTA S: %d\nDTA R: %d", s.Command.Cmd.GetLen(), s.Command.Response.GetLen(), s.Data.Data.GetLen(), s.Data.Response.GetLen())) + } + return nil + }) + } +} + +func quit(g *gocui.Gui, v *gocui.View) error { + return gocui.ErrQuit +} + +func toggleMode(g *gocui.Gui, v *gocui.View) error { + s.Protocol <- fmt.Sprintf(color.InPurple("Toggle mode\n")) + s.VARAMode = !s.VARAMode + return nil +}