From d9d6ff887b9f6784070e96ddaa1b93855f69dd80 Mon Sep 17 00:00:00 2001 From: Nonoo Date: Fri, 30 Oct 2020 15:21:19 +0100 Subject: [PATCH] Run a command when the virtual serial port is enabled --- README.md | 8 ++++++++ args.go | 3 +++ controlstream.go | 3 +++ runcmd.go | 39 ++++++++++++++++++++++++++++++++------- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4663f5a..a9427cf 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,14 @@ If the `-s` command line argument is specified, then kappanhang will create a **virtual serial port**, so other apps which don't support Hamlib can access the transceiver directly. Look at the app log to find out the name of the virtual serial port. It will be something like `/tmp/kappanhang-IC-705.pty` +(the server's name appended to the string *kappanhang*). After the virtual +serial port is created, the command specified with `-o` will be ran, which is +`socat /tmp/kappanhang-IC-705.pty /tmp/vmware.pty` by default. Running the +command can be disabled with `-o -`. The command is only executed once, as the +virtual serial port will stay opened even if the RS-BA1 server disconnects. +I use this command to link a COM port in a Windows OS running in VMware to +the virtual serial port, so I can use the original RS-BA1 software remote +control GUI. ### Icom IC-705 Wi-Fi notes diff --git a/args.go b/args.go index 03c678c..a7e9988 100644 --- a/args.go +++ b/args.go @@ -13,6 +13,7 @@ var connectAddress string var serialTCPPort uint16 var enableSerialDevice bool var runCmd string +var runCmdOnSerialPortCreated string var statusLogInterval time.Duration func parseArgs() { @@ -22,6 +23,7 @@ func parseArgs() { t := getopt.Uint16Long("serial-tcp-port", 'p', 4533, "Expose radio's serial port on this TCP port") s := getopt.BoolLong("enable-serial-device", 's', "Expose radio's serial port as a virtual serial port") r := getopt.StringLong("run", 'r', "rigctld -m 3085 -r :4533", "Exec cmd when connected, set to - to disable") + o := getopt.StringLong("run-serial", 'o', "socat /tmp/kappanhang-IC-705.pty /tmp/vmware.pty", "Exec cmd when virtual serial port is created, set to - to disable") i := getopt.Uint16Long("log-interval", 'i', 100, "Status bar/log interval in milliseconds") getopt.Parse() @@ -37,5 +39,6 @@ func parseArgs() { serialTCPPort = *t enableSerialDevice = *s runCmd = *r + runCmdOnSerialPortCreated = *o statusLogInterval = time.Duration(*i) * time.Millisecond } diff --git a/controlstream.go b/controlstream.go index 7f80e0e..2dec3ea 100644 --- a/controlstream.go +++ b/controlstream.go @@ -260,6 +260,9 @@ func (s *controlStream) handleRead(r []byte) error { statusLog.startPeriodicPrint() startCmdIfNeeded() + if enableSerialDevice { + startSerialPortCmdIfNeeded() + } } } return nil diff --git a/runcmd.go b/runcmd.go index 5a94a89..015f1b0 100644 --- a/runcmd.go +++ b/runcmd.go @@ -9,6 +9,7 @@ import ( const startCmdDelay = time.Second var startedCmd *exec.Cmd +var serialPortStartedCmd *exec.Cmd func doStartCmd() { c := strings.Split(runCmd, " ") @@ -17,7 +18,7 @@ func doStartCmd() { if err == nil { log.Print("cmd started: ", runCmd) } else { - log.Error("error starting ", runCmd, " - ", err) + log.Error("error starting ", runCmd, ": ", err) startedCmd = nil } } @@ -30,11 +31,35 @@ func startCmdIfNeeded() { time.AfterFunc(startCmdDelay, doStartCmd) } -func stopCmd() { - if startedCmd == nil { - return - } - if err := startedCmd.Process.Kill(); err != nil { - log.Error("failed to stop cmd ", runCmd) +func doSerialPortStartCmd() { + c := strings.Split(runCmdOnSerialPortCreated, " ") + serialPortStartedCmd = exec.Command(c[0], c[1:]...) + err := serialPortStartedCmd.Start() + if err == nil { + log.Print("cmd started: ", runCmdOnSerialPortCreated) + } else { + log.Error("error starting ", runCmdOnSerialPortCreated, ": ", err) + serialPortStartedCmd = nil + } +} + +func startSerialPortCmdIfNeeded() { + if serialPortStartedCmd != nil || runCmdOnSerialPortCreated == "-" { + return + } + + time.AfterFunc(startCmdDelay, doSerialPortStartCmd) +} + +func stopCmd() { + if startedCmd != nil { + if err := startedCmd.Process.Kill(); err != nil { + log.Error("failed to stop cmd ", runCmd, ": ", err) + } + } + if serialPortStartedCmd != nil { + if err := serialPortStartedCmd.Process.Kill(); err != nil { + log.Error("failed to stop cmd ", runCmdOnSerialPortCreated, ": ", err) + } } }