n9m/cmd/dev-server/main.go
Alexander Lazarenko eaaa634558
Refactor and simplify package structure and interfaces.
Reorganize code by removing unused files, restructuring package organization, and updating import references to new paths. This simplifies handling of smart and protocol-related operations, improves maintainability, and eliminates redundancy.
2025-04-27 17:05:45 +03:00

192 lines
4.1 KiB
Go

package main
import (
"errors"
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/models"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/smart"
"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(_ *smart.SmartPackage, pack protocol.Package) error {
switch pack.SSRC {
case protocol.SpecialPayloadTypeGPS:
fmt.Printf("%+v\n", pack.GPS)
return nil
default:
return fmt.Errorf("unhandled special operation: %d", pack.SSRC)
}
}
func handleCertificateConnect(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.CertificateConnectRequest
if err = pack.GetParametersAs(&params); err != nil {
return fmt.Errorf("failed to get parameters: %w", err)
}
var response = models.CertificateConnectResponse{
ErrorCode: 0,
CommandMask: models.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 models.ConfigModelGetRequest
request.MDVR = "?"
pack.Payload.Module = "CONFIGMODEL"
pack.Payload.Operation = "GET"
pack.SetParameters(request)
sPack.Write(pack.PackPackage())
return
}
func handleKeepAlive(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
serial := sPack.Storage["serial"]
fmt.Println(serial, "still alive!")
pack.SetResponse(nil)
sPack.Write(pack.PackPackage())
return
}
func handleGetConfig(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
serial := sPack.Storage["serial"]
os.WriteFile(fmt.Sprintf("./%s.json", serial), pack.RawPayload, 0644)
var request models.ConfigModelSetRequest
if err = pack.GetParametersAs(&request); err != nil {
fmt.Println(err)
return err
}
return
}
func handleUselessAlarms(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
return nil
}
func handleVideoLossAlarm(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
fmt.Println("Video loss alarm!")
return nil
}
func handleCameraCoveredAlarm(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
fmt.Println("Camera covered alarm!")
return nil
}
func handleSPI(_ *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.SpiParameters
if err = pack.GetParametersAs(&params); err != nil {
return
}
fmt.Printf("%+v\n", params)
return
}
func createSmartPackage(conn net.Conn) (pack *smart.SmartPackage) {
pack = smart.NewSmartPackage(conn)
pack.AddPayloadHandler(protocol.PayloadTypeSpecial, handleSpecialPackages)
pack.AddJSONHandler("CERTIFICATE", "CONNECT", handleCertificateConnect)
pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive)
pack.AddJSONHandler("CONFIGMODEL", "GET", handleGetConfig)
pack.AddJSONHandler("DEVEMM", "SPI", handleSPI)
pack.AddAlarmHandler(protocol.AlarmTypeMotionDetection, handleUselessAlarms)
pack.AddAlarmHandler(protocol.AlarmTypeVideoLoss, handleVideoLossAlarm)
pack.AddAlarmHandler(protocol.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
}
}
}
}