interactive.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. // Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved.
  2. // Use of this source code is governed by the MIT-license that can be
  3. // found in the LICENSE file.
  4. package main
  5. import (
  6. "bytes"
  7. "fmt"
  8. "log"
  9. "os"
  10. "runtime"
  11. "strings"
  12. "time"
  13. "github.com/la5nta/wl2k-go/transport/ax25"
  14. "github.com/peterh/liner"
  15. )
  16. func Interactive() {
  17. line := liner.NewLiner()
  18. defer line.Close()
  19. for {
  20. str, _ := line.Prompt(getPrompt())
  21. if str == "" {
  22. continue
  23. }
  24. line.AppendHistory(str)
  25. if str[0] == '#' {
  26. continue
  27. }
  28. if quit := execCmd(str); quit {
  29. break
  30. }
  31. }
  32. }
  33. func execCmd(line string) (quit bool) {
  34. cmd, param := parseCommand(line)
  35. switch cmd {
  36. case "connect":
  37. if param == "" {
  38. printInteractiveUsage()
  39. return
  40. }
  41. Connect(param)
  42. case "listen":
  43. Listen(param)
  44. case "unlisten":
  45. Unlisten(param)
  46. case "heard":
  47. PrintHeard()
  48. case "freq":
  49. freq(param)
  50. case "qtc":
  51. PrintQTC()
  52. case "debug":
  53. os.Setenv("ardop_debug", "1")
  54. os.Setenv("winmor_debug", "1")
  55. fmt.Println("Number of goroutines:", runtime.NumGoroutine())
  56. case "q", "quit":
  57. return true
  58. case "":
  59. return
  60. default:
  61. printInteractiveUsage()
  62. }
  63. return
  64. }
  65. func printInteractiveUsage() {
  66. fmt.Println("Uri examples: 'LA3F@5350', 'LA1B-10 v LA5NTA-1', 'LA5NTA:secret@192.168.1.1:54321'")
  67. methods := []string{
  68. MethodWinmor,
  69. MethodArdop,
  70. MethodAX25,
  71. MethodTelnet,
  72. MethodSerialTNC,
  73. }
  74. fmt.Println("Methods:", strings.Join(methods, ", "))
  75. cmds := []string{
  76. "connect METHOD:[URI] or alias Connect to a remote station.",
  77. "listen METHOD Listen for incoming connections.",
  78. "unlisten METHOD Unregister listener for incoming connections.",
  79. "freq METHOD:FREQ Change rig frequency.",
  80. "heard Display all stations heard over the air.",
  81. "qtc Print pending outbound messages.",
  82. }
  83. fmt.Println("Commands: ")
  84. for _, cmd := range cmds {
  85. fmt.Printf(" %s\n", cmd)
  86. }
  87. }
  88. func getPrompt() string {
  89. var buf bytes.Buffer
  90. status := getStatus()
  91. if len(status.ActiveListeners) > 0 {
  92. fmt.Fprintf(&buf, "L%v", status.ActiveListeners)
  93. }
  94. fmt.Fprint(&buf, "> ")
  95. return buf.String()
  96. }
  97. func PrintHeard() {
  98. pf := func(call string, t time.Time) {
  99. fmt.Printf(" %-10s (%s)\n", call, t.Format(time.RFC1123))
  100. }
  101. fmt.Println("winmor:")
  102. if wmTNC == nil {
  103. fmt.Println(" (not initialized)")
  104. } else if heard := wmTNC.Heard(); len(heard) == 0 {
  105. fmt.Println(" (none)")
  106. } else {
  107. for call, t := range heard {
  108. pf(call, t)
  109. }
  110. }
  111. fmt.Println("ardop:")
  112. if adTNC == nil {
  113. fmt.Println(" (not initialized)")
  114. } else if heard := adTNC.Heard(); len(heard) == 0 {
  115. fmt.Println(" (none)")
  116. } else {
  117. for call, t := range heard {
  118. pf(call, t)
  119. }
  120. }
  121. fmt.Println("ax25:")
  122. if heard, err := ax25.Heard(config.AX25.Port); err != nil {
  123. fmt.Printf(" (%s)\n", err)
  124. } else if len(heard) == 0 {
  125. fmt.Println(" (none)")
  126. } else {
  127. for call, t := range heard {
  128. pf(call, t)
  129. }
  130. }
  131. }
  132. func PrintQTC() {
  133. msgs, err := mbox.Outbox()
  134. if err != nil {
  135. log.Println(err)
  136. return
  137. }
  138. fmt.Printf("QTC: %d.\n", len(msgs))
  139. for _, msg := range msgs {
  140. fmt.Printf(`%-12.12s (%s): %s`, msg.MID(), msg.Subject(), fmt.Sprint(msg.To()))
  141. if msg.Header.Get("X-P2POnly") == "true" {
  142. fmt.Printf(" (P2P only)")
  143. }
  144. fmt.Println("")
  145. }
  146. }
  147. func parseCommand(str string) (mode, param string) {
  148. parts := strings.SplitN(str, " ", 2)
  149. if len(parts) == 1 {
  150. return parts[0], ""
  151. }
  152. return parts[0], parts[1]
  153. }