mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
replaced sched_hangup with sched_transfer
This commit is contained in:
committed by
Dan Christian Bogos
parent
e194979b99
commit
c233daef58
@@ -194,6 +194,27 @@ func TestDiamItSessionDisconnect(t *testing.T) {
|
||||
t.Run(diamConfigDIR, testDiamItKillEngine)
|
||||
}
|
||||
|
||||
func TestDiamItSessionDisconnectNoLoops(t *testing.T) {
|
||||
switch *utils.DBType {
|
||||
case utils.MetaInternal:
|
||||
diamConfigDIR = "diamagent_internal"
|
||||
case utils.MetaMySQL:
|
||||
diamConfigDIR = "diamagent_mysql"
|
||||
case utils.MetaMongo:
|
||||
diamConfigDIR = "diamagent_mongo"
|
||||
case utils.MetaPostgres:
|
||||
t.SkipNow()
|
||||
default:
|
||||
t.Fatal("Unknown Database type")
|
||||
}
|
||||
|
||||
for _, stest := range sTestsDiam[:7] {
|
||||
t.Run(diamConfigDIR, stest)
|
||||
}
|
||||
t.Run(diamConfigDIR, testDiamInitWithSessionDisconnectNoLoops)
|
||||
t.Run(diamConfigDIR, testDiamItKillEngine)
|
||||
}
|
||||
|
||||
func testDiamItInitCfg(t *testing.T) {
|
||||
daCfgPath = path.Join(*utils.DataDir, "conf", "samples", diamConfigDIR)
|
||||
// Init config first
|
||||
@@ -1137,6 +1158,100 @@ func testDiamInitWithSessionDisconnect(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testDiamInitWithSessionDisconnectNoLoops(t *testing.T) {
|
||||
attrSetBalance := utils.AttrSetBalance{Tenant: "cgrates.org",
|
||||
Account: "testDiamInitWithSessionDisconnect",
|
||||
BalanceType: utils.MetaVoice,
|
||||
Value: float64(time.Second),
|
||||
Balance: map[string]any{
|
||||
utils.ID: "testDiamInitWithSessionDisconnect",
|
||||
utils.RatingSubject: "*zero1ms",
|
||||
},
|
||||
}
|
||||
var reply string
|
||||
if err := apierRpc.Call(context.Background(), utils.APIerSv2SetBalance, attrSetBalance, &reply); err != nil {
|
||||
t.Error(err)
|
||||
} else if reply != utils.OK {
|
||||
t.Errorf("Received: %s", reply)
|
||||
}
|
||||
sessID := "bb97be2b9f37c2be9614fff71c8b1d08bdisconnect"
|
||||
m := diam.NewRequest(diam.CreditControl, 4, nil)
|
||||
m.NewAVP(avp.SessionID, avp.Mbit, 0, datatype.UTF8String(sessID))
|
||||
m.NewAVP(avp.OriginHost, avp.Mbit, 0, datatype.DiameterIdentity("192.168.1.1"))
|
||||
m.NewAVP(avp.OriginRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
|
||||
m.NewAVP(avp.AuthApplicationID, avp.Mbit, 0, datatype.Unsigned32(4))
|
||||
m.NewAVP(avp.CCRequestType, avp.Mbit, 0, datatype.Enumerated(1))
|
||||
m.NewAVP(avp.CCRequestNumber, avp.Mbit, 0, datatype.Unsigned32(1))
|
||||
m.NewAVP(avp.DestinationHost, avp.Mbit, 0, datatype.DiameterIdentity("CGR-DA"))
|
||||
m.NewAVP(avp.DestinationRealm, avp.Mbit, 0, datatype.DiameterIdentity("cgrates.org"))
|
||||
m.NewAVP(avp.ServiceContextID, avp.Mbit, 0, datatype.UTF8String("testSessionDisconnectNoLoops"))
|
||||
m.NewAVP(avp.EventTimestamp, avp.Mbit, 0, datatype.Time(time.Date(2018, 10, 4, 14, 42, 20, 0, time.UTC)))
|
||||
m.NewAVP(avp.UserName, avp.Mbit, 0, datatype.UTF8String("testDiamInitWithSessionDisconnect"))
|
||||
m.NewAVP(avp.SubscriptionID, avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(450, avp.Mbit, 0, datatype.Enumerated(0)), // Subscription-Id-Type
|
||||
diam.NewAVP(444, avp.Mbit, 0, datatype.UTF8String("testDiamInitWithSessionDisconnect")), // Subscription-Id-Data
|
||||
}})
|
||||
m.NewAVP(avp.ServiceIdentifier, avp.Mbit, 0, datatype.Unsigned32(0))
|
||||
m.NewAVP(avp.RequestedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(300))}})
|
||||
m.NewAVP(avp.UsedServiceUnit, avp.Mbit, 0, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(420, avp.Mbit, 0, datatype.Unsigned32(0))}})
|
||||
m.NewAVP(873, avp.Mbit, 10415, &diam.GroupedAVP{
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(20300, avp.Mbit, 2011, &diam.GroupedAVP{ // IN-Information
|
||||
AVP: []*diam.AVP{
|
||||
diam.NewAVP(831, avp.Mbit, 10415, datatype.UTF8String("1001")), // Calling-Party-Address
|
||||
diam.NewAVP(832, avp.Mbit, 10415, datatype.UTF8String("1002")), // Called-Party-Address
|
||||
diam.NewAVP(20327, avp.Mbit, 2011, datatype.UTF8String("1002")), // Real-Called-Number
|
||||
diam.NewAVP(20339, avp.Mbit, 2011, datatype.Unsigned32(0)), // Charge-Flow-Type
|
||||
diam.NewAVP(20302, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-Vlr-Number
|
||||
diam.NewAVP(20303, avp.Mbit, 2011, datatype.UTF8String("")), // Calling-CellID-Or-SAI
|
||||
diam.NewAVP(20313, avp.Mbit, 2011, datatype.OctetString("")), // Bearer-Capability
|
||||
diam.NewAVP(20321, avp.Mbit, 2011, datatype.UTF8String("bb97be2b9f37c2be9614fff71c8b1d08bdisconnect")), // Call-Reference-Number
|
||||
diam.NewAVP(20322, avp.Mbit, 2011, datatype.UTF8String("")), // MSC-Address
|
||||
diam.NewAVP(20324, avp.Mbit, 2011, datatype.Unsigned32(0)), // Time-Zone
|
||||
diam.NewAVP(20385, avp.Mbit, 2011, datatype.UTF8String("")), // Called-Party-NP
|
||||
diam.NewAVP(20386, avp.Mbit, 2011, datatype.UTF8String("")), // SSP-Time
|
||||
},
|
||||
}),
|
||||
}})
|
||||
// ============================================
|
||||
// prevent nil pointer dereference
|
||||
// ============================================
|
||||
if diamClnt == nil {
|
||||
t.Fatal("Diameter client should not be nil")
|
||||
}
|
||||
if diamClnt.conn == nil {
|
||||
t.Fatal("Diameter connection should not be nil")
|
||||
}
|
||||
if m == nil {
|
||||
t.Fatal("The mesage to diameter should not be nil")
|
||||
}
|
||||
// ============================================
|
||||
if err := diamClnt.SendMessage(m); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
msg := diamClnt.ReceivedMessage(rplyTimeout)
|
||||
if msg == nil {
|
||||
t.Fatal("No message returned")
|
||||
}
|
||||
// Result-Code
|
||||
eVal := "2001"
|
||||
if avps, err := msg.FindAVPsWithPath([]any{"Result-Code"}, dict.UndefinedVendorID); err != nil {
|
||||
t.Error(err)
|
||||
} else if len(avps) == 0 {
|
||||
t.Error("Missing AVP")
|
||||
} else if val, err := diamAVPAsString(avps[0]); err != nil {
|
||||
t.Error(err)
|
||||
} else if val != eVal {
|
||||
t.Errorf("expecting: %s, received: <%s>", eVal, val)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func testDiamItKillEngine(t *testing.T) {
|
||||
if err := engine.KillEngine(1000); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -120,11 +120,19 @@ func (fsa *FSsessions) setMaxCallDuration(uuid string, connIdx int,
|
||||
}
|
||||
return
|
||||
}
|
||||
if _, err = fsa.conns[connIdx].SendApiCmd(
|
||||
fmt.Sprintf("uuid_setvar %s execute_on_answer sched_hangup +%d alloted_timeout\n\n",
|
||||
uuid, int(maxDur.Seconds()))); err != nil {
|
||||
if fsa.cfg.SchedTransferExtension != utils.EmptyString {
|
||||
if _, err = fsa.conns[connIdx].SendApiCmd(fmt.Sprintf("uuid_setvar %s execute_on_answer sched_transfer +%d %s XML default\n\n",
|
||||
uuid, int(maxDur.Seconds()), fsa.cfg.SchedTransferExtension)); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<%s> Could not send sched_transfer to freeswitch, error: <%s>, connIdx: %v",
|
||||
utils.FreeSWITCHAgent, err.Error(), connIdx))
|
||||
}
|
||||
return
|
||||
}
|
||||
if _, err = fsa.conns[connIdx].SendApiCmd(fmt.Sprintf("uuid_setvar %s execute_on_answer sched_hangup +%d alloted_timeout\n\n",
|
||||
uuid, int(maxDur.Seconds()))); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<%s> Could not send sched_hangup command to freeswitch, error: <%s>, connIdx: %v",
|
||||
fmt.Sprintf("<%s> Could not send sched_hangup to freeswitch, error: <%s>, connIdx: %v",
|
||||
utils.FreeSWITCHAgent, err.Error(), connIdx))
|
||||
}
|
||||
return
|
||||
@@ -264,6 +272,36 @@ func (fsa *FSsessions) onChannelAnswer(fsev FSEvent, connIdx int) {
|
||||
fsa.disconnectSession(connIdx, chanUUID, "", err.Error())
|
||||
return
|
||||
}
|
||||
if fsa.cfg.SchedTransferExtension != utils.EmptyString {
|
||||
if initReply.MaxUsage != nil && *initReply.MaxUsage == -1 {
|
||||
lastSchedID, err := fsa.getLastSchedID(fsev.GetUUID(), connIdx)
|
||||
if err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<%s> Failed to retrieve last_sched_id for UUID %s, error: %s",
|
||||
utils.FreeSWITCHAgent, fsev.GetUUID(), err.Error()))
|
||||
return
|
||||
}
|
||||
if _, err = fsa.conns[connIdx].SendApiCmd(
|
||||
fmt.Sprintf("sched_del %s\n\n", lastSchedID)); err != nil {
|
||||
utils.Logger.Err(
|
||||
fmt.Sprintf("<%s> Could not cancel scheduled task for UUID %s, error: %s, connIdx: %v",
|
||||
utils.FreeSWITCHAgent, fsev.GetUUID(), err.Error(), connIdx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetLastSchedID retrieves the last_sched_id for scheduled tasks
|
||||
func (fsa *FSsessions) getLastSchedID(uuid string, connIdx int) (string, error) {
|
||||
lastSchedID, err := fsa.conns[connIdx].SendApiCmd(fmt.Sprintf("uuid_getvar %s last_sched_id\n\n", uuid))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
lastSchedID = strings.TrimSpace(lastSchedID)
|
||||
if lastSchedID == "" || lastSchedID == "_undef_" {
|
||||
return "", fmt.Errorf("no scheduled task found for UUID %s", uuid)
|
||||
}
|
||||
return lastSchedID, nil
|
||||
}
|
||||
|
||||
func (fsa *FSsessions) onChannelHangupComplete(fsev FSEvent, connIdx int) {
|
||||
|
||||
Reference in New Issue
Block a user