package services import ( "crypto/tls" "encoding/json" "fmt" "io/ioutil" "log" "os" "strconv" appConfig "github.com/xmpploadtesting/config" "gosrc.io/xmpp" "gosrc.io/xmpp/stanza" ) const rolingStockPresenceMessage = `ROLLING STOCK PRESENCE MESSAGE\n { "serial": "79101X02Y0029450001CJ2000", "model": "VEN032FSNWM00", "displayOrientation": "left", "macAddress": "1c:c0:e1:42:5a:c4", "node": "v8.16.2", "nodeJS": "v8.16.2", "fbi": "2.10-2ubuntu1", "libgif7": "5.1.4-2ubuntu0.1", "bsEdgeServer": "13.3.9-1", "initopciVersion": "0.4~24", "bspInstallVersion": "1.0~36", "awsConfigsVersion": "2021.21.26-e7c5738", "outGuard": "2021.36.23-dev-028972a", "val": "1.1.11~129", "broadSignPlayer": "13.3.9-1", "displayUnitExternalID": "L-0141-M7-7281-Right-3SM-G02-02-79101X02Y0020040003EJ2001", "privateIPaddress": "10.1.1.94", "linux": { "os": "Ubuntu 18.04.2 LTS", "kernel": "4.18.20+10+opci", "architecture": "x86-64" }, "digiID": "digi-00000000-00000000-0040FFFF-FF801D30" }` // XMPPService - struct containing type XMPPService struct { Router *xmpp.Router XMPPClients []XMPPClient } // XMPPClient - struct containing client and client configuration type XMPPClient struct { Config xmpp.Config Client *xmpp.Client } // ClientCredentials - credentials info for client configuration type ClientCredentials struct { Jid string `json:"username"` Credential string `json:"password"` Host string `json:"host"` Port int `json:"port"` Ping int `json:"ping"` } // Instance - get instance of xmpp service func Instance() *XMPPService { return &xmppService } var xmppService XMPPService // Init Initialise XMPP servie, and router func Init() { xmppService = XMPPService{ Router: xmpp.NewRouter(), } xmppService.Router.HandleFunc("message", handleMessage) //Get Client credentials from file clientCredentials, err := getClientConfigsFromFile(appConfig.AppConfig.Credentials.CredentialsFileLocation) if err != nil { log.Fatalf("Unable to load credentials from file path %v, ERROR : %v TERMINATING", appConfig.AppConfig.Credentials.CredentialsFileLocation, err) } log.Printf("Client credentials length %v", len(clientCredentials)) xmppService.XMPPClients = make([]XMPPClient, 0) for _, credential := range clientCredentials { log.Printf("Host %v", credential.Host+":"+strconv.Itoa(credential.Port)) log.Printf("Jid %v", credential.Jid+"@"+credential.Host) log.Printf("Port %v", credential.Port) log.Printf("Credential %v", credential.Credential) xmppClient := XMPPClient{ Config: xmpp.Config{ TransportConfiguration: xmpp.TransportConfiguration{ Address: credential.Host + ":" + strconv.Itoa(credential.Port), Domain: credential.Host, TLSConfig: &tls.Config{InsecureSkipVerify: true}, }, Jid: credential.Jid + "@" + credential.Host, Credential: xmpp.Password(credential.Credential), StreamLogger: os.Stdout, Insecure: true, }, } go func() { client, err := xmpp.NewClient(&xmppClient.Config, xmppService.Router, errorHandler) // Client connection if err := client.Connect(); err != nil { msg := fmt.Sprintf("XMPP connection failed: %v", err) fmt.Printf("Failed to connect to server. Exiting... %v", msg) return } if err != nil { log.Printf("Unable to initialise client for %v", xmppClient.Config.Jid) } xmppClient.Client = client xmppService.XMPPClients = append(xmppService.XMPPClients, xmppClient) }() } } // SendOnlinePresenceStanza - send online presence stnza with data, to server func SendOnlinePresenceStanza(client *xmpp.Client, jid string) error { onlinePresencePacket := stanza.NewPresence(stanza.Attrs{From: jid, Type: stanza.StanzaType(stanza.PresenceShowChat)}) onlinePresencePacket.Status = rolingStockPresenceMessage err := client.Send(onlinePresencePacket) log.Printf("Sending online presence stanza: %v", err) return err } func getClientConfigsFromFile(filePath string) ([]ClientCredentials, error) { var clientCredentials []ClientCredentials f, err := os.Open(filePath) if err != nil { return clientCredentials, err } defer f.Close() byteValue, err := ioutil.ReadAll(f) if err != nil { return clientCredentials, err } err = json.Unmarshal(byteValue, &clientCredentials) if err != nil { return clientCredentials, err } return clientCredentials, nil } func handleMessage(s xmpp.Sender, p stanza.Packet) { log.Printf("Handle message") msg, ok := p.(stanza.Message) if !ok { log.Printf(" message not OK") _, _ = fmt.Fprintf(os.Stdout, "Ignoring packet: %T\n", p) return } log.Printf("Received The message %v", msg) _, _ = fmt.Fprintf(os.Stdout, "Body = %s - from = %s\n", msg.Body, msg.From) reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: `{"status": "OK"}`} err := s.Send(reply) if err != nil { log.Printf("Error sending to %v message %v", msg.From, err) } } func errorHandler(err error) { fmt.Println(err.Error()) }