protocol.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. package ym485
  2. import (
  3. "encoding/hex"
  4. "errors"
  5. "fmt"
  6. "math"
  7. "strconv"
  8. "strings"
  9. "github.com/valyala/bytebufferpool"
  10. )
  11. var ErrorInvalidChecksum = errors.New("数据校验错误")
  12. var ErrorInvalidLenght = errors.New("数据长度不够")
  13. var ErrorEncode = errors.New("编码错误")
  14. type DataPack struct {
  15. Start byte //帧起始符,恒为0x68,1字节
  16. Addr string //地址域,6字节,整数,大端传输
  17. Start2 byte //帧起始符,恒为0x68,1字节
  18. Ctl uint8 //控制码,1字节
  19. DataLen uint8 //数据域长度,1字节
  20. Data []byte //数据域
  21. Cs uint8 //Start到Cs之前的所有字节模256
  22. End byte //结束符号,恒为0x16,1字节
  23. }
  24. func (o *DataPack) EnCode(Addr string, Ctl uint8, Data []byte) (*bytebufferpool.ByteBuffer, error) {
  25. //初始化成员
  26. o.Start = 0x68
  27. o.Addr = Addr
  28. o.Start2 = 0x68
  29. o.Ctl = Ctl
  30. o.DataLen = uint8(len(Data))
  31. o.Data = Data
  32. o.End = 0x16
  33. //addr
  34. tmpAddr := EncodeAddr(o.Addr)
  35. if tmpAddr == nil {
  36. return nil, ErrorEncode
  37. }
  38. //序列化
  39. buf := bytebufferpool.Get()
  40. buf.WriteByte(o.Start)
  41. buf.Write(tmpAddr)
  42. buf.WriteByte(o.Start2)
  43. buf.WriteByte(o.Ctl)
  44. buf.WriteByte(o.DataLen)
  45. if o.DataLen > 0 {
  46. TmpData := make([]byte, o.DataLen)
  47. for i, b := range o.Data {
  48. TmpData[i] = b + 0x33
  49. }
  50. buf.Write(TmpData)
  51. }
  52. //计算校验码
  53. o.Cs = CheckSum(buf.Bytes())
  54. buf.WriteByte(o.Cs)
  55. buf.WriteByte(o.End)
  56. return buf, nil
  57. }
  58. func CheckSum(data []byte) uint8 {
  59. var sum uint64
  60. for _, c := range data {
  61. sum += uint64(c)
  62. }
  63. return uint8(sum % 256)
  64. }
  65. func VerifySum(data []byte) bool {
  66. if len(data) >= 12 {
  67. sum := data[len(data)-2] //倒数第二个字节
  68. sum_ := CheckSum(data[0 : len(data)-2])
  69. if sum == sum_ {
  70. return true
  71. }
  72. }
  73. return false
  74. }
  75. func (o *DataPack) DeCode(data []byte) error {
  76. if len(data) >= 12 {
  77. o.Start = data[0]
  78. o.Addr = DecodeAddr(data[1:7])
  79. o.Start2 = data[7]
  80. o.Ctl = data[8]
  81. o.DataLen = data[9]
  82. if o.DataLen > 0 {
  83. if o.DataLen > uint8(len(data)-12) {
  84. return ErrorInvalidLenght
  85. }
  86. o.Data = make([]byte, o.DataLen)
  87. for i, b := range data[10 : 10+o.DataLen] {
  88. o.Data[i] = b - 0x33
  89. }
  90. }
  91. o.Cs = data[10+o.DataLen]
  92. o.End = data[10+o.DataLen+1]
  93. cs := CheckSum(data[0 : 10+o.DataLen])
  94. if o.Cs != cs {
  95. return ErrorInvalidChecksum
  96. }
  97. return nil
  98. }
  99. return ErrorInvalidLenght
  100. }
  101. func EncodeAddr(Addr string) []byte {
  102. len0 := len(Addr)
  103. repeat := 12 - len0 //地址长度最多12个字符
  104. if repeat > 0 {
  105. Addr = strings.Repeat("0", repeat) + Addr
  106. }
  107. buf, err := ASCII2Lbcd([]byte(Addr))
  108. if err != nil {
  109. return nil
  110. }
  111. buf = Rotate(buf)
  112. return buf
  113. }
  114. func DecodeAddr(addr []byte) string {
  115. if len(addr) == 0 {
  116. return ""
  117. }
  118. buf := Rotate(addr)
  119. buf = Lbcd2ASCII(buf)
  120. return strings.TrimLeft(string(buf), "0")
  121. }
  122. // DecodeFloat64 prec为小数部分的长度
  123. func DecodeFloat64(dat []byte, prec int) (float64, error) {
  124. if len(dat) == 0 {
  125. return 0.0, errors.New("参数为空")
  126. }
  127. data := Rotate(dat)
  128. ss := []byte(hex.EncodeToString(data))
  129. if prec == 0 {
  130. return strconv.ParseFloat(string(ss), 64)
  131. }
  132. fss := make([]byte, 0, len(ss)+1)
  133. fss = append(fss, ss[0:len(ss)-prec]...)
  134. fss = append(fss, '.')
  135. fss = append(fss, ss[len(ss)-prec:]...)
  136. return strconv.ParseFloat(string(fss), 64)
  137. }
  138. // EncodeFloat64 prec0为整数部分的长度
  139. //prec1为小数部分的长度
  140. func EncodeFloat64(fval float64, prec0, prec1 int) ([]byte, error) {
  141. if (prec0+prec1)%2 != 0 {
  142. return nil, errors.New("整数和小数总长度非双数")
  143. }
  144. ui := uint(fval * math.Pow10(prec1))
  145. ss := fmt.Sprintf("%d", ui)
  146. repeat := prec0 + prec1 - len(ss)
  147. ss = strings.Repeat("0", repeat) + ss
  148. buf, err := ASCII2Lbcd([]byte(ss))
  149. if err != nil {
  150. return nil, err
  151. }
  152. buf = Rotate(buf)
  153. return buf, nil
  154. }
  155. func ReleaseByteBuffer(p *bytebufferpool.ByteBuffer) {
  156. if p != nil {
  157. bytebufferpool.Put(p)
  158. }
  159. }