Run a command when the virtual serial port is enabled

This commit is contained in:
Nonoo 2020-10-30 15:21:19 +01:00
parent fab06c32e2
commit d9d6ff887b
4 changed files with 46 additions and 7 deletions

View file

@ -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

View file

@ -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
}

View file

@ -260,6 +260,9 @@ func (s *controlStream) handleRead(r []byte) error {
statusLog.startPeriodicPrint()
startCmdIfNeeded()
if enableSerialDevice {
startSerialPortCmdIfNeeded()
}
}
}
return nil

View file

@ -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)
}
}
}