5 Commit-ok 2170f4dccf ... bddaf0e47c

Szerző SHA1 Üzenet Dátum
  root bddaf0e47c 调整等待cpa发起的时间避免任务冲突异常,CPA发起之前检测当前是否有优先级更高的任务,ICP取消CABCAB清空任务创建标签 2 hete
  root 5a5e18367a fix 2 hete
  root 020cc47d06 update CPA acvtive 3 hete
  root 073f0eb082 修正pad接通太频繁导致接听无效的问题,修正PA打断PAD-OCC无法恢复CPA的问题 3 hete
  root ce3f94ac32 报警器打断之后再转OCC的顺序问题修正,pad超时时间取值更新 3 hete

+ 158 - 98
internal/app/ami/action/call.go

@@ -8,7 +8,6 @@ import (
 	alstatus "pbx-api-gin/internal/app/stc/sendstatus"
 	"pbx-api-gin/pkg/lfshook"
 	"pbx-api-gin/pkg/utils"
-	"sort"
 	"strings"
 	"sync"
 	"time"
@@ -151,22 +150,6 @@ func InterruptRunningTask(toRunTask string) string {
 		}
 	}
 
-	/*if toRunTask == "C2C" { //当司机对讲打断业务为PA/PAD-ICP/PAD-TMS时,检测是否有EMG和CPA存在,存在则恢复播放
-		if taskName == "PA" || taskName == "PAD-ICP" || taskName == "PAD-TMS" {
-			//check resume
-			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
-			if ok {
-				if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-				} else if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
-				}
-			}
-		}
-	}*/
-
 	utils.LoggerDebug.Printf("InterruptRunningTask  RunningTask:%+v", taskName)
 	//lfshook.NewLogger().Infof("InterruptRunningTask RunningTask:%+v  ", task)
 	//same type return
@@ -194,19 +177,15 @@ func InterruptRunningTask(toRunTask string) string {
 	case "SPC":
 		if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "SPC", "end")
 		} else {
 			ConfbridgeKick(task.ConfbridgeID, "all")
-			alstatus.PaStatus("", "SPC", "end")
 		}
 		time.Sleep(time.Millisecond * 200)
 	case "CHK":
 		if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "CHK", "end")
 		} else {
 			ConfbridgeKick(task.ConfbridgeID, "all")
-			alstatus.PaStatus("", "CHK", "end")
 		}
 		time.Sleep(time.Millisecond * 200)
 	case "DCS":
@@ -214,10 +193,8 @@ func InterruptRunningTask(toRunTask string) string {
 			return taskName
 		} else if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "DCS", "end")
 		} else {
 			ConfbridgeKick(task.ConfbridgeID, "all")
-			alstatus.PaStatus("", "DCS", "end")
 		}
 
 		time.Sleep(time.Millisecond * 200)
@@ -226,33 +203,29 @@ func InterruptRunningTask(toRunTask string) string {
 			return taskName
 		} else if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "STN", "end")
 		} else {
 			ConfbridgeKick(task.ConfbridgeID, "all")
-			alstatus.PaStatus("", "STN", "end")
 		}
 		time.Sleep(time.Millisecond * 200)
 	case "CPA":
 		//kick CPA members
 		if toRunTask != "C2C" {
-			CPAConfbridgeKick(task.ConfbridgeID)
-			alstatus.PaStatus("", "CPA", "end")
+			CPAConfbridgeKick(task)
+			//alstatus.PaStatus("", "CPA", "end")
 		} else if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "CPA", "end")
 		}
 		time.Sleep(time.Millisecond * 200)
 	case "EMG":
 		//kick EMG members
 		if toRunTask == "EMG" {
 			ConfbridgeKick(task.ConfbridgeID, "all")
-			//alstatus.PaStatus("", "EMG", "end")
 		} else if toRunTask != "C2C" {
-			EMGConfbridgeKick(task.ConfbridgeID)
+
+			EMGConfbridgeKick(task)
 			//alstatus.PaStatus("", "EMG", "end")
 		} else if toRunTask == "C2C" {
 			HangupICP()
-			//alstatus.PaStatus("", "EMG", "end")
 		}
 		time.Sleep(time.Millisecond * 200)
 	case "C2C": // Interrupt C2C task running,
@@ -346,8 +319,21 @@ func InterruptRunningTask(toRunTask string) string {
 			//lfshook.NewLogger().Infof("===InterruptRunningTask=Hangup connected PAD=== ")
 			Hangup(task.RunChannel)
 
-			//3. Hangup OI & ICP
-			HangupIO()
+			//3. interrupt OCC-PAD Hangup OI
+			if active.ActivedCab == "1" {
+				Hangup("1411")
+			} else if active.ActivedCab == "8" {
+				Hangup("1481")
+			} else {
+				if active.ActivedCabDelay == "1" {
+					Hangup("1411")
+				} else if active.ActivedCabDelay == "8" {
+					Hangup("1481")
+				} else {
+					Hangup("1411")
+				}
+			}
+
 			HangupAllLocalChan()
 			ConfbridgeKick(task.ConfbridgeID, "all")
 
@@ -434,7 +420,7 @@ func Dial(src, dst, dialrule, callerID, callerName string, callType string) {
 		"Variable": fmt.Sprintf("CAB=%s", callType),
 		"async":    "true",
 	}
-	lfshook.NewLogger().Infof("================dial action %+v", action)
+	//lfshook.NewLogger().Infof("================dial action %+v", action)
 	res, _, err := AminInstance.Send(action)
 	if err != nil {
 		lfshook.NewLogger().Errorf("%+v", err)
@@ -593,7 +579,7 @@ func SetPadTimer() {
 	}
 	if res.Calls != "0" {
 
-		utils.LoggerDebug.Printf("PAD SetPadTimer Set QueueTimer timeout 30s !")
+		utils.LoggerDebug.Printf("PAD SetPadTimer Set QueueTimer timeout %ds !", active.PADTimeout)
 		//active.SetTimer = true
 		//lfshook.NewLogger().Logger.Infof("=========Start PAD timer !=============")
 		if active.QueueTimer != nil {
@@ -622,7 +608,7 @@ func SetPadTimer() {
 			}
 
 			if res.Calls == "0" { // OCC queue empty
-				resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
+				/*resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
 				if err != nil {
 					lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
 					return
@@ -635,26 +621,18 @@ func SetPadTimer() {
 
 					for _, caller := range resCaller.Entrys {
 						priority.ICPAnswer = 0
-						//lfshook.NewLogger().Infof("====SetPadTimer==QueueTimer==2=")
-						//lfshook.NewLogger().Infof("Q300==SetPadTimer==Redirect to 0301 entry:%s=Pos:%s==", caller.CallerIDNum, caller.Position)
 						//order by pos
 						RedirectInQueue(caller.CallerIDNum, "0301", "queues-occ", caller.CallerIDNum) // redirect All ICP-PAD redirect to OCC queue
 						time.Sleep(time.Millisecond * 100)                                            //200 ms delay
 					}
+				}*/
+				for _, ret := range alstatus.PadQueues {
+					//utils.LoggerDebug.Printf("PAD to OCC exten:%s", ret.Exten)
+					priority.ICPAnswer = 0
+					//order by pos
+					RedirectInQueue(ret.Exten, "0301", "queues-occ", ret.Exten) // redirect All ICP-PAD redirect to OCC queue
+					time.Sleep(time.Millisecond * 100)
 				}
-
-				//==============test info =====================
-				/*
-					time.Sleep(2 * time.Second)
-					occque, err1 := QueueStatus("0301", "") // check ICP queue, get entries
-					if err1 != nil {
-						lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
-						return
-					}
-
-					for _, caller := range occque.Entrys {
-						lfshook.NewLogger().Infof("Q301==SetPadTimer==Redirect to 0301 entry:%s=Pos:%s==", caller.CallerIDNum, caller.Position)
-					}*/
 			}
 		})
 	}
@@ -682,48 +660,72 @@ func ConfbridgeKick(confnum, channel string) (res map[string]string, err error)
 	return res, nil
 }
 
-func CPAConfbridgeKick(confnum string) (res map[string]string, err error) {
+func CPAConfbridgeKick(confInfo priority.TaskInfo) (res map[string]string, err error) {
+
+	if !confInfo.Running {
+		utils.LoggerDebug.Printf("CPA CPAConfbridgeKick , not running, return .")
+		return
+	}
+
 	utils.LoggerDebug.Printf("CPA CPAConfbridgeKick , kick all members .")
 
-	chans, err := ConfbridgeList(confnum)
+	chans, err := ConfbridgeList(confInfo.ConfbridgeID)
 	if err != nil {
 		return nil, errors.New(res["Message"])
 	}
 
 	for _, confChan := range chans {
-		if !strings.Contains(confChan, "PJSIP/1481") {
-			ConfbridgeKick(confnum, confChan)
+		if active.TrainDevide == 1 {
+			if active.CabNum == "1" { //在1车车厢内
+				if !strings.Contains(confChan, "PJSIP/1411") {
+					ConfbridgeKick(confInfo.ConfbridgeID, confChan)
+				}
+			} else { //在8车车厢内
+				if !strings.Contains(confChan, "PJSIP/1481") {
+					ConfbridgeKick(confInfo.ConfbridgeID, confChan)
+				}
+			}
+		} else {
+			if active.ActivedCab != "1" {
+				if !strings.Contains(confChan, "PJSIP/1411") {
+					ConfbridgeKick(confInfo.ConfbridgeID, confChan)
+				}
+			} else {
+				if !strings.Contains(confChan, "PJSIP/1481") {
+					ConfbridgeKick(confInfo.ConfbridgeID, confChan)
+				}
+			}
 		}
 	}
+	if confInfo.Running {
+		alstatus.PaStatus("", "CPA", "end")
+	}
+	priority.RegistryTask.UpdateStatus("CPA", false)
 	return res, nil
 }
 
-func CPAConfbridgeReinvite(confID string) bool {
-	time.Sleep(time.Millisecond * 100)
-	utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , resume CPA .")
+func CPAConfbridgeReinvite(task priority.TaskInfo) bool {
 
-	/*if priority.TaskCreating == "" || priority.CABInterrupt == 1 { //高优先级被cabcab打断,或者高优先级直接挂断
+	if task.Running {
+		utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , already running, return .")
+		return false
+	}
 
-		for _, ext := range Speakers {
-			if utils.IsICP(ext) {
-				if priority.CABInterrupt == 0 {
-					utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , Get CABCAB Interrupt resume CPA , ignore %s continue .", ext)
-					continue
-				}
-			}
+	time.Sleep(time.Millisecond * 100)
+	utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , resume CPA .")
 
-			ConfbridgeReinvite(ext, "call-speakers-cpa", confID)
-		}
-	} else {
-		utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , Interrupt by other ,return !")
+	chans, err := ConfbridgeList(task.ConfbridgeID)
+	if len(chans) > 1 || err != nil {
+		utils.LoggerDebug.Printf("CPA CPAConfbridgeReinvite , return . ConfbridgeList chans > 1 or err !")
 		return false
 	}
-	return true*/
 
 	if priority.PAInterrupt == 1 { // PA 打断标签判断
 		utils.LoggerDebug.Printf("CPA ConfbridgeReinvite , PA ready to go , return !")
 		return false
 	} else if priority.CABInterrupt == 1 { //CABCAB 打断标签判断
+
+		priority.TaskCreating = "CPA"
 		for _, ext := range Speakers { //高优先级被cabcab打断,或者高优先级直接挂断
 			if utils.IsICP(ext) {
 				if priority.CABInterrupt == 1 {
@@ -731,42 +733,83 @@ func CPAConfbridgeReinvite(confID string) bool {
 					continue
 				}
 			}
-			ConfbridgeReinvite(ext, "call-speakers-cpa", confID)
+			ConfbridgeReinvite(ext, "call-speakers-cpa", task.ConfbridgeID)
 		}
+		//task.Running = true
+		priority.RegistryTask.UpdateStatus("CPA", true)
+		time.Sleep(time.Millisecond * 200) //等待通道建立
+		priority.TaskCreating = ""
+		alstatus.PaStatus("", "CPA", "start")
+		priority.CPAActived = 0
 	} else if priority.TaskCreating != "" {
 		utils.LoggerDebug.Printf("CPA ConfbridgeReinvite , other PA ready to go , return !")
 		return false
 	} else {
+		priority.TaskCreating = "CPA"
 		for _, ext := range Speakers {
-			ConfbridgeReinvite(ext, "call-speakers-cpa", confID)
+			ConfbridgeReinvite(ext, "call-speakers-cpa", task.ConfbridgeID)
 		}
+		//task.Running = true
+		priority.RegistryTask.UpdateStatus("CPA", true)
+		time.Sleep(time.Millisecond * 200) //等待通道建立
+		priority.TaskCreating = ""
+		alstatus.PaStatus("", "CPA", "start")
+		priority.CPAActived = 0
 	}
 	return true
 }
 
-func EMGConfbridgeKick(confnum string) (res map[string]string, err error) {
+func EMGConfbridgeKick(confInfo priority.TaskInfo) (res map[string]string, err error) {
+
+	if !confInfo.Running {
+		utils.LoggerDebug.Printf("EMG EMGConfbridgeKick , not running, return .")
+		return
+	}
+
 	utils.LoggerDebug.Printf("EMG EMGConfbridgeKick , kick all members .")
-	chans, err := ConfbridgeList(confnum)
+	chans, err := ConfbridgeList(confInfo.ConfbridgeID)
 	if err != nil {
 		return nil, errors.New(res["Message"])
 	}
 
 	for _, confChan := range chans {
 		if !strings.Contains(confChan, "0502@default") {
-			ConfbridgeKick(confnum, confChan)
+			ConfbridgeKick(confInfo.ConfbridgeID, confChan)
 		}
 	}
+
+	if confInfo.Running {
+		alstatus.PaStatus("", "EMG", "end")
+	}
+	//confInfo.Running = false
+	priority.RegistryTask.UpdateStatus("EMG", false)
 	return res, nil
 }
 
-func EMGConfbridgeReinvite(confID string) {
-	time.Sleep(time.Millisecond * 100)
+func EMGConfbridgeReinvite(task priority.TaskInfo) {
+
+	if priority.CPAActived == 1 && priority.AllTasks.EMG.Priority > priority.AllTasks.CPA.Priority {
+		utils.LoggerDebug.Printf("EMG ConfbridgeReinvite , CPA actived , return .")
+		return
+	}
+
+	//if priority.CABInterrupt != 1 {
+	//	time.Sleep(time.Millisecond * 100)
+	//} else {
+	//time.Sleep(time.Second * 1) //wait cpa start first
+	//}
+
 	utils.LoggerDebug.Printf("EMG ConfbridgeReinvite , resume EMG .")
+	if task.Running {
+		utils.LoggerDebug.Printf("EMG ConfbridgeReinvite , already running ,return .")
+		return
+	}
 
 	if priority.PAInterrupt == 1 { // PA 打断标签判断
 		utils.LoggerDebug.Printf("EMG ConfbridgeReinvite , PA ready to go , return !")
 		return
 	} else if priority.CABInterrupt == 1 { //CABCAB 打断标签判断
+		priority.TaskCreating = "EMG"
 		for _, ext := range Speakers { //高优先级被cabcab打断,或者高优先级直接挂断
 			if utils.IsICP(ext) {
 				if priority.CABInterrupt == 1 {
@@ -774,15 +817,26 @@ func EMGConfbridgeReinvite(confID string) {
 					continue
 				}
 			}
-			ConfbridgeReinvite(ext, "call-speakers-emg", confID)
+			ConfbridgeReinvite(ext, "call-speakers-emg", task.ConfbridgeID)
 		}
+		//task.Running = true
+		priority.RegistryTask.UpdateStatus("EMG", true)
+		time.Sleep(time.Millisecond * 200) //等待通道建立
+		priority.TaskCreating = ""
+		alstatus.PaStatus("", "EMG", "start")
 	} else if priority.TaskCreating != "" {
 		utils.LoggerDebug.Printf("EMG ConfbridgeReinvite , other PA ready to go , return !")
 		return
 	} else {
+		priority.TaskCreating = "EMG"
 		for _, ext := range Speakers {
-			ConfbridgeReinvite(ext, "call-speakers-emg", confID)
+			ConfbridgeReinvite(ext, "call-speakers-emg", task.ConfbridgeID)
 		}
+		//task.Running = true
+		priority.RegistryTask.UpdateStatus("EMG", true)
+		time.Sleep(time.Millisecond * 200) //等待通道建立
+		priority.TaskCreating = ""
+		alstatus.PaStatus("", "EMG", "start")
 	}
 }
 
@@ -886,12 +940,12 @@ func WaitTaskCreate(task string, args ...string) { //arg1(task chan)
 	case "C2C":
 		if /*task == "PA" ||*/ task == "CPA" {
 			//获取正在创建的任务的优先级
-			priorityC2C := priority.GetPriorityByKey("C2C")
+			//priorityC2C := priority.GetPriorityByKey("C2C")
 			//获取将要创建的任务的优先级
-			priorityTask := priority.GetPriorityByKey(task)
+			//priorityTask := priority.GetPriorityByKey(task)
 			//比较优先级,确定是否终止正在创建的任务
 
-			if priorityC2C < priorityTask {
+			/*if priorityC2C < priorityTask {
 				utils.LoggerDebug.Printf("%s check task C2C creating , hangup CPA %s ", task, args[0])
 
 				//结束task(CPA)
@@ -904,8 +958,11 @@ func WaitTaskCreate(task string, args ...string) { //arg1(task chan)
 				utils.LoggerDebug.Printf("%s check task C2C creating , hangup C2C ICPs ", task)
 				HangupICP()
 				goto DELAY
-			}
+			}*/
+		} else {
+			goto DEFAULT
 		}
+
 		return
 	case "CPA":
 		if task == "PA" /*|| task == "C2C"*/ {
@@ -934,6 +991,8 @@ func WaitTaskCreate(task string, args ...string) { //arg1(task chan)
 					goto DELAY
 				}
 			}
+		} else {
+			goto DEFAULT
 		}
 		return
 	case "PA":
@@ -963,26 +1022,27 @@ func WaitTaskCreate(task string, args ...string) { //arg1(task chan)
 					goto DELAY
 				}
 			}
+		} else {
+			goto DEFAULT
 		}
 		return
+	}
 
-	default:
-		//utils.LoggerDebug.Printf("%s waiting trd=============previous task:%s creating ..... ", task, priority.TaskCreating)
+DEFAULT:
+	//utils.LoggerDebug.Printf("%s waiting trd=============previous task:%s creating ..... ", task, priority.TaskCreating)
 
-		for i := 0; i < 4; i++ {
-			if priority.TaskCreating != "" {
-				utils.LoggerDebug.Printf("%s waiting previous task:%s creating ..... ", task, priority.TaskCreating)
-				time.Sleep(time.Millisecond * 500)
-			} else {
-				utils.LoggerDebug.Printf("TaskCreating is nill, Set TaskCreating=%s", task)
-				priority.TaskCreating = task
-				return
-			}
+	for i := 0; i < 20; i++ {
+		if priority.TaskCreating != "" {
+			utils.LoggerDebug.Printf("%s waiting previous task:%s creating ..... ", task, priority.TaskCreating)
+			time.Sleep(time.Millisecond * 100)
+		} else {
+			utils.LoggerDebug.Printf("TaskCreating is nill, Set TaskCreating=%s", task)
+			priority.TaskCreating = task
+			return
 		}
-		priority.TaskCreating = task
-		utils.LoggerDebug.Printf("%s waiting previous task:%s creating timeout ! Set TaskCreating=%s", task, priority.TaskCreating, task)
-		return
 	}
+	priority.TaskCreating = task
+	utils.LoggerDebug.Printf("%s waiting previous task:%s creating timeout ! Set TaskCreating=%s", task, priority.TaskCreating, task)
 
 DELAY:
 	time.Sleep(100 * time.Millisecond)

+ 125 - 76
internal/app/ami/action/index.go

@@ -10,7 +10,6 @@ import (
 	"pbx-api-gin/internal/pkg/configs"
 	"pbx-api-gin/pkg/lfshook"
 	"pbx-api-gin/pkg/utils"
-	"sort"
 	"strings"
 	"time"
 
@@ -29,7 +28,7 @@ func HandleAMI(event map[string]string) {
 	case "DTMFBegin": //ICP interrupt PAD
 		lfshook.NewLogger().Infof("=========%s====caller:%s=====digit:%s==", event["Event"], event["CallerIDNum"], event["Digit"])
 
-		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] != "" {
+		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] != "" && event["Direction"] == "Received" {
 
 			//PA interrupt PAD
 			switch event["Digit"] {
@@ -68,6 +67,8 @@ func HandleAMI(event map[string]string) {
 		if event["UserEvent"] == "CallType" && (event["Type"] == "PA" || event["Type"] == "CPA") { //PA start; check manual PA priority
 			//PA & CPA interrupt others
 			if utils.IsICP(event["CallerIDNum"]) { //PA
+				//清除标记
+
 				utils.LoggerDebug.Printf("Get UserEvent , %s calling !", event["Type"])
 				if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
 					Hangup(event["CallerIDNum"])
@@ -86,6 +87,10 @@ func HandleAMI(event map[string]string) {
 						time.Sleep(time.Millisecond * 100) //wait endpoint release
 					}
 
+					if priority.TaskCreating == "PA" {
+						utils.LoggerDebug.Printf("PA : Clean priority.TaskCreating = '' !")
+						priority.TaskCreating = ""
+					}
 				} else {
 					if priority.TaskCreating == "PA" {
 						utils.LoggerDebug.Printf("PA : Clean priority.TaskCreating = '' !")
@@ -96,12 +101,17 @@ func HandleAMI(event map[string]string) {
 				}
 
 				time.Sleep(1 * time.Second)
-				if priority.TaskCreating == "PA" {
-					utils.LoggerDebug.Printf("PA : Clean priority.TaskCreating = '' !")
-					priority.TaskCreating = ""
-				}
+				priority.PAInterrupt = 0
 			} else if utils.IsIO(event["CallerIDNum"]) { // CPA
 
+				priority.CPAActived = 1 //CPA触发
+				if /* priority.CABInterrupt == 1 || */ priority.PAInterrupt == 1 {
+					utils.LoggerDebug.Printf("Get UserEvent CPA calling !  Ignored because of PAInterrupt=1 !")
+					Hangup(event["CallerIDNum"])
+					priority.CPAActived = 0
+					return
+				}
+
 				utils.LoggerDebug.Printf("Get UserEvent , %s calling !", event["Type"])
 				WaitTaskCreate("CPA", event["CallerIDNum"])
 
@@ -116,6 +126,7 @@ func HandleAMI(event map[string]string) {
 						utils.LoggerDebug.Printf("CPA calling  , ActivedCab = %s !", active.ActivedCab)
 						if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
 							Hangup(event["CallerIDNum"])
+							priority.CPAActived = 0
 							if priority.TaskCreating == "CPA" {
 								utils.LoggerDebug.Printf("CPA : Clean priority.TaskCreating = '' !")
 								priority.TaskCreating = ""
@@ -123,6 +134,7 @@ func HandleAMI(event map[string]string) {
 							return
 						} else if active.ActivedCab == "1" && event["CallerIDNum"] == "1411" {
 							Hangup(event["CallerIDNum"])
+							priority.CPAActived = 0
 							if priority.TaskCreating == "CPA" {
 								utils.LoggerDebug.Printf("CPA : Clean priority.TaskCreating = '' !")
 								priority.TaskCreating = ""
@@ -130,6 +142,7 @@ func HandleAMI(event map[string]string) {
 							return
 						} else if active.ActivedCab == "8" && event["CallerIDNum"] == "1481" {
 							Hangup(event["CallerIDNum"])
+							priority.CPAActived = 0
 							if priority.TaskCreating == "CPA" {
 								utils.LoggerDebug.Printf("CPA : Clean priority.TaskCreating = '' !")
 								priority.TaskCreating = ""
@@ -138,11 +151,25 @@ func HandleAMI(event map[string]string) {
 						}
 					}
 
-					//hangup others if priority is higher
-					runningTaskName := InterruptRunningTask("CPA") //CPA interrupt other
-					if runningTaskName != "" {
-						time.Sleep(time.Millisecond * 100) //wait endpoint release
+					//CPA 发起之前检查是否有更高优先级任务在运行,有则不发起CPA
+					taskName, task, _ := priority.RegistryTask.HighestPriorityRunningTask1()
+					if len(taskName) > 0 && task.Priority < priority.AllTasks.CPA.Priority {
+						utils.LoggerDebug.Printf("CPA : other task running , return !")
+						Hangup(event["CallerIDNum"])
+						priority.CPAActived = 0
+						if priority.TaskCreating == "CPA" {
+							utils.LoggerDebug.Printf("CPA : Clean priority.TaskCreating = '' !")
+							priority.TaskCreating = ""
+						}
+						return
+					} else {
+						//hangup others if priority is higher
+						runningTaskName := InterruptRunningTask("CPA") //CPA interrupt other
+						if runningTaskName != "" {
+							time.Sleep(time.Millisecond * 100) //wait endpoint release
+						}
 					}
+
 				} else {
 					if priority.TaskCreating == "CPA" {
 						utils.LoggerDebug.Printf("CPA : Clean priority.TaskCreating = '' !")
@@ -150,6 +177,7 @@ func HandleAMI(event map[string]string) {
 					}
 					utils.LoggerDebug.Printf("CPA calling failed , check priority return false !")
 					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
+					priority.CPAActived = 0      //CPA触发,但未运行
 				}
 
 				time.Sleep(1 * time.Second)
@@ -160,7 +188,7 @@ func HandleAMI(event map[string]string) {
 			}
 		} else if event["UserEvent"] == "CallType" && event["Type"] == "C2C" { //CabCab start; check cab cab priority
 			utils.LoggerDebug.Printf("Get UserEvent , %s calling !", event["Type"])
-			priority.CABInterrupt = 0
+
 			WaitTaskCreate("C2C", event["CallerIDNum"])
 
 			if priority.CheckPriority("CabCab") { // interrupt OCC-PAD
@@ -188,6 +216,8 @@ func HandleAMI(event map[string]string) {
 					}
 					//}
 				}
+				time.Sleep(time.Second * 1)
+				priority.CABInterrupt = 0
 
 			} else { // hangup caller; C2C start failed
 				//lfshook.NewLogger().Infof("CabCab  hangup caller %s", event["CallerIDNum"])
@@ -362,15 +392,15 @@ func HandleAMI(event map[string]string) {
 				priority.RegistryTask.StopAndUnregister("PAD-OCC")
 				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
 
+				time.Sleep(time.Millisecond * 350) //wait CPA Active
+
 				//check resume
 				taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 				if ok {
 					if taskName == "EMG" {
-						EMGConfbridgeReinvite(task.ConfbridgeID)
+						EMGConfbridgeReinvite(task)
 					} else if taskName == "CPA" {
-						if CPAConfbridgeReinvite(task.ConfbridgeID) {
-							alstatus.PaStatus("", "CPA", "start")
-						}
+						CPAConfbridgeReinvite(task)
 					}
 				}
 
@@ -387,7 +417,7 @@ func HandleAMI(event map[string]string) {
 				//time.Sleep(time.Millisecond * 100) //wait io idle
 				//lfshook.NewLogger().Infof("====Start OCC-PAD===next==%+v", res)
 				if active.TrainDevide == 0 { //列车没有断开
-					if (active.ActivedCab == "1" && ExtenStatus("1411") == "Idle") || (active.ActivedCab == "" && active.ActivedCabDelay == "1" && ExtenStatus("1411") == "Idle") { //check active and OCC status
+					if (ExtenStatus("1411") == "Idle") && ((active.ActivedCab == "1" || (active.ActivedCab == "" && active.ActivedCabDelay == "1")) || (active.ActivedCab == "" && active.ActivedCabDelay == "")) { //check active and OCC status
 						time.Sleep(time.Second)
 						PADChan := ""
 
@@ -463,7 +493,7 @@ func HandleAMI(event map[string]string) {
 
 		if utils.IsPAIU(event["CallerIDNum"]) { // PAD hangup, check if PAD all end, send PAD end status
 
-			utils.LoggerDebug.Printf("===event:=====%+v======", event)
+			//utils.LoggerDebug.Printf("===event:=====%+v======", event)
 			number := strings.Split(strings.Split(event["Channel"], "-")[0], "/")[1]
 
 			//lfshook.NewLogger().Infof("===hangup PAD ===NUM:%s=================listAllTask:%+v===", number, priority.RegistryTask.ListAll())
@@ -487,6 +517,7 @@ func HandleAMI(event map[string]string) {
 
 				if event["Context"] == "chanspy-rule-whisper" {
 					alstatus.PaStatus("", "PAD", "end")
+					utils.LoggerDebug.Printf("Check PAD-ICP queue chanspy-rule-whisper !")
 
 					res, _ := QueueStatus("0301", "") // check ICP queue ,if empty PAD end
 					if res == nil {
@@ -500,16 +531,15 @@ func HandleAMI(event map[string]string) {
 				}
 
 				if priority.OCCAnswer == 0 { // not OCC-PAD
+					time.Sleep(time.Millisecond * 350) //wait CPA Active
+					utils.LoggerDebug.Printf("======================================")
 					//check resume
 					taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 					if ok {
 						if taskName == "EMG" {
-							EMGConfbridgeReinvite(task.ConfbridgeID)
-							//alstatus.PaStatus("", "EMG", "start")
+							EMGConfbridgeReinvite(task)
 						} else if taskName == "CPA" {
-							if CPAConfbridgeReinvite(task.ConfbridgeID) {
-								alstatus.PaStatus("", "CPA", "start")
-							}
+							CPAConfbridgeReinvite(task)
 						}
 					}
 				}
@@ -531,16 +561,21 @@ func HandleAMI(event map[string]string) {
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				} else if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				}
 			}
 		}
 
+		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "h" && event["ConnectedLineNum"] == "<unknown>" {
+			utils.LoggerDebug.Printf("CABCAB Canceled by ICP !")
+
+			if priority.TaskCreating == "C2C" {
+				utils.LoggerDebug.Printf("C2C : Clean priority.TaskCreating = '' !")
+				priority.TaskCreating = ""
+			}
+		}
 	case "QueueCallerJoin":
 		lfshook.NewLogger().Infof("=========%s", event["Event"])
 
@@ -602,7 +637,7 @@ func HandleAMI(event map[string]string) {
 					}
 
 					if res.Calls == "0" { // OCC queue empty
-						resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
+						/*resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
 						if err != nil {
 							lfshook.NewLogger().Infof("ICP QueueStatus err:%+v", err)
 							return
@@ -622,6 +657,13 @@ func HandleAMI(event map[string]string) {
 								RedirectInQueue(caller.CallerIDNum, "0301", "queues-occ", caller.CallerIDNum) // redirect All ICP-PAD redirect to OCC queue
 								time.Sleep(time.Millisecond * 100)                                            //200 ms delay
 							}
+						}*/
+
+						for _, ret := range alstatus.PadQueues {
+							priority.ICPAnswer = 0
+							//order by pos
+							RedirectInQueue(ret.Exten, "0301", "queues-occ", ret.Exten) // redirect All ICP-PAD redirect to OCC queue
+							time.Sleep(time.Millisecond * 100)
 						}
 					}
 				})
@@ -650,7 +692,7 @@ func HandleAMI(event map[string]string) {
 				time.Sleep(time.Millisecond * 300)
 
 				if active.TrainDevide == 0 { //列车没有断开
-					if (active.ActivedCab == "1" && ExtenStatus("1411") == "Idle") || (active.ActivedCab == "" && active.ActivedCabDelay == "1" && ExtenStatus("1411") == "Idle") { //check active and OCC status
+					if (ExtenStatus("1411") == "Idle") && ((active.ActivedCab == "1" || (active.ActivedCab == "" && active.ActivedCabDelay == "1")) || (active.ActivedCab == "" && active.ActivedCabDelay == "")) { //check active and OCC status
 						utils.LoggerDebug.Printf("PAD %s goto OCC1 .", event["CallerIDNum"])
 						alstatus.AlarmStatus(event["CallerIDNum"], "connect")
 						go RedirectInQueue(event["Channel"], "1411", "pad-page-occ-icp", event["CallerIDNum"]) //PAD Page(OCC+ICPs)
@@ -901,8 +943,8 @@ func HandleAMI(event map[string]string) {
 		*/
 		//Send PA start msg to STC
 		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA start
+			priority.PAInterrupt = 0
 
-			alstatus.PaStatus(event["CallerIDNum"], "PA", "start")
 			//================================
 			task := priority.TaskInfo{
 				RunChannel:   event["Channel"],
@@ -920,7 +962,6 @@ func HandleAMI(event map[string]string) {
 				priority.TaskCreating = ""
 			}
 
-			priority.PAInterrupt = 0 //清除标记
 			//check PAD timer
 			if priority.AllTasks.PADOCC.Priority > priority.AllTasks.PA.Priority {
 				if active.QueueTimer != nil {
@@ -931,6 +972,7 @@ func HandleAMI(event map[string]string) {
 					}
 				}
 			}
+			alstatus.PaStatus(event["CallerIDNum"], "PA", "start")
 
 			break
 		} else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA start
@@ -945,10 +987,11 @@ func HandleAMI(event map[string]string) {
 				ConfbridgeID: event["Conference"],
 				Running:      true,
 			}
+			priority.CPAActived = 0
 			utils.LoggerDebug.Printf("CPA Runing , Set CPA task info %+v .", task)
 			priority.RegistryTask.Register("CPA", task)
 
-			utils.LoggerDebug.Printf("CPA Runing , Set CPA task info %+v .", priority.RegistryTask.ListAll())
+			//utils.LoggerDebug.Printf("CPA Runing , Set CPA task info %+v .", priority.RegistryTask.ListAll())
 
 			if priority.TaskCreating == "CPA" {
 				utils.LoggerDebug.Printf("CPA Connected : Clean priority.TaskCreating = '' !")
@@ -985,6 +1028,8 @@ func HandleAMI(event map[string]string) {
 				Running:      true,
 			}
 			priority.RegistryTask.Register("PAD-ICP", task)
+
+			alstatus.PaStatus("", "PAD", "start")
 			if priority.TaskCreating == "PAD-ICP" {
 				utils.LoggerDebug.Printf("PAD-ICP Connected : Clean priority.TaskCreating = '' !")
 				priority.TaskCreating = ""
@@ -1011,6 +1056,8 @@ func HandleAMI(event map[string]string) {
 				Running:      true,
 			}
 			priority.RegistryTask.Register("PAD-ICP", task)
+
+			alstatus.PaStatus("", "PAD", "start")
 			if priority.TaskCreating == "PAD-ICP" {
 				utils.LoggerDebug.Printf("PAD-ICP Connected : Clean priority.TaskCreating = '' !")
 				priority.TaskCreating = ""
@@ -1050,41 +1097,44 @@ func HandleAMI(event map[string]string) {
 	case "ConfbridgeLeave":
 		lfshook.NewLogger().Infof("=========%s", event["Event"])
 		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA end
-
 			alstatus.PaStatus(event["CallerIDNum"], "PA", "end")
 
 			priority.RegistryTask.StopAndUnregister("PA")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			// check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				} else if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				}
 			}
 
 		} else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA end
 
-			alstatus.PaStatus(event["CallerIDNum"], "CPA", "end")
-
 			//CPA
 			taskTmp, ok := priority.RegistryTask.Get("CPA")
 			if ok {
 				ConfbridgeKick(taskTmp.ConfbridgeID, "all")
 			}
+
+			//已经被打断的CPA不会重复发送end
+			if taskTmp.Running {
+				alstatus.PaStatus(event["CallerIDNum"], "CPA", "end")
+			}
+
 			priority.RegistryTask.StopAndUnregister("CPA")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 
@@ -1100,13 +1150,13 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("EMG")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				}
 			}
 
@@ -1121,16 +1171,15 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("STN")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 
@@ -1145,16 +1194,15 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("DCS")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 
@@ -1169,16 +1217,15 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("SPC")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 
@@ -1193,16 +1240,15 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("CHK")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 
@@ -1217,16 +1263,15 @@ func HandleAMI(event map[string]string) {
 			}
 			priority.RegistryTask.StopAndUnregister("VOL")
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
-					//alstatus.PaStatus("", "EMG", "start")
+					EMGConfbridgeReinvite(task)
 				}
 			}
 		}
@@ -1246,6 +1291,7 @@ func HandleAMI(event map[string]string) {
 			}
 
 			priority.RegistryTask.Register("C2C", task)
+			priority.CABInterrupt = 0
 			alstatus.PaStatus(event["CallerIDNum"], "C2C", "start")
 			if priority.TaskCreating == "C2C" {
 				utils.LoggerDebug.Printf("C2C Connected : Clean priority.TaskCreating = '' !")
@@ -1291,6 +1337,8 @@ func HandleAMI(event map[string]string) {
 				Running:      true,
 			}
 			priority.RegistryTask.Register("PAD-TMS", task)
+
+			alstatus.PaStatus("", "PAD", "start")
 			if priority.TaskCreating == "PAD-TMS" {
 				utils.LoggerDebug.Printf("PAD-TMS Connected : Clean priority.TaskCreating = '' !")
 				priority.TaskCreating = ""
@@ -1313,20 +1361,19 @@ func HandleAMI(event map[string]string) {
 		//lfshook.NewLogger().Infof("=========%s", event["Event"])
 		//Cab Cab end
 		if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["Exten"] == "0400" {
-
 			alstatus.PaStatus(event["CallerIDNum"], "C2C", "end")
 			priority.RegistryTask.StopAndUnregister("C2C")
 			//time.Sleep(time.Millisecond * 100)
 			SetPadTimer()
+
+			time.Sleep(time.Millisecond * 350) //wait CPA Active
 			//check resume
 			taskName, task, ok := priority.RegistryTask.HighestPriorityRunningTask1()
 			if ok {
 				if taskName == "EMG" {
-					EMGConfbridgeReinvite(task.ConfbridgeID)
+					EMGConfbridgeReinvite(task)
 				} else if taskName == "CPA" {
-					if CPAConfbridgeReinvite(task.ConfbridgeID) {
-						alstatus.PaStatus("", "CPA", "start")
-					}
+					CPAConfbridgeReinvite(task)
 				} else {
 					ICPConfbridgeReinvite(task.ConfbridgeID, taskName)
 				}
@@ -1343,7 +1390,7 @@ func HandleAMI(event map[string]string) {
 			}
 		}
 
-	case "BridgeEnter": // TMS-ICP answer PAD; PACU connect ICP
+	case "BridgeEnter": //
 		lfshook.NewLogger().Infof("=========event:%s   callerid-num:%s callerid-name:%s", event["Event"], event["CallerIDNum"], event["CallerIDName"])
 
 		//PAD-OCC start
@@ -1404,6 +1451,8 @@ func HandleAMI(event map[string]string) {
 				Running:      true,
 			}
 			priority.RegistryTask.Register("PAD-TMS", task)
+
+			alstatus.PaStatus("", "PAD", "start")
 			if priority.TaskCreating == "PAD-TMS" {
 				utils.LoggerDebug.Printf("PAD-TMS Connected : Clean priority.TaskCreating = '' !")
 				priority.TaskCreating = ""

+ 18 - 29
internal/app/stc/broadcast/stc-broadcast.go

@@ -341,23 +341,11 @@ func processPacket(packet []byte) {
 	case 0x0e: //TMS answer PAD
 
 		handler := packet[8]
-		key := suppressKey("exten", handler)
 
 		//Drop other handler in 2 sec
 		//PACUs---call---->ICP1
 		//PAD---->Chanspy(WEq)-->ICP1;PAD--->Call---->ICP2
 		if handler == 0x01 { //answer PAD
-			if _, loaded := suppressedExts.LoadOrStore(key, struct{}{}); loaded {
-				utils.LoggerDebug.Printf("Suppressed duplicate ICP Alarm (handler=0x01) for PAD: within 4 seconds")
-				return
-			}
-
-			time.AfterFunc(4*time.Second, func() {
-				suppressedExts.Delete(key)
-				utils.LoggerDebug.Printf("Suppression released .")
-			})
-			//}
-
 			//检查是否有任务正在创建
 			action.WaitTaskCreate("PAD-TMS")
 
@@ -403,7 +391,7 @@ func processPacket(packet []byte) {
 		AlarmHoldResetAll(packet[8]) // reset all pad
 
 	case 0x0c: // Set PAD timeout
-		//lfshook.NewLogger().Logger.Infof("==type 0x0c===Get data from STC ====%x", packet)
+		//lfshook.NewLogger().Logger.Infof("==type PADTimeout 0x0c===Get data from STC ====%x", packet)
 		PadTimeOutSetting(packet[8:]) // timeout setting
 
 		getInfofromSTC(packet[8:])
@@ -411,22 +399,11 @@ func processPacket(packet []byte) {
 	case 0x0d: // ICP answer PAD
 
 		handler := packet[8]
-		key := suppressKey("exten", handler)
 
 		//Drop other handler in 2 sec
 		//PACUs---call---->ICP1
 		//PAD---->Chanspy(WEq)-->ICP1;PAD--->Call---->ICP2
 		if handler == 0x01 {
-			if _, loaded := suppressedExts.LoadOrStore(key, struct{}{}); loaded {
-				utils.LoggerDebug.Printf("Suppressed duplicate ICP Alarm (handler=0x01) for PAD: within 4 seconds")
-				return
-			}
-
-			time.AfterFunc(4*time.Second, func() {
-				suppressedExts.Delete(key)
-				utils.LoggerDebug.Printf("Suppression released for key: %s", key)
-			})
-			//}
 
 			//检查是否有任务正在创建
 			action.WaitTaskCreate("PAD-ICP")
@@ -479,7 +456,7 @@ func processPacket(packet []byte) {
 
 func PadTimeOutSetting(data []byte) {
 
-	Seconds := data[7]
+	Seconds := data[0]
 	if Seconds != 0 {
 		active.PADTimeout = int(Seconds)
 		//lfshook.NewLogger().Logger.Infof("=========Set PAD Timeout seconds to %d ! ============", active.PADTimeout)
@@ -773,7 +750,7 @@ func AlarmHandleICP(data []byte) {
 		//NotifyPaiu(exten, "answer")
 		priority.ICPAnswer = 1
 		//if priority.PADStart == 0 {
-		alstatus.PaStatus("", "PAD", "start")
+		//alstatus.PaStatus("", "PAD", "start")
 		priority.InterruptedPad = ""
 		//	priority.PADStart = 1
 		//}
@@ -786,7 +763,13 @@ func AlarmHandleICP(data []byte) {
 			action.Dial("0402", "0511", "pad-rule-pacus", "ani8", exten, "8") // PACUs dial ICP8
 			//goto ami event ConfbridgeJoin, ICP answer PAD
 		} else if active.ActivedCab == "" { // No cab occupied
-			action.Dial("0402", "0511", "pad-rule-pacus", "ani1", exten, "1") // PACUs dial ICP1
+			if active.ActivedCabDelay == "1" {
+				action.Dial("0402", "0511", "pad-rule-pacus", "ani1", exten, "1") // PACUs dial ICP1
+			} else if active.ActivedCabDelay == "8" {
+				action.Dial("0402", "0511", "pad-rule-pacus", "ani8", exten, "8") // PACUs dial ICP8
+			} else {
+				action.Dial("0402", "0511", "pad-rule-pacus", "ani1", exten, "1") // PACUs dial ICP1
+			}
 		}
 
 	case 0x02: //hold  重新放回队列里面
@@ -827,7 +810,7 @@ func AlarmHandleTMS(data []byte) {
 		//PACU---call---->ICP1
 		//PAD---->Chanspy(WEq)-->ICP1;PAD--->Call---->ICP2
 		//if priority.PADStart == 0 {
-		alstatus.PaStatus("", "PAD", "start")
+		//alstatus.PaStatus("", "PAD", "start")
 		priority.InterruptedPad = ""
 		//priority.PADStart = 1
 		//}
@@ -842,7 +825,13 @@ func AlarmHandleTMS(data []byte) {
 				action.Dial("0403", PacuNum, "pad-tms-dial-pacu", PacuNum, exten, "8") // PACU dial ICP8
 				//goto ami event BridgeEnter, ICP1 whisper ICP8
 			} else if active.ActivedCab == "" { // No cab occupied
-				action.Dial("0403", PacuNum, "pad-tms-dial-pacu", PacuNum, exten, "1") // PACU dial ICP1
+				if active.ActivedCabDelay == "1" {
+					action.Dial("0403", PacuNum, "pad-tms-dial-pacu", PacuNum, exten, "1") // PACU dial ICP1
+				} else if active.ActivedCabDelay == "8" {
+					action.Dial("0403", PacuNum, "pad-tms-dial-pacu", PacuNum, exten, "8") // PACU dial ICP8
+				} else {
+					action.Dial("0403", PacuNum, "pad-tms-dial-pacu", PacuNum, exten, "1") // PACU dial ICP1
+				}
 			}
 		} else {
 			action.RedirectInQueue(exten, "0405", "default", exten) // PAD dial ICPs

+ 3 - 0
internal/app/stc/priority/index.go

@@ -30,6 +30,9 @@ var InterruptedPad = ""
 var CABInterrupt = 0
 var PAInterrupt = 0
 
+// 是否有CPA激活
+var CPAActived = 0
+
 var filePath = "/etc/asterisk/priority.conf"
 
 type TaskInfo struct {

+ 8 - 2
internal/app/stc/priority/task.go

@@ -44,7 +44,13 @@ func (r *TaskRegistry) UpdateStatus(name string, newStatus bool) {
 	defer r.mu.Unlock()
 
 	if !newStatus {
-		delete(r.m, name) // 自动清理:Running=false → 移除
+		//delete(r.m, name) //:Running=false
+		if t, ok := r.m[name]; ok {
+			t.Running = false
+			r.m[name] = t
+		} else {
+			// 如果没有旧记录,但你要“重新启用”,需外部提供完整 TaskInfo → 建议用 Register()
+		}
 		return
 	}
 
@@ -97,7 +103,7 @@ func (r *TaskRegistry) HighestPriorityRunningTask() (string, TaskInfo, bool) {
 			found = true
 		}
 	}
-	utils.LoggerDebug.Printf("HighestPriorityRunningTask1 Get task:%+v", best)
+	utils.LoggerDebug.Printf("HighestPriorityRunningTask Get task:%+v", best)
 	return bestKey, best, found
 }
 

+ 58 - 1
internal/app/stc/sendstatus/status.go

@@ -5,10 +5,49 @@ import (
 	"net"
 	"pbx-api-gin/internal/app/stc/active"
 	msgdata "pbx-api-gin/internal/app/stc/data"
+	"pbx-api-gin/internal/app/stc/priority"
 	"pbx-api-gin/internal/app/stc/socket"
 	"pbx-api-gin/pkg/utils"
+	"time"
 )
 
+type PADQueue struct {
+	Exten      string    `json:"exten"`
+	ActiveTime time.Time `json:"activeTime"`
+}
+
+var PadQueues []PADQueue
+
+// 删除某个报警器
+func removeAllByExten(queues []PADQueue, target string) []PADQueue {
+	result := make([]PADQueue, 0, len(queues))
+	for _, q := range queues {
+		if q.Exten != target {
+			result = append(result, q)
+		}
+	}
+	return result
+}
+
+// 添加报警器
+func addExtenToQueue(queues []PADQueue, target string) []PADQueue {
+
+	var padInfo = PADQueue{Exten: target, ActiveTime: time.Now()}
+
+	for _, q := range queues {
+		if q.Exten == target {
+			return queues
+		}
+	}
+	queues = append(queues, padInfo)
+	return queues
+}
+
+// 初始化pad队列
+func init() {
+	PadQueues = make([]PADQueue, 0)
+}
+
 func SendToStc(conn net.Conn, data []byte) {
 
 	_, err := conn.Write(data)
@@ -71,13 +110,22 @@ func AlarmStatus(exten string, status string) {
 		protocol.Data[2] = 0
 	}
 
+	//将pad存储到队列中
+	if protocol.Data[2] == 0x03 { //排队状态
+		PadQueues = addExtenToQueue(PadQueues, exten)
+		utils.LoggerDebug.Printf("PAD:%s add to queue", exten)
+	} else if protocol.Data[2] == 0x01 { //空闲状态
+		utils.LoggerDebug.Printf("PAD:%s del from queue", exten)
+		PadQueues = removeAllByExten(PadQueues, exten)
+	}
+
 	encoded, errEn := protocol.Encode()
 	if errEn != nil {
 		fmt.Println("Encode error:", errEn)
 		return
 	}
 	//check if actived
-	utils.LoggerDebug.Printf("PAD number:%s		CarNum:%x 	 Pos:%x 	Status:%x", exten, protocol.Data[0], protocol.Data[1], protocol.Data[2])
+	utils.LoggerDebug.Printf("PAD number:%s		CarNum:%x 	 Pos:%x 	Status:%x(0=Offline,1=Idle,2=calling,3=Hold,4=Connected)", exten, protocol.Data[0], protocol.Data[1], protocol.Data[2])
 
 	if socket.Conn != nil {
 		SendToStc(socket.Conn, encoded)
@@ -96,6 +144,15 @@ func PaStatus(src string, patype string, operation string) {
 	if !active.Master {
 		return
 	}
+
+	//过滤掉非EMG运行模式下的continue状态发送
+	if operation == "continue" {
+		taskName, _, _ := priority.RegistryTask.HighestPriorityRunningTask()
+		if taskName != "EMG" {
+			return
+		}
+	}
+
 	utils.LoggerDebug.Printf("PA Status Src:%s 		Type:%s		Status:%s", src, patype, operation)
 	protocol := msgdata.NewProtocol()
 	protocol.MessageID = 0x22