BxDataPack.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package bx
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "fmt"
  6. )
  7. type BxDataPack struct {
  8. WRAP_A5_NUM int
  9. WRAP_5A_NUM int
  10. dstAddr uint16
  11. srcAddr uint16
  12. r0 byte
  13. r1 byte
  14. r2 byte
  15. option byte
  16. crcMode byte
  17. dispMode byte
  18. deviceType byte
  19. version byte
  20. dataLen uint16
  21. data []byte
  22. crc uint16
  23. }
  24. func NewBxDataPackData(data []byte) BxDataPack {
  25. return BxDataPack{
  26. data: data,
  27. dataLen: uint16(len(data)),
  28. WRAP_A5_NUM: 8,
  29. WRAP_5A_NUM: 1,
  30. dstAddr: 0xfffe,
  31. srcAddr: 0x8000,
  32. deviceType: 0xfe,
  33. version: 0x02,
  34. }
  35. }
  36. func NewBxDataPackCmd(cmd BxCmd) BxDataPack {
  37. b := cmd.Build()
  38. fmt.Printf("build Data:% 02x\n", b)
  39. return BxDataPack{
  40. data: b,
  41. dataLen: uint16(len(b)),
  42. WRAP_A5_NUM: 8,
  43. WRAP_5A_NUM: 1,
  44. dstAddr: 0x0002,
  45. srcAddr: 0x8000,
  46. deviceType: 0xfe,
  47. version: 0x02,
  48. }
  49. }
  50. // SetDispType 注:特殊动态区不支持动态模式
  51. // 0x00:普通模式,动态区与节目可同时显示,但各区域不可重叠。
  52. // 0x01:动态模式,优先显示动态区,无动态区则显示节目,动态区与节目区可重叠。
  53. func (dp *BxDataPack) SetDispType(typ byte) {
  54. dp.dispMode = typ
  55. }
  56. func (dp *BxDataPack) wrap(src []byte) []byte {
  57. len := len(src)
  58. for _, v := range src { //每次转义会使长度+1
  59. if v == 0xa5 || v == 0x5a || v == 0xa6 || v == 0x5b {
  60. len++
  61. }
  62. }
  63. len += dp.WRAP_5A_NUM
  64. len += dp.WRAP_A5_NUM
  65. dst := make([]byte, len)
  66. offset := 0
  67. for i := 0; i < dp.WRAP_A5_NUM; i++ {
  68. dst[offset] = 0xa5
  69. offset++
  70. }
  71. //转义
  72. for _, v := range src {
  73. if v == 0xa5 {
  74. dst[offset] = 0xa6
  75. offset++
  76. dst[offset] = 0xa2
  77. offset++
  78. } else if v == 0xa6 {
  79. dst[offset] = 0xa6
  80. offset++
  81. dst[offset] = 0xa1
  82. offset++
  83. } else if v == 0x5a {
  84. dst[offset] = 0x5b
  85. offset++
  86. dst[offset] = 0xa2
  87. offset++
  88. } else if v == 0x5b {
  89. dst[offset] = 0x5b
  90. offset++
  91. dst[offset] = 0x01
  92. offset++
  93. } else {
  94. dst[offset] = v
  95. offset++
  96. }
  97. }
  98. for i := 0; i < dp.WRAP_5A_NUM; i++ {
  99. dst[offset] = 0x5a
  100. offset++
  101. }
  102. return dst
  103. }
  104. func (dp *BxDataPack) Pack() []byte {
  105. w := bytes.NewBuffer(make([]byte, 0, 1024))
  106. //目标地址
  107. binary.Write(w, binary.LittleEndian, dp.dstAddr)
  108. //源地址
  109. binary.Write(w, binary.LittleEndian, dp.srcAddr)
  110. binary.Write(w, binary.LittleEndian, dp.r0)
  111. binary.Write(w, binary.LittleEndian, dp.r1)
  112. binary.Write(w, binary.LittleEndian, dp.r2)
  113. binary.Write(w, binary.LittleEndian, dp.option)
  114. binary.Write(w, binary.LittleEndian, dp.crcMode)
  115. binary.Write(w, binary.LittleEndian, dp.dispMode)
  116. binary.Write(w, binary.LittleEndian, dp.deviceType)
  117. binary.Write(w, binary.LittleEndian, dp.version)
  118. binary.Write(w, binary.LittleEndian, dp.dataLen)
  119. binary.Write(w, binary.LittleEndian, dp.data)
  120. dp.crc = 0x0
  121. binary.Write(w, binary.LittleEndian, dp.crc)
  122. data := w.Bytes()
  123. len := w.Len()
  124. dp.crc = CRC16(data, 0, len-2)
  125. data[len-2] = byte(dp.crc & 0xff)
  126. data[len-1] = byte(dp.crc >> 8)
  127. return dp.wrap(data)
  128. }
  129. func dpParse(src []byte, length int) *BxDataPack {
  130. dst := unwrap(src, length)
  131. if dst == nil {
  132. return nil
  133. }
  134. crcCalculated := CRC16(dst, 0, len(dst)-2)
  135. crcGot := bytesToUint16(dst, len(dst)-2, binary.LittleEndian)
  136. if crcCalculated != crcGot {
  137. return nil
  138. }
  139. dp := BxDataPack{}
  140. offset := 0
  141. //目标地址
  142. dp.dstAddr = bytesToUint16(dst, offset, binary.LittleEndian)
  143. offset += 2
  144. //源地址
  145. dp.srcAddr = bytesToUint16(dst, offset, binary.LittleEndian)
  146. offset += 2
  147. //保留字 r0,r1,r2
  148. dp.r0 = dst[offset]
  149. offset++
  150. dp.r1 = dst[offset]
  151. offset++
  152. dp.r2 = dst[offset]
  153. offset++
  154. dp.option = dst[offset]
  155. offset++
  156. dp.crcMode = dst[offset]
  157. offset++
  158. dp.dispMode = dst[offset]
  159. offset++
  160. dp.deviceType = dst[offset]
  161. offset++
  162. dp.version = dst[offset]
  163. offset++
  164. dp.dataLen = bytesToUint16(dst, offset, binary.LittleEndian)
  165. offset += 2
  166. //数据
  167. dp.data = dst[offset : offset+int(dp.dataLen)]
  168. offset += int(dp.dataLen)
  169. dp.crc = bytesToUint16(dst, offset, binary.LittleEndian)
  170. return &dp
  171. }
  172. func unwrap(src []byte, length int) []byte {
  173. len := length
  174. for _, v := range src {
  175. if v == 0xa5 || v == 0x5a || v == 0xa6 {
  176. len--
  177. }
  178. }
  179. //如果计算的帧长度为0, 说明数据不正确
  180. if len == 0 {
  181. return nil
  182. }
  183. dst := make([]byte, len)
  184. offset := 0
  185. for i := 0; i < length; {
  186. if src[i] == 0xa5 || src[i] == 0x5a {
  187. i++
  188. } else if src[i] == 0xa6 {
  189. if src[i+1] == 0x01 {
  190. dst[offset] = 0xa6
  191. offset++
  192. i = i + 2
  193. } else if src[i+1] == 0x02 {
  194. dst[offset] = 0xa5
  195. offset++
  196. i = i + 2
  197. } else {
  198. return nil
  199. }
  200. } else if src[i] == 0x5b {
  201. if src[i+1] == 0x01 {
  202. dst[offset] = 0x5b
  203. offset++
  204. i = i + 2
  205. } else if src[i+1] == 0x02 {
  206. dst[offset] = 0x5a
  207. offset++
  208. i = i + 2
  209. } else {
  210. return nil
  211. }
  212. } else {
  213. dst[offset] = src[i]
  214. offset++
  215. i++
  216. }
  217. }
  218. return dst
  219. }