Add CGR_PROCESS_CDR route in KamailioAgent

This commit is contained in:
TeoV
2019-06-21 15:34:06 +03:00
committed by Dan Christian Bogos
parent 0d6bbb6390
commit 3fa0293bfa
2 changed files with 99 additions and 1 deletions

View File

@@ -40,6 +40,7 @@ var (
kamCallEndRegexp = regexp.MustCompile(CGR_CALL_END)
kamDlgListRegexp = regexp.MustCompile(CGR_DLG_LIST)
kamProcessEventRegex = regexp.MustCompile(CGR_PROCESS_EVENT)
kamProcessCDRRegex = regexp.MustCompile(CGR_PROCESS_CDR)
)
func NewKamailioAgent(kaCfg *config.KamAgentCfg,
@@ -70,6 +71,7 @@ func (self *KamailioAgent) Connect() error {
kamCallEndRegexp: {self.onCallEnd},
kamDlgListRegexp: {self.onDlgList},
kamProcessEventRegex: {self.onCgrProcessEvent},
kamProcessCDRRegex: {self.onCgrProcessCDR},
}
errChan := make(chan error)
for connIdx, connCfg := range self.cfg.EvapiConns {
@@ -302,6 +304,50 @@ func (ka *KamailioAgent) onCgrProcessEvent(evData []byte, connIdx int) {
}
}
func (ka *KamailioAgent) onCgrProcessCDR(evData []byte, connIdx int) {
if connIdx >= len(ka.conns) { // protection against index out of range panic
err := fmt.Errorf("Index out of range[0,%v): %v ", len(ka.conns), connIdx)
utils.Logger.Err(fmt.Sprintf("<%s> %s", utils.FreeSWITCHAgent, err.Error()))
return
}
kev, err := NewKamEvent(evData, ka.cfg.EvapiConns[connIdx].Alias, ka.conns[connIdx].RemoteAddr().String())
if err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> unmarshalling event data: %s, error: %s",
utils.KamailioAgent, evData, err.Error()))
return
}
if kev.MissingParameter() {
if kRply, err := kev.AsKamProcessCDRReply(nil, nil, utils.ErrMandatoryIeMissing); err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> failed building process session event reply for event: %s, error: %s",
utils.KamailioAgent, kev[utils.OriginID], err.Error()))
} else if err = ka.conns[connIdx].Send(kRply.String()); err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> failed sending process session event reply for event: %s, error %s",
utils.KamailioAgent, kev[utils.OriginID], err.Error()))
}
return
}
procCDRArgs := kev.V1ProcessCDRArgs()
if procCDRArgs == nil {
utils.Logger.Err(fmt.Sprintf("<%s> event: %s cannot generate process cdr session arguments",
utils.KamailioAgent, kev[utils.OriginID]))
return
}
procCDRArgs.CGREvent.Event[EvapiConnID] = connIdx // Attach the connection ID
var processReply string
err = ka.sessionS.Call(utils.SessionSv1ProcessCDR, procCDRArgs, &processReply)
if kar, err := kev.AsKamProcessCDRReply(procCDRArgs, &processReply, err); err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> failed building process session event reply for event: %s, error: %s",
utils.KamailioAgent, kev[utils.OriginID], err.Error()))
} else if err = ka.conns[connIdx].Send(kar.String()); err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> failed sending auth reply for event: %s, error: %s",
utils.KamailioAgent, kev[utils.OriginID], err.Error()))
}
}
func (self *KamailioAgent) disconnectSession(connIdx int, dscEv *KamSessionDisconnect) error {
if err := self.conns[connIdx].Send(dscEv.String()); err != nil {
utils.Logger.Err(fmt.Sprintf("<%s> failed sending disconnect request: %s, connection id: %v, error %s",

View File

@@ -36,6 +36,7 @@ const (
CGR_CALL_START = "CGR_CALL_START"
CGR_CALL_END = "CGR_CALL_END"
CGR_PROCESS_EVENT = "CGR_PROCESS_EVENT"
CGR_PROCESS_CDR = "CGR_PROCESS_CDR"
KamTRIndex = "tr_index"
KamTRLabel = "tr_label"
KamHashEntry = "h_entry"
@@ -119,6 +120,16 @@ func (kev KamEvent) MissingParameter() bool {
kev[utils.Destination])
}
return utils.IsSliceMember(mndPrm, "")
case CGR_PROCESS_CDR:
// TRIndex and TRLabel must exist in order to know where to send back the response
return utils.IsSliceMember([]string{
kev[KamTRIndex],
kev[KamTRLabel],
kev[utils.OriginID],
kev[utils.AnswerTime],
kev[utils.Account],
kev[utils.Destination],
}, "")
default: // no/unsupported event
return true
}
@@ -173,6 +184,12 @@ func (kev KamEvent) AsCGREvent(timezone string) (cgrEv *utils.CGREvent, err erro
return nil, err
}
sTime = sTimePrv
case CGR_PROCESS_CDR:
sTimePrv, err := utils.ParseTimeDetectLayout(kev[utils.AnswerTime], timezone)
if err != nil {
return nil, err
}
sTime = sTimePrv
default: // no/unsupported event
return
}
@@ -315,7 +332,25 @@ func (kev KamEvent) V1ProcessEventArgs() (args *sessions.V1ProcessEventArgs) {
return
}
// AsKamAuthReply builds up a Kamailio ProcessEvent based on arguments and reply from SessionS
// V1ProcessCDRArgs returns the arguments used in SessionSv1.ProcessCDR
func (kev KamEvent) V1ProcessCDRArgs() (args *utils.CGREventWithArgDispatcher) {
cgrEv, err := kev.AsCGREvent(config.CgrConfig().GeneralCfg().DefaultTimezone)
if err != nil {
return
}
args = &utils.CGREventWithArgDispatcher{ // defaults
CGREvent: cgrEv,
}
subsystems, has := kev[utils.CGRSubsystems]
if !has {
return
}
cgrArgs := cgrEv.ConsumeArgs(strings.Index(subsystems, utils.MetaDispatchers) != -1, true)
args.ArgDispatcher = cgrArgs.ArgDispatcher
return
}
// AsKamProcessEventReply builds up a Kamailio ProcessEvent based on arguments and reply from SessionS
func (kev KamEvent) AsKamProcessEventReply(procEvArgs *sessions.V1ProcessEventArgs,
procEvReply *sessions.V1ProcessEventReply, rplyErr error) (kar *KamReply, err error) {
evName := CGR_PROCESS_EVENT
@@ -356,6 +391,23 @@ func (kev KamEvent) AsKamProcessEventReply(procEvArgs *sessions.V1ProcessEventAr
return
}
// AsKamProcessEventReply builds up a Kamailio ProcessEvent based on arguments and reply from SessionS
func (kev KamEvent) AsKamProcessCDRReply(cgrEvWithArgDisp *utils.CGREventWithArgDispatcher,
rply *string, rplyErr error) (kar *KamReply, err error) {
evName := CGR_PROCESS_CDR
if kamRouReply, has := kev[KamReplyRoute]; has {
evName = kamRouReply
}
kar = &KamReply{Event: evName,
TransactionIndex: kev[KamTRIndex],
TransactionLabel: kev[KamTRLabel],
}
if rplyErr != nil {
kar.Error = rplyErr.Error()
}
return
}
// AsKamProcessEventEmptyReply builds up a Kamailio ProcessEventEmpty
func (kev KamEvent) AsKamProcessEventEmptyReply() (kar *KamReply) {
evName := CGR_PROCESS_EVENT