FlexDXCluster/TCPClient.go

166 lines
3.6 KiB
Go
Raw Permalink Normal View History

2024-09-23 16:24:50 +07:00
package main
import (
"bufio"
"net"
"os"
"regexp"
"strings"
"time"
log "github.com/sirupsen/logrus"
)
var spotRe *regexp.Regexp = regexp.MustCompile(`DX\sde\s([\w\d]+).*:\s+(\d+.\d)\s+([\w\d]+)\s+(CW|SSB|FT8|FT4|RTTY|USB|LSB)?\s+(.*)\s\s\s+([\d]+\w{1})`)
2024-09-26 12:24:56 +07:00
var count int = 0
2024-09-23 16:24:50 +07:00
2024-09-24 11:57:48 +07:00
type TCPClient struct {
2024-09-23 16:24:50 +07:00
Login string
Password string
Address string
Port string
Timeout time.Duration
LogWriter *bufio.Writer
Reader *bufio.Reader
Writer *bufio.Writer
Conn *net.TCPConn
TCPServer TCPServer
FlexClient FlexClient
MsgChan chan string
CmdChan chan string
SpotChan chan TelnetSpot
Log *log.Logger
}
2024-09-24 11:57:48 +07:00
func NewTCPClient(cfg Config, TCPServer *TCPServer, FlexClient *FlexClient, log *log.Logger) *TCPClient {
return &TCPClient{
Address: Cfg.Cluster.Server,
Port: Cfg.Cluster.Port,
Login: Cfg.Cluster.Login,
MsgChan: TCPServer.MsgChan,
CmdChan: TCPServer.CmdChan,
SpotChan: FlexClient.SpotChan,
Log: log,
TCPServer: *TCPServer,
FlexClient: *FlexClient,
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
}
func (c *TCPClient) setDefaultParams() {
if c.Timeout == 0 {
c.Timeout = 600 * time.Second
}
if c.LogWriter == nil {
c.LogWriter = bufio.NewWriter(os.Stdout)
2024-09-23 16:24:50 +07:00
}
}
2024-09-24 11:57:48 +07:00
func (c *TCPClient) StartClient() {
2024-09-23 16:24:50 +07:00
var err error
2024-09-24 11:57:48 +07:00
addr, err := net.ResolveTCPAddr("tcp", c.Address+":"+c.Port)
2024-09-23 16:24:50 +07:00
if err != nil {
2024-09-24 11:57:48 +07:00
c.Log.Error("cannot resolve Telnet Client address:", err)
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
c.setDefaultParams()
c.Conn, err = net.DialTCP("tcp", nil, addr)
2024-09-23 16:24:50 +07:00
if err != nil {
2024-09-24 11:57:48 +07:00
c.Log.Error("cannot connect to Telnet Client:", err)
2024-09-23 16:24:50 +07:00
}
2024-09-26 12:24:56 +07:00
c.Log.Infof("connected to DX cluster %s:%s", c.Address, c.Port)
2024-09-23 16:24:50 +07:00
2024-09-24 11:57:48 +07:00
err = c.Conn.SetKeepAlive(true)
2024-09-23 16:24:50 +07:00
if err != nil {
2024-09-24 11:57:48 +07:00
c.Log.Error("error while setting keep alive:", err)
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
c.Reader = bufio.NewReader(c.Conn)
c.Writer = bufio.NewWriter(c.Conn)
2024-09-23 16:24:50 +07:00
2024-09-26 12:24:56 +07:00
go func() {
for message := range c.TCPServer.CmdChan {
c.Log.Infof("Received DX Command: %s", message)
2024-09-26 15:23:05 +07:00
message := message + "\n"
2024-09-26 12:24:56 +07:00
c.WriteString(message)
}
}()
2024-09-24 11:57:48 +07:00
go c.ReadLine()
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
func (c *TCPClient) Close() {
c.Writer.WriteString("bye")
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
func (c *TCPClient) SetFilters() {
2024-09-23 16:24:50 +07:00
if Cfg.Cluster.FT8 {
2024-09-24 11:57:48 +07:00
c.Write([]byte("set/ft8\r\n"))
c.Log.Info("FT8 is on as defined in the config file")
2024-09-23 16:24:50 +07:00
}
if Cfg.Cluster.Skimmer {
2024-09-24 11:57:48 +07:00
c.Write([]byte("set/skimmer\r\n"))
c.Log.Info("Skimmer is on as defined in the config file")
2024-09-23 16:24:50 +07:00
}
if !Cfg.Cluster.FT8 {
2024-09-24 11:57:48 +07:00
c.Write([]byte("set/noft8\r\n"))
c.Log.Info("FT8 is off as defined in the config file")
2024-09-23 16:24:50 +07:00
}
if !Cfg.Cluster.Skimmer {
2024-09-24 11:57:48 +07:00
c.Write([]byte("set/noskimmer\r\n"))
c.Log.Info("Skimmer is off as defined in the config file")
2024-09-23 16:24:50 +07:00
}
}
2024-09-24 11:57:48 +07:00
func (c *TCPClient) ReadLine() {
2024-09-26 12:24:56 +07:00
2024-09-23 16:24:50 +07:00
for {
2024-09-24 11:57:48 +07:00
message, err := c.Reader.ReadString('\n')
2024-09-23 16:24:50 +07:00
if err != nil {
2024-09-24 11:57:48 +07:00
c.Log.Errorf("Error reading message: %s", err)
2024-09-23 16:24:50 +07:00
continue
}
if strings.Contains(message, "Login: \r\n") || strings.Contains(message, "Please enter your call: \r\n") {
2024-09-24 11:57:48 +07:00
c.Log.Info("Found login prompt...sending callsign")
c.Write([]byte(c.Login + "\r\n"))
2024-09-23 16:24:50 +07:00
time.Sleep(time.Second * 2)
2024-09-24 11:57:48 +07:00
c.SetFilters()
2024-09-23 16:24:50 +07:00
}
2024-09-24 11:57:48 +07:00
ProcessTelnetSpot(spotRe, message, c.SpotChan, c.Log)
// Send the spot message to TCP server
if len(c.TCPServer.Clients) > 0 {
2024-09-26 12:24:56 +07:00
if count == 0 {
// wait 3 seconds before sending messages to allow the client to connect
time.Sleep(time.Second * 3)
count++
}
2024-09-24 11:57:48 +07:00
c.MsgChan <- message
}
2024-09-23 16:24:50 +07:00
}
}
// Write sends raw data to remove telnet server
2024-09-24 11:57:48 +07:00
func (tc *TCPClient) Write(data []byte) (n int, err error) {
2024-09-23 16:24:50 +07:00
n, err = tc.Writer.Write(data)
if err == nil {
err = tc.Writer.Flush()
}
return
}
2024-09-26 12:24:56 +07:00
func (tc *TCPClient) WriteString(data string) (n int, err error) {
n, err = tc.Writer.Write([]byte(data))
if err == nil {
err = tc.Writer.Flush()
}
return
}