5 Commits 4cd9e7f531 ... 5fb01dc065

Tác giả SHA1 Thông báo Ngày
  dujunchen 5fb01dc065 1.ICP被打断之后重新拉回原来业务中;2PAD被重新放回队列中排在队首 2 tuần trước cách đây
  dujunchen 7401a1f431 ICP打断报警优先级修正 2 tuần trước cách đây
  dujunchen c729a19b80 包含多个优先级的PAD超时计时器启动调整 3 tuần trước cách đây
  dujunchen f672c2bcef test3 3 tuần trước cách đây
  dujunchen ce1de9f706 update 3 tuần trước cách đây

+ 138 - 24
internal/app/ami/action/call.go

@@ -1,11 +1,14 @@
 package action
 
 import (
+	"errors"
 	"fmt"
 	"pbx-api-gin/internal/app/stc/active"
 	"pbx-api-gin/internal/app/stc/priority"
 	"pbx-api-gin/pkg/lfshook"
 	"pbx-api-gin/pkg/utils"
+	"sort"
+	"strconv"
 	"strings"
 	"time"
 )
@@ -103,35 +106,66 @@ func HangupRunningTask(toRunTask string) {
 
 	//same type return
 	if toRunTask == priority.RunningType {
+
 		if toRunTask == "PAD-ICP" || toRunTask == "PAD-TMS" {
 			lfshook.NewLogger().Infof("===HangupRunningTask=ret==== ")
 			return
 		}
 	}
 
+	if toRunTask == "AlarmHoldResetAll" {
+		Hangup(priority.RunningPATaskChan)
+		priority.CleanPriorityTag()
+		HangupAllLocalChan()
+		return
+	}
+
 	if priority.RunningPATaskChan != "" {
 
+		if priority.RunningType == "C2C" { // Interrupt C2C task running,
+			if toRunTask == "PA" || toRunTask == "PAD-ICP" || toRunTask == "PAD-TMS" {
+				HangupICP()
+				//priority.CleanPriorityTag()
+			}
+		}
+
 		switch priority.RunningType {
 
 		case "PAD-ICP", "PAD-TMS": // Interrupt PAD task running,
-			//lfshook.NewLogger().Infof("===HangupRunningTask=PAD=======%s==== ", priority.RunningType)
-			/*		chans, err := CoreShowChannels()
-					if err != nil {
-						lfshook.NewLogger().Errorf("CoreShowChannels %+v", err)
-					}
-					lfshook.NewLogger().Infof("===HangupRunningTask=PAD1=======%+v==== ", chans)
-					//1. Redirect the connected PAD to 0300
-					for _, ret := range chans {
-						exten := strings.Split(strings.Split(ret.Channel, "/")[1], "-")[0]
-						if utils.IsPAIU(ret.CallerIDNum) && ret.ChannelStateDesc == "Up" && utils.IsPAIU(exten) {
-							//err := RedirectInQueue(ret.Channel, "0300", "default", "PAD")
-							err := Redirect(ret.Channel, "0300", "default", exten, "PAD")
-							if err != nil {
-								lfshook.NewLogger().Errorf("Redirect %+v", err)
-							}
+			priority.InterruptedPad = priority.RunningType
+			//just in case
+			if toRunTask == "C2C" { //deal in DTMF event
+				lfshook.NewLogger().Infof("===HangupRunningTask==C2C=return==== ")
+				return
+			}
+
+			lfshook.NewLogger().Infof("===HangupRunningTask==hangup===PAD-ICP==%s==== ", priority.RunningType)
+			chans, err := CoreShowChannels()
+			if err != nil {
+				lfshook.NewLogger().Errorf("CoreShowChannels %+v", err)
+			}
+
+			//1. Redirect the connected PAD to 0300,hangup the other pad channel
+			for _, ret := range chans {
+
+				if utils.IsPAIU(ret.CallerIDNum) {
+					if ret.ConnectedLineNum == "<unknown>" { //redirect pad chanspy channel
+						//lfshook.NewLogger().Infof("===Redirect=Chan===%+v==== ", ret.Channel)
+						err := Redirect(ret.Channel, "0300", "queues-icp-redirect", "", "PAD")
+						if err != nil {
+							lfshook.NewLogger().Errorf("Redirect %+v", err)
 						}
+
+						number := strings.Split(strings.Split(ret.Channel, "-")[0], "/")[1]
+						active.NotifyPaiu(number, "hold")
+						HangupAllLocalChan()
+					} else if utils.IsPAIU(ret.CallerIDNum) && ret.ChannelStateDesc == "Up" && utils.IsICP(ret.ConnectedLineNum) {
+						lfshook.NewLogger().Infof("===Hangup=Chan===%+v==== ", ret.Channel)
+						Hangup(ret.Channel)
 					}
-			*/
+				}
+			}
+
 			//2. hangup task channel (ICP + PACU)
 			lfshook.NewLogger().Infof("===HangupRunningTask=2. hangup task channel === ")
 			HangupAllLocalChan()
@@ -144,14 +178,14 @@ func HangupRunningTask(toRunTask string) {
 				break
 
 			} else {
-
+				priority.InterruptedPad = priority.RunningType
 				//1. Redirect all the other pads in 0301 to 0300
 				resCaller, err := QueueStatus("0301", "") // check OCC queue, get entries
 				if err != nil {
 					lfshook.NewLogger().Infof("===QueueStatus==%+v", err)
 				}
 				for _, caller := range resCaller.Entrys {
-					go RedirectInQueue(caller.CallerIDNum, "0300", "default", caller.CallerIDNum) // redirect All PAD redirect to ICP queue
+					go RedirectInQueue(caller.CallerIDNum, "0300", "queues-icp-redirect", caller.CallerIDNum) // redirect All PAD redirect to ICP queue
 					time.Sleep(time.Microsecond * 200)
 				}
 
@@ -165,12 +199,6 @@ func HangupRunningTask(toRunTask string) {
 				priority.CleanPriorityTag()
 			}
 
-		case "C2C": // Interrupt C2C task running,
-			if toRunTask == "PA" || toRunTask == "PAD-ICP" || toRunTask == "PAD-TMS" {
-				HangupICP()
-				priority.CleanPriorityTag()
-			}
-
 		default:
 			lfshook.NewLogger().Infof("===HangupRunningTask=default=== ")
 			Hangup(priority.RunningPATaskChan)
@@ -245,6 +273,27 @@ func Dial(src, dst, dialrule, callerID, callerName string, callType string) {
 	lfshook.NewLogger().Info(res)
 }
 
+// Dial 拨打号码
+func DialICP(src, dst, dialrule, callerID, callerName string) {
+	chanel := fmt.Sprintf("%s/%s@call-icp", "Local", src)
+	action := map[string]string{
+		"Action":   "Originate",
+		"Channel":  chanel,
+		"Exten":    dst,
+		"Context":  dialrule,
+		"CallerID": fmt.Sprintf("%s<%s>", callerName, callerID),
+		"Priority": "1",
+		"Variable": fmt.Sprintf("CBID=%s", callerID),
+		"async":    "true",
+	}
+	lfshook.NewLogger().Infof("dial action %+v", action)
+	res, _, err := AminInstance.Send(action)
+	if err != nil {
+		lfshook.NewLogger().Errorf("%+v", err)
+	}
+	lfshook.NewLogger().Info(res)
+}
+
 // 获取分机状态
 func ExtenStatus(exten string) (Status string) {
 	action := map[string]string{
@@ -351,3 +400,68 @@ func Redirect(channel, dst, dialrule, callerID, callerName string) (err error) {
 	lfshook.NewLogger().Info(res)
 	return err
 }
+
+func SetPadTimer() {
+
+	toRunpriority, _ := strconv.Atoi(priority.GetPriorityByKey(priority.InterruptedPad)) // 获取之前打断的报警优先级
+	lfshook.NewLogger().Infof("==SetPadTimer====runing:%d==toRun:%d=", priority.RunningTypePriority, toRunpriority)
+
+	if priority.RunningTypePriority < toRunpriority || priority.RunningTypePriority == 0 {
+
+		res, err := QueueStatus("0300", "") // check OCC queue , if empty OCC-PAD start
+		if err != nil {
+			lfshook.NewLogger().Infof("===OCC-QueueStatus==%+v", err)
+			return
+		}
+		if res.Calls != "0" {
+
+			lfshook.NewLogger().Infof("==SetPadTimer==QueueTimer===1====")
+			active.QueueTimer = time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout
+
+				res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start
+				if err != nil {
+					lfshook.NewLogger().Infof("===OCC-QueueStatus==%+v", err)
+					return
+				}
+
+				if res.Calls == "0" { // OCC queue empty
+					resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
+					if err != nil {
+						lfshook.NewLogger().Infof("==ICP=QueueStatus==%+v", err)
+						return
+					}
+					sort.Slice(resCaller.Entrys, func(i, j int) bool {
+						return resCaller.Entrys[i].Position < resCaller.Entrys[j].Position
+					})
+
+					for _, caller := range resCaller.Entrys {
+						priority.ICPAnswer = 0
+						lfshook.NewLogger().Infof("====SetPadTimer==QueueTimer==2=")
+						lfshook.NewLogger().Infof("====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.Microsecond * 500)                                            //200 ms delay
+					}
+				}
+			})
+		}
+	}
+}
+
+func ConfbridgeKick(confnum, channel string) (res map[string]string, err error) {
+	action := map[string]string{
+		"Action":     "ConfbridgeKick",
+		"Conference": confnum,
+		"Channel":    channel,
+	}
+
+	res, _, err = AminInstance.Send(action)
+	if err != nil {
+		return nil, err
+	}
+	if res["Response"] != "Success" {
+		return nil, errors.New(res["Message"])
+	}
+
+	return res, nil
+}

+ 307 - 105
internal/app/ami/action/index.go

@@ -23,33 +23,111 @@ var AminInstance *amigo.Amigo
 var trainInfo = ""
 
 func HandleAMI(event map[string]string) {
-	//lfshook.NewLogger().Infof("===start======%s", event["Event"]
 
 	switch event["Event"] {
 
 	case "DTMFBegin": //ICP interrupt PAD
+		lfshook.NewLogger().Infof("=========%s====caller:%s=====digit:%s==", event["Event"], event["CallerIDNum"], event["Digit"])
+		if priority.RunningType != "PAD-ICP" && priority.RunningType != "PAD-TMS" && priority.RunningType != "PAD-OCC" {
+			break
+		}
 
-		if utils.IsICP(event["CallerIDNum"]) {
-			exten := strings.Split(strings.Split(event["Channel"], "/")[1], "-")[0] //get ICP exten number
-			if utils.IsICP(exten) {
-				chans, err := CoreShowChannels()
-				if err != nil {
-					lfshook.NewLogger().Errorf("CoreShowChannels %+v", err)
-				}
+		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] != "" {
+
+			chans, err := CoreShowChannels()
+			if err != nil {
+				lfshook.NewLogger().Errorf("CoreShowChannels %+v", err)
+			}
+
+			//PA interrupt PAD
+			if event["Digit"] == "#" {
 
 				//1. Redirect the connected PAD to 0300
-				for _, ret := range chans {
-					//lfshook.NewLogger().Infof("===HangupRunningTask=PAD1====Chans-ret===%+v==== ", ret)
-					if utils.IsPAIU(ret.CallerIDNum) && ret.ChannelStateDesc == "Up" && utils.IsICP(ret.ConnectedLineNum) { //hangup pad call ICP channel
-						//lfshook.NewLogger().Infof("===Hangup=Chan===%+v==== ", ret.Channel)
-						Hangup(ret.Channel)
-					} else if ret.ConnectedLineNum == "<unknown>" { //redirect pad chanspy channel
-						//lfshook.NewLogger().Infof("===Redirect=Chan===%+v==== ", ret.Channel)
-						err := Redirect(ret.Channel, "0300", "default", exten, "PAD")
-						if err != nil {
-							lfshook.NewLogger().Errorf("Redirect %+v", err)
+				if priority.RunningType == "PAD-ICP" || priority.RunningType == "PAD-TMS" {
+					for _, ret := range chans {
+						//hangup pad call ICP channel
+						if utils.IsPAIU(ret.CallerIDNum) {
+							if ret.ConnectedLineNum == "<unknown>" { //redirect pad chanspy channel
+								err := Redirect(ret.Channel, "0300", "queues-icp-redirect", "", "PAD")
+								if err != nil {
+									lfshook.NewLogger().Errorf("Redirect %+v", err)
+								}
+
+								number := strings.Split(strings.Split(ret.Channel, "-")[0], "/")[1]
+								active.NotifyPaiu(number, "hold")
+								//HangupAllLocalChan()
+							}
+						}
+					}
+
+					for _, ret := range chans {
+						//hangup pad call ICP channel
+						if utils.IsPAIU(ret.CallerIDNum) {
+							if utils.IsPAIU(ret.CallerIDNum) && ret.ChannelStateDesc == "Up" && utils.IsICP(ret.ConnectedLineNum) {
+								lfshook.NewLogger().Infof("===Hangup=Chan===%+v==== ", ret.Channel)
+								Hangup(ret.Channel)
+							}
+						}
+					}
+					HangupRunningTask("PA")
+				} else if priority.RunningType == "PAD-OCC" {
+					//2. hangup connected PAD, and redirect all PADs in 0301 to 0300
+					priority.OCCAnswer = 0
+
+					resCaller, err := QueueStatus("0301", "") // check OCC queue, get entries
+					if err != nil {
+						lfshook.NewLogger().Infof("===QueueStatus==%+v", err)
+					}
+					for _, caller := range resCaller.Entrys {
+						lfshook.NewLogger().Infof("===QueueStatus=entry=%+v", caller)
+						time.Sleep(time.Microsecond * 100)
+						RedirectInQueue(caller.CallerIDNum, "0300", "queues-icp-redirect", caller.CallerIDNum) // redirect All PAD redirect to ICP queue
+					}
+
+					/*	for _, ret := range chans {
+						//hangup pad call ICP channel
+						if utils.IsPAIU(ret.CallerIDNum) {
+							lfshook.NewLogger().Infof("===DTMFBegin=hangup=%+v==%s=== ", ret.Channel, ret.ChannelStateDesc)
+
+							if ret.ConnectedLineNum == "<unknown>" && ret.ChannelStateDesc != "Ring" { //redirect pad chanspy channel
+								Hangup(ret.Channel)
+							} else if utils.IsICP(ret.ConnectedLineNum) && ret.ChannelStateDesc == "Up" {
+								Hangup(ret.Channel)
+							}
+						}
+					}*/
+					HangupRunningTask("PA")
+					//HangupAllLocalChan()
+				}
+			} else if event["Digit"] == "*" { //Cab cab interrupt PAD
+				lfshook.NewLogger().Infof("===Cab cab interrupt PAD====== ")
+				if priority.RunningType == "PAD-ICP" || priority.RunningType == "PAD-TMS" {
+					for _, ret := range chans {
+
+						if utils.IsPAIU(ret.CallerIDNum) {
+							if ret.ConnectedLineNum == "<unknown>" && ret.ChannelStateDesc == "Up" { //redirect pad chanspy channel
+								err := Redirect(ret.Channel, "0300", "queues-icp-redirect", "", "PAD")
+								if err != nil {
+									lfshook.NewLogger().Errorf("Redirect %+v", err)
+								}
+
+								number := strings.Split(strings.Split(ret.Channel, "-")[0], "/")[1]
+								active.NotifyPaiu(number, "hold")
+								HangupAllLocalChan()
+
+							} else if utils.IsPAIU(ret.CallerIDNum) && ret.ChannelStateDesc == "Up" && utils.IsICP(ret.ConnectedLineNum) {
+								lfshook.NewLogger().Infof("===Hangup=Chan===%+v==== ", ret.Channel)
+								Hangup(ret.Channel)
+							}
 						}
 					}
+					priority.InterruptedPad = priority.RunningType
+					HangupAllLocalChan()
+					Hangup(priority.RunningPATaskChan)
+					priority.CleanPriorityTag()
+					//HangupRunningTask("C2C")
+				} else if priority.RunningType == "PAD-OCC" {
+					HangupICP()
 				}
 			}
 		}
@@ -57,8 +135,65 @@ func HandleAMI(event map[string]string) {
 	case "UserEvent": // RCD filename; PA;CPA; CabCab
 		lfshook.NewLogger().Infof("========event:%s   File:%s", event["Event"], event["FILENAME"])
 
-		//Get  record file name ,encode and upload
-		if event["UserEvent"] == "SetRecordFile" {
+		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"]) {
+				//priority.PAStart = 1
+				if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
+					Hangup(event["CallerIDNum"])
+				}
+
+				if priority.CheckPriority("ManuPa") {
+					//hangup others if priority is higher
+					HangupRunningTask("PA") //PA interrupt other
+				} else {
+					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
+				}
+
+			} else if utils.IsIO(event["CallerIDNum"]) { // CPA
+				if priority.CheckPriority("CPA") {
+					if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
+						Hangup(event["CallerIDNum"])
+					} else if active.ActivedCab == "1" && event["CallerIDNum"] == "1411" {
+						Hangup(event["CallerIDNum"])
+					} else if active.ActivedCab == "8" && event["CallerIDNum"] == "1481" {
+						Hangup(event["CallerIDNum"])
+					}
+
+					//hangup others if priority is higher
+					if priority.RunningType != "" {
+						HangupRunningTask("CPA") //CPA interrupt other
+					} else {
+						//call to ICP ; can not stop calling ICP
+						lfshook.NewLogger().Info("==Running CabCab , CPA start call ICP(ICP is on the phone)=====")
+					}
+				} else {
+					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
+				}
+			}
+		} else if event["UserEvent"] == "CallType" && event["Type"] == "C2C" { //CabCab start; check cab cab priority
+
+			if priority.CheckPriority("CabCab") { // interrupt OCC-PAD
+				//C2C start PAD interrupt
+				if priority.RunningType == "PAD-ICP" || priority.RunningType == "PAD-TMS" || priority.RunningType == "PA" {
+					HangupRunningTask("C2C")
+					//Hangup the other ICP
+
+				} else {
+					lfshook.NewLogger().Infof("========CabCab  hangup other one====caller %s", event["CallerIDNum"])
+					if event["CallerIDNum"] == "2311" {
+						Hangup("2381")
+					} else {
+						Hangup("2311")
+					}
+				}
+			} else { // hangup caller; C2C start failed
+				lfshook.NewLogger().Infof("========CabCab  hangup caller====%s", event["CallerIDNum"])
+				Hangup(event["CallerIDNum"])
+			}
+
+			//Get  record file name ,encode and upload
+		} else if event["UserEvent"] == "SetRecordFile" {
 
 			if configs.ConfigGlobal.ProcessRecord != "yes" {
 				break
@@ -114,7 +249,7 @@ func HandleAMI(event map[string]string) {
 					file := strings.Replace(filepath, ".wav", "", -1)
 					DstFile = fmt.Sprintf("%s-encrypted.wav", file)
 
-					lfshook.NewLogger().Infof("===========Bin file====%s", DstFile)
+					lfshook.NewLogger().Infof("Bin file====%s", DstFile)
 					err = utils.AudioFileEncode(DstFile, filepath)
 					if err != nil {
 						lfshook.NewLogger().Infof("Encode file: %s err: %+v", DstFile, err)
@@ -155,60 +290,6 @@ func HandleAMI(event map[string]string) {
 				lfshook.NewLogger().Infof("No files to upload!!!")
 				break
 			}
-
-		} else 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"]) {
-
-				if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
-					Hangup(event["CallerIDNum"])
-				}
-
-				if priority.CheckPriority("ManuPa") {
-					//hangup others if priority is higher
-					HangupRunningTask("PA") //PA interrupt other
-				} else {
-					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
-				}
-
-			} else if utils.IsIO(event["CallerIDNum"]) { // CPA
-				if priority.CheckPriority("CPA") {
-					if active.ActivedCab == "" { //No active Signal on both side,Hangup caller
-						Hangup(event["CallerIDNum"])
-					} else if active.ActivedCab == "1" && event["CallerIDNum"] == "1411" {
-						Hangup(event["CallerIDNum"])
-					} else if active.ActivedCab == "8" && event["CallerIDNum"] == "1481" {
-						Hangup(event["CallerIDNum"])
-					}
-
-					//hangup others if priority is higher
-					if priority.RunningType != "C2C" {
-						HangupRunningTask("CPA") //CPA interrupt other
-					} else {
-						//call to ICP ; can not stop calling ICP
-						lfshook.NewLogger().Info("==Running CabCab , CPA start call ICP(ICP is on the phone)=====")
-					}
-				} else {
-					Hangup(event["CallerIDNum"]) //lowwer priority ,hangup caller
-				}
-			}
-		} else if event["UserEvent"] == "CallType" && event["Type"] == "C2C" { //CabCab start; check cab cab priority
-
-			if priority.CheckPriority("CabCab") {
-
-				if priority.RunningType == "PA" || priority.RunningType == "PAD-ICP" || priority.RunningType == "PAD-TMS" {
-					HangupRunningTask("C2C") //C2C interrupt other
-				} else {
-					//Hangup the other ICP
-					if event["CallerIDNum"] == "2311" {
-						Hangup("2381")
-					} else {
-						Hangup("2311")
-					}
-				}
-			} else { // hangup caller; C2C start failed
-				Hangup(event["CallerIDNum"])
-			}
 		}
 
 	case "Hangup":
@@ -300,8 +381,15 @@ func HandleAMI(event map[string]string) {
 					//priority.CleanPriorityTag()
 					//HangupAllLocalChan()
 					if priority.PADStart == 1 {
+						SetPadTimer()
 						alstatus.PaStatus(event["CallerIDNum"], "PAD", "end")
 						priority.PADStart = 0
+
+						priority.CleanPriorityTag()
+
+						if active.CONBID != "" {
+							ConfbridgeKick(active.CONBID, "all")
+						}
 					}
 					/*if priority.ResumeEmgPara.FileName != "" {
 						CheckEmgResume()
@@ -331,34 +419,41 @@ func HandleAMI(event map[string]string) {
 			}
 
 			if priority.ICPAnswer == 0 && ICPQueue.Calls == "1" { //ICP did not answer any first call to the ICP queue ; Ready to Set Occ Queue Timer
+				toRunpriority, _ := strconv.Atoi(priority.GetPriorityByKey("PAD-ICP"))
 
-				active.QueueTimer = time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout
+				//PAD press key
+				lfshook.NewLogger().Infof("===QueueCallerJoin===runing:%d=====toRun:=%d==Status:%s", priority.RunningTypePriority, toRunpriority, event["ChannelStateDesc"])
+				if (priority.RunningTypePriority > toRunpriority || priority.RunningTypePriority == 0) && event["ChannelStateDesc"] != "Up" {
 
-					res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start
-					if err != nil {
-						lfshook.NewLogger().Infof("===OCC-QueueStatus==%+v", err)
-						return
-					}
+					active.QueueTimer = time.AfterFunc(30*time.Second, func() { // check the PAD 30s timeout
 
-					if res.Calls == "0" { // OCC queue empty
-						resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
+						res, err := QueueStatus("0301", "") // check OCC queue , if empty OCC-PAD start
 						if err != nil {
-							lfshook.NewLogger().Infof("==ICP=QueueStatus==%+v", err)
+							lfshook.NewLogger().Infof("===OCC-QueueStatus==%+v", err)
 							return
 						}
-						sort.Slice(resCaller.Entrys, func(i, j int) bool {
-							return resCaller.Entrys[i].Position < resCaller.Entrys[j].Position
-						})
-
-						for _, caller := range resCaller.Entrys {
-							priority.ICPAnswer = 0
-							lfshook.NewLogger().Infof("====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.Microsecond * 500)                                            //200 ms delay
+
+						if res.Calls == "0" { // OCC queue empty
+							resCaller, err := QueueStatus("0300", "") // check ICP queue, get entries
+							if err != nil {
+								lfshook.NewLogger().Infof("==ICP=QueueStatus==%+v", err)
+								return
+							}
+							sort.Slice(resCaller.Entrys, func(i, j int) bool {
+								return resCaller.Entrys[i].Position < resCaller.Entrys[j].Position
+							})
+
+							for _, caller := range resCaller.Entrys {
+								priority.ICPAnswer = 0
+								lfshook.NewLogger().Infof("====QueueCallerJoin==QueueTimer===%s", event["Event"])
+								lfshook.NewLogger().Infof("====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.Microsecond * 500)                                            //200 ms delay
+							}
 						}
-					}
-				})
+					})
+				}
 			}
 
 			break
@@ -417,6 +512,7 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "EMG"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.EMG)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "EMG", "start")
 				return
 			}
@@ -426,6 +522,7 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "SPC"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.SPC)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "SPC", "start")
 				return
 			}
@@ -435,6 +532,7 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "DCS"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.DCS)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "DCS", "start")
 				return
 			}
@@ -444,6 +542,7 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "STN"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.STN)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "STN", "start")
 				return
 			}
@@ -453,6 +552,7 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "CHK"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.CHK)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "CHK", "start")
 				return
 			}
@@ -462,11 +562,19 @@ func HandleAMI(event map[string]string) {
 				priority.RunningType = "VOL"
 				//Pa status report
 				priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.VOL)
+				active.CONBID = event["Conference"]
 				alstatus.PaStatus("", "VOL", "start")
 				return
 			}
 		}
 
+		//get confbridge id for join back to confbridge
+		if event["Context"] == "pad-page-occ-icp" && utils.IsPAIU(event["CallerIDNum"]) {
+			active.CONBID = event["Conference"]
+		} else if event["Context"] == "cpa-rule" && utils.IsIO(event["CallerIDNum"]) {
+			active.CONBID = event["Conference"]
+		}
+
 		//Send PA start msg to STC
 		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA start
 			lfshook.NewLogger().Infof("====PA status:%s=====", "start")
@@ -528,78 +636,172 @@ func HandleAMI(event map[string]string) {
 	case "ConfbridgeLeave":
 		lfshook.NewLogger().Infof("=========%s", event["Event"])
 		if utils.IsICP(event["CallerIDNum"]) && event["Exten"] == "0500" { // PA end
+			SetPadTimer()
 			lfshook.NewLogger().Infof("====PA  status =====%s", "end")
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDNum"], "PA", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if utils.IsIO(event["CallerIDNum"]) && event["Exten"] == "0501" { //CPA end
 			lfshook.NewLogger().Infof("====CPA  status =====%s", "end")
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDNum"], "CPA", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 			//lfshook.NewLogger().Infof("=========%s", event["Event"])
 		} else if event["CallerIDName"] == "EMG" && event["Exten"] == "0502" { // EMG broadcast hangup
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "EMG", "end")
 			priority.ResumeEmgPara = priority.BroadcastResumeParas{}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if event["CallerIDName"] == "STN" && event["Exten"] == "0503" {
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "STN", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if event["CallerIDName"] == "DCS" && event["Exten"] == "0504" {
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "DCS", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if event["CallerIDName"] == "SPC" && event["Exten"] == "0505" {
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "SPC", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if event["CallerIDName"] == "CHK" && event["Exten"] == "0510" {
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "CHK", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
-
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		} else if event["CallerIDName"] == "VOL" && event["Exten"] == "0513" {
+			SetPadTimer()
 			priority.CleanPriorityTag()
 			alstatus.PaStatus(event["CallerIDName"], "VOL", "end")
 			if priority.ResumeEmgPara.FileName != "" {
 				CheckEmgResume()
 			}
+			if active.CONBID != "" {
+				ConfbridgeKick(active.CONBID, "all")
+			}
 		}
 
 	case "DialEnd":
 		//lfshook.NewLogger().Infof("=========%s", event["Event"])
 		//Cab Cab start
 		if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["DialStatus"] == "ANSWER" {
+
+			priority.TmpRunningTypePriority = priority.RunningTypePriority
 			priority.RunningTypePriority, _ = strconv.Atoi(priority.Priority.CabCab)
+
+			priority.TmpRunningType = priority.RunningType
 			priority.RunningType = "C2C"
+
 			alstatus.PaStatus(event["CallerIDNum"], "C2C", "start")
+		} else if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["DialStatus"] == "NOANSWER" {
+
+			lfshook.NewLogger().Infof("===%s======%s", event["Event"], priority.RunningType)
+			//ICPs go back to confbridge
+			switch priority.RunningType {
+			case "PAD-OCC":
+				go DialICP("8", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("8", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "CPA":
+				go DialICP("2", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("2", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "EMG":
+				go DialICP("3", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("3", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "SPC":
+				go DialICP("6", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("6", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "STN":
+				go DialICP("4", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("4", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "DCS":
+				go DialICP("5", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("5", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "CHK":
+				go DialICP("10", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("10", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "VOL":
+				go DialICP("11", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("11", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			}
 		}
 
 	case "BridgeLeave":
 		//lfshook.NewLogger().Infof("=========%s", event["Event"])
 		//Cab Cab end
 		if utils.IsICP(event["CallerIDNum"]) && utils.IsICP(event["ConnectedLineNum"]) && event["Exten"] == "0400" {
-			priority.RunningTypePriority = 0
-			priority.RunningType = ""
+			SetPadTimer()
+
+			priority.RunningTypePriority = priority.TmpRunningTypePriority
+			priority.TmpRunningTypePriority = 0
+			priority.RunningType = priority.TmpRunningType
+
+			//ICPs go back to confbridge
+			switch priority.TmpRunningType {
+			case "PAD-OCC":
+				go DialICP("8", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("8", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "CPA":
+				go DialICP("2", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("2", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "EMG":
+				go DialICP("3", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("3", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "SPC":
+				go DialICP("6", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("6", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "STN":
+				go DialICP("4", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("4", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "DCS":
+				go DialICP("5", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("5", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "CHK":
+				go DialICP("10", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("10", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			case "VOL":
+				go DialICP("11", "2311", "confbridge-join", active.CONBID, "1") //ICP1---call
+				go DialICP("11", "2381", "confbridge-join", active.CONBID, "8") //ICP8---call
+			}
+
+			priority.TmpRunningType = ""
+
 			alstatus.PaStatus(event["CallerIDNum"], "C2C", "end")
 		}
 

+ 1 - 1
internal/app/index.go

@@ -18,7 +18,7 @@ func StartApp() {
 	//Get cab number acording to IP
 	SetMasterCabNum()
 
-	//lfshook.NewLogger().Infof("=================cab number:%s========Master:%+v===", active.CabNum, active.Master)
+	lfshook.NewLogger().Infof("=================cab number:%s========Master:%+v===", active.CabNum, active.Master)
 
 	//init the active status
 	//active.ActivedCab = ""

+ 41 - 2
internal/app/stc/active/index.go

@@ -1,6 +1,11 @@
 package active
 
-import "time"
+import (
+	"fmt"
+	"net/http"
+	"pbx-api-gin/pkg/lfshook"
+	"time"
+)
 
 // var ActiveCab string
 var CabNum string
@@ -10,4 +15,38 @@ var Master = false
 
 var QueueTimer *time.Timer = nil
 
-//var ActivedMC int
+//ICP join PAD-OCC confbridge id
+var CONBID = ""
+
+// 挂断所有报警器
+func NotifyPaiu(Exten, Action string) {
+	url := ""
+	switch Action {
+	case "answer":
+		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=answer", Exten[2:])
+	case "hold":
+		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=hold", Exten[2:])
+	case "hangup":
+		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=hangup", Exten[2:])
+	}
+
+	lfshook.NewLogger().Logger.Infof("======Notify PAIU Alarm====:%+v ", url)
+	resp, err := http.Get(url)
+	if err != nil {
+		lfshook.NewLogger().Logger.Infof("======Notify PAIU Alarm====:%+v ", err)
+		return
+	}
+	defer resp.Body.Close()
+	/*
+	   body, err := io.ReadAll(resp.Body)
+
+	   	if err != nil {
+	   		// 读取数据错误
+	   		lfshook.NewLogger().Warn("ioutil ReadAll failed :", err.Error())
+	   		return
+	   	}
+
+	   fmt.Printf("状态码: %d\n", resp.StatusCode)
+	   fmt.Printf("响应内容: %s\n", body)
+	*/
+}

+ 7 - 44
internal/app/stc/broadcast/stc-broadcast.go

@@ -6,7 +6,6 @@ import (
 	"fmt"
 	"io"
 	"net"
-	"net/http"
 	"pbx-api-gin/internal/app/ami/action"
 	"pbx-api-gin/internal/app/stc/active"
 	msgdata "pbx-api-gin/internal/app/stc/data"
@@ -238,8 +237,8 @@ func processPacket(packet []byte) {
 			alstatus.PaStatus("", "PAD-ICP", "refuse")
 		}
 
-	default:
-		fmt.Printf("Unknown command: %x\n", packet[5])
+		//default:
+		//fmt.Printf("Unknown command: %x\n", packet[5])
 	}
 }
 
@@ -394,8 +393,6 @@ func ToneTest(data []byte) {
 		action.PlaybackPacu(strconv.Quote(filename), int(cycleCount), int(delay), "VOL")
 
 	case 0x02: //stop
-
-		//alstatus.PaStatus("", "VOL", "end")
 		action.HangupAllExcept("")
 	}
 }
@@ -418,8 +415,7 @@ func SelfCheck(data []byte) {
 	case 0x02: //stop
 
 		//Pa status report
-		priority.CleanPriorityTag()
-		//alstatus.PaStatus("", "CHK", "end")
+		//priority.CleanPriorityTag()
 		action.HangupAllExcept("")
 	}
 }
@@ -479,8 +475,8 @@ func AlarmHandleICP(data []byte) {
 		}
 
 	case 0x02: //hold  重新放回队列里面
-		NotifyPaiu(exten, "hold")
-		err := action.RedirectInQueue(exten, "0300", "default", "1")
+		active.NotifyPaiu(exten, "hold")
+		err := action.RedirectInQueue(exten, "0300", "queues-icp-redirect", "1")
 		if err != nil {
 			lfshook.NewLogger().Info(err)
 		}
@@ -545,8 +541,8 @@ func AlarmHandleTMS(data []byte) {
 		}
 
 	case 0x02: //hold  重新放回队列里面
-		NotifyPaiu(exten, "hold")
-		err := action.RedirectInQueue(exten, "0300", "default", "1")
+		active.NotifyPaiu(exten, "hold")
+		err := action.RedirectInQueue(exten, "0300", "queues-icp-redirect", "1")
 		if err != nil {
 			lfshook.NewLogger().Info(err)
 		}
@@ -561,39 +557,6 @@ func AlarmHandleTMS(data []byte) {
 	}
 }
 
-// 挂断所有报警器
-func NotifyPaiu(Exten, Action string) {
-	url := ""
-	switch Action {
-	case "answer":
-		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=answer", Exten[2:])
-	case "hold":
-		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=hold", Exten[2:])
-	case "hangup":
-		url = fmt.Sprintf("http://10.0.24.%s/api/sipphone?action=hangup", Exten[2:])
-	}
-
-	lfshook.NewLogger().Logger.Infof("======Notify PAIU Alarm====:%+v ", url)
-	resp, err := http.Get(url)
-	if err != nil {
-		lfshook.NewLogger().Logger.Infof("======Notify PAIU Alarm====:%+v ", err)
-		return
-	}
-	defer resp.Body.Close()
-	/*
-	   body, err := io.ReadAll(resp.Body)
-
-	   	if err != nil {
-	   		// 读取数据错误
-	   		lfshook.NewLogger().Warn("ioutil ReadAll failed :", err.Error())
-	   		return
-	   	}
-
-	   fmt.Printf("状态码: %d\n", resp.StatusCode)
-	   fmt.Printf("响应内容: %s\n", body)
-	*/
-}
-
 // 挂断所有报警器
 func AlarmHoldResetAll(handler byte) {
 

+ 1 - 1
internal/app/stc/index.go

@@ -28,7 +28,7 @@ func StartStcConnection(conn net.Conn, cab string) {
 		conn1, err = CreateConnection(cab)
 		if err != nil || conn1 == nil {
 			time.Sleep(2 * time.Second)
-			lfshook.NewLogger().Logger.Infof("===========Reconnecting====To Cab:%s=======", cab)
+			//lfshook.NewLogger().Logger.Infof("===========Reconnecting====To Cab:%s=======", cab)
 			continue
 		}
 

+ 10 - 1
internal/app/stc/priority/index.go

@@ -11,12 +11,21 @@ import (
 
 var ICPAnswer = 0
 var OCCAnswer = 0
+
 var RunningTypePriority = 0
 var RunningType = ""
-var SpecialVoice = 0
 var RunningPATaskChan = ""
+
+var TmpRunningTypePriority = 0
+var TmpRunningType = ""
+
+var SpecialVoice = 0
+
 var PADStart = 0
 var PADOccStart = 0
+var PAStart = 0
+
+var InterruptedPad = ""
 
 type BroadcastResumeParas struct {
 	FileName      string `json:"filename"`

+ 1 - 2
pkg/utils/file.go

@@ -9,7 +9,6 @@ import (
 	"os/exec"
 	"path/filepath"
 	"pbx-api-gin/internal/pkg/configs"
-	"pbx-api-gin/pkg/lfshook"
 	"strconv"
 	"strings"
 )
@@ -113,7 +112,7 @@ func ConvertAndSegmentWAV(inputFile string, outputPrefix string) ([]string, erro
 	// 解析输出,提取所有生成的文件名
 	files := extractFilenamesFromFFmpegOutput(outputPrefix)
 
-	lfshook.NewLogger().Infof("=============== found after convert outfiles %+v ", files)
+	//lfshook.NewLogger().Infof("found after convert outfiles %+v ", files)
 	return files, nil
 }