msgdata.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package msgdata
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. )
  7. // Protocol 定义协议数据结构
  8. type Protocol struct {
  9. StartBytes [3]byte // 协议开始符
  10. SourceID uint8 // 源设备号
  11. DestinationID uint8 // 目的设备号
  12. MessageID uint8 // 消息号
  13. DataLength uint16 // 数据长度
  14. Data []byte // 数据
  15. Checksum uint8 // 异或校验码
  16. EndByte uint8 // 协议结束符
  17. }
  18. // NewProtocol 创建一个新的 Protocol 实例
  19. func NewProtocol() *Protocol {
  20. return &Protocol{
  21. StartBytes: [3]byte{0x7F, 0x8E, 0x9D},
  22. EndByte: 0xFE,
  23. }
  24. }
  25. // Encode 将 Protocol 结构体编码为字节切片
  26. func (p *Protocol) Encode() ([]byte, error) {
  27. // 初始化字节缓冲区
  28. var buf bytes.Buffer // 写入协议开始符
  29. buf.Write(p.StartBytes[:])
  30. //init src and dst ID
  31. p.SourceID = 0x02
  32. p.DestinationID = 0x01
  33. // 写入源设备号、目的设备号和消息号
  34. binary.Write(&buf, binary.BigEndian, p.SourceID)
  35. binary.Write(&buf, binary.BigEndian, p.DestinationID)
  36. binary.Write(&buf, binary.BigEndian, p.MessageID)
  37. // 写入数据长度
  38. binary.Write(&buf, binary.BigEndian, p.DataLength)
  39. // 写入数据
  40. buf.Write(p.Data[:])
  41. // 计算校验码
  42. checksum := p.CalculateChecksum()
  43. p.Checksum = checksum // 写入校验码
  44. binary.Write(&buf, binary.BigEndian, p.Checksum)
  45. // 写入协议结束符
  46. binary.Write(&buf, binary.BigEndian, p.EndByte)
  47. return buf.Bytes(), nil
  48. }
  49. // CalculateChecksum 计算校验码
  50. func (p *Protocol) CalculateChecksum() uint8 {
  51. // 初始化校验码
  52. checksum := uint8(0)
  53. // 跳过协议开始符
  54. data := append([]byte{byte(p.SourceID), byte(p.DestinationID), byte(p.MessageID)},
  55. append([]byte{byte(p.DataLength >> 8), byte(p.DataLength)}, p.Data...)...)
  56. // 计算校验码
  57. for _, b := range data {
  58. checksum ^= b
  59. }
  60. return checksum
  61. }
  62. // Decode 解码字节切片为 Protocol 结构体
  63. func Decode(data []byte) (*Protocol, error) {
  64. if len(data) < 10 { // 最小长度:3(StartBytes) +1(SourceID) +1(DestinationID) +1(MessageID) +2(DataLength) +1(Checksum) +1(EndByte)
  65. return nil, fmt.Errorf("data too short")
  66. }
  67. p := NewProtocol()
  68. // 读取协议开始符
  69. copy(p.StartBytes[:], data[:3])
  70. // 读取源设备号、目的设备号和消息号
  71. p.SourceID = data[3]
  72. p.DestinationID = data[4]
  73. p.MessageID = data[5]
  74. // 读取数据长度
  75. p.DataLength = binary.BigEndian.Uint16(data[6:8])
  76. // 读取数据
  77. dataLength := int(p.DataLength)
  78. if len(data) < 10+dataLength {
  79. return nil, fmt.Errorf("data length mismatch")
  80. }
  81. p.Data = data[8 : 8+dataLength]
  82. // 读取校验码
  83. p.Checksum = data[8+dataLength]
  84. // 读取协议结束符
  85. p.EndByte = data[9+dataLength]
  86. // 验证校验码
  87. if p.Checksum != p.CalculateChecksum() {
  88. return nil, fmt.Errorf("checksum mismatch")
  89. }
  90. return p, nil
  91. }
  92. func SubstrByRune(s string, start, length int) string {
  93. runes := []rune(s)
  94. if start >= len(runes) {
  95. return ""
  96. }
  97. end := start + length
  98. if end > len(runes) {
  99. end = len(runes)
  100. }
  101. return string(runes[start:end])
  102. }
  103. // extractPacket 从 buffer 中提取第一个完整数据包
  104. func ExtractPacket(buf *bytes.Buffer) ([]byte, error) {
  105. data := buf.Bytes()
  106. startIdx := -1
  107. endIdx := -1
  108. // 查找起始标记 0x7f 0x83 0x9d
  109. for i := 0; i < len(data)-2; i++ {
  110. if data[i] == 0x7f && data[i+1] == 0x8e && data[i+2] == 0x9d {
  111. startIdx = i
  112. break
  113. }
  114. }
  115. if startIdx == -1 {
  116. // 没找到起始标记,清掉前面无用数据(防止 OOM)
  117. if buf.Len() > 1024 {
  118. buf.Next(buf.Len() - 10) // 保留最后10字节继续查找
  119. }
  120. return nil, fmt.Errorf("no start marker found")
  121. }
  122. // 从起始位置开始查找结束标记 0xFE
  123. for i := startIdx; i < len(data); i++ {
  124. if data[i] == 0xFE {
  125. endIdx = i
  126. break
  127. }
  128. }
  129. if endIdx == -1 {
  130. return nil, fmt.Errorf("no end marker found")
  131. }
  132. // 提取完整包 [startIdx 到 endIdx]
  133. packet := make([]byte, endIdx-startIdx+1)
  134. copy(packet, data[startIdx:endIdx+1])
  135. // 从 buffer 中删除已处理的数据
  136. buf.Next(endIdx + 1)
  137. return packet, nil
  138. }