psul.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. // 协议栈上行模块模块
  2. // 秒寻科技
  3. // zt 2024-08-31
  4. package psul
  5. import (
  6. "encoding/binary"
  7. "errors"
  8. "fmt"
  9. "ipsomc/core/dao/redis/redisapi"
  10. "ipsomc/module/oam"
  11. "ipsomc/module/ps/ap"
  12. "ipsomc/module/ps/mcp"
  13. "ipsomc/module/ps/mcpb"
  14. "ipsomc/module/ps/psdl"
  15. "ipsomc/module/ps/psmodel"
  16. "ipsomc/module/socket/socketmodel"
  17. "ipsomc/util"
  18. "net"
  19. )
  20. type PsUl struct {
  21. psDlApi psdl.PsDl
  22. apApi ap.Ap
  23. mcpApi mcp.Mcp
  24. mcpbApi mcpb.McpB
  25. oamReportApi oam.OamReport
  26. }
  27. // 协议栈上行模块
  28. // udpAddress:客户端地址
  29. // dataList:数据队列
  30. // dataListLen:数据队列长度
  31. func (obj *PsUl) PsUl(udpAddress *net.UDPAddr, dataList []byte, dataListLen int) error {
  32. var dwLen int = dataListLen
  33. var wStopIndex = 0
  34. var redisObj redisapi.RedisApi
  35. var clientAddr socketmodel.ClientAddr
  36. //AP层处理
  37. pstHeadModel, pstTailModel, err := obj.apApi.ApUl(dataList, &dwLen)
  38. if err != nil {
  39. return err
  40. }
  41. //更新redis中的客户端连接
  42. myViper := util.GetViper()
  43. expireTime := myViper.GetInt("token.pc_expire")
  44. if expireTime <= 0 {
  45. expireTime = 10 //10分钟
  46. }
  47. //保存客户端IP和端口资料
  48. redisKey := fmt.Sprintf("%08X", int(pstHeadModel.StVpHead.ProjectID)) + "-" + fmt.Sprintf("%08X", int(pstHeadModel.StVpHead.DeviceID))
  49. ip := udpAddress.IP
  50. clientAddr.IP = append(clientAddr.IP, ip[0])
  51. clientAddr.IP = append(clientAddr.IP, ip[1])
  52. clientAddr.IP = append(clientAddr.IP, ip[2])
  53. clientAddr.IP = append(clientAddr.IP, ip[3])
  54. clientAddr.Port = udpAddress.Port
  55. clientAddr.Zone = udpAddress.Zone
  56. redisObj.SetModelData(redisKey, &clientAddr, uint16(expireTime))
  57. //VP层处理
  58. wStopIndex = dwLen - 3
  59. if err := obj.VpUl(pstHeadModel, pstTailModel, dataList[14:wStopIndex], dwLen-psmodel.PS_FRAME_MIN_LEN); err != nil {
  60. return err
  61. }
  62. return nil
  63. }
  64. // 协议栈上行模块
  65. // tcpAddress:客户端地址
  66. // dataList:数据队列
  67. // dataListLen:数据队列长度
  68. func (obj *PsUl) PsUlTcp(clientAddress string, dataList []byte, dataListLen int) error {
  69. var dwLen int = dataListLen
  70. var wStopIndex = 0
  71. var redisObj redisapi.RedisApi
  72. var clientAddr socketmodel.ClientAddr
  73. //AP层处理
  74. pstHeadModel, pstTailModel, err := obj.apApi.ApUl(dataList, &dwLen)
  75. if err != nil {
  76. return err
  77. }
  78. //更新redis中的客户端连接
  79. myViper := util.GetViper()
  80. expireTime := myViper.GetInt("token.pc_expire")
  81. if expireTime <= 0 {
  82. expireTime = 10 //10分钟
  83. }
  84. //保存客户端IP和端口资料
  85. redisKey := fmt.Sprintf("%08X", int(pstHeadModel.StVpHead.ProjectID)) + "-" + fmt.Sprintf("%08X", int(pstHeadModel.StVpHead.DeviceID))
  86. clientAddr.Address = clientAddress
  87. redisObj.SetModelData(redisKey, &clientAddr, uint16(expireTime))
  88. //VP层处理
  89. wStopIndex = dwLen - 3
  90. if err := obj.VpUl(pstHeadModel, pstTailModel, dataList[14:wStopIndex], dwLen-psmodel.PS_FRAME_MIN_LEN); err != nil {
  91. return err
  92. }
  93. return nil
  94. }
  95. // VP层上行
  96. func (obj *PsUl) VpUl(stHeadModel *psmodel.PS_HEAD_T, stTailModel *psmodel.PS_TAIL_T, dataList []byte, dwLen int) error {
  97. vpModel := &stHeadModel.StVpHead
  98. //vp层解析
  99. if vpModel.McpType == psmodel.MCP_A { //MCP-A
  100. switch vpModel.VpFlag {
  101. case psmodel.VP_CMMD: //MCP-A命令
  102. if err := obj.McpUlCmdA(stHeadModel, stTailModel, dataList, dwLen); err != nil {
  103. return err
  104. }
  105. case psmodel.VP_RESP: //MCP-A应答
  106. obj.McpUlRespA(stHeadModel, dataList, dwLen)
  107. default:
  108. return errors.New("VP层格式错误")
  109. }
  110. } else if vpModel.McpType == psmodel.MCP_B { //MCP-B
  111. if vpModel.VpFlag == psmodel.VP_RESP {
  112. obj.mcpbApi.McpUlRespB(stHeadModel, dataList, dwLen)
  113. }
  114. } else {
  115. return errors.New("MCP层格式错误")
  116. }
  117. return nil
  118. }
  119. // MCP-A设置命令
  120. // dataList:MCP层数据队列
  121. // wLen:数据队列长度
  122. func (obj *PsUl) McpUlCmdA(stHeadModel *psmodel.PS_HEAD_T, stTailModel *psmodel.PS_TAIL_T, dataList []byte, wLen int) error {
  123. var wCurrentLen uint16 = 0
  124. var wLtvLen uint16 = 0
  125. var wCommand uint16 = 0
  126. ltvData := make([]byte, psmodel.PS_MCP_A_DATA_LEN)
  127. var byRespFlag uint8 = 0
  128. //遍历数据队列
  129. for {
  130. if wCurrentLen >= uint16(wLen) {
  131. break
  132. }
  133. //组织一个ltv数据
  134. wLtvLen = uint16(binary.LittleEndian.Uint16(dataList[wCurrentLen : wCurrentLen+2])) //长度
  135. wCommand = uint16(binary.LittleEndian.Uint16(dataList[wCurrentLen+2 : wCurrentLen+4])) //命令
  136. copy(ltvData, dataList[wCurrentLen+4:wCurrentLen+wLtvLen]) //数据
  137. //根据监控命令处理
  138. if wCommand >= 0x0201 && wCommand <= 0x02FF { // 上报
  139. obj.oamReportApi.OamReportCmd(stHeadModel, wCommand, ltvData, wLtvLen-4)
  140. byRespFlag = 1
  141. }
  142. //数据后移
  143. wCurrentLen += wLtvLen
  144. }
  145. //发送上行命令的应答
  146. if byRespFlag == 1 {
  147. if err := obj.psDlApi.PsDlResp(stHeadModel, dataList); err != nil {
  148. return err
  149. }
  150. }
  151. return nil
  152. }
  153. // MCP-A层上行应答
  154. // stHeadModel:协议头
  155. // dataList:MCP层数据队列
  156. // dataListLen:数据队列长度
  157. func (obj *PsUl) McpUlRespA(stHeadModel *psmodel.PS_HEAD_T, dataList []byte, dwLen int) error {
  158. mcpModel := stHeadModel.StMcpHead
  159. //应答标识符检查
  160. if mcpModel.Resp != psmodel.MCP_RESP_SUCC {
  161. return errors.New("响应消息失败")
  162. }
  163. //MCP命令检查
  164. switch mcpModel.Comd {
  165. case psmodel.MCP_A_REPORT: //上报
  166. case psmodel.MCP_A_QUERY: //查询
  167. obj.mcpApi.McpAUlRespQuery(stHeadModel, dataList, dwLen) //响应
  168. case psmodel.MCP_A_CONFIGURE: //配置
  169. obj.mcpApi.McpAUlRespSet(stHeadModel, dataList, dwLen) //响应
  170. default:
  171. return errors.New("MCP命令类型错误")
  172. }
  173. return nil
  174. }