123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- package bx
- import (
- "bytes"
- "encoding/binary"
- )
- type BxDataPack struct {
- WRAP_A5_NUM int
- WRAP_5A_NUM int
- dstAddr uint16
- srcAddr uint16
- r0 byte
- r1 byte
- r2 byte
- option byte
- crcMode byte
- dispMode byte
- deviceType byte
- version byte
- dataLen uint16
- data []byte
- crc uint16
- }
- func NewBxDataPackData(data []byte) BxDataPack {
- return BxDataPack{
- data: data,
- dataLen: uint16(len(data)),
- WRAP_A5_NUM: 8,
- WRAP_5A_NUM: 1,
- dstAddr: 0xfffe,
- srcAddr: 0x8000,
- deviceType: 0xfe,
- version: 0x02,
- }
- }
- func NewBxDataPackCmd(cmd BxCmd) BxDataPack {
- b := cmd.Build()
- return BxDataPack{
- data: b,
- dataLen: uint16(len(b)),
- WRAP_A5_NUM: 8,
- WRAP_5A_NUM: 1,
- dstAddr: 0x0002,
- srcAddr: 0x8000,
- deviceType: 0xfe,
- version: 0x02,
- }
- }
- // SetDispType 注:特殊动态区不支持动态模式
- // 0x00:普通模式,动态区与节目可同时显示,但各区域不可重叠。
- // 0x01:动态模式,优先显示动态区,无动态区则显示节目,动态区与节目区可重叠。
- func (dp *BxDataPack) SetDispType(typ byte) {
- dp.dispMode = typ
- }
- func (dp *BxDataPack) wrap(src []byte) []byte {
- len := len(src)
- for _, v := range src { //每次转义会使长度+1
- if v == 0xa5 || v == 0x5a || v == 0xa6 || v == 0x5b {
- len++
- }
- }
- len += dp.WRAP_5A_NUM
- len += dp.WRAP_A5_NUM
- dst := make([]byte, len)
- offset := 0
- for i := 0; i < dp.WRAP_A5_NUM; i++ {
- dst[offset] = 0xa5
- offset++
- }
- //转义
- for _, v := range src {
- if v == 0xa5 {
- dst[offset] = 0xa6
- offset++
- dst[offset] = 0xa2
- offset++
- } else if v == 0xa6 {
- dst[offset] = 0xa6
- offset++
- dst[offset] = 0xa1
- offset++
- } else if v == 0x5a {
- dst[offset] = 0x5b
- offset++
- dst[offset] = 0xa2
- offset++
- } else if v == 0x5b {
- dst[offset] = 0x5b
- offset++
- dst[offset] = 0x01
- offset++
- } else {
- dst[offset] = v
- offset++
- }
- }
- for i := 0; i < dp.WRAP_5A_NUM; i++ {
- dst[offset] = 0x5a
- offset++
- }
- return dst
- }
- func (dp *BxDataPack) Pack() []byte {
- w := bytes.NewBuffer(make([]byte, 0, 1024))
- //目标地址
- binary.Write(w, binary.LittleEndian, dp.dstAddr)
- //源地址
- binary.Write(w, binary.LittleEndian, dp.srcAddr)
- binary.Write(w, binary.LittleEndian, dp.r0)
- binary.Write(w, binary.LittleEndian, dp.r1)
- binary.Write(w, binary.LittleEndian, dp.r2)
- binary.Write(w, binary.LittleEndian, dp.option)
- binary.Write(w, binary.LittleEndian, dp.crcMode)
- binary.Write(w, binary.LittleEndian, dp.dispMode)
- binary.Write(w, binary.LittleEndian, dp.deviceType)
- binary.Write(w, binary.LittleEndian, dp.version)
- binary.Write(w, binary.LittleEndian, dp.dataLen)
- binary.Write(w, binary.LittleEndian, dp.data)
- dp.crc = 0x0
- binary.Write(w, binary.LittleEndian, dp.crc)
- data := w.Bytes()
- len := w.Len()
- dp.crc = CRC16(data, 0, len-2)
- data[len-2] = byte(dp.crc & 0xff)
- data[len-1] = byte(dp.crc >> 8)
- return dp.wrap(data)
- }
- func dpParse(src []byte, length int) *BxDataPack {
- dst := unwrap(src, length)
- if dst == nil {
- return nil
- }
- crcCalculated := CRC16(dst, 0, len(dst)-2)
- crcGot := bytesToUint16(dst, len(dst)-2, binary.LittleEndian)
- if crcCalculated != crcGot {
- return nil
- }
- dp := BxDataPack{}
- offset := 0
- //目标地址
- dp.dstAddr = bytesToUint16(dst, offset, binary.LittleEndian)
- offset += 2
- //源地址
- dp.srcAddr = bytesToUint16(dst, offset, binary.LittleEndian)
- offset += 2
- //保留字 r0,r1,r2
- dp.r0 = dst[offset]
- offset++
- dp.r1 = dst[offset]
- offset++
- dp.r2 = dst[offset]
- offset++
- dp.option = dst[offset]
- offset++
- dp.crcMode = dst[offset]
- offset++
- dp.dispMode = dst[offset]
- offset++
- dp.deviceType = dst[offset]
- offset++
- dp.version = dst[offset]
- offset++
- dp.dataLen = bytesToUint16(dst, offset, binary.LittleEndian)
- offset += 2
- //数据
- dp.data = dst[offset : offset+int(dp.dataLen)]
- offset += int(dp.dataLen)
- dp.crc = bytesToUint16(dst, offset, binary.LittleEndian)
- return &dp
- }
- func unwrap(src []byte, length int) []byte {
- len := length
- for _, v := range src {
- if v == 0xa5 || v == 0x5a || v == 0xa6 {
- len--
- }
- }
- //如果计算的帧长度为0, 说明数据不正确
- if len == 0 {
- return nil
- }
- dst := make([]byte, len)
- offset := 0
- for i := 0; i < length; {
- if src[i] == 0xa5 || src[i] == 0x5a {
- i++
- } else if src[i] == 0xa6 {
- if src[i+1] == 0x01 {
- dst[offset] = 0xa6
- offset++
- i = i + 2
- } else if src[i+1] == 0x02 {
- dst[offset] = 0xa5
- offset++
- i = i + 2
- } else {
- return nil
- }
- } else if src[i] == 0x5b {
- if src[i+1] == 0x01 {
- dst[offset] = 0x5b
- offset++
- i = i + 2
- } else if src[i+1] == 0x02 {
- dst[offset] = 0x5a
- offset++
- i = i + 2
- } else {
- return nil
- }
- } else {
- dst[offset] = src[i]
- offset++
- i++
- }
- }
- return dst
- }
|