stc-broadcast.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. package broadcast
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "io"
  7. "net"
  8. "pbx-api-gin/internal/app/ami/action"
  9. "pbx-api-gin/internal/app/stc/active"
  10. msgdata "pbx-api-gin/internal/app/stc/data"
  11. "pbx-api-gin/internal/app/stc/priority"
  12. alstatus "pbx-api-gin/internal/app/stc/sendstatus"
  13. "pbx-api-gin/pkg/utils"
  14. "strconv"
  15. "time"
  16. )
  17. var tagLog = 0
  18. func HandleStcCmd(ctx context.Context, conn net.Conn) {
  19. for {
  20. select {
  21. case <-ctx.Done():
  22. return
  23. default:
  24. var buf bytes.Buffer
  25. tmp := make([]byte, 1024)
  26. if conn != nil {
  27. n, err := conn.Read(tmp)
  28. if err != nil {
  29. if err != io.EOF {
  30. conn.Close()
  31. }
  32. return
  33. }
  34. buf.Write(tmp[:n])
  35. }
  36. //lfshook.NewLogger().Logger.Infof("buf:%x==============================", buf.Bytes())
  37. for {
  38. packet, err := msgdata.ExtractPacket(&buf)
  39. if err != nil {
  40. utils.LoggerDebug.Printf("Parse error: %v, resetting buffer", err)
  41. buf.Reset() // 解析失败,清空避免污染
  42. break
  43. }
  44. if packet == nil {
  45. break // 当前无完整包,等待下次 ReadFrom
  46. }
  47. //处理 packet...
  48. go processPacket(packet)
  49. }
  50. }
  51. }
  52. }
  53. // 处理单个数据包(原 switch 逻辑迁移过来)
  54. func processPacket(packet []byte) {
  55. if len(packet) < 6 {
  56. utils.LoggerDebug.Printf("Get data wrong length from STC ! Data:%x", packet)
  57. return
  58. }
  59. //for recv data log debug
  60. if packet[5] != 0x0b && packet[5] != 0x09 {
  61. utils.LoggerDebug.Printf("Get data from STC:%x", packet)
  62. }
  63. //重联模式判断
  64. if packet[5] == 0x0b {
  65. active.TrainUnionID = int(packet[8])
  66. active.TrainUnionMaster = int(packet[9])
  67. active.TrainUnionMode = int(packet[10])
  68. if active.TrainUnionID != 0 {
  69. utils.LoggerDebug.Printf("active.TrainUnionID:%x active.TrainUnionMaster:%x active.TrainUnionMode:%x ", active.TrainUnionID, active.TrainUnionMaster, active.TrainUnionMode)
  70. }
  71. if active.TrainUnionMode == 1 && active.TrainUnionMaster == 1 { //尾--头,重联主车,6车服务器停用
  72. if active.CabNum == "6" {
  73. return
  74. }
  75. } else if active.TrainUnionMode == 1 && active.TrainUnionMaster == 2 { //尾--头,重联从车,1车服务器停用
  76. if active.CabNum == "1" {
  77. return
  78. }
  79. } else if active.TrainUnionMode == 2 && active.TrainUnionMaster == 1 { //尾--尾,重联主车,6车服务器停用
  80. if active.CabNum == "6" {
  81. return
  82. }
  83. } else if active.TrainUnionMode == 2 && active.TrainUnionMaster == 2 { //尾--尾,重联从车,6车服务器停用
  84. if active.CabNum == "6" {
  85. return
  86. }
  87. } else if active.TrainUnionMode == 3 && active.TrainUnionMaster == 1 { //头--头,重联主车,1车服务器停用
  88. if active.CabNum == "1" {
  89. return
  90. }
  91. } else if active.TrainUnionMode == 3 && active.TrainUnionMaster == 2 { //头--头,重联从车,1车服务器停用
  92. if active.CabNum == "1" {
  93. return
  94. }
  95. } else if active.TrainUnionMode == 4 && active.TrainUnionMaster == 1 { //头--尾,重联主车,1车服务器停用
  96. if active.CabNum == "1" {
  97. return
  98. }
  99. } else if active.TrainUnionMode == 4 && active.TrainUnionMaster == 2 { //头--尾,重联从车,6车服务器停用
  100. if active.CabNum == "6" {
  101. return
  102. }
  103. }
  104. }
  105. //check if Master role
  106. if !active.Master {
  107. if tagLog == 0 {
  108. utils.LoggerDebug.Printf("Not Master Role , Ignore all data from STC !")
  109. tagLog = 1
  110. }
  111. return
  112. }
  113. tagLog = 0
  114. switch packet[5] {
  115. case 0x01: //心跳
  116. return
  117. case 0x02: // 自动报站
  118. if priority.CheckPriority("STNA") {
  119. action.HangupTask()
  120. StationAnnAuto(packet[8:])
  121. } else {
  122. alstatus.PaStatus("", "STNA", "refuse")
  123. }
  124. case 0x03: // 手动报站
  125. if priority.CheckPriority("STNS") {
  126. action.HangupTask()
  127. StationAnnAuto(packet[8:])
  128. } else {
  129. alstatus.PaStatus("", "STNS", "refuse")
  130. }
  131. case 0x04: // 手动服务消息、紧急广播
  132. if priority.CheckPriority("SVM") {
  133. action.HangupTask()
  134. EmgMsg(packet[8:])
  135. } else {
  136. alstatus.PaStatus("", "SVM", "refuse")
  137. }
  138. case 0x05: // STOP
  139. AnnStop([4]byte{packet[8], packet[9], packet[10], packet[11]})
  140. //case 0x06: // 关门提示(预留)
  141. //DoorStatusNotice(packet[8:])
  142. //case 0x07: // 司机室位置(预留)
  143. case 0x08: // EED报警
  144. EEDAlarm(packet[8:])
  145. //case 0x09: // 列车运行模式(预留)
  146. // RuningStatus(packet[8:])
  147. //case 0x0a:(预留)
  148. //case 0x0b: // 重联方式
  149. // active.TrainUnionMode = int(packet[9])
  150. }
  151. }
  152. // EED报警,激活报警器到队列
  153. func EEDAlarm(data []byte) {
  154. cab := data[0]
  155. pos := data[1]
  156. alarm := fmt.Sprintf("7%02d%d", cab, pos)
  157. //utils.LoggerDebug.Printf("Type:STN FileName:%x Count:%x SpecialVoice:%+v Interval:%+v", filename, cycleCount, specialVoice, delay)
  158. action.Dial(alarm, "0300", "queues", "", "")
  159. }
  160. // DSN ,开关门提示
  161. func DoorStatusNotice(data []byte) (err error) {
  162. delay := data[0]
  163. cycleCount := data[1]
  164. FileLen := int(data[2])
  165. filename := msgdata.SubstrByRune(string(data[3:]), 0, int(FileLen)-4)
  166. //utils.LoggerDebug.Printf("Type:STN FileName:%x Count:%x SpecialVoice:%+v Interval:%+v", filename, cycleCount, specialVoice, delay)
  167. action.PlaybackPacu(strconv.Quote(filename), int(cycleCount), int(delay), "DCS")
  168. return nil
  169. }
  170. // APA , 自动报站广播
  171. func StationAnnAuto(data []byte) (err error) {
  172. //StationStatus := int(data[0])
  173. filelen := data[1]
  174. filename := msgdata.SubstrByRune(string(data[2:]), 0, int(filelen)-4)
  175. //utils.LoggerDebug.Printf("Type:STN FileName:%x Count:%x SpecialVoice:%+v Interval:%+v", filename, cycleCount, specialVoice, delay)
  176. action.PlaybackPacu(strconv.Quote(filename), 1, 0, "STNA")
  177. return nil
  178. }
  179. // SPA , 手动报站广播
  180. func StationAnnManu(data []byte) (err error) {
  181. //StationStatus := int(data[0])
  182. filelen := data[1]
  183. filename := msgdata.SubstrByRune(string(data[2:]), 0, int(filelen)-4)
  184. //utils.LoggerDebug.Printf("Type:STN FileName:%x Count:%x SpecialVoice:%+v Interval:%+v", filename, cycleCount, specialVoice, delay)
  185. action.PlaybackPacu(strconv.Quote(filename), 1, 0, "STNS")
  186. return nil
  187. }
  188. // EMG ,紧急服务消息广播
  189. func EmgMsg(data []byte) {
  190. delay := data[0]
  191. cycleCount := data[1]
  192. filelen := int(data[2])
  193. filename := msgdata.SubstrByRune(string(data[3:]), 0, filelen-4)
  194. utils.LoggerDebug.Printf("Type:EMG FileName:%x Count:%x Interval:%+v", filename, cycleCount, delay)
  195. if int(cycleCount) == 255 {
  196. action.PlaybackPacu(strconv.Quote(filename), 9999999, int(delay), "SVM")
  197. } else {
  198. action.PlaybackPacu(strconv.Quote(filename), int(cycleCount), int(delay), "SVM")
  199. }
  200. }
  201. // 停止指定类型广播
  202. func AnnStop(data [4]byte) {
  203. //lfshook.NewLogger().Logger.Infof("=========AnnStop Type %x", data[0])
  204. utils.LoggerDebug.Printf("Stop PA Type:%x (自动报站=1,手动报站=2,服务信息=3)", data[0])
  205. switch data[0] {
  206. case 0x01: //停止自动广播(自动报站)
  207. taskInfo, ok := priority.RegistryTask.Get("STNA")
  208. if ok {
  209. action.ConfbridgeKick(taskInfo.ConfbridgeID, "all")
  210. action.Hangup(taskInfo.RunChannel)
  211. }
  212. time.Sleep(time.Millisecond * 100)
  213. case 0x02: //停止半自动广播(手动报站)
  214. taskInfo, ok := priority.RegistryTask.Get("STNS")
  215. if ok {
  216. action.ConfbridgeKick(taskInfo.ConfbridgeID, "all")
  217. action.Hangup(taskInfo.RunChannel)
  218. }
  219. time.Sleep(time.Millisecond * 100)
  220. case 0x03: //停止服务信息广播(紧急广播)
  221. taskInfo, ok := priority.RegistryTask.Get("SVM")
  222. if ok {
  223. action.ConfbridgeKick(taskInfo.ConfbridgeID, "all")
  224. action.Hangup(taskInfo.RunChannel)
  225. }
  226. time.Sleep(time.Millisecond * 100)
  227. }
  228. }