5 Commits

Author SHA1 Message Date
4c631db418 Добавен новый раздел настроек и добавлены комментарии к некоторым другим разделам 2025-05-17 19:10:22 +03:00
26f354d82d Remove unused counter logic in live source callback
The incrementing counter and related condition were unnecessary and have been removed. This simplifies the callback function and improves code clarity without altering functionality.
2025-05-16 17:43:51 +03:00
edc86fb706 Added auto channel creation 2025-04-28 17:10:27 +03:00
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
51308a2395 Working video receiver 2025-04-26 20:11:26 +03:00
23 changed files with 915 additions and 327 deletions

View File

@ -1 +0,0 @@
# N9M

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

@ -0,0 +1,256 @@
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"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/utils"
"io"
"net"
"os"
"syscall"
)
var videoPack *smart.SmartChannelPackage
func main() {
conn, err := net.Dial("tcp", "10.100.100.99:9006")
if err != nil {
panic(err)
}
var pack = protocol.Package{}
pack.Payload.Module = "CERTIFICATE"
pack.Payload.Operation = "CONNECT"
pack.SetParameters(models.CertificateConnectClientRequest{})
conn.Write(pack.PackPackage())
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 handleLivePackages(_ *smart.SmartPackage, pack protocol.Package) error {
fmt.Printf("%+v\n", pack)
return nil
}
func handleCertificateConnect(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.CertificateConnectClientResponse
if err = pack.GetResponseAs(&params); err != nil {
return fmt.Errorf("failed to get response: %w", err)
}
var response = models.CertificateVerificationRequest{
S0: utils.GenerateVerifyKey(params.S0),
}
pack.Payload.Operation = "VERIFY"
pack.SetParameters(response)
sPack.Write(pack.PackPackage())
return
}
func handleVerify(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.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 = models.CertificateLoginRequest{
ClientID: 0,
MAC: "",
User: "admin",
Password: "",
}
pack.Payload.Operation = "LOGIN"
pack.SetParameters(request)
sPack.Write(pack.PackPackage())
return
}
func handleLogin(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.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")
if err != nil {
panic(err)
}
videoPack, err = smart.NewSmartChannelPackage(conn, sPack)
if err != nil {
panic(err)
}
go videoPack.Run()
videoPack.AddLiveSource(2, func(data []byte) error {
fmt.Println("Есть контакт!")
return nil
})
var request = models.MediaStreamModelRequestLiveVideoRequest{
StreamName: videoPack.GetChannelName(),
StreamType: models.StreamTypeMain,
Channel: 4,
AudioValid: 4,
FrameMode: 0,
}
pack.Payload.Module = "MEDIASTREAMMODEL"
pack.Payload.Operation = "REQUESTALIVEVIDEO"
pack.SetParameters(request)
sPack.Write(pack.PackPackage())
return
}
func handleRequestLiveVideo(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.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
}
fmt.Printf("%+v\n", params)
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.PayloadTypeLive, handleLivePackages)
pack.AddPayloadHandler(protocol.PayloadTypeSpecial, handleSpecialPackages)
pack.AddJSONHandler("CERTIFICATE", "CONNECT", handleCertificateConnect)
pack.AddJSONHandler("CERTIFICATE", "VERIFY", handleVerify)
pack.AddJSONHandler("CERTIFICATE", "LOGIN", handleLogin)
pack.AddJSONHandler("CERTIFICATE", "KEEPALIVE", handleKeepAlive)
pack.AddJSONHandler("MEDIASTREAMMODEL", "REQUESTALIVEVIDEO", handleRequestLiveVideo)
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
}
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
}
}
}
}

View File

@ -3,7 +3,9 @@ package main
import (
"errors"
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2"
"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"
@ -30,9 +32,9 @@ func main() {
}
}
func handleSpecialPackages(_ *n9m.SmartPackage, pack n9m.Package) error {
func handleSpecialPackages(_ *smart.SmartPackage, pack protocol.Package) error {
switch pack.SSRC {
case n9m.SpecialPayloadTypeGPS:
case protocol.SpecialPayloadTypeGPS:
fmt.Printf("%+v\n", pack.GPS)
return nil
default:
@ -40,16 +42,16 @@ func handleSpecialPackages(_ *n9m.SmartPackage, pack n9m.Package) error {
}
}
func handleCertificateConnect(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.CertificateConnectRequest
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 = n9m.CertificateConnectResponse{
var response = models.CertificateConnectResponse{
ErrorCode: 0,
CommandMask: n9m.CommandMaskAll,
CommandMask: models.CommandMaskAll,
}
pack.SetResponse(response)
@ -61,7 +63,7 @@ func handleCertificateConnect(sPack *n9m.SmartPackage, pack n9m.Package) (err er
fmt.Println("Connected:", params.SerialNumber)
sPack.Storage["serial"] = params.SerialNumber
var request n9m.ConfigModelGetRequest
var request models.ConfigModelGetRequest
request.MDVR = "?"
pack.Payload.Module = "CONFIGMODEL"
@ -73,7 +75,7 @@ func handleCertificateConnect(sPack *n9m.SmartPackage, pack n9m.Package) (err er
return
}
func handleKeepAlive(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
func handleKeepAlive(sPack *smart.SmartPackage, pack protocol.Package) (err error) {
serial := sPack.Storage["serial"]
fmt.Println(serial, "still alive!")
@ -83,12 +85,12 @@ func handleKeepAlive(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
return
}
func handleGetConfig(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
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 n9m.ConfigModelSetRequest
var request models.ConfigModelSetRequest
if err = pack.GetParametersAs(&request); err != nil {
fmt.Println(err)
@ -98,22 +100,22 @@ func handleGetConfig(sPack *n9m.SmartPackage, pack n9m.Package) (err error) {
return
}
func handleUselessAlarms(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) {
func handleUselessAlarms(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
return nil
}
func handleVideoLossAlarm(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) {
func handleVideoLossAlarm(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
fmt.Println("Video loss alarm!")
return nil
}
func handleCameraCoveredAlarm(sPack *n9m.SmartPackage, pack n9m.Package, response n9m.SendAlarmInfoResponse) (err error) {
func handleCameraCoveredAlarm(sPack *smart.SmartPackage, pack protocol.Package, response models.SendAlarmInfoResponse) (err error) {
fmt.Println("Camera covered alarm!")
return nil
}
func handleSPI(_ *n9m.SmartPackage, pack n9m.Package) (err error) {
var params n9m.SpiParameters
func handleSPI(_ *smart.SmartPackage, pack protocol.Package) (err error) {
var params models.SpiParameters
if err = pack.GetParametersAs(&params); err != nil {
return
@ -124,20 +126,20 @@ func handleSPI(_ *n9m.SmartPackage, pack n9m.Package) (err error) {
return
}
func createSmartPackage(conn net.Conn) (pack *n9m.SmartPackage) {
pack = n9m.NewSmartPackage(conn)
func createSmartPackage(conn net.Conn) (pack *smart.SmartPackage) {
pack = smart.NewSmartPackage(conn)
pack.AddPayloadHandler(n9m.PayloadTypeSpecial, handleSpecialPackages)
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(n9m.AlarmTypeMotionDetection, handleUselessAlarms)
pack.AddAlarmHandler(protocol.AlarmTypeMotionDetection, handleUselessAlarms)
pack.AddAlarmHandler(n9m.AlarmTypeVideoLoss, handleVideoLossAlarm)
pack.AddAlarmHandler(n9m.AlarmTypeCameraCovered, handleCameraCoveredAlarm)
pack.AddAlarmHandler(protocol.AlarmTypeVideoLoss, handleVideoLossAlarm)
pack.AddAlarmHandler(protocol.AlarmTypeCameraCovered, handleCameraCoveredAlarm)
return
}

190
evem.go
View File

@ -1,190 +0,0 @@
package n9m
// 3.4.1.3
type EventModelGetAlarmStatusInfoResponse struct {
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
StorageErrors []StorageErrorStatus `json:"ST"`
AnotherStorageErrors []AnotherStorageErrorStatus `json:"VS"`
VideoLossErrors []VideoLossErrorStatus `json:"VL"`
GPSError GPSErrorStatus `json:"GFA"`
GPSAntennaError GPSAntennaErrorStatus `json:"GPSS"`
}
// 3.4.1.4.21
type StorageErrorStatus struct {
CameraCovered uint `json:"ISA"`
ChannelBind uint `json:"LHC"`
}
// 3.4.1.4.4
type AnotherStorageErrorStatus struct {
}
// 3.4.1.4.5
type VideoLossErrorStatus struct {
}
// 3.4.1.4.44
type GPSErrorStatus struct {
}
// 3.4.1.4.46
type GPSAntennaErrorStatus struct {
}
// 3.4.1.5
// Alarm upload
type SendAlarmInfoParameters struct {
AlarmType AlarmType `json:"ALARMTYPE"`
CommandType uint `json:"CMDTYPE"`
AlarmUID uint `json:"ALARMUID"`
NumberOfRestarts uint `json:"RUN"`
AlarmLevel AlarmLevel `json:"ALARMAS"`
AlarmCount uint `json:"ALARMCOUNT"`
TriggerType TriggerType `json:"TRIGGERTYPE"`
ContinueTime uint `json:"CONTINUETIME"`
CurrentTime uint `json:"CURRENTTIME"`
Language Language `json:"L"`
GPSData GPSData `json:"P"`
RealTimeUpload uint `json:"REAL"`
InstructionSerial uint `json:"CMDNO"`
}
// 3.4.1.5
// Alarm upload
type SendAlarmInfoResponse struct {
ErrorCode uint `json:"ERRORCODE"`
AlarmType AlarmType `json:"ALARMTYPE"`
ErrorCause string `json:"ERRORCAUSE"`
CommandType uint `json:"CMDTYPE"`
AlarmUID uint `json:"ALARMUID"`
NumberOfRestarts uint `json:"RUN"`
InstructionSerial uint `json:"CMDNO"`
}
// 3.4.1.5.1
type SendAlarmInfoCameraParameters struct {
SendAlarmInfoParameters
Channel uint `json:"CHANNEL"`
ChannelMask uint `json:"CHANNELMASK"`
LCH []uint `json:"LCH"`
Push uint `json:"PUSH"`
AlarmName string `json:"ALARMNAME"`
AlarmAbbreviation string `json:"SER"`
}
type AlarmType uint
const (
AlarmTypeVideoLoss AlarmType = iota
AlarmTypeCameraCovered
AlarmTypeMotionDetection
AlarmTypeStorageAbnormal
AlarmTypeUserDefined
AlarmTypeSentriesInspection
AlarmTypeViolation
AlarmTypeEmergency
AlarmTypeSpeedAlarm
AlarmTypeLowVoltage
AlarmTypeOutOfFence = iota + 7
AlarmTypeAccAlarm
AlarmTypePeripheralsDropped
AlarmTypeStopAnnouncement
AlarmTypeGpsAntenna
AlarmTypeDayNightSwitch
AlarmTypeProhibitDriving
AlarmTypeSerialAlarm = iota + 15
AlarmTypeFatigueAlarm
AlarmTypeTakeOutParking
AlarmTypeGestureAlarm
AlarmTypeGreenDriving
AlarmTypeIllegalIgnition
AlarmTypeIllegalShutdown
AlarmTypeCustomExternal
AlarmTypeThinkingLKJ
AlarmTypeTAX3
AlarmTypeOilAlarm
AlarmTypeBusLineOccupation
AlarmTypeForgottenAlarm
AlarmTypeSpecialCustomerFault
AlarmTypeTemperatureAbnormal
AlarmTypeTemperatureChangeAbnormal
AlarmTypeSmokeAlarm
AlarmTypeGBox
AlarmTypeLicensePlateRecognition
AlarmTypeAnotherSpeedAlarm
AlarmTypeWirelessSignalAbnormal
AlarmTypeArming
AlarmTypePhoneCall
AlarmTypeGPSFault
AlarmTypeDSMFault
AlarmTypeFireBox
)
type AlarmLevel uint
const (
AlarmLevelImportant AlarmLevel = iota
AlarmLevelGeneral
AlarmLevelEmergency
)
type TriggerType uint
const (
TriggerTypeManual TriggerType = iota
TriggerTypeAutomatic
)
type Language uint
const (
LanguageSimplifiedChinese Language = iota
LanguageEnglish
LanguageKorean
LanguageItalian
LanguageGerman
LanguageThai
LanguageTurkey
LanguagePortugal
LanguageSpain
LanguageRomania
LanguageGreece
LanguageFrench
LanguageRussian
LanguageDutch
LanguageHebrew
LanguageChineseTraditional
)
type EventModelGetAlarmingResponse struct {
CameraCoveredChannelMask uint `json:"VS_CH"`
CameraCoveredAlarmMask uint `json:"VS_AT"`
CameraCoveredStatusMask uint `json:"VS_AS"`
VideoLossChannelMask uint `json:"VL_CH"`
VideoLossAlarmMask uint `json:"VL_AT"`
VideoLossStatusMask uint `json:"VL_AS"`
}
/*
// main server util
func (e *Package) ResponseAlarm(alarmType int64, alarmUID int64, cmdno int64, cmdtype int64, run int64, serial string, Sid string) {
e.Payload = map[string]any{
"MODULE": "EVEM",
"OPERATION": "SENDALARMINFO",
"RESPONSE": map[string]any{
"ALARMTYPE": alarmType,
"ALARMUID": alarmUID,
"CMDNO": cmdno,
"CMDTYPE": cmdtype,
"ERRORCODE": 0,
"RUN": run,
},
"SESSION": Sid,
}
}
*/

View File

@ -1,4 +1,4 @@
package n9m
package models
type NetConnectionType uint
@ -35,12 +35,64 @@ type CertificateConnectRequest struct {
EvidenceSupport string `json:"EV"`
}
type CertificateConnectClientRequest struct {
UK string `json:"UK"`
}
type CertificateConnectResponse struct {
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
CommandMask uint `json:"MASKCMD"`
}
type CertificateConnectClientResponse struct {
S0 string `json:"S0"`
}
type CertificateVerificationRequest struct {
S0 string `json:"S0"`
}
type CertificateVerificationResponse struct {
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
ReturnFlag bool `json:"RETURN"`
}
type CertificateLoginRequest struct {
ClientID uint `json:"CID,omitempty"`
MAC string `json:"MAC,omitempty"`
User string `json:"USER"`
Password string `json:"PASSWD"`
PlayDevID uint `json:"PLAYDEVID"`
}
type CertificateLoginResponse struct {
SerialNumber string `json:"DSNO"`
DeviceName string `json:"DEVNAME"`
ChannelsNumber uint `json:"CHANNEL"`
UID string `json:"UID"`
AlarmInputNumber uint `json:"ALARMIN"`
AlarmOutputNumber uint `json:"ALARMOUT"`
DeviceType string `json:"TYPE"`
DeviceClass DeviceType `json:"DEVCLASS"`
CurrentVersion string `json:"PRO"`
LicensePlate string `json:"CARNUM"`
UserLever UserAccessLevel `json:"LEVEL"`
CompanyName string `json:"CPN"`
CustomerName string `json:"CNAME"`
AudioChannelsNumber uint `json:"ACHN"`
}
type CertificateCreateStreamRequest struct {
StreamName string `json:"STREAMNAME"`
}
type CertificateCreateStreamResponse struct {
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
}
type CommandMaskParameters uint
const (
@ -54,6 +106,24 @@ const (
CommandMaskAll = 0b1111111
)
type DeviceType uint
const (
DeviceTypeDVR DeviceType = 1 + iota
DeviceTypeIPC
DeviceTypeNVR
DeviceTypeMIPC
DeviceTypeMDVR
)
type UserAccessLevel uint
const (
UserAccessLevelSuperAdmin UserAccessLevel = iota
UserAccessLevelAdministrator
UserAccessLeverUser
)
/*
func (e *Package) RequestConnect(session string, serial string, numOfCams int) {
e.Payload = map[string]any{

View File

@ -1,4 +1,8 @@
package n9m
package models
import (
"gitea.unprism.ru/KRBL/n9m/v2/pkg/parameters"
)
/*
@ -31,7 +35,7 @@ func (e *Package) SetParameters(params map[string]any, serial int, session strin
*/
type ConfigModelSetRequest struct {
MDVR Setting `json:"MDVR"`
MDVR parameters.Setting `json:"MDVR"`
}
type ConfigModelGetRequest struct {
@ -39,27 +43,27 @@ type ConfigModelGetRequest struct {
}
type ConfigModelSetResponse struct {
MDVR Setting `json:"MDVR"`
MDVR parameters.Setting `json:"MDVR"`
}
func (e *Package) InitialConfigModelSetRequest() {
e.SetParameters(ConfigModelSetRequest{
MDVR: Setting{
KEYS: KEYS{
func InitialConfig() ConfigModelSetRequest {
return ConfigModelSetRequest{
MDVR: parameters.Setting{
KEYS: parameters.KEYS{
GV: 1, // GPS version
},
PGDSM: PGDSM{
PGPS: PGPS{
PGDSM: parameters.PGDSM{
PGPS: parameters.PGPS{
EN: 1, // Real-time position monitoring
MODE: 0b10, // Enable timer
TM: 10, // Time interval
},
},
SUBSTRNET: SUBSTRNET{
SUBSTRNET: parameters.SUBSTRNET{
SM: 1,
},
},
})
}
}
/*

View File

@ -1,8 +1,9 @@
package n9m
package models
import (
"encoding/json"
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
"strconv"
"time"
)
@ -46,10 +47,10 @@ func (e *Package) ResponseGeolocation(errorCode int, errorCause string, serial i
// 3.4.5.28
type SpiParameters struct {
DriveFlag uint `json:"T"`
DataMask uint `json:"M"`
Position GPSData `json:"P"`
DeviceStatus SpiDeviceStatus `json:"S"`
DriveFlag uint `json:"T"`
DataMask uint `json:"M"`
Position protocol.GPSData `json:"P"`
DeviceStatus SpiDeviceStatus `json:"S"`
}
// 3.4.5.28.1

90
pkg/models/evem.go Normal file
View File

@ -0,0 +1,90 @@
package models
import (
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
)
// 3.4.1.3
type EventModelGetAlarmStatusInfoResponse struct {
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
StorageErrors []StorageErrorStatus `json:"ST"`
AnotherStorageErrors []AnotherStorageErrorStatus `json:"VS"`
VideoLossErrors []VideoLossErrorStatus `json:"VL"`
GPSError GPSErrorStatus `json:"GFA"`
GPSAntennaError GPSAntennaErrorStatus `json:"GPSS"`
}
// 3.4.1.4.21
type StorageErrorStatus struct {
CameraCovered uint `json:"ISA"`
ChannelBind uint `json:"LHC"`
}
// 3.4.1.4.4
type AnotherStorageErrorStatus struct {
}
// 3.4.1.4.5
type VideoLossErrorStatus struct {
}
// 3.4.1.4.44
type GPSErrorStatus struct {
}
// 3.4.1.4.46
type GPSAntennaErrorStatus struct {
}
// 3.4.1.5
// Alarm upload
type SendAlarmInfoParameters struct {
AlarmType protocol.AlarmType `json:"ALARMTYPE"`
CommandType uint `json:"CMDTYPE"`
AlarmUID uint `json:"ALARMUID"`
NumberOfRestarts uint `json:"RUN"`
AlarmLevel protocol.AlarmLevel `json:"ALARMAS"`
AlarmCount uint `json:"ALARMCOUNT"`
TriggerType protocol.TriggerType `json:"TRIGGERTYPE"`
ContinueTime uint `json:"CONTINUETIME"`
CurrentTime uint `json:"CURRENTTIME"`
Language protocol.Language `json:"L"`
GPSData protocol.GPSData `json:"P"`
RealTimeUpload uint `json:"REAL"`
InstructionSerial uint `json:"CMDNO"`
}
// 3.4.1.5
// Alarm upload
type SendAlarmInfoResponse struct {
ErrorCode uint `json:"ERRORCODE"`
AlarmType protocol.AlarmType `json:"ALARMTYPE"`
ErrorCause string `json:"ERRORCAUSE"`
CommandType uint `json:"CMDTYPE"`
AlarmUID uint `json:"ALARMUID"`
NumberOfRestarts uint `json:"RUN"`
InstructionSerial uint `json:"CMDNO"`
}
// 3.4.1.5.1
type SendAlarmInfoCameraParameters struct {
SendAlarmInfoParameters
Channel uint `json:"CHANNEL"`
ChannelMask uint `json:"CHANNELMASK"`
LCH []uint `json:"LCH"`
Push uint `json:"PUSH"`
AlarmName string `json:"ALARMNAME"`
AlarmAbbreviation string `json:"SER"`
}
type EventModelGetAlarmingResponse struct {
CameraCoveredChannelMask uint `json:"VS_CH"`
CameraCoveredAlarmMask uint `json:"VS_AT"`
CameraCoveredStatusMask uint `json:"VS_AS"`
VideoLossChannelMask uint `json:"VL_CH"`
VideoLossAlarmMask uint `json:"VL_AT"`
VideoLossStatusMask uint `json:"VL_AS"`
}

View File

@ -1,4 +1,56 @@
package n9m
package models
import "gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
type StreamType uint
const (
StreamTypeSub StreamType = iota
StreamTypeMain
StreamTypeMobile
)
type MediaStreamModelRequestLiveVideoRequest struct {
SSRC uint `json:"SSRC,omitempty"`
StreamName string `json:"STREAMNAME"`
StreamType StreamType `json:"STREAMTYPE"`
Channel uint `json:"CHANNEL"`
AudioValid uint `json:"AUDIOVALID"`
Destination string `json:"IPANDPORT,omitempty"`
FrameCount uint `json:"FRAMECOUNT,omitempty"`
FrameMode uint `json:"FRAMEMODE"`
}
type MediaStreamModelRequestLiveVideoResponse struct {
SSRC uint `json:"SSRC"`
StreamName string `json:"STREAMNAME"`
StreamType StreamType `json:"STREAMTYPE"`
ErrorCode uint `json:"ERRORCODE"`
ErrorCause string `json:"ERRORCAUSE"`
}
type MediaStreamCommand uint
const (
MediaStreamCommandStop MediaStreamCommand = iota
MediaStreamCommandResume
MediaStreamCommandPause
MediaStreamCommandSwitchVideoStream
MediaStreamAudioManagement
MediaStreamFrameRate
MediaStreamSendingMode
)
type MediaStreamModelControlStreamRequest struct {
PayloadType protocol.PayloadType `json:"PT"`
SSRC uint16 `json:"SSRC"`
StreamName string `json:"STREAMNAME"`
Command MediaStreamCommand `json:"CMD"`
StreamType StreamType `json:"STREAMTYPE,omitempty"`
AudioValid uint `json:"AUDIOVALID,omitempty"`
FrameMode uint `json:"FRAMEMODE,omitempty"`
}
/*
var ip string = os.Getenv("SERVER_IP")

View File

@ -1,4 +1,4 @@
package n9m
package models
/*

View File

@ -1,4 +1,4 @@
package n9m
package parameters
// 7.2
type RIP struct {
@ -152,6 +152,8 @@ type SAP struct {
UN int
}
// 7.24.3
// Alarm processing parameters
type APR struct {
AR ARR
SS SS
@ -167,13 +169,6 @@ type SS struct {
EN int
}
type UAP struct {
EN int
AS int
VT int
SDT int
}
type PVLAS struct {
EN int
AS int
@ -257,8 +252,10 @@ type MCMS struct {
SP []SP // Параметры сервера
}
// 7.12.1
// Central server configuration
type SP struct {
EN int // Статус сервера
EN int // Флаг включения
CP int // Протокол подключения
NWT int // Способ подключения
CS string // Адрес сервера
@ -269,7 +266,45 @@ type SP struct {
MUPORT int // UDP-порт медиасервера
}
// 7.28
// NVR remote device parameters
type REDEV struct {
EN int // Флаг включения
LOCK int // ???
CHL int // Номер канала на устройстве
RECHL int // ???
ONLINE int // Доступно ли сейчас устройство
RETYPE int // Тип устройства
PROTYPE int // Тип протокола
IPTYPE int // Тип IP-адреса (IPv4/IPv6)
CONTYPE int // ???
SW int // Источник поступаемого сигнала
REPORT int // Порт камеры
REIP int // IP камеры
ID int // Идентификатор камеры
RENAME string // Название устройства
USER string // Имя пользователя
PWD string // Пароль
URL string // ???
CMDPORT string // ???
}
// 7.29
// Panel emergency alarm
type UAP struct {
EN int // Флаг включения
AS int // Уровень тревоги
T int // ???
VT int // ???
UN string // Имя тревоги
UO string // Имя тривоги на экране водителя
APR APR // Параметры обработки тревоги
// AP AP // Параметры тревоги
SDT int // ???
}
// 7.30
// Network monitoring status parameters
type PGDSM struct {
PGPS PGPS `json:"PGPS,omitempty"`
PDSM PDSM `json:"PDSM,omitempty"`
@ -286,6 +321,7 @@ type PGPS struct {
}
// 7.30.2
// Device status parameter
type PDSM struct {
}
@ -323,6 +359,7 @@ type Setting struct {
EOSD []EOSD `json:"EOSD,omitempty"`
IOP []IOP `json:"IOP,omitempty"`
SAP SAP `json:"SAP,omitempty"`
REDEV []REDEV `json:"REDEV,omitempty"`
UAP UAP `json:"UAP,omitempty"`
PGDSM PGDSM `json:"PGDSM,omitempty"`
PVLAS PVLAS `json:"PVLAS,omitempty"`

57
pkg/protocol/alarms.go Normal file
View File

@ -0,0 +1,57 @@
package protocol
type AlarmType uint
const (
AlarmTypeVideoLoss AlarmType = iota
AlarmTypeCameraCovered
AlarmTypeMotionDetection
AlarmTypeStorageAbnormal
AlarmTypeUserDefined
AlarmTypeSentriesInspection
AlarmTypeViolation
AlarmTypeEmergency
AlarmTypeSpeedAlarm
AlarmTypeLowVoltage
AlarmTypeOutOfFence = iota + 7
AlarmTypeAccAlarm
AlarmTypePeripheralsDropped
AlarmTypeStopAnnouncement
AlarmTypeGpsAntenna
AlarmTypeDayNightSwitch
AlarmTypeProhibitDriving
AlarmTypeSerialAlarm = iota + 15
AlarmTypeFatigueAlarm
AlarmTypeTakeOutParking
AlarmTypeGestureAlarm
AlarmTypeGreenDriving
AlarmTypeIllegalIgnition
AlarmTypeIllegalShutdown
AlarmTypeCustomExternal
AlarmTypeThinkingLKJ
AlarmTypeTAX3
AlarmTypeOilAlarm
AlarmTypeBusLineOccupation
AlarmTypeForgottenAlarm
AlarmTypeSpecialCustomerFault
AlarmTypeTemperatureAbnormal
AlarmTypeTemperatureChangeAbnormal
AlarmTypeSmokeAlarm
AlarmTypeGBox
AlarmTypeLicensePlateRecognition
AlarmTypeAnotherSpeedAlarm
AlarmTypeWirelessSignalAbnormal
AlarmTypeArming
AlarmTypePhoneCall
AlarmTypeGPSFault
AlarmTypeDSMFault
AlarmTypeFireBox
)
type AlarmLevel uint
const (
AlarmLevelImportant AlarmLevel = iota
AlarmLevelGeneral
AlarmLevelEmergency
)

View File

@ -1,4 +1,4 @@
package n9m
package protocol
import (
"bytes"
@ -88,8 +88,8 @@ func (e *Package) ReadPackage() bool {
default:
fmt.Println("N9M parser warning: unknown special payload type", e.SSRC)
}
default:
fmt.Println("N9M parser warning: unknown payload type", e.PayloadType)
// default:
// fmt.Println("N9M parser warning: unknown payload type", e.PayloadType)
}
if r.TryError != nil {
@ -168,7 +168,7 @@ func (e *Package) GetParametersAs(parameters any) error {
}
func (e *Package) SetParameters(parameters any) {
e.Payload.Response = struct{}{}
e.Payload.Response = nil
e.Payload.Parameter = parameters
}
@ -183,6 +183,10 @@ func (e *Package) GetResponseAs(response any) error {
}
func (e *Package) SetResponse(response any) {
e.Payload.Parameter = struct{}{}
e.Payload.Parameter = nil
e.Payload.Response = response
}
func (e *Package) AddToAccum(data []byte) {
e.Accum = append(e.Accum, data...)
}

22
pkg/protocol/languages.go Normal file
View File

@ -0,0 +1,22 @@
package protocol
type Language uint
const (
LanguageSimplifiedChinese Language = iota
LanguageEnglish
LanguageKorean
LanguageItalian
LanguageGerman
LanguageThai
LanguageTurkey
LanguagePortugal
LanguageSpain
LanguageRomania
LanguageGreece
LanguageFrench
LanguageRussian
LanguageDutch
LanguageHebrew
LanguageChineseTraditional
)

View File

@ -1,9 +1,8 @@
package n9m
package protocol
import (
"encoding/json"
"fmt"
"net"
"strconv"
"time"
)
@ -138,18 +137,3 @@ type Package struct {
Accum []byte
}
type ProcessFunc func(*SmartPackage, Package) error
type AlarmProcessFunc func(*SmartPackage, Package, SendAlarmInfoResponse) error
type SmartPackage struct {
pack Package
conn net.Conn
buff []byte
payloadProcess map[PayloadType]ProcessFunc
jsonProcess map[string]ProcessFunc
alarmProcess map[AlarmType]AlarmProcessFunc
Storage map[string]interface{}
}

8
pkg/protocol/trigger.go Normal file
View File

@ -0,0 +1,8 @@
package protocol
type TriggerType uint
const (
TriggerTypeManual TriggerType = iota
TriggerTypeAutomatic
)

177
pkg/smart/channel.go Normal file
View File

@ -0,0 +1,177 @@
package smart
import (
"errors"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/models"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/utils"
"net"
"sync"
)
const (
charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
length = 6
)
func NewAutoSmartChannelPackage(mainSmartPackage *SmartPackage) (*SmartChannelPackage, error) {
conn, err := net.Dial(mainSmartPackage.conn.RemoteAddr().Network(), mainSmartPackage.conn.RemoteAddr().String())
if err != nil {
return nil, err
}
return NewSmartChannelPackage(conn, mainSmartPackage)
}
func NewSmartChannelPackage(conn net.Conn, mainSmartPackage *SmartPackage) (*SmartChannelPackage, error) {
pack := NewSmartPackage(conn)
pack.pack.Payload.Session = mainSmartPackage.pack.Payload.Session
channelName, err := registerChannelHandles(pack)
if err != nil {
return nil, err
}
smartChannelPackage := &SmartChannelPackage{
pack: pack,
mainPack: mainSmartPackage,
channelName: channelName,
mutex: sync.RWMutex{},
ssrc: make(map[uint16][]func([]byte) error),
}
pack.AddPayloadHandler(protocol.PayloadTypeLive, smartChannelPackage.handleLiveVideo)
return smartChannelPackage, nil
}
func (channelPack *SmartChannelPackage) Run() error {
for {
if err := channelPack.pack.Handle(); err != nil {
return err
}
}
}
func (channelPack *SmartChannelPackage) GetChannelName() string {
return channelPack.channelName
}
func (channelPack *SmartChannelPackage) AddLiveSource(ssrc uint16, source func([]byte) error) {
channelPack.mutex.Lock()
defer channelPack.mutex.Unlock()
channelPack.ssrc[ssrc] = append(channelPack.ssrc[ssrc], source)
}
func (channelPack *SmartChannelPackage) handleLiveVideo(sPack *SmartPackage, pack protocol.Package) error {
channelPack.mutex.RLock()
sources, ok := channelPack.ssrc[uint16(pack.SSRC)]
if !ok || len(sources) == 0 {
channelPack.mutex.RUnlock()
var request = models.MediaStreamModelControlStreamRequest{
PayloadType: protocol.PayloadTypeLive,
SSRC: uint16(pack.SSRC),
StreamName: channelPack.channelName,
Command: models.MediaStreamCommandStop,
}
pack.PayloadType = protocol.PayloadTypeData
pack.Payload.Module = "MEDIASTREAMMODEL"
pack.Payload.Operation = "CONTROLSTREAM"
pack.SetParameters(request)
if _, err := channelPack.mainPack.Write(pack.PackPackage()); err != nil {
panic(err)
}
return nil
}
var errorMask = map[int]bool{}
for i, source := range sources {
if err := source(pack.RawPayload); err != nil {
errorMask[i] = true
}
}
channelPack.mutex.RUnlock()
if len(errorMask) > 0 {
newSources := make([]func([]byte) error, 0, len(sources))
for i, source := range sources {
if !errorMask[i] {
newSources = append(newSources, source)
}
}
channelPack.mutex.Lock()
channelPack.ssrc[uint16(pack.SSRC)] = newSources
channelPack.mutex.Unlock()
}
return nil
}
func registerChannelHandles(pack *SmartPackage) (string, error) {
res := make(chan error, 1)
pack.AddJSONHandler("CERTIFICATE", "CREATESTREAM", func(smartPackage *SmartPackage, p protocol.Package) error {
var params models.CertificateCreateStreamResponse
if err := p.GetResponseAs(&params); err != nil {
return err
}
if params.ErrorCode != 0 {
res <- errors.New(params.ErrorCause)
} else {
res <- nil
}
return nil
})
channelName := utils.RandomString(length, charset)
var request = models.CertificateCreateStreamRequest{
StreamName: channelName,
}
pack.pack.Payload.Module = "CERTIFICATE"
pack.pack.Payload.Operation = "CREATESTREAM"
pack.pack.SetParameters(request)
pack.Write(pack.pack.PackPackage())
for {
if err := pack.Handle(); err != nil {
return "", err
}
select {
case err := <-res:
close(res)
if err != nil {
return "", err
}
pack.AddJSONHandler("CERTIFICATE", "CREATESTREAM", func(smartPackage *SmartPackage, p protocol.Package) error {
return errors.New("stream already exists")
})
return channelName, nil
default:
}
}
}

33
pkg/smart/scheme.go Normal file
View File

@ -0,0 +1,33 @@
package smart
import (
"gitea.unprism.ru/KRBL/n9m/v2/pkg/models"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
"net"
"sync"
)
type ProcessFunc func(*SmartPackage, protocol.Package) error
type AlarmProcessFunc func(*SmartPackage, protocol.Package, models.SendAlarmInfoResponse) error
type SmartPackage struct {
pack protocol.Package
conn net.Conn
buff []byte
payloadProcess map[protocol.PayloadType]ProcessFunc
jsonProcess map[string]ProcessFunc
alarmProcess map[protocol.AlarmType]AlarmProcessFunc
Storage map[string]interface{}
}
type SmartChannelPackage struct {
pack *SmartPackage
mainPack *SmartPackage
channelName string
mutex sync.RWMutex
ssrc map[uint16][]func([]byte) error
}

View File

@ -1,8 +1,10 @@
package n9m
package smart
import (
"errors"
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/models"
"gitea.unprism.ru/KRBL/n9m/v2/pkg/protocol"
"net"
)
@ -16,17 +18,17 @@ func (e *notFoundError) Error() string {
func NewSmartPackage(conn net.Conn) *SmartPackage {
return &SmartPackage{
pack: Package{},
pack: protocol.Package{},
conn: conn,
buff: make([]byte, 1024),
payloadProcess: make(map[PayloadType]ProcessFunc),
payloadProcess: make(map[protocol.PayloadType]ProcessFunc),
jsonProcess: make(map[string]ProcessFunc),
alarmProcess: make(map[AlarmType]AlarmProcessFunc),
alarmProcess: make(map[protocol.AlarmType]AlarmProcessFunc),
Storage: make(map[string]interface{}),
}
}
func (pack *SmartPackage) AddPayloadHandler(payloadType PayloadType, processFunc ProcessFunc) {
func (pack *SmartPackage) AddPayloadHandler(payloadType protocol.PayloadType, processFunc ProcessFunc) {
pack.payloadProcess[payloadType] = processFunc
}
@ -34,16 +36,16 @@ func (pack *SmartPackage) AddJSONHandler(module, operation string, processFunc P
pack.jsonProcess[fmt.Sprintf("%s:%s", module, operation)] = processFunc
}
func (pack *SmartPackage) AddAlarmHandler(alarmType AlarmType, processFunc AlarmProcessFunc) {
func (pack *SmartPackage) AddAlarmHandler(alarmType protocol.AlarmType, processFunc AlarmProcessFunc) {
pack.alarmProcess[alarmType] = processFunc
}
func (pack *SmartPackage) handleAlarm() (err error) {
if !(pack.pack.PayloadType == PayloadTypeData && pack.pack.Payload.Module == "EVEM" && pack.pack.Payload.Operation == "SENDALARMINFO") {
if !(pack.pack.PayloadType == protocol.PayloadTypeData && pack.pack.Payload.Module == "EVEM" && pack.pack.Payload.Operation == "SENDALARMINFO") {
return fmt.Errorf("invalid payload type or operation for alarm handling")
}
var params SendAlarmInfoParameters
var params models.SendAlarmInfoParameters
if err = pack.pack.GetParametersAs(&params); err != nil {
return fmt.Errorf("invalid payload")
}
@ -56,7 +58,7 @@ func (pack *SmartPackage) handleAlarm() (err error) {
}
}
var response SendAlarmInfoResponse
var response models.SendAlarmInfoResponse
response.ErrorCode = 0
response.AlarmType = params.AlarmType
@ -69,7 +71,7 @@ func (pack *SmartPackage) handleAlarm() (err error) {
}
func (pack *SmartPackage) handleJson() (err error) {
if pack.pack.PayloadType != PayloadTypeData {
if pack.pack.PayloadType != protocol.PayloadTypeData {
return fmt.Errorf("invalid json payload type")
}
@ -133,7 +135,7 @@ func (pack *SmartPackage) Handle() (err error) {
return pack.handleLoop()
}
func (pack *SmartPackage) GetPackage() Package {
func (pack *SmartPackage) GetPackage() protocol.Package {
return pack.pack
}

15
pkg/utils/crypto.go Normal file
View File

@ -0,0 +1,15 @@
package utils
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))
}

18
pkg/utils/random.go Normal file
View File

@ -0,0 +1,18 @@
package utils
import (
"math/rand"
"time"
)
// seededRand is a source of random numbers seeded with the current time.
var seededRand *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano()))
// randomString generates a random string of the specified length using the given charset.
func RandomString(length int, charset string) string {
b := make([]byte, length)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
}
return string(b)
}

View File

@ -1,28 +0,0 @@
package test
import (
"fmt"
"gitea.unprism.ru/KRBL/n9m/v2"
"testing"
)
func TestCertificateConnection(t *testing.T) {
dump := []byte{0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0xe9, 0x52, 0x0, 0x0, 0x0, 0x7b, 0x22, 0x4d, 0x4f, 0x44, 0x55, 0x4c, 0x45, 0x22, 0x3a, 0x22, 0x43, 0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x22, 0x2c, 0x22, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x22, 0x3a, 0x22, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x22, 0x2c, 0x22, 0x50, 0x41, 0x52, 0x41, 0x4d, 0x45, 0x54, 0x45, 0x52, 0x22, 0x3a, 0x7b, 0x22, 0x41, 0x55, 0x54, 0x4f, 0x43, 0x41, 0x52, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x41, 0x55, 0x54, 0x4f, 0x4e, 0x4f, 0x22, 0x3a, 0x22, 0x30, 0x22, 0x2c, 0x22, 0x43, 0x41, 0x52, 0x4e, 0x55, 0x4d, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x43, 0x48, 0x41, 0x4e, 0x4e, 0x45, 0x4c, 0x22, 0x3a, 0x31, 0x32, 0x2c, 0x22, 0x43, 0x49, 0x44, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x43, 0x4e, 0x41, 0x4d, 0x45, 0x22, 0x3a, 0x22, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x45, 0x52, 0x5f, 0x4e, 0x55, 0x4c, 0x4c, 0x22, 0x2c, 0x22, 0x44, 0x45, 0x56, 0x43, 0x4c, 0x41, 0x53, 0x53, 0x22, 0x3a, 0x34, 0x2c, 0x22, 0x44, 0x45, 0x56, 0x4e, 0x41, 0x4d, 0x45, 0x22, 0x3a, 0x22, 0x4d, 0x44, 0x56, 0x52, 0x22, 0x2c, 0x22, 0x44, 0x45, 0x56, 0x54, 0x59, 0x50, 0x45, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x44, 0x4c, 0x49, 0x50, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x4c, 0x49, 0x50, 0x22, 0x3a, 0x22, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x2e, 0x30, 0x22, 0x2c, 0x22, 0x4d, 0x54, 0x22, 0x3a, 0x22, 0x65, 0x74, 0x68, 0x30, 0x22, 0x7d, 0x5d, 0x2c, 0x22, 0x44, 0x4c, 0x50, 0x22, 0x3a, 0x5b, 0x38, 0x30, 0x2c, 0x39, 0x30, 0x30, 0x36, 0x5d, 0x2c, 0x22, 0x44, 0x53, 0x4e, 0x4f, 0x22, 0x3a, 0x22, 0x30, 0x30, 0x38, 0x38, 0x30, 0x33, 0x36, 0x31, 0x42, 0x38, 0x22, 0x2c, 0x22, 0x45, 0x49, 0x44, 0x22, 0x3a, 0x22, 0x6e, 0x6f, 0x74, 0x65, 0x62, 0x6f, 0x6f, 0x6b, 0x22, 0x2c, 0x22, 0x45, 0x56, 0x22, 0x3a, 0x22, 0x56, 0x31, 0x2e, 0x31, 0x22, 0x2c, 0x22, 0x46, 0x53, 0x56, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x4c, 0x49, 0x4e, 0x45, 0x4e, 0x4f, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x4d, 0x41, 0x43, 0x22, 0x3a, 0x5b, 0x7b, 0x22, 0x49, 0x4d, 0x41, 0x43, 0x22, 0x3a, 0x22, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x22, 0x2c, 0x22, 0x4d, 0x54, 0x22, 0x3a, 0x22, 0x65, 0x74, 0x68, 0x30, 0x22, 0x7d, 0x5d, 0x2c, 0x22, 0x4d, 0x4f, 0x44, 0x45, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x4d, 0x54, 0x59, 0x50, 0x45, 0x22, 0x3a, 0x33, 0x31, 0x2c, 0x22, 0x4e, 0x45, 0x54, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x50, 0x52, 0x4f, 0x22, 0x3a, 0x22, 0x31, 0x2e, 0x30, 0x2e, 0x35, 0x22, 0x2c, 0x22, 0x53, 0x54, 0x59, 0x50, 0x45, 0x22, 0x3a, 0x35, 0x34, 0x2c, 0x22, 0x54, 0x53, 0x45, 0x22, 0x3a, 0x31, 0x2c, 0x22, 0x55, 0x4e, 0x41, 0x4d, 0x45, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x55, 0x4e, 0x4f, 0x22, 0x3a, 0x22, 0x22, 0x7d, 0x2c, 0x22, 0x53, 0x45, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x22, 0x3a, 0x22, 0x36, 0x63, 0x65, 0x64, 0x35, 0x63, 0x66, 0x37, 0x2d, 0x61, 0x34, 0x35, 0x63, 0x2d, 0x34, 0x61, 0x63, 0x61, 0x2d, 0x62, 0x39, 0x64, 0x35, 0x2d, 0x66, 0x65, 0x39, 0x34, 0x61, 0x62, 0x36, 0x32, 0x66, 0x39, 0x65, 0x61, 0x22, 0x7d, 0xa}
pack := n9m.Package{}
pack.AddToAccum(dump)
if !pack.ReadPackage() {
t.Error("Package wasn't read!")
return
}
var connectionParams n9m.CertificateConnectRequest
if err := pack.GetParametersAs(&connectionParams); err != nil {
t.Error(err)
return
}
fmt.Println(connectionParams)
}

View File

@ -1,25 +0,0 @@
package n9m
import (
"encoding/hex"
)
// add bytes to accum
func (e *Package) AddToAccum(data []byte) {
e.Accum = append(e.Accum, data...)
}
// why store a string and constantly change it to the same thing
// the stored string is not used
func (e *Package) GetToken() {
hexStream := "3876431502000010380000007b224b4559223a22434c49454e544c4f47494e222c22524553504f4e5345223a7b22434c49454e544944223a2237643531323030227d7d00"
e.RawPayload, _ = hex.DecodeString(hexStream)
}
// the same
func (e *Package) RequestGetTokenDop() {
hexStream := "3876431501000010360000007b224b4559223a224c4f47494e222c22504152414d223a7b224355534552223a2231222c22505744223a22313233343536227d7d0a00"
e.RawPayload, _ = hex.DecodeString(hexStream)
}