index.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. package action
  2. import (
  3. "fmt"
  4. "os"
  5. "pbx-api-gin/internal/app/stc/active"
  6. "pbx-api-gin/internal/app/stc/priority"
  7. alstatus "pbx-api-gin/internal/app/stc/sendstatus"
  8. "pbx-api-gin/internal/pkg/configs"
  9. "pbx-api-gin/pkg/lfshook"
  10. "pbx-api-gin/pkg/utils"
  11. "sort"
  12. "strings"
  13. "time"
  14. "github.com/sirupsen/logrus"
  15. "github.com/tqcenglish/amigo-go"
  16. "github.com/tqcenglish/amigo-go/pkg"
  17. )
  18. var AminInstance *amigo.Amigo
  19. var trainInfo = ""
  20. func HandleAMI(event map[string]string) {
  21. switch event["Event"] {
  22. case "DTMFBegin": //ICP interrupt PAD
  23. lfshook.NewLogger().Infof("=========%s====caller:%s=====digit:%s==", event["Event"], event["CallerIDNum"], event["Digit"])
  24. if utils.IsICP(event["CallerIDNum"]) && event["Exten"] != "" {
  25. //PA interrupt PAD
  26. switch event["Digit"] {
  27. case "#":
  28. //lfshook.NewLogger().Infof("===PA interrupt PAD====== ")
  29. InterruptRunningTask("PA")
  30. case "*": //Cab cab interrupt PAD
  31. //lfshook.NewLogger().Infof("===Cab cab interrupt PAD====== ")
  32. InterruptRunningTask("C2C")
  33. }
  34. }
  35. case "UserEvent": // RCD filename; PA;CPA; CabCab
  36. lfshook.NewLogger().Infof("========event:%s File:%s", event["Event"], event["FILENAME"])
  37. if event["UserEvent"] == "CallType" && (event["Type"] == "PA" || event["Type"] == "CPA") { //PA start; check manual PA priority
  38. //PA & CPA interrupt others
  39. if utils.IsICP(event["CallerIDNum"]) { //PA
  40. if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
  41. Hangup(event["CallerIDNum"])
  42. }
  43. if priority.CheckPriority("ManuPa") {
  44. //hangup others if priority is higher
  45. lfshook.NewLogger().Infof("UserEvent event :PA start")
  46. InterruptRunningTask("PA") //PA interrupt other
  47. } else {
  48. Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
  49. }
  50. } else if utils.IsIO(event["CallerIDNum"]) { // CPA
  51. if priority.CheckPriority("CPA") {
  52. if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
  53. Hangup(event["CallerIDNum"])
  54. } else if active.ActivedCab == "1" && event["CallerIDNum"] == "1411" {
  55. Hangup(event["CallerIDNum"])
  56. } else if active.ActivedCab == "8" && event["CallerIDNum"] == "1481" {
  57. Hangup(event["CallerIDNum"])
  58. }
  59. //hangup others if priority is higher
  60. InterruptRunningTask("CPA") //CPA interrupt other
  61. } else {
  62. Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
  63. }
  64. }
  65. } else if event["UserEvent"] == "CallType" && event["Type"] == "C2C" { //CabCab start; check cab cab priority
  66. if priority.CheckPriority("CabCab") { // interrupt OCC-PAD
  67. //C2C start PAD interrupt
  68. taskName, _, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  69. lfshook.NewLogger().Infof("HighestPriorityRunningTask get task :%+v", taskName)
  70. if ok {
  71. if taskName == "PAD-ICP" || taskName == "PAD-TMS" || taskName == "PA" {
  72. InterruptRunningTask("C2C")
  73. } else {
  74. lfshook.NewLogger().Infof("CabCab hangup other the one caller %s", event["CallerIDNum"])
  75. if event["CallerIDNum"] == "2311" {
  76. Hangup("2381")
  77. } else {
  78. Hangup("2311")
  79. }
  80. }
  81. }
  82. } else { // hangup caller; C2C start failed
  83. lfshook.NewLogger().Infof("CabCab hangup caller %s", event["CallerIDNum"])
  84. Hangup(event["CallerIDNum"])
  85. }
  86. break
  87. //Get record file name ,encode and upload
  88. } else if event["UserEvent"] == "SetRecordFile" {
  89. if configs.ConfigGlobal.ProcessRecord != "yes" {
  90. break
  91. }
  92. //检测录音文件是否存在;最多检测5次,每次间隔1秒
  93. var fileExists bool
  94. for i := 0; i < 5; i++ {
  95. time.Sleep(time.Second) // 等待1秒
  96. if _, err := os.Stat(event["FILENAME"]); err == nil {
  97. fileExists = true
  98. //lfshook.NewLogger().Infof("File found: %s", event["FILENAME"])
  99. break
  100. } else if os.IsNotExist(err) {
  101. //lfshook.NewLogger().Infof("File not found (attempt %d): %s", i+1, event["FILENAME"])
  102. } else {
  103. //lfshook.NewLogger().Infof("Error checking file: %v", err)
  104. }
  105. }
  106. if !fileExists { //5秒内没有生成录音文件
  107. lfshook.NewLogger().Infof("File %s not found after 5 attempts", event["FILENAME"])
  108. break
  109. }
  110. //获取录音文件时长,检测录音文件是否超过3min;
  111. duration, err := utils.GetDuration(event["FILENAME"])
  112. if err != nil {
  113. utils.Logger.Printf("Get duration err: %+v", err)
  114. break
  115. }
  116. //lfshook.NewLogger().Infof("==========duration===== %d", duration)
  117. //转wav文件的采样率到22kHz,并切割位180秒每段
  118. var FileNames []string
  119. if duration >= 600 { //超过600秒的超长文件,不处理
  120. lfshook.NewLogger().Infof("File over 600 sec, Ignored !")
  121. break
  122. } else if duration < 600 { //小于600秒文件进行转换和切割
  123. FileNames, err = utils.ConvertAndSegmentWAV(event["FILENAME"], strings.Replace(event["FILENAME"], ".wav", "", -1))
  124. if err != nil {
  125. lfshook.NewLogger().Infof("Get duration err: %+v", err)
  126. break
  127. }
  128. //lfshook.NewLogger().Infof("=============== File %+v found after convert", FileNames)
  129. }
  130. //执行加密操作,并将录音信息写入日志文件
  131. DstFile := ""
  132. if len(FileNames) > 0 { // 文件切割之后进入循环处理
  133. for _, filepath := range FileNames {
  134. file := strings.Replace(filepath, ".wav", "", -1)
  135. DstFile = fmt.Sprintf("%s-encrypted.wav", file)
  136. //lfshook.NewLogger().Infof("Bin file====%s", DstFile)
  137. err = utils.AudioFileEncode(DstFile, filepath)
  138. if err != nil {
  139. lfshook.NewLogger().Infof("Encode file: %s err: %+v", DstFile, err)
  140. continue
  141. }
  142. //切割&加密之后发送生成的文件名到STC;
  143. alstatus.SendRecordFile(DstFile, event["RecordType"])
  144. trainInfo = active.ActivedCab
  145. if strings.Contains(event["FILENAME"], "PAD") {
  146. _, caller, callee := utils.GetPadInfo(event["FILENAME"])
  147. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: PAD , CabNumber: %c , LocationCode: %c, Connected: %s, RecordFileName:%s", trainInfo, caller[2], caller[3], callee, DstFile)
  148. } else if strings.Contains(event["FILENAME"], "PA") {
  149. _, caller, _ := utils.GetPadInfo(event["FILENAME"])
  150. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: PA, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
  151. } else if strings.Contains(event["FILENAME"], "C2C") {
  152. _, caller, _ := utils.GetPadInfo(event["FILENAME"])
  153. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: CabCab, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
  154. } else if strings.Contains(event["FILENAME"], "CPA") {
  155. _, caller, _ := utils.GetPadInfo(event["FILENAME"])
  156. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: CPA, Caller: %s, RecordFileName: %s", trainInfo, caller, DstFile)
  157. } else if strings.Contains(event["FILENAME"], "EMG") {
  158. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: EMG, RecordFileName: %s", trainInfo, DstFile)
  159. } else if strings.Contains(event["FILENAME"], "STN") {
  160. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: STN, RecordFileName: %s", trainInfo, DstFile)
  161. } else if strings.Contains(event["FILENAME"], "DCS") {
  162. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: DCS, RecordFileName: %s", trainInfo, DstFile)
  163. } else if strings.Contains(event["FILENAME"], "SPC") {
  164. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: SPC, RecordFileName: %s", trainInfo, DstFile)
  165. } else if strings.Contains(event["FILENAME"], "CHK") {
  166. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: Self Check, RecordFileName: %s", trainInfo, DstFile)
  167. } else if strings.Contains(event["FILENAME"], "TONE") {
  168. utils.Logger.Printf("Train Information: CabNumber %s, MessageType: TONE Test, RecordFileName: %s", trainInfo, DstFile)
  169. }
  170. }
  171. } else {
  172. lfshook.NewLogger().Infof("No files to upload!!!")
  173. break
  174. }
  175. }
  176. case "Hangup":
  177. lfshook.NewLogger().Infof("%s", event["Event"])
  178. //OCC answer PAD, hangup, redirect the next PAD to OCC
  179. if utils.IsIO(event["CallerIDNum"]) && (event["ConnectedLineNum"] == "ano1" || event["ConnectedLineNum"] == "ano8") && event["Context"] == "default" {
  180. lfshook.NewLogger().Infof("Hangup OCC-PAD event: %+v", event)
  181. // OCC hangup detected, hangup other running channels
  182. InterruptRunningTask("PAD-OCC")
  183. res, _ := QueueStatus("0301", "") // check OCC queue ,if empty PAD end
  184. if res.Calls == "0" { //OCC queue is empty
  185. alstatus.OccPad("end")
  186. priority.OCCAnswer = 0
  187. priority.PADOccStart = 0
  188. //clean confbridge
  189. taskTmp, _ := priority.RegistryTask.Get("PAD-OCC")
  190. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  191. //check resume
  192. priority.RegistryTask.StopAndUnregister("PAD-OCC")
  193. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  194. if ok {
  195. if taskName == "EMG" {
  196. EMGConfbridgeReinvite(task.ConfbridgeID)
  197. } else if taskName == "CPA" {
  198. CPAConfbridgeReinvite(task.ConfbridgeID)
  199. }
  200. }
  201. break
  202. } else { //OCC queue is not empty
  203. time.Sleep(time.Millisecond * 100) //wait io idle
  204. //lfshook.NewLogger().Infof("====Start OCC-PAD===next==%+v", res)
  205. if active.ActivedCab == "1" && ExtenStatus("1411") == "Idle" { //check active and OCC status
  206. time.Sleep(time.Second)
  207. PADChan := ""
  208. for _, chanEntry := range res.Entrys {
  209. lfshook.NewLogger().Infof("PAD answered by OCC1 pos:%s chan:%s", chanEntry.Position, chanEntry.Channel)
  210. if chanEntry.Position == "1" {
  211. PADChan = chanEntry.Channel
  212. break
  213. }
  214. }
  215. if PADChan != "" {
  216. Ext := strings.Split(strings.Split(res.Entrys[0].Channel, "/")[1], "-")[0]
  217. alstatus.AlarmStatus(Ext, "connect")
  218. go RedirectInQueue(PADChan, "1411", "pad-page-occ-icp", Ext) //PAD Page(OCC+ICPs)
  219. go Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", "ano1", "1") // PACUs dial OCC1
  220. } else {
  221. lfshook.NewLogger().Infof("OCC-QueueStatus PADCchan NULL")
  222. }
  223. break
  224. } else if active.ActivedCab == "8" && ExtenStatus("1481") == "Idle" {
  225. time.Sleep(time.Second)
  226. PADChan := ""
  227. for _, chanEntry := range res.Entrys {
  228. lfshook.NewLogger().Infof("PAD answered by OCC1 pos:%s chan:%s", chanEntry.Position, chanEntry.Channel)
  229. if chanEntry.Position == "1" {
  230. PADChan = chanEntry.Channel
  231. break
  232. }
  233. }
  234. if PADChan != "" {
  235. Ext := strings.Split(strings.Split(res.Entrys[0].Channel, "/")[1], "-")[0]
  236. alstatus.AlarmStatus(Ext, "connect")
  237. go RedirectInQueue(PADChan, "1481", "pad-page-occ-icp", Ext) //PAD Page(OCC+ICPs)
  238. go Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", "ano8", "8") // PACUs dial OCC1
  239. } else {
  240. lfshook.NewLogger().Infof("OCC QueueStatus PADCchan NULL")
  241. }
  242. break
  243. }
  244. }
  245. }
  246. if utils.IsPAIU(event["CallerIDNum"]) { // PAD hangup, check if PAD all end, send PAD end status
  247. number := strings.Split(strings.Split(event["Channel"], "-")[0], "/")[1]
  248. //lfshook.NewLogger().Infof("===hangup PAD =======================%s", number)
  249. if utils.IsPAIU(number) {
  250. res, _ := QueueStatus("0300", "") // check ICP queue ,if empty PAD end
  251. res1, _ := QueueStatus("0301", "") // check OCC queue ,if empty PAD end
  252. lfshook.NewLogger().Infof("ICP Queue calls:%s OCC Queue calls:%s", res.Calls, res1.Calls)
  253. if res.Calls == "0" && res1.Calls == "0" {
  254. if priority.PADStart == 1 {
  255. //SetPadTimer()
  256. alstatus.PaStatus("", "PAD", "end")
  257. priority.PADStart = 0
  258. priority.PADTMSStart = 0
  259. //clean confbridge
  260. //PAD-ICP
  261. taskTmp, ok := priority.RegistryTask.Get("PAD-ICP")
  262. if ok {
  263. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  264. }
  265. priority.RegistryTask.StopAndUnregister("PAD-ICP")
  266. // PAD-TMS
  267. taskTmp, ok = priority.RegistryTask.Get("PAD-TMS")
  268. if ok {
  269. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  270. }
  271. priority.RegistryTask.StopAndUnregister("PAD-TMS")
  272. //PAD-OCC
  273. taskTmp, ok = priority.RegistryTask.Get("PAD-OCC")
  274. if ok {
  275. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  276. }
  277. priority.RegistryTask.StopAndUnregister("PAD-OCC")
  278. //check resume
  279. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  280. if ok {
  281. if taskName == "EMG" {
  282. EMGConfbridgeReinvite(task.ConfbridgeID)
  283. } else if taskName == "CPA" {
  284. CPAConfbridgeReinvite(task.ConfbridgeID)
  285. }
  286. }
  287. }
  288. priority.ICPAnswer = 0
  289. priority.OCCAnswer = 0
  290. break
  291. }
  292. }
  293. }
  294. case "QueueCallerJoin":
  295. lfshook.NewLogger().Infof("=========%s", event["Event"])
  296. if priority.OCCAnswer == 1 && event["Queue"] == "0300" { //New PAD Goto the OCC queue in the first time, if OCC answered
  297. alstatus.AlarmStatus(event["CallerIDNum"], "queue") //send status to STC
  298. go RedirectInQueue(event["CallerIDNum"], "0301", "queues-occ", event["CallerIDNum"])
  299. break
  300. }
  301. if utils.IsPAIU(event["CallerIDNum"]) && utils.IsPAIU(event["CallerIDName"]) && event["Queue"] == "0300" { // Alarm join the queue, PAD in the queue
  302. alstatus.AlarmStatus(event["CallerIDNum"], "queue") //send status to STC
  303. ICPQueue, err := QueueStatus("0300", "") // check ICP queue, get entries
  304. if err != nil {
  305. lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
  306. return
  307. }
  308. if priority.ICPAnswer == 0 && ICPQueue.Calls == "1" { //ICP did not answer any first call to the ICP queue ; Ready to Set Occ Queue Timer
  309. toRunpriority := priority.GetPriorityByKey("PAD-ICP")
  310. time.Sleep(time.Millisecond * 500) //wait high priority task start
  311. _, taskTmp, ok := priority.RegistryTask.HighestPriorityRunningTask()
  312. if ok {
  313. //lfshook.NewLogger().Infof("=1==QueueCallerJoin===runing:%d=====toRun:=%d==Status:%s", taskTmp, toRunpriority, event["ChannelStateDesc"])
  314. if taskTmp.Priority < toRunpriority { //higher priority task running ,do not set timer
  315. break
  316. }
  317. }
  318. //lfshook.NewLogger().Infof("==2=QueueCallerJoin===runing:%d=====toRun:=%d==Status:%s", taskTmp, toRunpriority, event["ChannelStateDesc"])
  319. //if (priority.RunningTypePriority > toRunpriority || priority.RunningTypePriority == 0) && event["ChannelStateDesc"] != "Up" {
  320. active.SetTimer = true
  321. active.QueueTimer = time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout
  322. //if both not active , return
  323. if active.ActivedCab == "" {
  324. return
  325. }
  326. res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start
  327. if err != nil {
  328. lfshook.NewLogger().Infof("OCC QueueStatus err:%+v", err)
  329. return
  330. }
  331. if res.Calls == "0" { // OCC queue empty
  332. resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
  333. if err != nil {
  334. lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
  335. return
  336. }
  337. sort.Slice(resCaller.Entrys, func(i, j int) bool {
  338. return resCaller.Entrys[i].Position < resCaller.Entrys[j].Position
  339. })
  340. for _, caller := range resCaller.Entrys {
  341. priority.ICPAnswer = 0
  342. //lfshook.NewLogger().Infof("====QueueCallerJoin==QueueTimer===%s", event["Event"])
  343. lfshook.NewLogger().Infof("Redirect to 0301 extension:%s Pos:%s", caller.CallerIDNum, caller.Position)
  344. //order by pos
  345. RedirectInQueue(caller.CallerIDNum, "0301", "queues-occ", caller.CallerIDNum) // redirect All ICP-PAD redirect to OCC queue
  346. time.Sleep(time.Millisecond * 100) //200 ms delay
  347. }
  348. }
  349. })
  350. }
  351. break
  352. }
  353. //first PAD caller goto OCC
  354. //OCC dial PACUs;
  355. //PAD Page OCC+ICPs;
  356. if utils.IsPAIU(event["CallerIDNum"]) && event["Queue"] == "0301" && priority.OCCAnswer == 0 { // The first PAD to OCC ,caller is PAD
  357. if priority.CheckPriority("PAD-OCC") {
  358. InterruptRunningTask("PAD-OCC") //PAD-OCC interrupt other
  359. priority.OCCAnswer = 1
  360. time.Sleep(time.Millisecond * 300)
  361. if active.ActivedCab == "1" && ExtenStatus("1411") == "Idle" { //check active and OCC status
  362. alstatus.AlarmStatus(event["CallerIDNum"], "connect")
  363. go RedirectInQueue(event["Channel"], "1411", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
  364. go Dial("0401", "0512", "pad-rule-pacus-occ", "ano1", "ano1", "1") // PACUs dial OCC1
  365. } else if active.ActivedCab == "8" && ExtenStatus("1481") == "Idle" {
  366. alstatus.AlarmStatus(event["CallerIDNum"], "connect")
  367. go RedirectInQueue(event["Channel"], "1481", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
  368. go Dial("0401", "0512", "pad-rule-pacus-occ", "ano8", "ano8", "8") // PACUs dial OCC8
  369. }
  370. } else {
  371. lfshook.NewLogger().Infof("====PAD-OCC Priority false===")
  372. }
  373. }
  374. case "ConfbridgeJoin":
  375. lfshook.NewLogger().Infof("=========%+v", event["Event"])
  376. //set priority and send PA status msg
  377. switch event["CallerIDName"] {
  378. case "EMG":
  379. if event["Exten"] == "0502" {
  380. //================================
  381. task := priority.TaskInfo{
  382. RunChannel: event["Channel"],
  383. LocalChan: event["Channel"],
  384. RunType: "EMG",
  385. Priority: priority.AllTasks.EMG.Priority,
  386. ConfbridgeID: event["Conference"],
  387. Running: true,
  388. }
  389. priority.RegistryTask.Register("EMG", task)
  390. alstatus.PaStatus("", "EMG", "start")
  391. //check PAD timer
  392. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.EMG.Priority {
  393. if active.SetTimer {
  394. active.QueueTimer.Stop()
  395. active.SetTimer = false
  396. }
  397. }
  398. return
  399. }
  400. case "SPC":
  401. if event["Exten"] == "0505" {
  402. //================================
  403. task := priority.TaskInfo{
  404. RunChannel: event["Channel"],
  405. LocalChan: event["Channel"],
  406. RunType: "SPC",
  407. Priority: priority.AllTasks.SPC.Priority,
  408. ConfbridgeID: event["Conference"],
  409. Running: true,
  410. }
  411. priority.RegistryTask.Register("SPC", task)
  412. alstatus.PaStatus("", "SPC", "start")
  413. //check PAD timer
  414. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.SPC.Priority {
  415. if active.SetTimer {
  416. active.QueueTimer.Stop()
  417. active.SetTimer = false
  418. }
  419. }
  420. return
  421. }
  422. case "DCS":
  423. if event["Exten"] == "0504" {
  424. //================================
  425. task := priority.TaskInfo{
  426. RunChannel: event["Channel"],
  427. LocalChan: event["Channel"],
  428. RunType: "DCS",
  429. Priority: priority.AllTasks.DCS.Priority,
  430. ConfbridgeID: event["Conference"],
  431. Running: true,
  432. }
  433. priority.RegistryTask.Register("DCS", task)
  434. alstatus.PaStatus("", "DCS", "start")
  435. //check PAD timer
  436. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.DCS.Priority {
  437. if active.SetTimer {
  438. active.QueueTimer.Stop()
  439. active.SetTimer = false
  440. }
  441. }
  442. return
  443. }
  444. case "STN":
  445. if event["Exten"] == "0503" {
  446. //================================
  447. task := priority.TaskInfo{
  448. RunChannel: event["Channel"],
  449. LocalChan: event["Channel"],
  450. RunType: "STN",
  451. Priority: priority.AllTasks.STN.Priority,
  452. ConfbridgeID: event["Conference"],
  453. Running: true,
  454. }
  455. priority.RegistryTask.Register("STN", task)
  456. alstatus.PaStatus("", "STN", "start")
  457. //check PAD timer
  458. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.STN.Priority {
  459. if active.SetTimer {
  460. active.QueueTimer.Stop()
  461. active.SetTimer = false
  462. }
  463. }
  464. return
  465. }
  466. case "CHK":
  467. if event["Exten"] == "0510" {
  468. //================================
  469. task := priority.TaskInfo{
  470. RunChannel: event["Channel"],
  471. LocalChan: event["Channel"],
  472. RunType: "CHK",
  473. Priority: priority.AllTasks.CHK.Priority,
  474. ConfbridgeID: event["Conference"],
  475. Running: true,
  476. }
  477. priority.RegistryTask.Register("CHK", task)
  478. alstatus.PaStatus("", "CHK", "start")
  479. //check PAD timer
  480. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.CHK.Priority {
  481. if active.SetTimer {
  482. active.QueueTimer.Stop()
  483. active.SetTimer = false
  484. }
  485. }
  486. return
  487. }
  488. case "VOL": // tone-test
  489. if event["Exten"] == "0513" {
  490. //================================
  491. task := priority.TaskInfo{
  492. RunChannel: event["Channel"],
  493. LocalChan: event["Channel"],
  494. RunType: "VOL",
  495. Priority: priority.AllTasks.VOL.Priority,
  496. ConfbridgeID: event["Conference"],
  497. Running: true,
  498. }
  499. priority.RegistryTask.Register("VOL", task)
  500. alstatus.PaStatus("", "VOL", "start")
  501. //check PAD timer
  502. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.VOL.Priority {
  503. if active.SetTimer {
  504. active.QueueTimer.Stop()
  505. active.SetTimer = false
  506. }
  507. }
  508. return
  509. }
  510. }
  511. /*
  512. //get confbridge id for join back to confbridge
  513. if event["Context"] == "pad-page-occ-icp" && utils.IsPAIU(event["CallerIDNum"]) {
  514. //active.ICPCONBID = event["Conference"] //pad-occ
  515. priority.AllTasks.PADOCC.ConfbridgeID = event["Conference"]
  516. }
  517. */
  518. //Send PA start msg to STC
  519. if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA start
  520. alstatus.PaStatus(event["CallerIDNum"], "PA", "start")
  521. //================================
  522. task := priority.TaskInfo{
  523. RunChannel: event["Channel"],
  524. LocalChan: event["Channel"],
  525. RunType: "PA",
  526. Priority: priority.AllTasks.PA.Priority,
  527. ConfbridgeID: event["Conference"],
  528. Running: true,
  529. }
  530. priority.RegistryTask.Register("PA", task)
  531. //check PAD timer
  532. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.PA.Priority {
  533. if active.SetTimer {
  534. active.QueueTimer.Stop()
  535. active.SetTimer = false
  536. }
  537. }
  538. break
  539. } else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA start
  540. alstatus.PaStatus(event["CallerIDNum"], "CPA", "start")
  541. //================================
  542. task := priority.TaskInfo{
  543. RunChannel: event["Channel"],
  544. LocalChan: event["Channel"],
  545. RunType: "CPA",
  546. Priority: priority.AllTasks.CPA.Priority,
  547. ConfbridgeID: event["Conference"],
  548. Running: true,
  549. }
  550. priority.RegistryTask.Register("CPA", task)
  551. //check PAD timer
  552. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.CPA.Priority {
  553. if active.SetTimer {
  554. active.QueueTimer.Stop()
  555. active.SetTimer = false
  556. }
  557. }
  558. return
  559. }
  560. //ICP answer PAD;PACUs connected ICP
  561. //PAD chanspy ICP1
  562. //ICP8 call PAD
  563. if event["ConnectedLineNum"] == "ani1" && event["Exten"] == "0511" { //PAD answered by ICP; PACUs connected ICP1
  564. lfshook.NewLogger().Infof("====PAD answered by ICP1:%s=====", event["ConnectedLineName"])
  565. alstatus.AlarmStatus(event["ConnectedLineName"], "connect")
  566. //================================
  567. task := priority.TaskInfo{
  568. RunChannel: event["Channel"],
  569. LocalChan: event["Channel"],
  570. RunType: "PAD-ICP",
  571. Priority: priority.AllTasks.PADICP.Priority,
  572. ConfbridgeID: event["Conference"],
  573. Running: true,
  574. }
  575. priority.RegistryTask.Register("PAD-ICP", task)
  576. lfshook.NewLogger().Infof("=========PAD-ICP answer==ListAll===%+v", priority.RegistryTask.ListAll())
  577. go RedirectInQueue(event["ConnectedLineName"], "2311", "chanspy-rule-whisper", event["ConnectedLineName"]) //PAD chanspy(EqW) ICP1
  578. if ExtenStatus("2381") == "Idle" {
  579. go Dial("0402", event["ConnectedLineName"], "call-pad-rule", event["ConnectedLineName"], event["ConnectedLineName"], "8") // PAD call ICP8
  580. }
  581. }
  582. if event["ConnectedLineNum"] == "ani8" && event["Exten"] == "0511" { //PAD ansered by ICP8; PACUs connected ICP8
  583. lfshook.NewLogger().Infof("====PAD answered by ICP8:%s=====", event["ConnectedLineName"])
  584. alstatus.AlarmStatus(event["ConnectedLineName"], "connect")
  585. //================================
  586. task := priority.TaskInfo{
  587. RunChannel: event["Channel"],
  588. LocalChan: event["Channel"],
  589. RunType: "PAD-ICP",
  590. Priority: priority.AllTasks.PADICP.Priority,
  591. ConfbridgeID: event["Conference"],
  592. Running: true,
  593. }
  594. priority.RegistryTask.Register("PAD-ICP", task)
  595. lfshook.NewLogger().Infof("=========PAD-ICP answer==ListAll===%+v", priority.RegistryTask.ListAll())
  596. go RedirectInQueue(event["ConnectedLineName"], "2381", "chanspy-rule-whisper", event["ConnectedLineName"]) //PAD chanspy(EqW) ICP8
  597. if ExtenStatus("2311") == "Idle" {
  598. go Dial("0402", event["ConnectedLineName"], "call-pad-rule", event["ConnectedLineName"], event["ConnectedLineName"], "1") // PAD call ICP1
  599. }
  600. break
  601. }
  602. //OCC answer PAD;Set the task channel
  603. if utils.IsPAIU(event["CallerIDNum"]) && utils.IsIO(event["Exten"]) && event["Context"] == "pad-page-occ-icp" { //PAD Page OCC1+ICPs connected
  604. lfshook.NewLogger().Infof("====PAD answered by OCC:====")
  605. //================================
  606. task := priority.TaskInfo{
  607. RunChannel: event["Channel"],
  608. LocalChan: event["Channel"],
  609. RunType: "PAD-OCC",
  610. Priority: priority.AllTasks.PADOCC.Priority,
  611. ConfbridgeID: event["Conference"],
  612. Running: true,
  613. }
  614. priority.RegistryTask.Register("PAD-OCC", task)
  615. break
  616. }
  617. case "ConfbridgeLeave":
  618. lfshook.NewLogger().Infof("=========%s", event["Event"])
  619. if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA end
  620. alstatus.PaStatus(event["CallerIDNum"], "PA", "end")
  621. priority.RegistryTask.StopAndUnregister("PA")
  622. SetPadTimer()
  623. // check resume
  624. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  625. if ok {
  626. if taskName == "EMG" {
  627. EMGConfbridgeReinvite(task.ConfbridgeID)
  628. } else if taskName == "CPA" {
  629. CPAConfbridgeReinvite(task.ConfbridgeID)
  630. }
  631. }
  632. } else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA end
  633. alstatus.PaStatus(event["CallerIDNum"], "CPA", "end")
  634. //CPA
  635. taskTmp, ok := priority.RegistryTask.Get("CPA")
  636. if ok {
  637. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  638. }
  639. priority.RegistryTask.StopAndUnregister("CPA")
  640. SetPadTimer()
  641. //check resume
  642. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  643. if ok {
  644. if taskName == "EMG" {
  645. EMGConfbridgeReinvite(task.ConfbridgeID)
  646. }
  647. }
  648. //lfshook.NewLogger().Infof("=========%s", event["Event"])
  649. } else if event["CallerIDName"] == "EMG" && event["Exten"] == "0502" { // EMG broadcast hangup
  650. alstatus.PaStatus("", "EMG", "end")
  651. //EMG
  652. taskTmp, ok := priority.RegistryTask.Get("EMG")
  653. if ok {
  654. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  655. }
  656. priority.RegistryTask.StopAndUnregister("EMG")
  657. SetPadTimer()
  658. //check resume
  659. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  660. if ok {
  661. if taskName == "CPA" {
  662. CPAConfbridgeReinvite(task.ConfbridgeID)
  663. }
  664. }
  665. } else if event["CallerIDName"] == "STN" && event["Exten"] == "0503" {
  666. alstatus.PaStatus("", "STN", "end")
  667. //STN
  668. taskTmp, ok := priority.RegistryTask.Get("STN")
  669. if ok {
  670. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  671. }
  672. priority.RegistryTask.StopAndUnregister("STN")
  673. SetPadTimer()
  674. //check resume
  675. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  676. if ok {
  677. if taskName == "CPA" {
  678. CPAConfbridgeReinvite(task.ConfbridgeID)
  679. } else if taskName == "EMG" {
  680. EMGConfbridgeReinvite(task.ConfbridgeID)
  681. }
  682. }
  683. } else if event["CallerIDName"] == "DCS" && event["Exten"] == "0504" {
  684. alstatus.PaStatus("", "DCS", "end")
  685. //DSC
  686. taskTmp, ok := priority.RegistryTask.Get("DCS")
  687. if ok {
  688. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  689. }
  690. priority.RegistryTask.StopAndUnregister("DCS")
  691. SetPadTimer()
  692. //check resume
  693. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  694. if ok {
  695. if taskName == "CPA" {
  696. CPAConfbridgeReinvite(task.ConfbridgeID)
  697. } else if taskName == "EMG" {
  698. EMGConfbridgeReinvite(task.ConfbridgeID)
  699. }
  700. }
  701. } else if event["CallerIDName"] == "SPC" && event["Exten"] == "0505" {
  702. alstatus.PaStatus("", "SPC", "end")
  703. //SPC
  704. taskTmp, ok := priority.RegistryTask.Get("SPC")
  705. if ok {
  706. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  707. }
  708. priority.RegistryTask.StopAndUnregister("SPC")
  709. SetPadTimer()
  710. //check resume
  711. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  712. if ok {
  713. if taskName == "CPA" {
  714. CPAConfbridgeReinvite(task.ConfbridgeID)
  715. } else if taskName == "EMG" {
  716. EMGConfbridgeReinvite(task.ConfbridgeID)
  717. }
  718. }
  719. } else if event["CallerIDName"] == "CHK" && event["Exten"] == "0510" {
  720. alstatus.PaStatus("", "CHK", "end")
  721. //CHK
  722. taskTmp, ok := priority.RegistryTask.Get("CHK")
  723. if ok {
  724. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  725. }
  726. priority.RegistryTask.StopAndUnregister("CHK")
  727. SetPadTimer()
  728. //check resume
  729. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  730. if ok {
  731. if taskName == "CPA" {
  732. CPAConfbridgeReinvite(task.ConfbridgeID)
  733. } else if taskName == "EMG" {
  734. EMGConfbridgeReinvite(task.ConfbridgeID)
  735. }
  736. }
  737. } else if event["CallerIDName"] == "VOL" && event["Exten"] == "0513" {
  738. alstatus.PaStatus("", "VOL", "end")
  739. //VOL
  740. taskTmp, ok := priority.RegistryTask.Get("VOL")
  741. if ok {
  742. ConfbridgeKick(taskTmp.ConfbridgeID, "all")
  743. }
  744. priority.RegistryTask.StopAndUnregister("VOL")
  745. SetPadTimer()
  746. //check resume
  747. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  748. if ok {
  749. if taskName == "CPA" {
  750. CPAConfbridgeReinvite(task.ConfbridgeID)
  751. } else if taskName == "EMG" {
  752. EMGConfbridgeReinvite(task.ConfbridgeID)
  753. }
  754. }
  755. }
  756. case "DialEnd":
  757. //lfshook.NewLogger().Infof("=========%s", event["Event"])
  758. //Cab Cab start
  759. if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == " 0400" && event["DialStatus"] == "ANSWER" {
  760. //================================
  761. task := priority.TaskInfo{
  762. RunChannel: "",
  763. LocalChan: "",
  764. RunType: "C2C",
  765. Priority: priority.AllTasks.C2C.Priority,
  766. ConfbridgeID: "",
  767. Running: true,
  768. }
  769. priority.RegistryTask.Register("C2C", task)
  770. alstatus.PaStatus(event["CallerIDNum"], "C2C", "start")
  771. //check PAD timer
  772. if priority.AllTasks.PADOCC.Priority > priority.AllTasks.C2C.Priority {
  773. if active.SetTimer {
  774. active.QueueTimer.Stop()
  775. active.SetTimer = false
  776. }
  777. }
  778. } else if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["DialStatus"] == "NOANSWER" {
  779. //lfshook.NewLogger().Infof("===%s======%s", event["Event"], event["DialStatus"])
  780. time.Sleep(time.Millisecond * 300)
  781. //check resume
  782. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  783. if ok {
  784. ICPConfbridgeReinvite(task.ConfbridgeID, taskName)
  785. }
  786. }
  787. case "BridgeLeave":
  788. //lfshook.NewLogger().Infof("=========%s", event["Event"])
  789. //Cab Cab end
  790. if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["Exten"] == "0400" {
  791. alstatus.PaStatus(event["CallerIDNum"], "C2C", "end")
  792. priority.RegistryTask.StopAndUnregister("C2C")
  793. time.Sleep(time.Millisecond * 300)
  794. SetPadTimer()
  795. //check resume
  796. taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
  797. if ok {
  798. ICPConfbridgeReinvite(task.ConfbridgeID, taskName)
  799. }
  800. }
  801. case "ExtensionStatus":
  802. //lfshook.NewLogger().Infof("=========event:%s Ext:%s status:%s ", event["Event"], event["Exten"], event["StatusText"])
  803. //update extension status
  804. if event["StatusText"] == "Idle" || event["StatusText"] == "Unavailable" {
  805. if len(event["Exten"]) > 3 && utils.IsPAIU(event["Exten"]) {
  806. alstatus.AlarmStatus(event["Exten"], event["StatusText"]) // PAD idle + unavailable
  807. }
  808. }
  809. case "BridgeEnter": // TMS-ICP answer PAD; PACU connect ICP
  810. //lfshook.NewLogger().Infof("=========event:%s callerid:%s", event["Event"], event["CallerIDNum"])
  811. //PAD-OCC start
  812. if utils.IsIO(event["CallerIDNum"]) && utils.IsPAIU(event["ConnectedLineNum"]) {
  813. if priority.PADOccStart == 0 {
  814. alstatus.OccPad("start")
  815. priority.PADOccStart = 1
  816. }
  817. }
  818. if utils.IsPACU(event["CallerIDNum"]) && utils.IsPAIU(event["CallerIDName"]) { //ICP and PACU connected
  819. //lfshook.NewLogger().Infof("====BridgeEnter==IN action===%s===ID:%s Name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"])
  820. alstatus.AlarmStatus(event["CallerIDName"], "connect") // Alarm connected
  821. //=============================
  822. task := priority.TaskInfo{
  823. RunChannel: event["Channel"],
  824. LocalChan: event["Channel"],
  825. RunType: "PAD-TMS",
  826. Priority: priority.AllTasks.PADTMS.Priority,
  827. ConfbridgeID: "",
  828. Running: true,
  829. }
  830. priority.RegistryTask.Register("PAD-TMS", task)
  831. lfshook.NewLogger().Infof("=========PAD-TMS answer==ListAll===%+v", priority.RegistryTask.ListAll())
  832. if active.ActivedCab == "1" {
  833. go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
  834. go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8") //ICP8---call----PAD
  835. } else if active.ActivedCab == "8" {
  836. go RedirectInQueue(event["CallerIDName"], "2381", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP8
  837. go Dial("0403", event["CallerIDName"], "call-pad-rule", "2311", "2311", "1") //ICP1---call----PAD
  838. } else if active.ActivedCab == "" {
  839. go RedirectInQueue(event["CallerIDName"], "2311", "chanspy-rule-whisper", "") //PAD chanspy(EqW) ICP1
  840. go Dial("0403", event["CallerIDName"], "call-pad-rule", "2381", "2381", "8") //ICP8---call----PAD
  841. }
  842. } else if utils.IsPAIU(event["CallerIDNum"]) && event["Exten"] == "0405" { // PAD connect ICP-TMS;PACU not available
  843. //=============================
  844. task := priority.TaskInfo{
  845. RunChannel: event["Channel"],
  846. LocalChan: event["Channel"],
  847. RunType: "PAD-TMS",
  848. Priority: priority.AllTasks.PADTMS.Priority,
  849. ConfbridgeID: "",
  850. Running: true,
  851. }
  852. priority.RegistryTask.Register("PAD-TMS", task)
  853. lfshook.NewLogger().Infof("=========PAD-TMS answer==ListAll===%+v", priority.RegistryTask.ListAll())
  854. alstatus.AlarmStatus(event["CallerIDNum"], "connect") // PAD connect ICP-TMS
  855. }
  856. }
  857. }
  858. func StartAMI(connectOKCallBack func(), handleEvents []func(event map[string]string)) {
  859. lfshook.NewLogger().Info("Start AMI")
  860. settings := &amigo.Settings{
  861. Host: configs.ConfigGlobal.AsteriskAMIHost,
  862. Port: configs.ConfigGlobal.AsteriskAMIPort,
  863. Username: configs.ConfigGlobal.AsteriskAMIUser,
  864. Password: configs.ConfigGlobal.AsteriskAMISecret,
  865. LogLevel: logrus.ErrorLevel}
  866. //lfshook.NewLogger().Infof("ami setting: %+v", settings)
  867. AminInstance = amigo.New(settings, lfshook.NewLogger())
  868. AminInstance.EventOn(func(payload ...interface{}) {
  869. // lfshook.NewLogger().Infof("ami event on %+v", payload[0])
  870. event := payload[0].(map[string]string)
  871. go HandleAMI(event)
  872. for _, handle := range handleEvents {
  873. go handle(event)
  874. }
  875. })
  876. AminInstance.ConnectOn(func(payload ...interface{}) {
  877. //lfshook.NewLogger().Infof("ami connect on %+v", payload[0])
  878. if payload[0] == pkg.Connect_OK {
  879. connectOKCallBack()
  880. } else {
  881. lfshook.NewLogger().Errorf("ami connect failure %+v", payload)
  882. active.Master = false
  883. }
  884. })
  885. AminInstance.Connect()
  886. }
  887. func Connected() bool {
  888. if AminInstance != nil {
  889. return AminInstance.Connected()
  890. }
  891. return false
  892. }