2016-02-22 22:07:02 +01:00
|
|
|
// Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
|
2015-05-22 20:01:56 +02:00
|
|
|
// Use of this source code is governed by the MIT-license that can be
|
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2022-02-16 20:58:10 +01:00
|
|
|
"context"
|
2015-05-22 20:01:56 +02:00
|
|
|
"fmt"
|
2015-10-05 18:36:04 +02:00
|
|
|
"log"
|
2017-08-24 22:04:44 +02:00
|
|
|
"os"
|
|
|
|
|
"runtime"
|
2015-05-22 20:01:56 +02:00
|
|
|
"strings"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/la5nta/wl2k-go/transport/ax25"
|
2015-05-25 13:25:24 +02:00
|
|
|
"github.com/peterh/liner"
|
2015-05-22 20:01:56 +02:00
|
|
|
)
|
|
|
|
|
|
2022-02-16 20:58:10 +01:00
|
|
|
func Interactive(ctx context.Context) {
|
2015-05-25 13:25:24 +02:00
|
|
|
line := liner.NewLiner()
|
|
|
|
|
defer line.Close()
|
|
|
|
|
|
2022-02-16 20:58:10 +01:00
|
|
|
done := make(chan struct{})
|
|
|
|
|
go func() {
|
|
|
|
|
defer close(done)
|
|
|
|
|
for {
|
|
|
|
|
str, _ := line.Prompt(getPrompt())
|
|
|
|
|
if str == "" {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
line.AppendHistory(str)
|
2015-08-15 22:54:00 +02:00
|
|
|
|
2022-02-16 20:58:10 +01:00
|
|
|
if str[0] == '#' {
|
|
|
|
|
continue
|
|
|
|
|
}
|
2015-05-22 20:01:56 +02:00
|
|
|
|
2022-02-16 20:58:10 +01:00
|
|
|
if quit := execCmd(str); quit {
|
|
|
|
|
break
|
|
|
|
|
}
|
2015-05-22 20:01:56 +02:00
|
|
|
}
|
2022-02-16 20:58:10 +01:00
|
|
|
}()
|
|
|
|
|
select {
|
|
|
|
|
case <-ctx.Done():
|
|
|
|
|
case <-done:
|
2015-05-22 20:01:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func execCmd(line string) (quit bool) {
|
|
|
|
|
cmd, param := parseCommand(line)
|
|
|
|
|
switch cmd {
|
|
|
|
|
case "connect":
|
2015-10-04 13:38:02 +02:00
|
|
|
if param == "" {
|
|
|
|
|
printInteractiveUsage()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-22 20:01:56 +02:00
|
|
|
Connect(param)
|
|
|
|
|
case "listen":
|
|
|
|
|
Listen(param)
|
|
|
|
|
case "unlisten":
|
|
|
|
|
Unlisten(param)
|
|
|
|
|
case "heard":
|
|
|
|
|
PrintHeard()
|
|
|
|
|
case "freq":
|
|
|
|
|
freq(param)
|
2015-10-05 18:36:04 +02:00
|
|
|
case "qtc":
|
|
|
|
|
PrintQTC()
|
2017-08-24 22:04:44 +02:00
|
|
|
case "debug":
|
|
|
|
|
os.Setenv("ardop_debug", "1")
|
|
|
|
|
fmt.Println("Number of goroutines:", runtime.NumGoroutine())
|
2015-05-22 20:01:56 +02:00
|
|
|
case "q", "quit":
|
|
|
|
|
return true
|
|
|
|
|
case "":
|
|
|
|
|
return
|
|
|
|
|
default:
|
|
|
|
|
printInteractiveUsage()
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func printInteractiveUsage() {
|
|
|
|
|
fmt.Println("Uri examples: 'LA3F@5350', 'LA1B-10 v LA5NTA-1', 'LA5NTA:secret@192.168.1.1:54321'")
|
|
|
|
|
|
|
|
|
|
methods := []string{
|
2015-10-07 13:14:48 +02:00
|
|
|
MethodArdop,
|
2023-02-21 11:14:17 +01:00
|
|
|
MethodAX25, MethodAX25AGWPE, MethodAX25Linux, MethodAX25SerialTNC,
|
|
|
|
|
MethodPactor,
|
2015-05-22 20:01:56 +02:00
|
|
|
MethodTelnet,
|
2022-10-31 09:43:06 +01:00
|
|
|
MethodVaraHF,
|
|
|
|
|
MethodVaraFM,
|
2015-05-22 20:01:56 +02:00
|
|
|
}
|
|
|
|
|
fmt.Println("Methods:", strings.Join(methods, ", "))
|
|
|
|
|
|
|
|
|
|
cmds := []string{
|
2015-10-04 13:38:02 +02:00
|
|
|
"connect METHOD:[URI] or alias Connect to a remote station.",
|
|
|
|
|
"listen METHOD Listen for incoming connections.",
|
|
|
|
|
"unlisten METHOD Unregister listener for incoming connections.",
|
|
|
|
|
"freq METHOD:FREQ Change rig frequency.",
|
|
|
|
|
"heard Display all stations heard over the air.",
|
2015-10-05 18:36:04 +02:00
|
|
|
"qtc Print pending outbound messages.",
|
2015-05-22 20:01:56 +02:00
|
|
|
}
|
|
|
|
|
fmt.Println("Commands: ")
|
|
|
|
|
for _, cmd := range cmds {
|
|
|
|
|
fmt.Printf(" %s\n", cmd)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getPrompt() string {
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
2017-08-20 11:10:49 +02:00
|
|
|
status := getStatus()
|
2015-05-22 20:01:56 +02:00
|
|
|
|
2017-08-20 11:10:49 +02:00
|
|
|
if len(status.ActiveListeners) > 0 {
|
|
|
|
|
fmt.Fprintf(&buf, "L%v", status.ActiveListeners)
|
2015-05-22 20:01:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Fprint(&buf, "> ")
|
|
|
|
|
return buf.String()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func PrintHeard() {
|
|
|
|
|
pf := func(call string, t time.Time) {
|
|
|
|
|
fmt.Printf(" %-10s (%s)\n", call, t.Format(time.RFC1123))
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-25 12:36:16 +01:00
|
|
|
fmt.Println("ardop:")
|
|
|
|
|
if adTNC == nil {
|
|
|
|
|
fmt.Println(" (not initialized)")
|
|
|
|
|
} else if heard := adTNC.Heard(); len(heard) == 0 {
|
|
|
|
|
fmt.Println(" (none)")
|
|
|
|
|
} else {
|
|
|
|
|
for call, t := range heard {
|
|
|
|
|
pf(call, t)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 11:14:17 +01:00
|
|
|
fmt.Println("ax25+linux:")
|
|
|
|
|
if heard, err := ax25.Heard(config.AX25Linux.Port); err != nil {
|
2015-05-22 20:01:56 +02:00
|
|
|
fmt.Printf(" (%s)\n", err)
|
|
|
|
|
} else if len(heard) == 0 {
|
|
|
|
|
fmt.Println(" (none)")
|
|
|
|
|
} else {
|
|
|
|
|
for call, t := range heard {
|
|
|
|
|
pf(call, t)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 18:36:04 +02:00
|
|
|
func PrintQTC() {
|
|
|
|
|
msgs, err := mbox.Outbox()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Println(err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("QTC: %d.\n", len(msgs))
|
|
|
|
|
for _, msg := range msgs {
|
|
|
|
|
fmt.Printf(`%-12.12s (%s): %s`, msg.MID(), msg.Subject(), fmt.Sprint(msg.To()))
|
|
|
|
|
if msg.Header.Get("X-P2POnly") == "true" {
|
|
|
|
|
fmt.Printf(" (P2P only)")
|
|
|
|
|
}
|
|
|
|
|
fmt.Println("")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-22 20:01:56 +02:00
|
|
|
func parseCommand(str string) (mode, param string) {
|
|
|
|
|
parts := strings.SplitN(str, " ", 2)
|
|
|
|
|
if len(parts) == 1 {
|
|
|
|
|
return parts[0], ""
|
|
|
|
|
}
|
|
|
|
|
return parts[0], parts[1]
|
|
|
|
|
}
|