Working video receiver
This commit is contained in:
279
cmd/dev-client/main.go
Normal file
279
cmd/dev-client/main.go
Normal 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(¶ms); 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(¶ms); 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(¶ms); 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(¶ms); 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(¶ms); 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(¶ms); 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
15
cmd/dev-client/utils.go
Normal 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))
|
||||
}
|
9
cmd/dev-client/utils_test.go
Normal file
9
cmd/dev-client/utils_test.go
Normal file
@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGenerateVerifyKey(t *testing.T) {
|
||||
if GenerateVerifyKey("45792d55-0844-4053-848a-64fd0685fb32") != "fae5f19b8452c7bd03dc4f3471966c42" {
|
||||
t.Error()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user