Files
nbi_alarm/decoder/decode_omc.go
2023-08-21 11:00:22 +08:00

89 lines
2.6 KiB
Go

package decoder
import (
"bytes"
"encoding/binary"
"encoding/hex"
"github.com/aceld/zinx/ziface"
"github.com/aceld/zinx/zlog"
"math"
)
//ffff 01 00999999 000a 68656c6c6f2074657374
// +---------------+---------------+--------------------+----------------+-------------------
// | 开始标志 | type | 秒时间戳 | 长度 | 消息体
// | 0xffff(2byte) | uint8(1byte) | uint32(4byte) | uint16(2byte) | bytes(N byte)
// +---------------+---------------+--------------------+----------------+-------------------
const OmcMsgHeaderSize = 9 //表示OMC空包长度
type OmcDecoder struct {
StartSign uint16
MsgType uint8
TimeStamp uint32
LenOfBody uint16
Value []byte
}
func NewOmcDecoder() ziface.IDecoder {
return &OmcDecoder{}
}
func (omc *OmcDecoder) GetLengthField() *ziface.LengthField {
return &ziface.LengthField{
MaxFrameLength: math.MaxUint16 + 9,
LengthFieldOffset: 7,
LengthFieldLength: 2,
LengthAdjustment: 0,
InitialBytesToStrip: 0,
//注意现在默认是大端,使用小端需要指定编码方式
Order: binary.BigEndian,
}
}
func (omc *OmcDecoder) decode(data []byte) *OmcDecoder {
ltvData := OmcDecoder{}
ltvData.StartSign = binary.BigEndian.Uint16(data[0:2])
ltvData.MsgType = data[2]
ltvData.TimeStamp = binary.BigEndian.Uint32(data[3:7])
ltvData.LenOfBody = binary.BigEndian.Uint16(data[7:9])
//Determine the length of V. (确定V的长度)
ltvData.Value = make([]byte, ltvData.LenOfBody)
//5. Get V
binary.Read(bytes.NewBuffer(data[OmcMsgHeaderSize:OmcMsgHeaderSize+ltvData.LenOfBody]), binary.BigEndian, ltvData.Value)
return &ltvData
}
func (omc *OmcDecoder) Intercept(chain ziface.IChain) ziface.IcResp {
//1. Get the IMessage of zinx
iMessage := chain.GetIMessage()
if iMessage == nil {
// Go to the next layer in the chain of responsibility
return chain.ProceedWithIMessage(iMessage, nil)
}
//2. Get Data
data := iMessage.GetData()
zlog.Ins().DebugF("omc-RawData size:%d data:%s\n", len(data), hex.EncodeToString(data))
// (读取的数据不超过包头,直接进入下一层)
if len(data) < OmcMsgHeaderSize {
return chain.ProceedWithIMessage(iMessage, nil)
}
//4. Decode
ltvData := omc.decode(data)
zlog.Ins().DebugF("omc-decode %v", ltvData)
// (将解码后的数据重新设置到IMessage中, Zinx的Router需要MsgID来寻址)
iMessage.SetDataLen(uint32(ltvData.LenOfBody))
iMessage.SetMsgID(uint32(ltvData.MsgType))
iMessage.SetData(ltvData.Value)
//6. Pass the decoded data to the next layer.
// (将解码后的数据进入下一层)
return chain.ProceedWithIMessage(iMessage, *ltvData)
}