package lockserver import ( "bufio" // "io" "fmt" "net" "net/url" "strings" "time" log "github.com/sirupsen/logrus" ) // DoorCardRequest is the JSON payload for /issue-door-card. type DoorCardRequest struct { RoomField string `json:"roomField"` CheckinTime string `json:"checkinTime"` CheckoutTime string `json:"checkoutTime"` FollowStr string `json:"followStr"` } const ( AssaAbloy = "assaabloy" Omnitec = "omnitec" Salto = "salto" TLJ = "tlj" ) var ( Cert string LockServerURL string ) type ( LockServer interface { BuildCommand(doorReq DoorCardRequest, checkIn, checkOut time.Time) error LockSequence() error } AssaLockServer struct { encoderAddr string command string } OmniLockServer struct { encoderAddr string // Encoder unit address command []byte // Command to be sent to the lock server } SaltoLockServer struct { encoderAddr string command []byte } TLJLockServer struct { encoderAddr string command string } ) func NewLockServer(lockType, encoderAddr string, fatalError func(error)) LockServer { switch strings.ToLower(lockType) { case AssaAbloy: return &AssaLockServer{encoderAddr: encoderAddr} case Omnitec: return &OmniLockServer{encoderAddr: encoderAddr} case Salto: return &SaltoLockServer{encoderAddr: encoderAddr} case TLJ: return &TLJLockServer{encoderAddr: encoderAddr} default: fatalError(fmt.Errorf("unsupported LockType: %s; must be 'assaabloy' or 'omnitec'", lockType)) return nil // This line will never be reached, but is needed to satisfy the compiler } } func InitializeServerConnection(LockserverUrl string) (net.Conn, error) { const funcName = "InitializeServerConnection" // Parse the URL to extract host and port parsedUrl, err := url.Parse(LockserverUrl) if err != nil { return nil, fmt.Errorf("[%s] failed to parse LockserverUrl: %v", funcName, err) } // Remove any leading/trailing slashes just in case address := strings.Trim(parsedUrl.Host, "/") // Establish a TCP connection to the Visionline server conn, err := net.Dial("tcp", address) if err != nil { return nil, fmt.Errorf("failed to connect to lock server: %v", err) } return conn, nil } // sendAndReceive sends a command to the lock server and waits for a response. func sendAndReceive(conn net.Conn, command []byte) (string, error) { log.Printf("Sending command: %q", command) _, err := conn.Write(command) if err != nil { return "", fmt.Errorf("failed to send command: %v", err) } conn.SetReadDeadline(time.Now().Add(10 * time.Second)) buf := make([]byte, 128) reader := bufio.NewReader(conn) n, err := reader.Read(buf) if err != nil { return "", fmt.Errorf("error reading response: %v", err) } response := buf[:n] return string(response), nil }