From d97b99673966d80d9bff0a4f9b8aa2a2bd443a83 Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 26 May 2015 12:50:36 +0200 Subject: [PATCH 1/3] Adding template files for FreeSWITCH default .csv format --- data/conf/samples/fscsv/cgrates.json | 28 +++++++++++++++++++ .../conf/samples/fscsv/freeswitch_csvcdr.json | 27 ++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 data/conf/samples/fscsv/cgrates.json create mode 100644 data/conf/samples/fscsv/freeswitch_csvcdr.json diff --git a/data/conf/samples/fscsv/cgrates.json b/data/conf/samples/fscsv/cgrates.json new file mode 100644 index 000000000..6c4ebb308 --- /dev/null +++ b/data/conf/samples/fscsv/cgrates.json @@ -0,0 +1,28 @@ +{ + +"listen": { + "rpc_json": ":2012", // RPC JSON listening address + "rpc_gob": ":2013", // RPC GOB listening address + "http": ":2080", // HTTP listening address +}, + +"rater": { + "enabled": true, // enable Rater service: + "cdrstats": "internal", // address where to reach the cdrstats service, empty to disable stats functionality<""|internal|x.y.z.y:1234> +}, + +"scheduler": { + "enabled": true, // start Scheduler service: +}, + +"cdrs": { + "enabled": true, // start the CDR Server service: + "rater": "internal", // address where to reach the Rater for cost calculation, empty to disable functionality: <""|internal|x.y.z.y:1234> + "cdrstats": "internal", // address where to reach the cdrstats service, empty to disable stats functionality<""|internal|x.y.z.y:1234> +}, + +"cdr_stats": { + "enabled": true, // starts the cdrstats service: +}, + +} diff --git a/data/conf/samples/fscsv/freeswitch_csvcdr.json b/data/conf/samples/fscsv/freeswitch_csvcdr.json new file mode 100644 index 000000000..80056fbb4 --- /dev/null +++ b/data/conf/samples/fscsv/freeswitch_csvcdr.json @@ -0,0 +1,27 @@ +{ +// Contains CDRC template for FreeSWITCH CDR + +"cdrc": { + "CDRC-CSV2": { + "enabled": true, // enable CDR client functionality + "cdr_in_dir": "/tmp/cgrates/cdrc_fs/in", // absolute path towards the directory where the CDRs are stored + "cdr_out_dir": "/tmp/cgrates/cdrc_fs/out", // absolute path towards the directory where processed CDRs will be moved + "cdr_source_id": "fs_csv", // free form field, tag identifying the source of the CDRs within CDRS database + "cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value + {"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "^*voice", "mandatory": true}, + {"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "10", "mandatory": true}, + {"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "^rated", "mandatory": true}, + {"tag": "direction", "cdr_field_id": "direction", "type": "cdrfield", "value": "^*out", "mandatory": true}, + {"tag": "tenant", "cdr_field_id": "tenant", "type": "cdrfield", "value": "^cgrates.org", "mandatory": true}, + {"tag": "category", "cdr_field_id": "category", "type": "cdrfield", "value": "^call", "mandatory": true}, + {"tag": "account", "cdr_field_id": "account", "type": "cdrfield", "value": "12", "mandatory": true}, + {"tag": "subject", "cdr_field_id": "subject", "type": "cdrfield", "value": "12", "mandatory": true}, + {"tag": "destination", "cdr_field_id": "destination", "type": "cdrfield", "value": "2", "mandatory": true}, + {"tag": "setup_time", "cdr_field_id": "setup_time", "type": "cdrfield", "value": "4", "mandatory": true}, + {"tag": "answer_time", "cdr_field_id": "answer_time", "type": "cdrfield", "value": "5", "mandatory": true}, + {"tag": "usage", "cdr_field_id": "usage", "type": "cdrfield", "value": "~8:s/^(\\d+)$/${1}s/", "mandatory": true}, + ], + }, +}, + +} From f4f56937b7a28a10bac7592c54933d334690a9e0 Mon Sep 17 00:00:00 2001 From: Radu Ioan Fericean Date: Tue, 26 May 2015 13:50:54 +0300 Subject: [PATCH 2/3] fix for maxcost callcost information --- engine/balances.go | 4 +++- engine/calldesc.go | 2 +- engine/calldesc_test.go | 23 +++++++++++++++++++++++ engine/timespans.go | 11 ++++++++++- engine/timespans_test.go | 2 +- 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/engine/balances.go b/engine/balances.go index f5c7e8efb..52b8d386d 100644 --- a/engine/balances.go +++ b/engine/balances.go @@ -337,7 +337,7 @@ func (b *Balance) DebitUnits(cd *CallDescriptor, ub *Account, moneyBalances Bala if ts.Increments == nil { ts.createIncrementsSlice() } - //log.Printf("TS: %+v", ts) + if ts.RateInterval == nil { Logger.Err(fmt.Sprintf("Nil RateInterval ERROR on TS: %+v, CC: %+v, from CD: %+v", ts, cc, cd)) return nil, errors.New("timespan with no rate interval assigned") @@ -472,6 +472,8 @@ func (b *Balance) DebitMoney(cd *CallDescriptor, ub *Account, count bool, dryRun if count { ub.countUnits(&Action{BalanceType: utils.MONETARY, Direction: cc.Direction, Balance: &Balance{Value: amount, DestinationIds: cc.Destination}}) } + + //log.Printf("TS: %+v", cc.Cost) // go to nextincrement continue } diff --git a/engine/calldesc.go b/engine/calldesc.go index 2a69a8830..7aa77fcd8 100644 --- a/engine/calldesc.go +++ b/engine/calldesc.go @@ -576,7 +576,7 @@ func (cd *CallDescriptor) debit(account *Account, dryRun bool, goNegative bool) } //log.Printf("Debit CD: %+v", cd) cc, err = account.debitCreditBalance(cd, !dryRun, dryRun, goNegative) - //log.Print("HERE: ", cc, err) + //log.Printf("HERE: %+v %v", cc, err) if err != nil { Logger.Err(fmt.Sprintf(" Error getting cost for account key <%s>: %s", cd.GetAccountKey(), err.Error())) return nil, err diff --git a/engine/calldesc_test.go b/engine/calldesc_test.go index 56d4cb2a3..df68c9a0a 100644 --- a/engine/calldesc_test.go +++ b/engine/calldesc_test.go @@ -558,6 +558,29 @@ func TestMaxSessionTimeWithMaxCostFree(t *testing.T) { } } +func TestMaxDebitWithMaxCostFree(t *testing.T) { + ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT") + for _, at := range ap { + at.Execute() + } + cd := &CallDescriptor{ + Direction: "*out", + Category: "call", + Tenant: "cgrates.org", + Subject: "max", + Account: "max", + Destination: "0723123113", + TimeStart: time.Date(2015, 3, 23, 19, 0, 0, 0, time.UTC), + TimeEnd: time.Date(2015, 3, 23, 19, 30, 0, 0, time.UTC), + MaxCostSoFar: 0, + } + cc, err := cd.MaxDebit() + expected := 10.0 + if cc.Cost != expected || err != nil { + t.Errorf("Expected %v was %v", expected, cc.Cost) + } +} + func TestGetCostWithMaxCostFree(t *testing.T) { ap, _ := accountingStorage.GetActionTimings("TOPUP10_AT") for _, at := range ap { diff --git a/engine/timespans.go b/engine/timespans.go index 0da7e3040..30d76b292 100644 --- a/engine/timespans.go +++ b/engine/timespans.go @@ -274,7 +274,16 @@ func (ts *TimeSpan) getCost() float64 { ts.Cost = utils.Round(cost, ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod) return ts.Cost } else { - return ts.Increments[0].Cost * float64(ts.Increments.Length()) + cost := 0.0 + // some increments may have 0 cost because of the max cost strategy + for _, inc := range ts.Increments { + cost += inc.Cost + } + if ts.RateInterval != nil && ts.RateInterval.Rating != nil { + return utils.Round(cost, ts.RateInterval.Rating.RoundingDecimals, ts.RateInterval.Rating.RoundingMethod) + } else { + return utils.Round(cost, globalRoundingDecimals, utils.ROUNDING_MIDDLE) + } } } diff --git a/engine/timespans_test.go b/engine/timespans_test.go index 57539eb7d..468e2a51e 100644 --- a/engine/timespans_test.go +++ b/engine/timespans_test.go @@ -235,7 +235,7 @@ func TestTimespanGetCostIntervals(t *testing.T) { ts.Increments[i] = &Increment{Cost: 0.02} } if ts.getCost() != 0.22 { - t.Error("Error caclulating timspan cost: ", ts.getCost()) + t.Error("Error caclulating timespan cost: ", ts.getCost()) } } From a2e36b6ae6273a61db2d5e3b2194cd281c105e0e Mon Sep 17 00:00:00 2001 From: DanB Date: Tue, 26 May 2015 19:09:20 +0200 Subject: [PATCH 3/3] Adding disconnect cause in kamailio SM, modified tests --- .../etc/kamailio/kamailio-cgrates.cfg | 9 +++- .../kamailio/etc/kamailio/kamailio.cfg | 3 -- general_tests/tutorial_kam_calls_test.go | 45 ++++++++++++------- sessionmanager/kamevent.go | 4 +- sessionmanager/kamevent_test.go | 2 +- utils/consts.go | 2 +- 6 files changed, 41 insertions(+), 24 deletions(-) diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg index 2dfccbc20..4ca8454c2 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio-cgrates.cfg @@ -29,6 +29,12 @@ event_route[dialog:end] { route(CGR_CALL_END); } +# Called by Kamailio on local disconnect +event_route[tm:local-request] { + route(CGR_CALL_END); +} + + # Send AUTH_REQUEST to CGRateS route[CGRATES_AUTH_REQUEST] { # Auth INVITEs with CGRateS @@ -106,6 +112,7 @@ route[CGR_CALL_END] { \"cgr_destination\":\"$dlg_var(cgrDestination)\", \"cgr_answertime\":\"$dlg(start_ts)\", \"cgr_duration\":\"$var(callDur)\", - \"cgr_supplier\":\"$dlg_var(cgrSupplier)\"}"); + \"cgr_supplier\":\"$dlg_var(cgrSupplier)\", + \"cgr_disconnectcause\":\"$T_reply_code\"}"); } diff --git a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg index 956d7a611..2028b4be1 100644 --- a/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg +++ b/data/tutorials/kamevapi/kamailio/etc/kamailio/kamailio.cfg @@ -187,18 +187,15 @@ request_route { # Here will land requests after processing them with CGRateS. Call RELAY or other routes following this route route[CGRATES_AUTH_REPLY] { - xlog("CGRATES_AUTH_REPLY reply, got CgrError: $var(CgrError)"); if $var(CgrError) != "" { xlog("CGR_AUTH_ERROR: $var(CgrError)"); sl_send_reply("503","CGR_ERROR"); exit; } - xlog("CGRATES_AUTH_REPLY, CgrMaxSessionTime: $var(CgrMaxSessionTime)"); if $var(CgrMaxSessionTime) != -1 && !dlg_set_timeout("$var(CgrMaxSessionTime)") { sl_send_reply("503","CGR_MAX_SESSION_TIME_ERROR"); exit; } - xlog("CGRATES_AUTH_REPLY, CgrSuppliers: $var(CgrSuppliers)"); if $var(CgrSuppliers) != "" { # Enforce the supplier variable to the first one received from CGRateS, more for testing purposes $dlg_var(cgrSupplier) = $(var(CgrSuppliers){s.select,0,,}); } diff --git a/general_tests/tutorial_kam_calls_test.go b/general_tests/tutorial_kam_calls_test.go index 3be9123e8..399a948cd 100644 --- a/general_tests/tutorial_kam_calls_test.go +++ b/general_tests/tutorial_kam_calls_test.go @@ -304,35 +304,46 @@ func TestTutKamCallsCall1007To1002(t *testing.T) { } /* -// Should hangup at 62 seconds -func TestTutKamCallsCall1006To1007(t *testing.T) { +// Should hangup at 62 seconds, disconnect from SM +func TestTutKamCallsCall1007To1007(t *testing.T) { if !*testCalls { return } - if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1006@127.0.0.1", Username: "1006", Password: "CGRateS.org", Realm: "*"}, "sip:1007@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(90)*time.Second, 5077); err != nil { + if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1007@127.0.0.1", Username: "1007", Password: "CGRateS.org", Realm: "*"}, "sip:1007@127.0.0.1", + "sip:127.0.0.1:5060", time.Duration(75)*time.Second, 5077); err != nil { t.Fatal(err) } } +// Should hangup at 62 seconds, disconnect from Kamailio +func TestTutKamCallsCall1003To1007(t *testing.T) { + if !*testCalls { + return + } + if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1003@127.0.0.1", Username: "1003", Password: "CGRateS.org", Realm: "*"}, "sip:1007@127.0.0.1", + "sip:127.0.0.1:5060", time.Duration(73)*time.Second, 5078); err != nil { + t.Fatal(err) + } +} +*/ + // Call from 1001 (prepaid) to 1007, should not cost more than 62 which is MaxCallCost func TestTutKamCallsCall1001To1007(t *testing.T) { if !*testCalls { return } if err := engine.PjsuaCallUri(&engine.PjsuaAccount{Id: "sip:1001@127.0.0.1", Username: "1001", Password: "CGRateS.org", Realm: "*"}, "sip:1007@127.0.0.1", - "sip:127.0.0.1:5060", time.Duration(100)*time.Second, 5079); err != nil { + "sip:127.0.0.1:5060", time.Duration(70)*time.Second, 5079); err != nil { t.Fatal(err) } } -*/ // Make sure account was debited properly func TestTutKamCallsAccount1001(t *testing.T) { if !*testCalls { return } - time.Sleep(time.Duration(70) * time.Second) // Allow calls to finish before start querying the results + time.Sleep(time.Duration(80) * time.Second) // Allow calls to finish before start querying the results var reply *engine.Account attrs := &utils.AttrGetAccount{Tenant: "cgrates.org", Account: "1001", Direction: "*out"} if err := tutKamCallsRpc.Call("ApierV1.GetAccount", attrs, &reply); err != nil { @@ -353,7 +364,7 @@ func TestTutKamCallsCdrs(t *testing.T) { req := utils.RpcCdrsFilter{Accounts: []string{"1001"}, RunIds: []string{utils.META_DEFAULT}} if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { + } else if len(reply) != 2 { t.Error("Unexpected number of CDRs returned: ", len(reply)) } else { if reply[0].CdrSource != "KAMAILIO_CGR_CALL_END" { @@ -363,7 +374,7 @@ func TestTutKamCallsCdrs(t *testing.T) { t.Errorf("Unexpected ReqType for CDR: %+v", reply[0]) } if reply[0].Usage != "67" { // Usage as seconds - t.Errorf("Unexpected Usage for CDR: %+v", reply[0]) + t.Errorf("Unexpected Usage for 428CDR: %+v", reply[0]) } if reply[0].Supplier != "suppl2" { // Usage as seconds t.Errorf("Unexpected Supplier for CDR: %+v", reply[0]) @@ -372,7 +383,7 @@ func TestTutKamCallsCdrs(t *testing.T) { req = utils.RpcCdrsFilter{Accounts: []string{"1001"}, RunIds: []string{"derived_run1"}, FilterOnDerived: true} if err := tutKamCallsRpc.Call("ApierV2.GetCdrs", req, &reply); err != nil { t.Error("Unexpected error: ", err.Error()) - } else if len(reply) != 1 { + } else if len(reply) != 2 { t.Error("Unexpected number of CDRs returned: ", len(reply)) } else { if reply[0].ReqType != utils.META_RATED { @@ -503,43 +514,43 @@ func TestTutKamCallsCdrStatsAfter(t *testing.T) { return } var statMetrics map[string]float64 - eMetrics := map[string]float64{engine.ACC: 0.9707714286, engine.ACD: 64.2857142857, engine.ASR: 100} + eMetrics := map[string]float64{engine.ACC: 0.9015222222, engine.ACD: 65.5555555556, engine.ASR: 100} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: utils.META_DEFAULT}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.ACC: 0.927, engine.ACD: 63.8333333333, engine.ASR: 100, engine.TCC: 5.562, engine.TCD: 383} + eMetrics = map[string]float64{engine.ACC: 0.8829, engine.ACD: 64.7142857143, engine.ASR: 100, engine.TCC: 6.1803, engine.TCD: 453} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST1"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.TCC: 5.562, engine.TCD: 383, engine.ACC: 0.0217, engine.ACD: 67, engine.ASR: 100} + eMetrics = map[string]float64{engine.TCC: 6.1803, engine.TCD: 453, engine.ACC: 0.32, engine.ACD: 68.5, engine.ASR: 100} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1001"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.ACD: 61, engine.ASR: 100, engine.TCC: 5.562, engine.TCD: 383, engine.ACC: 1.2334} + eMetrics = map[string]float64{engine.ACD: 61, engine.ASR: 100, engine.TCC: 6.1803, engine.TCD: 453, engine.ACC: 1.2334} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1002"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.TCC: 5.562, engine.TCD: 383, engine.ACC: 1.2334, engine.ACD: -1, engine.ASR: -1} + eMetrics = map[string]float64{engine.TCC: 6.1803, engine.TCD: 453, engine.ACC: 1.2334, engine.ACD: -1, engine.ASR: -1} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "CDRST_1003"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.ACC: 1.2334, engine.ACD: 62, engine.ASR: 100, engine.TCC: 3.7002, engine.TCD: 186} + eMetrics = map[string]float64{engine.ACC: 1.00404, engine.ACD: 65.2, engine.ASR: 100, engine.TCC: 5.0202, engine.TCD: 326} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL1"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { t.Errorf("Expecting: %v, received: %v", eMetrics, statMetrics) } - eMetrics = map[string]float64{engine.ACD: 67, engine.ASR: 100, engine.TCC: 1.2551, engine.TCD: 134, engine.ACC: 0.62755} + eMetrics = map[string]float64{engine.ACD: 67, engine.ASR: 100, engine.TCC: 1.2534, engine.TCD: 134, engine.ACC: 0.6267} if err := tutKamCallsRpc.Call("CDRStatsV1.GetMetrics", v1.AttrGetMetrics{StatsQueueId: "STATS_SUPPL2"}, &statMetrics); err != nil { t.Error("Calling CDRStatsV1.GetMetrics, got error: ", err.Error()) } else if !reflect.DeepEqual(eMetrics, statMetrics) { diff --git a/sessionmanager/kamevent.go b/sessionmanager/kamevent.go index 736395593..3ba62cfa6 100644 --- a/sessionmanager/kamevent.go +++ b/sessionmanager/kamevent.go @@ -51,7 +51,7 @@ const ( ) var primaryFields = []string{EVENT, CALLID, FROM_TAG, HASH_ENTRY, HASH_ID, CGR_ACCOUNT, CGR_SUBJECT, CGR_DESTINATION, - CGR_CATEGORY, CGR_TENANT, CGR_REQTYPE, CGR_ANSWERTIME, CGR_SETUPTIME, CGR_STOPTIME, CGR_DURATION} + CGR_CATEGORY, CGR_TENANT, CGR_REQTYPE, CGR_ANSWERTIME, CGR_SETUPTIME, CGR_STOPTIME, CGR_DURATION, utils.CGR_SUPPLIER, utils.CGR_DISCONNECT_CAUSE} type KamAuthReply struct { Event string // Kamailio will use this to differentiate between requests and replies @@ -326,8 +326,10 @@ func (kev KamEvent) AsStoredCdr() *engine.StoredCdr { storCdr.AnswerTime, _ = kev.GetAnswerTime(utils.META_DEFAULT) storCdr.Usage, _ = kev.GetDuration(utils.META_DEFAULT) storCdr.Supplier = kev.GetSupplier(utils.META_DEFAULT) + storCdr.DisconnectCause = kev.GetDisconnectCause(utils.META_DEFAULT) storCdr.ExtraFields = kev.GetExtraFields() storCdr.Cost = -1 + return storCdr } diff --git a/sessionmanager/kamevent_test.go b/sessionmanager/kamevent_test.go index fff4643c2..b06057e48 100644 --- a/sessionmanager/kamevent_test.go +++ b/sessionmanager/kamevent_test.go @@ -47,7 +47,7 @@ func TestNewKamEvent(t *testing.T) { "cgr_answertime":"1419839310", "cgr_duration":"3", "cgr_supplier":"supplier2", - "cgr_disconnect_cause": "200"}` + "cgr_disconnectcause": "200"}` eKamEv := KamEvent{"event": "CGR_CALL_END", "callid": "46c01a5c249b469e76333fc6bfa87f6a@0:0:0:0:0:0:0:0", "from_tag": "bf71ad59", "to_tag": "7351fecf", "cgr_reqtype": utils.META_POSTPAID, "cgr_account": "1001", "cgr_destination": "1002", "cgr_answertime": "1419839310", "cgr_duration": "3", utils.CGR_SUPPLIER: "supplier2", utils.CGR_DISCONNECT_CAUSE: "200"} diff --git a/utils/consts.go b/utils/consts.go index 856b2ff09..2aa4571e6 100644 --- a/utils/consts.go +++ b/utils/consts.go @@ -185,7 +185,7 @@ const ( CONFIG_DIR = "/etc/cgrates/" CGR_SUPPLIER = "cgr_supplier" DISCONNECT_CAUSE = "disconnect_cause" - CGR_DISCONNECT_CAUSE = "cgr_disconnect_cause" + CGR_DISCONNECT_CAUSE = "cgr_disconnectcause" CGR_COMPUTELCR = "cgr_computelcr" )