Working video receiver

This commit is contained in:
2025-04-26 20:11:26 +03:00
parent 9d2db3672c
commit 51308a2395
5 changed files with 400 additions and 0 deletions

279
cmd/dev-client/main.go Normal file
View File

@ -0,0 +1,279 @@
package main
import (
"errors"
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2"
"io"
"net"
"os"
"syscall"
)
var mainPack *n9m.SmartPackage
var videoPack *n9m.SmartPackage
func main() {
conn, err := net.Dial("tcp", "10.100.100.99:9006")
if err != nil {
panic(err)
}
var pack = n9m.Package{}
pack.Payload.Module = "CERTIFICATE"
pack.Payload.Operation = "CONNECT"
pack.SetParameters(n9m.CertificateConnectClientRequest{})
conn.Write(pack.PackPackage())
handle(conn, &mainPack)
}
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.CertificateConnectClientResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
var response = n9m.CertificateVerificationRequest{
S0: GenerateVerifyKey(params.S0),
}
pack.Payload.Operation = "VERIFY"
pack.SetParameters(response)
sPack.Write(pack.PackPackage())
return
}
func handleVerify(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.CertificateVerificationResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
if params.ErrorCode == 0 {
fmt.Println("ШАЛОСТЬ УДАЛАСЬ!")
} else {
fmt.Println("шалость НЕ удалась(((")
}
var request = n9m.CertificateLoginRequest{
ClientID: 0,
MAC: "",
User: "admin",
Password: "",
}
pack.Payload.Operation = "LOGIN"
pack.SetParameters(request)
sPack.Write(pack.PackPackage())
return
}
func handleLogin(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.CertificateLoginResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
conn, err := net.Dial("tcp", "10.100.100.99:9006")
var request = n9m.CertificateCreateStreamRequest{
StreamName: "KRBL",
}
pack.Payload.Operation = "CREATESTREAM"
pack.SetParameters(request)
conn.Write(pack.PackPackage())
go handle(conn, &videoPack)
return
}
func handleCreateStream(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.CertificateCreateStreamResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
if params.ErrorCode != 0 {
fmt.Println("Create stream error:", params.ErrorCode, params.ErrorCause)
return
}
var request = n9m.MediaStreamModelRequestLiveVideoRequest{
StreamName: "KRBL",
StreamType: 2,
Channel: 1,
AudioValid: 1,
FrameMode: 0,
}
pack.Payload.Module = "MEDIASTREAMMODEL"
pack.Payload.Operation = "REQUESTALIVEVIDEO"
pack.SetParameters(request)
mainPack.Write(pack.PackPackage())
return
}
func handleRequestLiveVideo(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.MediaStreamModelRequestLiveVideoResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
if params.ErrorCode != 0 {
fmt.Println("Request live stream error:", params.ErrorCode, params.ErrorCause)
return
}
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)
var request n9m.ConfigModelSetRequest
if err = pack.GetParametersAs(&request); err != nil {
fmt.Println(err)
return err
}
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 handleSPI(_ *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.SpiParameters
if err = pack.GetParametersAs(&params); err != nil {
return
}
fmt.Printf("%+v\n", params)
return
}
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", "VERIFY", handleVerify)
pack.AddJSONHandler("CERTIFICATE", "LOGIN", handleLogin)
pack.AddJSONHandler("CERTIFICATE", "CREATESTREAM", handleCreateStream)
pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive)
pack.AddJSONHandler("MEDIASTREAMMODEL", "REQUESTALIVEVIDEO", handleRequestLiveVideo)
pack.AddJSONHandler("CONFIGMODEL", "GET", handleGetConfig)
pack.AddJSONHandler("DEVEMM", "SPI", handleSPI)
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 **n9m.SmartPackage) {
if pack != nil {
*pack = createSmartPackage(conn)
} else {
tmp := createSmartPackage(conn)
pack = &tmp
}
var err error
for {
if err = (*pack).Handle(); err != nil {
fmt.Println("Error:", err)
if isNetConnClosedErr(err) {
return
}
}
}
}

15
cmd/dev-client/utils.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"crypto/hmac"
"crypto/md5"
"encoding/hex"
)
func GenerateVerifyKey(key string) string {
mac := hmac.New(md5.New, []byte(key))
mac.Write([]byte(key))
return hex.EncodeToString(mac.Sum(nil))
}

View File

@ -0,0 +1,9 @@
package main
import "testing"
func TestGenerateVerifyKey(t *testing.T) {
if GenerateVerifyKey("45792d55-0844-4053-848a-64fd0685fb32") != "fae5f19b8452c7bd03dc4f3471966c42" {
t.Error()
}
}