package main import ( "errors" "fmt" "gitea.unprism.ru/KRBL/n9m" "io" "net" "os" "syscall" ) func main() { ln, err := net.Listen("tcp", "0.0.0.0:5556") if err != nil { panic(err) } for { var conn net.Conn conn, err = ln.Accept() if err != nil { continue } go handle(conn) } } func handleSpecialPackages(_ *n9m.SmartPackage, pack n9m.Package) error { switch pack.SSRC { case n9m.SpecialPayloadTypeGPS: fmt.Printf("%+v\n", pack.GPS) return nil default: return fmt.Errorf("unhandled special operation: %d", pack.SSRC) } } func handleCertificateConnect(sPack *n9m.SmartPackage, pack n9m.Package) (err error) { var params n9m.CertificateConnectRequest if err = pack.GetParametersAs(¶ms); err != nil { return fmt.Errorf("failed to get parameters: %w", err) } var response = n9m.CertificateConnectResponse{ ErrorCode: 0, CommandMask: n9m.CommandMaskAll, } pack.SetResponse(response) if _, err = sPack.Write(pack.PackPackage()); err != nil { return fmt.Errorf("failed to write package: %w", err) } fmt.Println("Connected:", params.SerialNumber) sPack.Storage["serial"] = params.SerialNumber var request n9m.ConfigModelGetRequest request.MDVR = "?" pack.Payload.Module = "CONFIGMODEL" pack.Payload.Operation = "GET" pack.SetParameters(request) sPack.Write(pack.PackPackage()) return } func handleKeepAlive(sPack *n9m.SmartPackage, pack n9m.Package) (err error) { serial := sPack.Storage["serial"] fmt.Println(serial, "still alive!") pack.SetResponse(nil) sPack.Write(pack.PackPackage()) return } func handleGetConfig(sPack *n9m.SmartPackage, pack n9m.Package) (err error) { serial := sPack.Storage["serial"] os.WriteFile(fmt.Sprintf("./%s.json", serial), pack.RawPayload, 0644) return } func handleUselessAlarms(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) { return nil } func handleVideoLossAlarm(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) { fmt.Println("Video loss alarm!") return nil } func handleCameraCoveredAlarm(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) { fmt.Println("Camera covered alarm!") return nil } func createSmartPackage(conn net.Conn) (pack *n9m.SmartPackage) { pack = n9m.NewSmartPackage(conn) pack.AddPayloadHandler(n9m.PayloadTypeSpecial, handleSpecialPackages) pack.AddJSONHandler("CERTIFICATE", "CONNECT", handleCertificateConnect) pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive) pack.AddJSONHandler("CONFIGMODEL", "GET", handleGetConfig) pack.AddAlarmHandler(n9m.AlarmTypeMotionDetection, handleUselessAlarms) pack.AddAlarmHandler(n9m.AlarmTypeVideoLoss, handleVideoLossAlarm) pack.AddAlarmHandler(n9m.AlarmTypeCameraCovered, handleCameraCoveredAlarm) return } /* go func() { pack := packS pack.Payload.Module = "EVEM" pack.Payload.Operation = "GALARMING" ticker := time.NewTicker(5 * time.Second) defer ticker.Stop() for range ticker.C { fmt.Println("Sent!") if _, err := conn.Write(pack.PackPackage()); err != nil { fmt.Println("Failed to send GALARMING:", err) return } } }() */ func isNetConnClosedErr(err error) bool { switch { case errors.Is(err, net.ErrClosed), errors.Is(err, io.EOF), errors.Is(err, syscall.EPIPE): return true default: return false } } func handle(conn net.Conn) { pack := createSmartPackage(conn) var err error for { if err = pack.Handle(); err != nil { fmt.Println("Error:", err) if isNetConnClosedErr(err) { return } } } }