From a7716a65c7694fcde72d7dcdf5ccfbea52c8aa64 Mon Sep 17 00:00:00 2001 From: Greg Date: Sun, 7 Sep 2025 20:29:55 +0200 Subject: [PATCH] update --- TCPClient.go | 110 ++++++++++++++++++++++++++------------------------- TCPServer.go | 2 +- config.yml | 14 +++---- country.xml | 27 ------------- database.go | 4 +- flexradio.go | 2 + gotify.go | 2 +- main.go | 1 + spot.go | 5 ++- xml.go | 6 +-- 10 files changed, 78 insertions(+), 95 deletions(-) diff --git a/TCPClient.go b/TCPClient.go index 8a03b5f..66f180a 100644 --- a/TCPClient.go +++ b/TCPClient.go @@ -12,6 +12,8 @@ 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})`) +var defaultLoginRe *regexp.Regexp = regexp.MustCompile("[\\w\\d-_]+ login:") +var defaultPasswordRe *regexp.Regexp = regexp.MustCompile("Password:") type TCPClient struct { Login string @@ -24,7 +26,7 @@ type TCPClient struct { Reader *bufio.Reader Writer *bufio.Writer Scanner *bufio.Scanner - Conn *net.TCPConn + Conn net.Conn TCPServer TCPServer MsgChan chan string CmdChan chan string @@ -33,6 +35,8 @@ type TCPClient struct { Log *log.Logger Config *Config Countries Countries + LoginRe *regexp.Regexp + PasswordRe *regexp.Regexp } func NewTCPClient(TCPServer *TCPServer, Countries Countries) *TCPClient { @@ -58,35 +62,32 @@ func (c *TCPClient) setDefaultParams() { c.LogWriter = bufio.NewWriter(os.Stdout) } c.LoggedIn = false + + if c.LoginRe == nil { + c.LoginRe = defaultLoginRe + } + + if c.PasswordRe == nil { + c.PasswordRe = defaultPasswordRe + } } func (c *TCPClient) StartClient() { var err error - - addr, err := net.ResolveTCPAddr("tcp", c.Address+":"+c.Port) - if err != nil { - Log.Error("Cannot resolve Telnet Client address:", err) - } - c.setDefaultParams() - c.Conn, err = net.DialTCP("tcp", nil, addr) + + c.Conn, err = net.Dial("tcp", c.Address+":"+c.Port) if err != nil { Log.Error("Cannot connect to Telnet Client:", err) } - // err = c.Conn.SetKeepAlive(true) - // if err != nil { - // Log.Error("Error while setting keep alive:", err) - // } - c.Reader = bufio.NewReader(c.Conn) c.Writer = bufio.NewWriter(c.Conn) go func() { for message := range c.TCPServer.CmdChan { Log.Infof("Received Command: %s", message) - message := message + "\n" - c.WriteString(message) + c.Write([]byte(message + "\r\n")) } }() @@ -133,64 +134,67 @@ func (c *TCPClient) SetFilters() { func (c *TCPClient) ReadLine() { for { - // Need to check data with space first to find login and then use \n if !c.LoggedIn { - message, err := c.Reader.ReadString(' ') - message, _ = strings.CutSuffix(message, "\n") - message, _ = strings.CutSuffix(message, "\r") - + message, err := c.Reader.ReadBytes(':') if err != nil { Log.Errorf("Error reading message: %s", err) c.Conn.Close() c.StartClient() } - if strings.Contains(message, Cfg.Cluster.LoginPrompt) { + // message, _ = strings.CutSuffix(message, "\n") + // message, _ = strings.CutSuffix(message, "\r") + + if strings.Contains(string(message), Cfg.Cluster.LoginPrompt) || strings.Contains(string(message), "login:") { + time.Sleep(time.Second * 1) Log.Debug("Found login prompt...sending callsign") - c.Write([]byte(c.Login + "\r\n")) + c.Write([]byte(c.Login + "\n\r")) c.LoggedIn = true - c.SetFilters() - if Cfg.Cluster.Command != "" { - c.WriteString(Cfg.Cluster.Command + "\n\r") - } Log.Infof("Connected to DX cluster %s:%s", Cfg.Cluster.Server, Cfg.Cluster.Port) - Log.Info("Start receiving spots") continue } } if c.LoggedIn { - message, err := c.Reader.ReadString('\n') - message, _ = strings.CutSuffix(message, "\n") - message, _ = strings.CutSuffix(message, "\r") + message, err := c.Reader.ReadBytes('\n') + messageString := string(message) + // Log.Println(messageString) - if strings.Contains(message, "password") { - Log.Debug("Found password prompt...sending password") - c.Write([]byte(c.Password + "\r\n")) - } - - if err != nil { - Log.Errorf("Error reading message: %s", err) - c.Conn.Close() - c.StartClient() - } - - if strings.Contains(message, "Error reading from server: read tcp") { - Log.Error("Disconnected from Telnet Server, reconnecting") - c.Close() - c.StartClient() - } else { - if c.LoggedIn && strings.Contains(message, "DX") { - ProcessTelnetSpot(spotRe, message, c.SpotChanToFlex, c.SpotChanToHTTPServer, c.Countries) + if messageString != "" { + if err != nil { + Log.Errorf("Error reading message: %s", err) + c.Conn.Close() + c.StartClient() } + + if strings.Contains(messageString, "password") { + Log.Debug("Found password prompt...sending password...") + c.Write([]byte(c.Password + "\r\n")) + } + + if strings.Contains(messageString, "Hello") || strings.Contains(messageString, "Welcome") { + go c.SetFilters() + if Cfg.Cluster.Command != "" { + c.WriteString(Cfg.Cluster.Command + "\n\r") + Log.Debugf("Sending Command: %s", Cfg.Cluster.Command) + } + } + + if strings.Contains(messageString, "Error reading from server: read tcp") { + Log.Error("Disconnected from Telnet Server, reconnecting") + c.Close() + c.StartClient() + } + + if strings.Contains(messageString, "DX") { + ProcessTelnetSpot(spotRe, messageString, c.SpotChanToFlex, c.SpotChanToHTTPServer, c.Countries) + } + + // Send the spot message to TCP server + c.MsgChan <- messageString } - - // Send the spot message to TCP server - c.MsgChan <- message - } - } } diff --git a/TCPServer.go b/TCPServer.go index ed294ce..c178c26 100644 --- a/TCPServer.go +++ b/TCPServer.go @@ -64,7 +64,7 @@ func (s *TCPServer) StartServer() { for { s.Conn, err = s.Listener.Accept() - Log.Info("Client connected", s.Conn.RemoteAddr().String()) + Log.Info("Client connected: ", s.Conn.RemoteAddr().String()) if err != nil { Log.Error("Could not accept connections to telnet server") continue diff --git a/config.yml b/config.yml index 6580567..d715499 100644 --- a/config.yml +++ b/config.yml @@ -2,12 +2,12 @@ general: delete_log_file_at_start: true callsign: F4BPO # Log4OM Callsign used to check if you get spotted by someone log_to_file: true - log_level: DEBUG # INFO or DEBUG or WARN + log_level: INFO # INFO or DEBUG or WARN telnetserver: true # not in use for now flexradiospot: true # not in use for now database: - mysql: true #only one of the two can be true - sqlite: false + mysql: false #only one of the two can be true + sqlite: true mysql_db_user: rouggy mysql_db_password: 89DGgg290379 mysql_db_name: log_f4bpo @@ -16,17 +16,17 @@ database: sqlite: sqlite_path: 'C:\Perso\Seafile\Radio\Logs\Log4OM\F4BPO.SQLite' # SQLite Db oath of Log4OM cluster: - server: dxc.sm7iun.se # dxc.k0xm.net dxc.sm7iun.se + server: cluster.f4bpo.com # dxc.k0xm.net dxc.sm7iun.se port: 7300 login: f4bpo password: 89DGgg - skimmer: true + skimmer: false ft8: false ft4: false - command: "SET/NOFILTER" #"SET/FILTER DOC/PASS EA,OH,G,F,DL,I,SV,9A,SK,S5,LX,OE,HA,CT" + command: "SET/FILTER DOC/PASS 1A,3A,4O,9A,9H,C3,CT,CU,DL,E7,EA,EA6,EI,ER,ES,EU,F,G,GD,GI,GJ,GM,GU,GW,HA,HB,HB0,HV,I,IS,IT9,JW,JX,LA,LX,LY,LZ,OE,OH,OH0,OJ0,OK,OM,ON,OY,OZ,PA,S5,SM,SP,SV,SV5,SV9,T7,TA1,TF,TK,UA,UR,YL,YO,YU,Z6,Z3,ZA,ZB" #"SET/FILTER DOC/PASS 1A,3A,4O,9A,9H,C3,CT,CU,DL,E7,EA,EA6,EI,ER,ES,EU,F,G,GD,GI,GJ,GM,GU,GW,HA,HB,HB0,HV,I,IS,IT9,JW,JX,LA,LX,LY,LZ,OE,OH,OH0,OJ0,OK,OM,ON,OY,OZ,PA,S5,SM,SP,SV,SV5,SV9,T7,TA1,TF,TK,UA,UR,YL,YO,YU,Z6,Z3,ZA,ZB" login_prompt: "login:" flex: - discovery: false # Radio must be on same LAN than the program + discovery: true # Radio must be on same LAN than the program ip: 82.67.157.19 # if discovery is true no need to put an IP spot_life: 600 #seconds telnetserver: # Log4OM must be connected to this server ie: localhost:7301 if on same machine as this program else ip:7301 diff --git a/country.xml b/country.xml index 799700f..5341e4e 100644 --- a/country.xml +++ b/country.xml @@ -9921,33 +9921,6 @@ - - VS2 - - AS - Malaya - 28 - - 28 - - 155 - 54 - 3 - - 54 - - 1.3 - 103.8 - false - - - - ^9M2.*|^VS2.* - - 1963-09-15T23:59:59Z - - - 8Q diff --git a/database.go b/database.go index 2190e48..9a6e6e0 100644 --- a/database.go +++ b/database.go @@ -145,9 +145,9 @@ func (r *Log4OMContactsRepository) ListByCountry(countryID string, contactsChan func (r *Log4OMContactsRepository) ListByCountryMode(countryID string, mode string, contactsModeChan chan []Contact, wg *sync.WaitGroup) { defer wg.Done() - if mode == "USB" || mode == "LSB" { + if mode == "USB" || mode == "LSB" || mode == "SSB" { - rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND (mode = ? OR mode = ?)", countryID, "USB", "LSB") + rows, err := r.db.Query("SELECT callsign, band, mode, dxcc, stationcallsign, country FROM log WHERE dxcc = ? AND (mode = ? OR mode = ? OR mode = ?)", countryID, "USB", "LSB", "SSB") if err != nil { log.Error("could not query database", err) } diff --git a/flexradio.go b/flexradio.go index e523841..00d2ae9 100644 --- a/flexradio.go +++ b/flexradio.go @@ -36,6 +36,7 @@ type FlexSpot struct { NewMode bool NewSlot bool Worked bool + CountryName string } type Discovery struct { @@ -167,6 +168,7 @@ func (fc *FlexClient) SendSpottoFlex(spot TelnetSpot) { NewMode: spot.NewMode, NewSlot: spot.NewSlot, Worked: spot.CallsignWorked, + CountryName: spot.CountryName, } flexSpot.Comment = flexSpot.Comment + " [" + flexSpot.Mode + "] [" + flexSpot.SpotterCallsign + "]" diff --git a/gotify.go b/gotify.go index b0ae1d5..c68f738 100644 --- a/gotify.go +++ b/gotify.go @@ -20,7 +20,7 @@ func Gotify(spot FlexSpot) { if Cfg.Gotify.Enable && !strings.Contains(ExceptionList, spot.DX) { - message := fmt.Sprintf("DX: %s\nFrom: %s\nFreq: %s\nMode: %s\nTime: %v\n", spot.DX, spot.SpotterCallsign, spot.FrequencyMhz, spot.Mode, spot.TimeStamp) + message := fmt.Sprintf("DX: %s\nFrom: %s\nFreq: %s\nMode: %s\nCountry: %s\nTime: %s\n", spot.DX, spot.SpotterCallsign, spot.FrequencyMhz, spot.Mode, spot.CountryName, spot.UTCTime) gotifyMsg := GotifyMessage{ Title: "", diff --git a/main.go b/main.go index e5e7b6b..4f5627b 100644 --- a/main.go +++ b/main.go @@ -54,6 +54,7 @@ func main() { // Load country.xml to get all the DXCC number Countries := LoadCountryFile() + log.Debug("XML Country File has been loaded properly.") // Database to keep track of all spots fRepo := NewFlexDXDatabase("flex.sqlite") diff --git a/spot.go b/spot.go index 089242a..e80ae45 100644 --- a/spot.go +++ b/spot.go @@ -17,6 +17,7 @@ type TelnetSpot struct { Band string Time string DXCC string + CountryName string Comment string CommandNumber int FlexSpotNumber int @@ -43,7 +44,9 @@ func ProcessTelnetSpot(re *regexp.Regexp, spotRaw string, SpotChanToFlex chan Te Time: match[6], } - spot.DXCC = GetDXCC(spot.DX, Countries) + DXCC := GetDXCC(spot.DX, Countries) + spot.DXCC = DXCC.DXCC + spot.CountryName = DXCC.CountryName if spot.DXCC == "" { Log.Errorf("Could not identify the DXCC for %s", spot.DX) diff --git a/xml.go b/xml.go index 10eee27..8033c11 100644 --- a/xml.go +++ b/xml.go @@ -75,7 +75,7 @@ func LoadCountryFile() Countries { return countries } -func GetDXCC(dxCall string, Countries Countries) string { +func GetDXCC(dxCall string, Countries Countries) DXCC { DXCCList := []DXCC{} d := DXCC{} @@ -130,10 +130,10 @@ func GetDXCC(dxCall string, Countries Countries) string { DXCCMatch = DXCCList[0] } - return DXCCMatch.DXCC + return DXCCMatch } else { Log.Errorf("Could not find %s in country list", dxCall) } - return "" + return DXCC{} }