89 lines
2.6 KiB
Go
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 <vData
|
|
}
|
|
|
|
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)
|
|
}
|