2024-10-21 21:03:22 +02:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/binary"
|
2024-10-21 21:49:06 +02:00
|
|
|
"fmt"
|
2024-10-21 21:03:22 +02:00
|
|
|
"io"
|
2024-10-21 21:49:06 +02:00
|
|
|
"net"
|
|
|
|
"sync"
|
2024-10-21 21:03:22 +02:00
|
|
|
|
|
|
|
"git.espin.casa/albert/cml04-falcon-system/labeler/service"
|
2024-10-21 21:49:06 +02:00
|
|
|
"git.espin.casa/albert/logger"
|
2024-10-21 21:03:22 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
type Header struct {
|
2024-10-21 21:49:06 +02:00
|
|
|
MessageLength int16
|
2024-10-21 21:03:22 +02:00
|
|
|
TelegramID int16
|
|
|
|
SequenceCounter int16
|
|
|
|
Flags int16
|
|
|
|
TimeStamp [8]int16
|
|
|
|
}
|
|
|
|
|
|
|
|
type LabelData struct {
|
|
|
|
Header Header
|
|
|
|
DateTime [23]byte
|
|
|
|
L2PackageId int16
|
|
|
|
L3PackageId [6]byte
|
|
|
|
ProductionOrderNo int32
|
|
|
|
CustomerOrderNo int32
|
|
|
|
CustomerName [30]byte
|
|
|
|
LogoCode [3]byte
|
|
|
|
SteelGrade [15]byte
|
|
|
|
MaterialCode [18]byte
|
|
|
|
HeatId [10]byte
|
|
|
|
SectionType [20]byte
|
|
|
|
PackageDimensions [3]float32
|
|
|
|
PackageWeight float32
|
|
|
|
SectionDimensions [3]float32
|
|
|
|
NumberSections int32
|
|
|
|
NumberLayers int32
|
|
|
|
NumberSectionsInLayer int32
|
|
|
|
FreeTxtLp [180]byte
|
|
|
|
}
|
|
|
|
|
2024-10-21 21:49:06 +02:00
|
|
|
func (l *LabelData) FillTelegram(reader io.Reader) (int, error) {
|
|
|
|
// Read into the LabelData struct and return the number of bytes read
|
|
|
|
err := binary.Read(reader, binary.LittleEndian, l)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2024-10-21 21:03:22 +02:00
|
|
|
}
|
2024-10-21 21:49:06 +02:00
|
|
|
// Calculate total number of bytes read based on struct size
|
|
|
|
labelDataSize := binary.Size(l)
|
|
|
|
return labelDataSize, nil
|
2024-10-21 21:03:22 +02:00
|
|
|
}
|
|
|
|
|
2024-10-21 21:49:06 +02:00
|
|
|
type Server struct {
|
|
|
|
address string
|
|
|
|
svc service.Service
|
|
|
|
mu sync.Mutex
|
|
|
|
log logger.LoggerAdapter
|
|
|
|
}
|
2024-10-21 21:03:22 +02:00
|
|
|
|
2024-10-21 21:49:06 +02:00
|
|
|
// Start begins the TCP server and listens for incoming connections
|
2024-10-21 21:03:22 +02:00
|
|
|
func (s *Server) Start() error {
|
2024-10-21 21:49:06 +02:00
|
|
|
listener, err := net.Listen("tcp", s.address)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to start server: %v", err)
|
|
|
|
}
|
|
|
|
defer listener.Close()
|
|
|
|
s.log.Info("server is listening", logger.LogFields{
|
|
|
|
"address": s.address,
|
|
|
|
})
|
|
|
|
for {
|
|
|
|
conn, err := listener.Accept()
|
|
|
|
if err != nil {
|
|
|
|
s.log.Error("accepting connections failed", err, logger.LogFields{})
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
// Handle the connection concurrently
|
|
|
|
go s.handleConnection(conn)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// handleConnection reads telegram data from the TCP connection and keeps the connection open
|
|
|
|
func (s *Server) handleConnection(conn net.Conn) {
|
|
|
|
defer conn.Close()
|
|
|
|
s.log.Info("new connection", logger.LogFields{
|
|
|
|
"from": conn.RemoteAddr(),
|
|
|
|
})
|
|
|
|
|
|
|
|
for {
|
|
|
|
// Initialize LabelData struct to hold the incoming telegram
|
|
|
|
var labelData LabelData
|
2024-10-21 21:03:22 +02:00
|
|
|
|
2024-10-21 21:49:06 +02:00
|
|
|
// Read the telegram from the connection and track the number of bytes read
|
|
|
|
bytesRead, err := labelData.FillTelegram(conn)
|
|
|
|
if err != nil {
|
|
|
|
// If the client disconnects or there's a read error, exit the loop
|
|
|
|
if err == io.EOF {
|
|
|
|
s.log.Info("client disconnected", logger.LogFields{"client": conn.RemoteAddr()})
|
|
|
|
break
|
|
|
|
}
|
|
|
|
s.log.Error("reading telegram failed", err, logger.LogFields{})
|
|
|
|
continue // Keep reading from the connection
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if TelegramID is 6500, if not discard but keep connection
|
|
|
|
if labelData.Header.TelegramID != 6500 {
|
|
|
|
s.log.Error("invalid telegram id", fmt.Errorf("invalid telegram"), logger.LogFields{
|
|
|
|
"id": labelData.Header.TelegramID,
|
|
|
|
"from": conn.RemoteAddr(),
|
|
|
|
})
|
|
|
|
continue // Discard the content but keep reading from the connection
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if MessageLength matches the data received
|
|
|
|
if labelData.Header.MessageLength != int16(bytesRead) {
|
|
|
|
fmt.Printf("MessageLength mismatch: expected %d, got %d bytes from %s\n", labelData.Header.MessageLength, bytesRead, conn.RemoteAddr())
|
|
|
|
continue // Discard the content but keep reading from the connection
|
|
|
|
}
|
|
|
|
|
|
|
|
// Locking if necessary when interacting with shared resources (svc, etc.)
|
|
|
|
s.mu.Lock()
|
|
|
|
// Process the valid telegram
|
|
|
|
s.log.Info("received valid label data", logger.LogFields{"from": conn.RemoteAddr()})
|
|
|
|
fmt.Printf("label: %+v\n", labelData)
|
|
|
|
s.mu.Unlock()
|
|
|
|
|
|
|
|
// Continue reading next telegrams from this connection
|
|
|
|
}
|
2024-10-21 21:03:22 +02:00
|
|
|
}
|
|
|
|
|
2024-10-21 21:49:06 +02:00
|
|
|
// New creates a new Server instance
|
|
|
|
func New(address string, svc service.Service, log logger.LoggerAdapter) *Server {
|
|
|
|
return &Server{
|
|
|
|
address: address,
|
|
|
|
svc: svc,
|
|
|
|
mu: sync.Mutex{},
|
|
|
|
log: log,
|
|
|
|
}
|
2024-10-21 21:03:22 +02:00
|
|
|
}
|