2025-02-22 16:23:16 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2025-02-22 18:15:03 +00:00
|
|
|
"errors"
|
2025-02-22 16:23:16 +00:00
|
|
|
"fmt"
|
|
|
|
"gitea.unprism.ru/KRBL/n9m"
|
2025-02-22 18:15:03 +00:00
|
|
|
"io"
|
2025-02-22 16:23:16 +00:00
|
|
|
"net"
|
|
|
|
"os"
|
2025-02-22 18:15:03 +00:00
|
|
|
"syscall"
|
2025-02-22 16:23:16 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2025-02-22 16:23:16 +00:00
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
func handleCertificateConnect(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
|
|
|
|
var params n9m.CertificateConnectRequest
|
2025-02-22 16:23:16 +00:00
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
if err = pack.GetParametersAs(¶ms); err != nil {
|
|
|
|
return fmt.Errorf("failed to get parameters: %w", err)
|
|
|
|
}
|
2025-02-22 16:23:16 +00:00
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
var response = n9m.CertificateConnectResponse{
|
|
|
|
ErrorCode: 0,
|
|
|
|
CommandMask: n9m.CommandMaskAll,
|
|
|
|
}
|
2025-02-22 16:23:16 +00:00
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
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
|
|
|
|
}
|
2025-02-22 16:23:16 +00:00
|
|
|
}
|
2025-02-22 18:15:03 +00:00
|
|
|
}()
|
|
|
|
*/
|
|
|
|
|
|
|
|
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)
|
2025-02-22 16:23:16 +00:00
|
|
|
|
2025-02-22 18:15:03 +00:00
|
|
|
if isNetConnClosedErr(err) {
|
|
|
|
return
|
2025-02-22 16:23:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|