mirror of
https://github.com/nonoo/kappanhang.git
synced 2026-01-06 08:49:58 +01:00
Run a cmd (rigctld by default) when connected to the server
This commit is contained in:
parent
c2b48b8ea0
commit
a0efee9eb4
13
README.md
13
README.md
|
|
@ -59,11 +59,11 @@ After it is connected and logged in:
|
|||
transmit your voice.
|
||||
- Starts a **TCP server** on port `4533` for exposing the **serial port**.
|
||||
This can be used for controlling the server (the transceiver) with
|
||||
[Hamlib](https://hamlib.github.io/):
|
||||
|
||||
```
|
||||
rigctld -m 3085 -r 127.0.0.1:4533
|
||||
```
|
||||
[Hamlib](https://hamlib.github.io/) (`rigctld`).
|
||||
- Runs the command `rigctld -m 3085 -r :4533` which starts `rigctld` and
|
||||
connects it to kappanhang's TCP serial port server. You can specify a custom
|
||||
command with the `-r` command line argument. Running any command can be
|
||||
disabled with `-r -`.
|
||||
|
||||
3085 is the model number for the Icom IC-705. `rigctld` will connect to
|
||||
kappanhang's TCP serial port server, and waits connections on it's default
|
||||
|
|
@ -84,7 +84,8 @@ Note that the built-in Wi-Fi in the Icom IC-705 has **very limited range**,
|
|||
and **sensitive to interference**. If you see a lot of retransmits in the log,
|
||||
or packet loss, then:
|
||||
|
||||
- Place the IC-705 close to your Wi-Fi AP/router
|
||||
- Place the IC-705 close to your Wi-Fi AP/router, or use a Wi-Fi range
|
||||
extender device.
|
||||
- Make sure the Wi-Fi bandwith is set to max. 20Mhz in the Wi-Fi router (see
|
||||
explanation [here](https://superuser.com/questions/542191/does-moving-my-router-from-20mhz-to-40-mhz-increase-my-wireless-speed))
|
||||
- Try switching Wi-Fi channel on your Wi-Fi router. Only channels 1, 6 or 11
|
||||
|
|
|
|||
3
args.go
3
args.go
|
|
@ -12,6 +12,7 @@ var verboseLog bool
|
|||
var connectAddress string
|
||||
var serialTCPPort uint16
|
||||
var enableSerialDevice bool
|
||||
var runCmd string
|
||||
var statusLogInterval time.Duration
|
||||
|
||||
func parseArgs() {
|
||||
|
|
@ -20,6 +21,7 @@ func parseArgs() {
|
|||
a := getopt.StringLong("address", 'a', "IC-705", "Connect to address")
|
||||
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")
|
||||
i := getopt.Uint16Long("log-interval", 'i', 100, "Status bar/log interval in milliseconds")
|
||||
|
||||
getopt.Parse()
|
||||
|
|
@ -34,5 +36,6 @@ func parseArgs() {
|
|||
connectAddress = *a
|
||||
serialTCPPort = *t
|
||||
enableSerialDevice = *s
|
||||
runCmd = *r
|
||||
statusLogInterval = time.Duration(*i) * time.Millisecond
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,6 +259,8 @@ func (s *controlStream) handleRead(r []byte) error {
|
|||
|
||||
s.serialAndAudioStreamOpened = true
|
||||
statusLog.startPeriodicPrint()
|
||||
|
||||
startCmdIfNeeded()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
72
log.go
72
log.go
|
|
@ -27,18 +27,14 @@ func (l *logger) GetCallerFileName(withLine bool) string {
|
|||
}
|
||||
}
|
||||
|
||||
func (l *logger) Printf(a string, b ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
}
|
||||
l.logger.Infof(l.GetCallerFileName(false)+": "+a, b...)
|
||||
}
|
||||
|
||||
func (l *logger) Print(a ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
statusLog.mutex.Lock()
|
||||
statusLog.clearInternal()
|
||||
defer func() {
|
||||
statusLog.mutex.Unlock()
|
||||
statusLog.print()
|
||||
}()
|
||||
}
|
||||
l.logger.Info(append([]interface{}{l.GetCallerFileName(false) + ": "}, a...)...)
|
||||
}
|
||||
|
|
@ -47,62 +43,42 @@ func (l *logger) PrintStatusLog(a ...interface{}) {
|
|||
l.logger.Info(append([]interface{}{l.GetCallerFileName(false) + ": "}, a...)...)
|
||||
}
|
||||
|
||||
func (l *logger) Debugf(a string, b ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
}
|
||||
l.logger.Debugf(l.GetCallerFileName(true)+": "+a, b...)
|
||||
}
|
||||
|
||||
func (l *logger) Debug(a ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
statusLog.mutex.Lock()
|
||||
statusLog.clearInternal()
|
||||
defer func() {
|
||||
statusLog.mutex.Unlock()
|
||||
statusLog.print()
|
||||
}()
|
||||
}
|
||||
l.logger.Debug(append([]interface{}{l.GetCallerFileName(true) + ": "}, a...)...)
|
||||
}
|
||||
|
||||
func (l *logger) Errorf(a string, b ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
}
|
||||
l.logger.Errorf(l.GetCallerFileName(true)+": "+a, b...)
|
||||
}
|
||||
|
||||
func (l *logger) Error(a ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
statusLog.mutex.Lock()
|
||||
statusLog.clearInternal()
|
||||
defer func() {
|
||||
statusLog.mutex.Unlock()
|
||||
statusLog.print()
|
||||
}()
|
||||
}
|
||||
l.logger.Error(append([]interface{}{l.GetCallerFileName(true) + ": "}, a...)...)
|
||||
}
|
||||
|
||||
func (l *logger) ErrorC(a ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
statusLog.mutex.Lock()
|
||||
statusLog.clearInternal()
|
||||
defer func() {
|
||||
statusLog.mutex.Unlock()
|
||||
statusLog.print()
|
||||
}()
|
||||
}
|
||||
l.logger.Error(a...)
|
||||
}
|
||||
|
||||
func (l *logger) Fatalf(a string, b ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
}
|
||||
l.logger.Fatalf(l.GetCallerFileName(true)+": "+a, b...)
|
||||
}
|
||||
|
||||
func (l *logger) Fatal(a ...interface{}) {
|
||||
if statusLog.isRealtime() {
|
||||
statusLog.clear()
|
||||
defer statusLog.print()
|
||||
}
|
||||
l.logger.Fatal(append([]interface{}{l.GetCallerFileName(true) + ": "}, a...)...)
|
||||
}
|
||||
|
||||
func (l *logger) Init() {
|
||||
// Example: https://stackoverflow.com/questions/50933936/zap-logger-does-not-print-on-console-rather-print-in-the-log-file/50936341
|
||||
pe := zap.NewProductionEncoderConfig()
|
||||
|
|
|
|||
1
main.go
1
main.go
|
|
@ -110,6 +110,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
|
||||
stopCmd()
|
||||
audio.deinit()
|
||||
serialTCPSrv.deinit()
|
||||
serialPort.deinit()
|
||||
|
|
|
|||
40
runcmd.go
Normal file
40
runcmd.go
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const startCmdDelay = time.Second
|
||||
|
||||
var startedCmd *exec.Cmd
|
||||
|
||||
func doStartCmd() {
|
||||
c := strings.Split(runCmd, " ")
|
||||
startedCmd = exec.Command(c[0], c[1:]...)
|
||||
err := startedCmd.Start()
|
||||
if err == nil {
|
||||
log.Print("cmd started: ", runCmd)
|
||||
} else {
|
||||
log.Error("error starting ", runCmd, " - ", err)
|
||||
startedCmd = nil
|
||||
}
|
||||
}
|
||||
|
||||
func startCmdIfNeeded() {
|
||||
if startedCmd != nil || runCmd == "-" {
|
||||
return
|
||||
}
|
||||
|
||||
time.AfterFunc(startCmdDelay, doStartCmd)
|
||||
}
|
||||
|
||||
func stopCmd() {
|
||||
if startedCmd == nil {
|
||||
return
|
||||
}
|
||||
if err := startedCmd.Process.Kill(); err != nil {
|
||||
log.Error("failed to stop cmd ", runCmd)
|
||||
}
|
||||
}
|
||||
|
|
@ -97,13 +97,6 @@ func (s *statusLogStruct) clearInternal() {
|
|||
fmt.Printf("%c[2K", 27)
|
||||
}
|
||||
|
||||
func (s *statusLogStruct) clear() {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
||||
s.clearInternal()
|
||||
}
|
||||
|
||||
func (s *statusLogStruct) print() {
|
||||
s.mutex.Lock()
|
||||
defer s.mutex.Unlock()
|
||||
|
|
|
|||
Loading…
Reference in a new issue