ap.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // 协议栈模块
  2. // 秒寻科技
  3. // zt 2024-09-15
  4. package ap
  5. import (
  6. "encoding/binary"
  7. "errors"
  8. "ipsomc/module/ps/psmodel"
  9. )
  10. type Ap struct {
  11. }
  12. // 全局变量
  13. var (
  14. s_crc_table = [16]uint16{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef}
  15. )
  16. // AP层上行处理单元
  17. func (obj *Ap) ApUl(dataList []byte, dataListLen *int) (*psmodel.PS_HEAD_T, *psmodel.PS_TAIL_T, error) {
  18. newLen := *dataListLen
  19. var wCrc uint16 = 0
  20. var psCrc uint16 = 0
  21. var psHeadModel *psmodel.PS_HEAD_T
  22. var psTailModel *psmodel.PS_TAIL_T
  23. var wStopIndex uint16 = 0
  24. //长度容错检查
  25. if newLen < psmodel.PS_FRAME_MIN_LEN {
  26. return nil, nil, errors.New("帧长度不合法")
  27. }
  28. //帧头帧尾检查
  29. if dataList[0] != psmodel.PS_AP_END_FLAG || dataList[newLen-1] != psmodel.PS_AP_END_FLAG {
  30. return nil, nil, errors.New("数据错误")
  31. }
  32. //逆向转义处理
  33. if err := obj.ApTransferReverse(dataList, &newLen); err != nil {
  34. return nil, nil, err
  35. }
  36. *dataListLen = newLen
  37. //解析数据到结构(协议头,协议尾)
  38. psHeadModel, psTailModel = obj.ApParseSlicToStruct(dataList, int32(newLen))
  39. //CRC校验
  40. psCrc = psTailModel.Crc //数据报文中的CRC校验码
  41. wStopIndex = uint16(newLen - 3)
  42. wCrc = obj.ApGenCrc16(dataList[1:wStopIndex], uint16(newLen), 0) //基于数据报文生成CRC校验码
  43. if wCrc != psCrc {
  44. return psHeadModel, psTailModel, errors.New("CRC校验错误")
  45. }
  46. return psHeadModel, psTailModel, nil
  47. }
  48. // 对输入数据实施逆向转义处理
  49. // byData:待逆转义数据,返回参数
  50. // pdwLen:数据长度,返回参数
  51. func (obj *Ap) ApTransferReverse(byData []byte, pdwLen *int) error {
  52. outData := make([]byte, 0)
  53. wCounter := 0
  54. // 逆向转义处理
  55. for i := 1; i < (*pdwLen - 1); i++ {
  56. //处理0x5E和0x5D两个连续字符
  57. if byData[i] == 0x5E && byData[i+1] == 0x5D {
  58. outData = append(outData, 0x5E)
  59. i++
  60. wCounter++
  61. } else if byData[i] == 0x5E && byData[i+1] == 0x7D { //处理0x5E和0x7D两个连续字符
  62. outData = append(outData, 0x7E)
  63. i++
  64. wCounter++
  65. } else { //处理其它字符
  66. outData = append(outData, byData[i])
  67. wCounter++
  68. }
  69. }
  70. // 将临时数据拷贝回byData切片中
  71. byData = byData[:0] //清空切片
  72. byData = append(byData, 0x7E) //保存帧头
  73. byData = append(byData, outData...) //保存数据
  74. byData = append(byData, 0x7E) //保存帧尾
  75. *pdwLen = wCounter + 2
  76. return nil
  77. }
  78. // 将切片数据解析到结构体中
  79. // dataList:数据切片
  80. func (obj *Ap) ApParseSlicToStruct(dataList []byte, dwLen int32) (*psmodel.PS_HEAD_T, *psmodel.PS_TAIL_T) {
  81. var psHeadModel psmodel.PS_HEAD_T
  82. var psTailModel psmodel.PS_TAIL_T
  83. var wTailIndex uint16 = 0
  84. var wStopIndex uint16 = 0
  85. //AP层
  86. psHeadModel.StApHead.StartFlag = dataList[0] //协议头
  87. //VP层
  88. psHeadModel.StVpHead.ProjectID = int(binary.LittleEndian.Uint32(dataList[1:5])) //项目编号 //项目编号
  89. psHeadModel.StVpHead.PacketNo = dataList[5] //协议包号
  90. psHeadModel.StVpHead.DeviceID = int(binary.LittleEndian.Uint32(dataList[6:10])) //设备编号
  91. psHeadModel.StVpHead.VpFlag = dataList[10] //VP层标识符
  92. psHeadModel.StVpHead.McpType = dataList[11] //MCP层协议类型
  93. //MCP层
  94. psHeadModel.StMcpHead.Comd = dataList[12] //MCP命令标识符
  95. psHeadModel.StMcpHead.Resp = dataList[13] //MCP响应标识符
  96. ////帧尾
  97. wTailIndex = uint16(dwLen - 3)
  98. wStopIndex = uint16(dwLen - 1)
  99. psTailModel.Crc = uint16(binary.LittleEndian.Uint16(dataList[wTailIndex:wStopIndex])) //CRC校验码
  100. psTailModel.StopFlag = dataList[wStopIndex] //结束标识符
  101. return &psHeadModel, &psTailModel
  102. }
  103. // 生成CRC16校验码
  104. // data:数据
  105. // len:数据长度
  106. // def_crc
  107. func (obj *Ap) ApGenCrc16(data []byte, len uint16, def_crc uint16) uint16 {
  108. var crc uint16 = def_crc
  109. var crc_h4 uint8 = 0
  110. for _, v := range data {
  111. crc_h4 = (uint8)(crc >> 12)
  112. crc <<= 4
  113. crc ^= s_crc_table[crc_h4^(v>>4)]
  114. crc_h4 = (uint8)(crc >> 12)
  115. crc <<= 4
  116. crc ^= s_crc_table[crc_h4^(v&0x0f)]
  117. }
  118. return crc
  119. }
  120. // AP层下行处理单元
  121. func (obj *Ap) ApDl(dataList []byte, dataListLen int) ([]byte, int, error) {
  122. newLen := dataListLen
  123. //长度容错检查
  124. if newLen < psmodel.PS_FRAME_MIN_LEN {
  125. return nil, 0, errors.New("帧长度不合法")
  126. }
  127. //帧头帧尾检查
  128. if dataList[0] != psmodel.PS_AP_END_FLAG || dataList[newLen-1] != psmodel.PS_AP_END_FLAG {
  129. return nil, 0, errors.New("数据错误")
  130. }
  131. //转义处理
  132. apFrame, err := obj.ApTransfer(dataList, &newLen)
  133. if err != nil {
  134. return nil, 0, err
  135. }
  136. return apFrame, newLen, nil
  137. }
  138. // 对输入数据实施转义处理
  139. // byData:待逆转义数据,返回参数
  140. // pdwLen:数据长度,返回参数
  141. func (obj *Ap) ApTransfer(byData []byte, pdwLen *int) ([]byte, error) {
  142. outData := make([]byte, 0)
  143. //帧头
  144. outData = append(outData, 0x7E)
  145. // 转义处理
  146. for i := 1; i < (*pdwLen - 1); i++ {
  147. if byData[i] == 0x5E { //将0x5E转义成0x5E,0x5D
  148. outData = append(outData, 0x5E)
  149. outData = append(outData, 0x5D)
  150. } else if byData[i] == 0x7E { //将0x7E转义成0x5E,0x7D
  151. outData = append(outData, 0x5E)
  152. outData = append(outData, 0x7D)
  153. } else { //其它字符
  154. outData = append(outData, byData[i])
  155. }
  156. }
  157. //帧尾
  158. outData = append(outData, 0x7E) //保存帧头
  159. *pdwLen = len(byData) //队列长度
  160. return outData, nil
  161. }