123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- package protocol
- import (
- "bytes"
- "dlt645-server/errors"
- "encoding/binary"
- "encoding/json"
- "fmt"
- log "github.com/sirupsen/logrus"
- "reflect"
- "strconv"
- )
- // 消息包
- type Message struct {
- Header Header
- Body Entity
- }
- type DHeader struct {
- MsgID MsgID
- }
- // 协议编码
- func (message *Message) Encode() ([]byte, error) {
- // 编码消息体
- var err error
- var body []byte
- if message.Body != nil && !reflect.ValueOf(message.Body).IsNil() {
- body, err = message.Body.Encode()
- if err != nil {
- return nil, err
- }
- }
- // 二进制转义
- buffer := bytes.NewBuffer(nil)
- message.write(buffer, body)
- return buffer.Bytes(), nil
- }
- // 协议解码
- func (message *Message) Decode(data []byte) error {
- // 检验标志位
- length := len(data)
- if length == 0 {
- return errors.ErrInvalidMessage
- }
- if data[0] != ReceiveByte && data[0] != RegisterByte {
- return errors.ErrInvalidMessage
- }
- if !message.checkSum(data){
- return errors.ErrInvalidCheckSum
- }
- var header Header
- var err error
- //处理注册包
- if data[0] == RegisterByte {
- header := Header{}
- _ = json.Unmarshal(data, &header)
- //fmt.Println(header.Imei)
- //fmt.Println()
- header.IccID, err = strconv.ParseUint(header.Imei, 10, 64)
- header.MsgID = 0x0040 //消息ID
- if err == nil {
- message.Body = nil
- } else {
- log.WithFields(log.Fields{
- "id": fmt.Sprintf("0x%x", header.MsgID),
- "reason": err,
- }).Warn("failed to decode message")
- }
- message.Header = header
- return nil
- } else if len(data) < 8 {
- log.WithFields(log.Fields{
- "data": fmt.Sprintf("V:%v", data),
- "reason": "error datalen",
- }).Warn("failed to decode message")
- } else {
- header.MsgID = MsgID(binary.BigEndian.Uint32(data[10:15])) //消息ID
- entity, _, err := message.decode(uint32(header.MsgID), data[:]) //解析实体对象 entity buffer : 为消息标识
- if err == nil {
- message.Body = entity
- } else {
- log.WithFields(log.Fields{
- "id": fmt.Sprintf("0x%x", header.MsgID),
- "reason": err,
- }).Warn("failed to decode message")
- }
- }
- message.Header = header
- return nil
- }
- //--->
- func (message *Message) decode(dataType uint32, data []byte) (Entity, int, error) {
- creator, ok := entityMapper[dataType]
- if !ok {
- return nil, 0, errors.ErrTypeNotRegistered
- }
- entity := creator()
- count, err := entity.Decode(data) //解析data数据
- if err != nil {
- return nil, 0, err
- }
- return entity, count, nil
- }
- // 写入二进制数据
- 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
- }
|