This commit is contained in:
Gregory Salaun 2024-09-24 11:57:48 +07:00
parent 9ddc3ce347
commit ab17255bdc
11 changed files with 912 additions and 194790 deletions

BIN
FlexDXCluster.exe Normal file

Binary file not shown.

View File

@ -13,7 +13,7 @@ import (
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})`)
type TelnetClient struct {
type TCPClient struct {
Login string
Password string
Address string
@ -31,89 +31,107 @@ type TelnetClient struct {
Log *log.Logger
}
func (tc *TelnetClient) setDefaultParams() {
if tc.Timeout == 0 {
tc.Timeout = 600 * time.Second
}
if tc.LogWriter == nil {
tc.LogWriter = bufio.NewWriter(os.Stdout)
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,
}
}
func (tc *TelnetClient) StartClient() {
func (c *TCPClient) setDefaultParams() {
if c.Timeout == 0 {
c.Timeout = 600 * time.Second
}
if c.LogWriter == nil {
c.LogWriter = bufio.NewWriter(os.Stdout)
}
}
func (c *TCPClient) StartClient() {
var err error
addr, err := net.ResolveTCPAddr("tcp", tc.Address+":"+tc.Port)
addr, err := net.ResolveTCPAddr("tcp", c.Address+":"+c.Port)
if err != nil {
tc.Log.Error("cannot resolve Telnet Client address:", err)
c.Log.Error("cannot resolve Telnet Client address:", err)
}
tc.setDefaultParams()
tc.Conn, err = net.DialTCP("tcp", nil, addr)
c.setDefaultParams()
c.Conn, err = net.DialTCP("tcp", nil, addr)
if err != nil {
tc.Log.Error("cannot connect to Telnet Client:", err)
c.Log.Error("cannot connect to Telnet Client:", err)
}
tc.Log.Infof("connected to %s:%s", tc.Address, tc.Port)
c.Log.Infof("connected to %s:%s", c.Address, c.Port)
err = tc.Conn.SetKeepAlive(true)
err = c.Conn.SetKeepAlive(true)
if err != nil {
tc.Log.Error("error while setting keep alive:", err)
c.Log.Error("error while setting keep alive:", err)
}
tc.Reader = bufio.NewReader(tc.Conn)
tc.Writer = bufio.NewWriter(tc.Conn)
c.Reader = bufio.NewReader(c.Conn)
c.Writer = bufio.NewWriter(c.Conn)
go tc.ReadLine()
go c.ReadLine()
}
func (tc *TelnetClient) Close() {
tc.Writer.WriteString("bye")
func (c *TCPClient) Close() {
c.Writer.WriteString("bye")
}
func (tc *TelnetClient) SetFilters() {
func (c *TCPClient) SetFilters() {
if Cfg.Cluster.FT8 {
tc.Write([]byte("set/ft8\r\n"))
tc.Log.Info("FT8 is on as defined in the config file")
c.Write([]byte("set/ft8\r\n"))
c.Log.Info("FT8 is on as defined in the config file")
}
if Cfg.Cluster.Skimmer {
tc.Write([]byte("set/skimmer\r\n"))
tc.Log.Info("Skimmer is on as defined in the config file")
c.Write([]byte("set/skimmer\r\n"))
c.Log.Info("Skimmer is on as defined in the config file")
}
if !Cfg.Cluster.FT8 {
tc.Write([]byte("set/noft8\r\n"))
tc.Log.Info("FT8 is off as defined in the config file")
c.Write([]byte("set/noft8\r\n"))
c.Log.Info("FT8 is off as defined in the config file")
}
if !Cfg.Cluster.Skimmer {
tc.Write([]byte("set/noskimmer\r\n"))
tc.Log.Info("Skimmer is off as defined in the config file")
c.Write([]byte("set/noskimmer\r\n"))
c.Log.Info("Skimmer is off as defined in the config file")
}
}
func (tc *TelnetClient) ReadLine() {
func (c *TCPClient) ReadLine() {
for {
message, err := tc.Reader.ReadString('\n')
message, err := c.Reader.ReadString('\n')
if err != nil {
tc.Log.Errorf("Error reading message: %s", err)
c.Log.Errorf("Error reading message: %s", err)
continue
}
if strings.Contains(message, "Login: \r\n") || strings.Contains(message, "Please enter your call: \r\n") {
tc.Log.Info("Found login prompt...sending callsign")
tc.Write([]byte(tc.Login + "\r\n"))
c.Log.Info("Found login prompt...sending callsign")
c.Write([]byte(c.Login + "\r\n"))
time.Sleep(time.Second * 2)
tc.SetFilters()
c.SetFilters()
}
ProcessTelnetSpot(spotRe, message, tc.SpotChan, tc.Log)
tc.MsgChan <- message
ProcessTelnetSpot(spotRe, message, c.SpotChan, c.Log)
// Send the spot message to TCP server
if len(c.TCPServer.Clients) > 0 {
c.MsgChan <- message
}
}
}
// Write sends raw data to remove telnet server
func (tc *TelnetClient) Write(data []byte) (n int, err error) {
func (tc *TCPClient) Write(data []byte) (n int, err error) {
n, err = tc.Writer.Write(data)
if err == nil {
err = tc.Writer.Flush()

View File

@ -50,7 +50,7 @@ func (s *TCPServer) StartServer() {
defer s.Listener.Close()
s.Log.Info("telnet server listening on %s:%s", Cfg.Telnet.Host, Cfg.Telnet.Port)
s.Log.Infof("telnet server listening on %s:%s", Cfg.Telnet.Host, Cfg.Telnet.Port)
go func() {
for message := range s.MsgChan {
@ -74,39 +74,43 @@ func (s *TCPServer) StartServer() {
}
func (s *TCPServer) handleConnection() {
defer s.Conn.Close()
s.Conn.Write([]byte("Welcome to the FlexDXCluster telnet server! Type 'bye' to exit.\n"))
// s.Conn.Write([]byte(`To ALL de XV9Q <0234Z> : Clicked on "JH2UNG"\n`))
s.Reader = bufio.NewReader(s.Conn)
s.Writer = bufio.NewWriter(s.Conn)
reader := bufio.NewReader(s.Conn)
for {
message, err := reader.ReadString('\n')
message, err := s.Reader.ReadString('\n')
if err != nil {
s.Mutex.Lock()
delete(s.Clients, s.Conn)
s.Mutex.Unlock()
s.Log.Info("client disconnected")
s.Log.Infof("client %s disconnected", s.Conn.RemoteAddr().String())
return
}
message = strings.TrimSpace(message)
if message == "bye" {
s.Log.Infof("Message reçu du client: %s\n", message)
switch message {
case "bye":
s.Mutex.Lock()
delete(s.Clients, s.Conn)
s.Mutex.Unlock()
s.Log.Info("client disconnected")
s.Log.Infof("client %s disconnected", s.Conn.RemoteAddr().String())
return
case "SH/DX 30":
return
default:
s.Write("cannot identify command\n")
}
s.Log.Info("Message reçu du client: %s\n", message)
}
}
func (s *TCPServer) Write(message string) (n int, err error) {
n, err = s.Writer.Write([]byte(message))
_, err = s.Writer.Write([]byte(message))
if err == nil {
err = s.Writer.Flush()
}

View File

@ -11,7 +11,7 @@ cluster:
ft8: false
flex:
ip: 10.10.10.120
spot_life: 300
spot_life: 600
clublog:
api: 5767f19333363a9ef432ee9cd4141fe76b8adf38
telnet:

View File

@ -54,7 +54,7 @@ func NewFlexDXDatabase(filePath string, log *log.Logger) *FlexDXClusterRepositor
`CREATE TABLE IF NOT EXISTS "spots" (
"id" INTEGER NOT NULL UNIQUE,
"commandNumber" INTEGER NOT NULL UNIQUE,
"flexSpotNumber" INTEGER UNIQUE,
"flexSpotNumber" INTEGER,
"dx" TEXT NOT NULL,
"freqMhz" TEXT,
"freqHz" TEXT,
@ -63,6 +63,7 @@ func NewFlexDXDatabase(filePath string, log *log.Logger) *FlexDXClusterRepositor
"spotter" INTEGER,
"flexMode" TEXT,
"source" TEXT,
"time" TEXT,
"timestamp" INTEGER,
"lifeTime" TEXT,
"priority" TEXT,
@ -195,7 +196,7 @@ func (r *FlexDXClusterRepository) FindDXSameBand(spot FlexSpot) (*FlexSpot, erro
s := FlexSpot{}
for rows.Next() {
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.TimeStamp, &s.LifeTime, &s.Priority,
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
@ -205,8 +206,8 @@ func (r *FlexDXClusterRepository) FindDXSameBand(spot FlexSpot) (*FlexSpot, erro
}
func (r *FlexDXClusterRepository) CreateSpot(spot FlexSpot) {
query := "INSERT INTO `spots` (`commandNumber`, `flexSpotNumber`, `dx`, `freqMhz`, `freqHz`, `band`, `mode`, `spotter`, `flexMode`, `source`, `timestamp`, `lifeTime`, `priority`, `comment`, `color`, `backgroundColor`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
insertResult, err := r.db.ExecContext(context.Background(), query, spot.CommandNumber, spot.CommandNumber, spot.DX, spot.FrequencyMhz, spot.FrequencyHz, spot.Band, spot.Mode, spot.SpotterCallsign, spot.FlexMode, spot.Source, time.Now().Unix(), spot.LifeTime, spot.Priority, spot.Comment, spot.Color, spot.BackgroundColor)
query := "INSERT INTO `spots` (`commandNumber`, `flexSpotNumber`, `dx`, `freqMhz`, `freqHz`, `band`, `mode`, `spotter`, `flexMode`, `source`, `time`, `timestamp`, `lifeTime`, `priority`, `comment`, `color`, `backgroundColor`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
insertResult, err := r.db.ExecContext(context.Background(), query, spot.CommandNumber, spot.CommandNumber, spot.DX, spot.FrequencyMhz, spot.FrequencyHz, spot.Band, spot.Mode, spot.SpotterCallsign, spot.FlexMode, spot.Source, spot.UTCTime, time.Now().Unix(), spot.LifeTime, spot.Priority, spot.Comment, spot.Color, spot.BackgroundColor)
if err != nil {
log.Errorf("cannot insert spot in database: %s", err)
}
@ -231,7 +232,7 @@ func (r *FlexDXClusterRepository) FindSpotByCommandNumber(commandNumber string)
s := FlexSpot{}
for rows.Next() {
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.TimeStamp, &s.LifeTime, &s.Priority,
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
@ -249,7 +250,7 @@ func (r *FlexDXClusterRepository) FindSpotByFlexSpotNumber(spotNumber string) (*
s := FlexSpot{}
for rows.Next() {
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.TimeStamp, &s.LifeTime, &s.Priority,
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
@ -258,8 +259,8 @@ func (r *FlexDXClusterRepository) FindSpotByFlexSpotNumber(spotNumber string) (*
return &s, nil
}
func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpot string, spot FlexSpot) (*FlexSpot, error) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpot)
func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpotNumber string, spot FlexSpot) (*FlexSpot, error) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpotNumber)
rows, err := r.db.Query(`UPDATE spots SET flexSpotNumber = ? WHERE id = ? RETURNING *`, flexSpotNumberInt, spot.ID)
if err != nil {
r.Log.Errorf("could not update database: %s", err)
@ -267,7 +268,7 @@ func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpot string, spot
s := FlexSpot{}
for rows.Next() {
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.TimeStamp, &s.LifeTime, &s.Priority,
if err := rows.Scan(&s.ID, &s.CommandNumber, &s.FlexSpotNumber, &s.DX, &s.FrequencyMhz, &s.FrequencyHz, &s.Band, &s.Mode, &s.SpotterCallsign, &s.FlexMode, &s.Source, &s.UTCTime, &s.TimeStamp, &s.LifeTime, &s.Priority,
&s.Comment, &s.Color, &s.BackgroundColor); err != nil {
fmt.Println(err)
return nil, err
@ -277,6 +278,15 @@ func (r *FlexDXClusterRepository) UpdateFlexSpotNumberByID(flexSpot string, spot
return &s, nil
}
func (r *FlexDXClusterRepository) DeleteSpotByFlexSpotNumber(flexSpotNumber string) {
flexSpotNumberInt, _ := strconv.Atoi(flexSpotNumber)
query := "DELETE from spots WHERE flexSpotNumber = ?"
_, err := r.db.Exec(query, flexSpotNumberInt)
if err != nil {
r.Log.Errorf("could not delete spot %v from database", flexSpotNumberInt)
}
}
func DeleteDatabase(filePath string, log *log.Logger) {
_, err := os.Stat(filePath)
if !os.IsNotExist(err) {

Binary file not shown.

View File

@ -5,14 +5,14 @@ import (
"fmt"
"net"
"os"
"strconv"
"regexp"
"strings"
"time"
log "github.com/sirupsen/logrus"
)
var command int = 1
var CommandNumber int = 1
type FlexSpot struct {
ID int
@ -27,6 +27,7 @@ type FlexSpot struct {
Source string
SpotterCallsign string
TimeStamp int64
UTCTime string
LifeTime string
Priority string
Comment string
@ -46,10 +47,10 @@ type FlexClient struct {
MsgChan chan string
Repo FlexDXClusterRepository
Log *log.Logger
TCPServer *TCPServer
TCPServer TCPServer
}
func NewFlexClient(repo FlexDXClusterRepository, TCPServer *TCPServer, log *log.Logger) *FlexClient {
func NewFlexClient(repo FlexDXClusterRepository, TCPServer TCPServer, log *log.Logger) *FlexClient {
return &FlexClient{
Address: Cfg.Flex.IP,
Port: "4992",
@ -74,7 +75,7 @@ func (fc *FlexClient) StartFlexClient() {
fc.Timeout = 600 * time.Second
fc.Conn, err = net.DialTCP("tcp", nil, addr)
if err != nil {
fc.Log.Error("could not dial flex client:", err)
fc.Log.Error("could not connect to flex radio, exiting...", err)
os.Exit(1)
}
fc.Log.Infof("connected to %s:%s", fc.Address, fc.Port)
@ -94,14 +95,22 @@ func (fc *FlexClient) StartFlexClient() {
}
go fc.ReadLine()
subSpotAllCmd := fmt.Sprintf("C%v|sub spot all", CommandNumber)
fc.Write(subSpotAllCmd)
CommandNumber++
clrSpotAllCmd := fmt.Sprintf("C%v|spot clear", CommandNumber)
fc.Write(clrSpotAllCmd)
CommandNumber++
}
func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) (n int, err error) {
func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) {
freq := FreqMhztoHz(spot.Frequency)
flexSpot := FlexSpot{
CommandNumber: command,
CommandNumber: CommandNumber,
DX: spot.DX,
FrequencyMhz: freq,
FrequencyHz: spot.Frequency,
@ -110,6 +119,7 @@ func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) (n int, err error) {
Source: "FlexDXCluster",
SpotterCallsign: spot.Spotter,
TimeStamp: time.Now().Unix(),
UTCTime: spot.Time,
LifeTime: Cfg.Flex.SpotLife,
Comment: spot.Comment,
Color: "#eaeaea",
@ -149,70 +159,82 @@ func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) (n int, err error) {
fc.Log.Error("could not find the DX in the database: ", err)
}
var stringSpot string
spotLife, _ := strconv.Atoi(Cfg.Flex.SpotLife)
spotTime := time.Unix(srcFlexSpot.TimeStamp, 0)
elapsed := time.Since(spotTime)
if srcFlexSpot.DX == "" {
fc.Repo.CreateSpot(flexSpot)
stringSpot = fmt.Sprintf("C%v|spot add rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, flexSpot.FrequencyMhz,
stringSpot := fmt.Sprintf("C%v|spot add rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, flexSpot.FrequencyMhz,
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
} else if srcFlexSpot.DX != "" && elapsed > time.Duration(spotLife) {
fc.SendSpot(stringSpot)
} else if srcFlexSpot.DX != "" && srcFlexSpot.Band == flexSpot.Band && srcFlexSpot.FrequencyMhz != flexSpot.FrequencyMhz {
fc.Repo.UpdateSpotSameBand(flexSpot)
stringSpot = fmt.Sprintf("C%v|spot add rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, flexSpot.FrequencyMhz,
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
} else if srcFlexSpot.DX != "" && srcFlexSpot.Band == flexSpot.Band && srcFlexSpot.FrequencyMhz != flexSpot.FrequencyMhz && elapsed < time.Duration(spotLife) {
fc.Repo.UpdateSpotSameBand(flexSpot)
stringSpot = fmt.Sprintf("C%v|spot set %v rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, srcFlexSpot.CommandNumber, flexSpot.FrequencyMhz,
stringSpot := fmt.Sprintf("C%v|spot set %v rx_freq=%v callsign=%s mode=%s source=%s spotter_callsign=%s timestamp=%v lifetime_seconds=%s comment=%s color=%s background_color=%s priority=%s", flexSpot.CommandNumber, srcFlexSpot.CommandNumber, flexSpot.FrequencyMhz,
flexSpot.DX, flexSpot.Mode, flexSpot.Source, flexSpot.SpotterCallsign, flexSpot.TimeStamp, flexSpot.LifeTime, flexSpot.Comment, flexSpot.Color, flexSpot.BackgroundColor, flexSpot.Priority)
CommandNumber++
stringDelete := fmt.Sprintf("C%v|spot remove %v", CommandNumber, srcFlexSpot.FlexSpotNumber)
fc.DeleteAndSendSpot(stringSpot, stringDelete)
}
fc.Write(stringSpot)
command++
return
CommandNumber++
}
func (fc *FlexClient) SendSpot(stringSpot string) {
fc.Write(stringSpot)
}
func (fc *FlexClient) DeleteAndSendSpot(stringSpot string, deleteSpot string) {
fc.Write(deleteSpot)
fc.Write(stringSpot)
}
func (fc *FlexClient) ReadLine() {
for {
message, err := fc.Reader.ReadString(byte('\n'))
if err != nil {
fc.Log.Errorf("error reading message: %s", err)
continue
fc.Log.Errorf("error reading message from flexradio closing program: %s", err)
os.Exit(1)
}
// regRespSpot := *regexp.MustCompile(`R(\d+)\|0\|(\d+)\n`)
// respSpot := regRespSpot.FindStringSubmatch(message)
// msgRaw := strings.TrimSpace(message)
// fc.Log.Info(msgRaw)
// if len(respSpot) > 0 {
// spot, _ := fc.Repo.FindSpotByCommandNumber(respSpot[1])
// _, err := fc.Repo.UpdateFlexSpotNumberByID(respSpot[2], *spot)
// if err != nil {
// fc.Log.Errorf("could not update flex spot number in database: %s", err)
// }
// }
// Response when spot is added
regRespSpot := *regexp.MustCompile(`R(\d+)\|0\|(\d+)\n`)
respSpot := regRespSpot.FindStringSubmatch(message)
// regTriggerSpot := *regexp.MustCompile(`.*\|spot\s(\d+)\striggered.*`)
// respTrigger := regTriggerSpot.FindStringSubmatch(message)
if len(respSpot) > 0 {
spot, _ := fc.Repo.FindSpotByCommandNumber(respSpot[1])
_, err := fc.Repo.UpdateFlexSpotNumberByID(respSpot[2], *spot)
if err != nil {
fc.Log.Errorf("could not update flex spot number in database: %s", err)
}
}
// if len(respTrigger) > 0 {
// spot, err := fc.Repo.FindSpotByFlexSpotNumber(respTrigger[1])
// if err != nil {
// fc.Log.Errorf("could not find spot by flex spot number in database: %s", err)
// }
// Response when a spot is clicked
regTriggerSpot := *regexp.MustCompile(`.*spot (\d+) triggered.*\n`)
respTrigger := regTriggerSpot.FindStringSubmatch(message)
// msg := fmt.Sprintf(`To ALL de %s <0233z> : Clicked on %s at %s`, Cfg.SQLite.Callsign, spot.DX, spot.FrequencyHz)
// if len(fc.TCPServer.Clients) > 0 {
// fc.MsgChan <- msg
// }
if len(respTrigger) > 0 {
spot, err := fc.Repo.FindSpotByFlexSpotNumber(respTrigger[1])
if err != nil {
fc.Log.Errorf("could not find spot by flex spot number in database: %s", err)
}
// }
msg := fmt.Sprintf(`To ALL de %s <%s> : Clicked on "%s" at %s`, Cfg.SQLite.Callsign, spot.UTCTime, spot.DX, spot.FrequencyHz)
if len(fc.TCPServer.Clients) > 0 {
fc.MsgChan <- msg
fc.Log.Infof("%s clicked on spot \"%s\" at %s", Cfg.SQLite.Callsign, spot.DX, spot.FrequencyMhz)
}
}
msg := strings.TrimSpace(message)
fc.Log.Info(msg)
// Status when a spot is deleted
regSpotDeleted := *regexp.MustCompile(`S\d+\|spot (\d+) removed`)
respDelete := regSpotDeleted.FindStringSubmatch(message)
if len(respDelete) > 0 {
fc.Repo.DeleteSpotByFlexSpotNumber(respDelete[1])
fc.Log.Infof("deleted spot %v from database", respDelete[1])
}
}
}

195396
flexradio.log

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,6 @@ import (
prefixed "github.com/x-cray/logrus-prefixed-formatter"
)
var Log *log.Logger
func NewLog() *log.Logger {
f, err := os.OpenFile("flexradio.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
@ -18,7 +16,7 @@ func NewLog() *log.Logger {
w := io.MultiWriter(os.Stdout, f)
Log := &log.Logger{
l := &log.Logger{
Out: w,
Level: log.DebugLevel,
Formatter: &prefixed.TextFormatter{
@ -29,7 +27,9 @@ func NewLog() *log.Logger {
},
}
return Log
l.Level = log.DebugLevel
return l
}
// Info ...
@ -47,6 +47,10 @@ func Error(format string, v ...interface{}) {
log.Errorf(format, v...)
}
func Debug(format string, v ...interface{}) {
log.Debugf(format, v...)
}
var (
// ConfigError ...

23
main.go
View File

@ -44,33 +44,18 @@ func main() {
log := logger.NewLog()
log.Info("config loaded.")
log.Infof("Callsign: %s\n", Cfg.SQLite.Callsign)
log.Infof("Callsign: %s", Cfg.SQLite.Callsign)
DeleteDatabase("./flex.sqlite", log)
repo := NewFlexDXDatabase("flex.sqlite", log)
// Create TelnetServer
TCPServer := NewTCPServer(Cfg.Telnet.Host, Cfg.Telnet.Port, log)
FlexClient := NewFlexClient(*repo, *TCPServer, log)
TCPClient := NewTCPClient(*Cfg, TCPServer, FlexClient, log)
// Connect to Flex Radio (ip defined in config file)
FlexClient := NewFlexClient(*repo, TCPServer, log)
go FlexClient.StartFlexClient()
// Connect to DX Cluster
TelnetClient := TelnetClient{
Address: Cfg.Cluster.Server,
Port: Cfg.Cluster.Port,
Login: Cfg.Cluster.Login,
MsgChan: TCPServer.MsgChan,
CmdChan: TCPServer.CmdChan,
SpotChan: FlexClient.SpotChan,
Log: log,
}
go TelnetClient.StartClient()
// Start TelnetServer
go TCPClient.StartClient()
go TCPServer.StartServer()
select {}

View File

@ -105,6 +105,7 @@ func ProcessTelnetSpot(re *regexp.Regexp, spotRaw string, SpotChan chan TelnetSp
spot.DX, spot.Spotter, spot.Frequency, spot.Band, spot.Mode, spot.Comment, spot.Time, spot.DXCC)
}
// send spot to SpotChan to Flex Client to send the spot to Flex radio
SpotChan <- spot
}