123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- package protocol
- import (
- "bytes"
- "dlt645-server/errors"
- "encoding/binary"
- "encoding/json"
- "github.com/gogf/gf/os/glog"
- "reflect"
- "strconv"
- )
- // 消息包
- type Message struct {
- Header Header
- Body Entity
- }
- type DHeader struct {
- MsgID MsgID
- }
- type Data struct {
- PowerData
- VIData
- }
- type PowerData struct {
- ActivePower float64 `json:"active_power"`
- }
- type VIData struct {
- AV float64 `json:"av"` // A相电压
- AI float64 `json:"ai"` // A相电流
- BV float64 `json:"bv"` // B相电压
- BI float64 `json:"bi"` // B相电流
- CV float64 `json:"cv"` // C相电压
- CI float64 `json:"ci"` // C相电流
- }
- // 协议编码
- func (message *Message) Encode() ([]byte, error) {
- // 编码消息体
- var err error
- var data []byte
- if message.Body != nil && !reflect.ValueOf(message.Body).IsNil() {
- data, err = message.Body.Encode(nil)
- if err != nil {
- return nil, err
- }
- }
- // 二进制转义
- buffer := bytes.NewBuffer(nil)
- message.write(buffer, data)
- return buffer.Bytes(), nil
- }
- // 协议解码
- func (message *Message) Decode(ctx *PacketContext, data []byte) (result Data, err error) {
- // 检验标志位
- length := len(data)
- if length == 0 {
- return result, errors.ErrInvalidMessage
- }
- for i := 0; i <= length; i++ {
- if data[i] == SendByte {
- continue
- } else {
- data = data[i:length]
- glog.Debugf("收到数据:%2X", data)
- break
- }
- }
- if data[0] != ReceiveByte {
- return result, nil
- }
- if data[len(data)-1] != EndByte {
- data = append(data, 0x16)
- }
- if !message.checkSum(data) {
- return result, errors.ErrInvalidCheckSum
- }
- //处理注册包
- if data[0] == RegisterByte {
- header := Header{}
- _ = json.Unmarshal(data, &header)
- header.IccID, err = strconv.ParseUint(header.Imei, 10, 64)
- header.MsgID = 0x0040 //消息ID
- if err != nil {
- if err != nil {
- glog.Errorf("解析报文失败:%s", err.Error())
- }
- }
- message.Body = nil
- message.Header = header
- return result, nil
- }
- if len(data) < 8 {
- if err != nil {
- glog.Errorf("解析报文失败:%s", errors.ErrInvalidBody)
- }
- }
- if data[8] == 0x93 {
- result, err = message.decode(ctx, uint32(0x93), data[:])
- if err != nil {
- glog.Errorf("解析报文失败:%s", err.Error())
- }
- } else {
- msgID := MsgID(binary.BigEndian.Uint32(data[10:15])) //消息ID
- result, err = message.decode(ctx, uint32(msgID), data[:]) //解析实体对象 entity buffer : 为消息标识
- if err != nil {
- glog.Errorf("解析报文失败:%s", err.Error())
- }
- }
- return result, nil
- }
- //--->
- func (message *Message) decode(ctx *PacketContext, dataType uint32, data []byte) (result Data, err error) {
- creator, ok := entityMapper[dataType]
- if !ok {
- return result, errors.ErrTypeNotRegistered
- }
- entity := creator()
- result, err = entity.Decode(ctx, data) //解析data数据
- if err != nil {
- return result, err
- }
- return result, err
- }
- // 写入二进制数据
- func (message *Message) write(buffer *bytes.Buffer, data []byte) *Message {
- for _, b := range data {
- if b == PrefixID {
- buffer.WriteByte(EscapeByte)
- buffer.WriteByte(EscapeByteSufix2)
- } else if b == EscapeByte {
- buffer.WriteByte(EscapeByte)
- buffer.WriteByte(EscapeByteSufix1)
- } else {
- buffer.WriteByte(b)
- }
- }
- return message
- }
- // 和校验
- func (message *Message) checkSum(data []byte) bool {
- var checkSum byte
- for _, b := range data[:len(data)-2] {
- checkSum += b
- }
- checkSum = checkSum & 0xFF
- if checkSum == data[len(data)-2] {
- return true
- }
- return false
- }
|