TRX control through the modem using rigctl
This commit is contained in:
2
go.mod
2
go.mod
@@ -14,7 +14,9 @@ require (
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||||
|
github.com/augustoroman/hexdump v0.0.0-20231204223853-3694912baadb // indirect
|
||||||
github.com/creack/goselect v0.1.2 // indirect
|
github.com/creack/goselect v0.1.2 // indirect
|
||||||
|
github.com/creack/pty v1.1.24 // indirect
|
||||||
github.com/kr/pretty v0.3.1 // indirect
|
github.com/kr/pretty v0.3.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||||
github.com/nsf/termbox-go v1.1.1 // indirect
|
github.com/nsf/termbox-go v1.1.1 // indirect
|
||||||
|
9
main.go
9
main.go
@@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
//log "github.com/fangdingjun/go-log"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
@@ -32,6 +31,8 @@ type TCPServer struct {
|
|||||||
Protocol chan string
|
Protocol chan string
|
||||||
ToPactor *ByteFIFO
|
ToPactor *ByteFIFO
|
||||||
FromPactor *ByteFIFO
|
FromPactor *ByteFIFO
|
||||||
|
ToTRX *ByteFIFO
|
||||||
|
FromTRX *ByteFIFO
|
||||||
VARAMode bool
|
VARAMode bool
|
||||||
DaemonMode bool
|
DaemonMode bool
|
||||||
GPSdMode bool
|
GPSdMode bool
|
||||||
@@ -54,6 +55,8 @@ func NewTCPServer(varamode bool, daemonmode bool, gpsdmode bool, nmeapassthrough
|
|||||||
Protocol: make(chan string, 1024),
|
Protocol: make(chan string, 1024),
|
||||||
ToPactor: NewByteFIFO(1024),
|
ToPactor: NewByteFIFO(1024),
|
||||||
FromPactor: NewByteFIFO(1024),
|
FromPactor: NewByteFIFO(1024),
|
||||||
|
ToTRX: NewByteFIFO(1024),
|
||||||
|
FromTRX: NewByteFIFO(1024),
|
||||||
VARAMode: varamode,
|
VARAMode: varamode,
|
||||||
DaemonMode: daemonmode,
|
DaemonMode: daemonmode,
|
||||||
GPSdMode: gpsdmode,
|
GPSdMode: gpsdmode,
|
||||||
@@ -178,6 +181,10 @@ func main() {
|
|||||||
go readAndBroadcast()
|
go readAndBroadcast()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if true { // TODO: later change to Config
|
||||||
|
go trxControl()
|
||||||
|
}
|
||||||
|
|
||||||
if !daemonMode {
|
if !daemonMode {
|
||||||
// Initialize the gocui GUI
|
// Initialize the gocui GUI
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal)
|
g, err := gocui.NewGui(gocui.OutputNormal)
|
||||||
|
40
ptc.go
40
ptc.go
@@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"github.com/TwiN/go-color"
|
"github.com/TwiN/go-color"
|
||||||
"github.com/albenik/go-serial/v2"
|
"github.com/albenik/go-serial/v2"
|
||||||
|
"github.com/augustoroman/hexdump"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
@@ -75,11 +76,12 @@ type Modem struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SerialTimeout = 1
|
SerialTimeout = 1
|
||||||
PactorChannel = 4
|
PactorChannel = 4
|
||||||
NMEAChannel = 249
|
NMEAChannel = 249
|
||||||
MaxSendData = 255
|
TRXControlChannel = 253
|
||||||
MaxFrameNotTX = 2
|
MaxSendData = 255
|
||||||
|
MaxFrameNotTX = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
// ToPactor states
|
// ToPactor states
|
||||||
@@ -226,7 +228,9 @@ func (p *Modem) init() (err error) {
|
|||||||
}
|
}
|
||||||
writeDebug("Found a "+modem+" modem at "+p.devicePath, 0)
|
writeDebug("Found a "+modem+" modem at "+p.devicePath, 0)
|
||||||
s.DeviceType = modem
|
s.DeviceType = modem
|
||||||
|
|
||||||
writeDebug("Running init commands", 1)
|
writeDebug("Running init commands", 1)
|
||||||
|
|
||||||
ct := time.Now()
|
ct := time.Now()
|
||||||
commands := []string{"DD", "RESTART", "MYcall " + p.localAddr, "PTCH " + strconv.Itoa(PactorChannel),
|
commands := []string{"DD", "RESTART", "MYcall " + p.localAddr, "PTCH " + strconv.Itoa(PactorChannel),
|
||||||
"MAXE 35", "REM 0", "CHOB 0", "PD 1",
|
"MAXE 35", "REM 0", "CHOB 0", "PD 1",
|
||||||
@@ -353,6 +357,22 @@ func (p *Modem) modemThread() {
|
|||||||
// TODO: Catch errors!
|
// TODO: Catch errors!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TX TRX control data
|
||||||
|
|
||||||
|
trxcmd, err := s.ToTRX.Dequeue(1024)
|
||||||
|
if err == nil {
|
||||||
|
writeDebug("Write TRX command ("+strconv.Itoa(len(trxcmd))+"): "+hexdump.Dump(trxcmd), 1)
|
||||||
|
_, _, err := p.writeAndGetResponse(string(trxcmd), TRXControlChannel, false, chunkSize)
|
||||||
|
if err != nil {
|
||||||
|
writeDebug("Error when sending TRX Command: "+err.Error(), 0)
|
||||||
|
}
|
||||||
|
/*if len(ans) > 2 {
|
||||||
|
s.FromTRX.Enqueue([]byte(ans[2:]))
|
||||||
|
}*/
|
||||||
|
//s.FromTRX.Enqueue([]byte(ans))
|
||||||
|
//writeDebug("TRX CMD answer from modem: \n"+hexdump.Dump([]byte(ans)), 1)
|
||||||
|
}
|
||||||
|
|
||||||
// RX
|
// RX
|
||||||
var res []byte
|
var res []byte
|
||||||
|
|
||||||
@@ -371,6 +391,11 @@ func (p *Modem) modemThread() {
|
|||||||
case 254: //Status update
|
case 254: //Status update
|
||||||
p.chanbusy = int(res[0])&112 == 112 // See PTC-IIIusb manual "STATUS" command
|
p.chanbusy = int(res[0])&112 == 112 // See PTC-IIIusb manual "STATUS" command
|
||||||
writeDebug("PACTOR state: "+strconv.FormatInt(int64(res[0]), 2), 2)
|
writeDebug("PACTOR state: "+strconv.FormatInt(int64(res[0]), 2), 2)
|
||||||
|
case TRXControlChannel:
|
||||||
|
//if !bytes.Equal(res, trxcmd) {
|
||||||
|
s.FromTRX.Enqueue(res)
|
||||||
|
writeDebug("TRX CMD answer:\n"+hexdump.Dump(res), 1)
|
||||||
|
//}
|
||||||
default:
|
default:
|
||||||
writeDebug("Channel "+strconv.Itoa(c)+": "+string(res), 1)
|
writeDebug("Channel "+strconv.Itoa(c)+": "+string(res), 1)
|
||||||
}
|
}
|
||||||
@@ -571,6 +596,11 @@ func (p *Modem) checkResponse(resp string, ch int) (n int, data []byte, err erro
|
|||||||
s.GPSStream.Enqueue("$" + string(bytes.Trim(payload, "\x00"))) //need to remove the trailing NULL byte
|
s.GPSStream.Enqueue("$" + string(bytes.Trim(payload, "\x00"))) //need to remove the trailing NULL byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* if ch == TRXControlChannel {
|
||||||
|
writeDebug("TRX Control channel message: "+string(payload), 1)
|
||||||
|
s.FromTRX.Enqueue(payload)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
if int(head[1]) == 2 {
|
if int(head[1]) == 2 {
|
||||||
|
58
trxcontrol.go
Normal file
58
trxcontrol.go
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"github.com/augustoroman/hexdump"
|
||||||
|
"github.com/creack/pty"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func trxControl() {
|
||||||
|
ptypath := "/tmp/my_virtual_serial"
|
||||||
|
master, slave, err := pty.Open()
|
||||||
|
if err != nil {
|
||||||
|
writeDebug(fmt.Sprintf("trxControl: error opening PTY: %v", err), 0)
|
||||||
|
}
|
||||||
|
defer master.Close()
|
||||||
|
defer slave.Close()
|
||||||
|
|
||||||
|
err = os.Remove(ptypath)
|
||||||
|
if err := os.Symlink(slave.Name(), ptypath); err != nil {
|
||||||
|
writeDebug(fmt.Sprintf("trxControl: error creating link: %v", err), 0)
|
||||||
|
}
|
||||||
|
writeDebug(fmt.Sprintf("trxControl: opening PTY: %s\n", ptypath), 0)
|
||||||
|
// Receive from TRX
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
cmd, err := s.FromTRX.Dequeue(1024)
|
||||||
|
if err == nil {
|
||||||
|
master.Write(cmd)
|
||||||
|
writeDebug("From TRX response ("+strconv.Itoa(len(cmd))+"):\n"+hexdump.Dump(cmd), 1)
|
||||||
|
}
|
||||||
|
time.Sleep(30 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
//scanner := bufio.NewScanner(master)
|
||||||
|
//for scanner.Scan() {
|
||||||
|
//t := scanner.Text()
|
||||||
|
rd := bufio.NewReader(master)
|
||||||
|
for {
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
// looks like gpsd does not expect \n terminated lines so read what is there from the socket
|
||||||
|
master.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||||
|
buff := make([]byte, 1024)
|
||||||
|
n, err := rd.Read(buff)
|
||||||
|
t := buff[:n]
|
||||||
|
writeDebug("To TRX data ("+strconv.Itoa(len(t))+"):\n"+hexdump.Dump(t), 1)
|
||||||
|
// Send to TRX
|
||||||
|
err = s.ToTRX.Enqueue(t)
|
||||||
|
if err != nil {
|
||||||
|
writeDebug(fmt.Sprintf("trxControl: error enqueuing command: %v", err), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user