mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-13 02:56:24 +05:00
Merge branch 'master' into load
This commit is contained in:
28
data/tutorials/fs_evsock/cgrates/etc/cgrates/cdrc_fs.json
Normal file
28
data/tutorials/fs_evsock/cgrates/etc/cgrates/cdrc_fs.json
Normal file
@@ -0,0 +1,28 @@
|
||||
{
|
||||
// Contains CDRC template for FreeSWITCH CDR
|
||||
|
||||
"cdrc": {
|
||||
"CDRC-FS": {
|
||||
"enabled": true, // enable CDR client functionality
|
||||
"cdr_in_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/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": "^*pseudoprepaid", "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},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ ENABLE=true
|
||||
DAEMON_OPTS="-config_dir=$TUTFOLDER/etc/cgrates"
|
||||
HISTDIR=$TMP_DIR/history
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
CDRCINDIR=$TMP_DIR/cdrc/in
|
||||
CDRCOUTDIR=$TMP_DIR/cdrc/out
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
@@ -54,6 +56,13 @@ if [ ! -d $RUNDIR ]; then
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdrc folder
|
||||
if [ ! -d $CDRCINDIR ]; then
|
||||
mkdir -p $CDRCINDIR
|
||||
chown $USER:$GROUP $CDRCINDIR
|
||||
mkdir -p $CDRCOUTDIR
|
||||
chown $USER:$GROUP $CDRCOUTDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
|
||||
@@ -140,23 +140,49 @@
|
||||
{"tag":"Cost", "cdr_field_id": "cost", "type": "cdrfield", "value": "cost"},
|
||||
],
|
||||
"trailer_fields": [], // template of the exported trailer fields
|
||||
},
|
||||
"customer_tpl": {
|
||||
"cdr_format": "csv", // exported CDRs format <csv>
|
||||
"field_separator": ";",
|
||||
"data_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from KBytes to Bytes)
|
||||
"sms_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from SMS unit to call duration in some billing systems)
|
||||
"cost_multiply_factor": 1, // multiply cost before export, eg: add VAT
|
||||
"cost_rounding_decimals": -1, // rounding decimals for Cost values. -1 to disable rounding
|
||||
"cost_shift_digits": 0, // shift digits in the cost on export (eg: convert from EUR to cents)
|
||||
"mask_destination_id": "MASKED_DESTINATIONS", // destination id containing called addresses to be masked on export
|
||||
"mask_length": 0, // length of the destination suffix to be masked
|
||||
"export_dir": "/tmp/cgr_kamevapi/cgrates/cdre", // path where the exported CDRs will be placed
|
||||
"header_fields": [], // template of the exported header fields
|
||||
"content_fields": [ // template of the exported content fields
|
||||
{"tag": "CgrId", "cdr_field_id": "cgrid", "type": "cdrfield", "value": "cgrid"},
|
||||
{"tag":"AccId", "cdr_field_id": "accid", "type": "cdrfield", "value": "accid"},
|
||||
{"tag":"ReqType", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "reqtype"},
|
||||
{"tag":"Tenant", "cdr_field_id": "tenant", "type": "cdrfield", "value": "tenant"},
|
||||
{"tag":"Category", "cdr_field_id": "category", "type": "cdrfield", "value": "category"},
|
||||
{"tag":"Subject", "cdr_field_id": "account", "type": "cdrfield", "value": "account"},
|
||||
{"tag":"Destination", "cdr_field_id": "destination", "type": "cdrfield", "value": "~destination:s/^1(\\d+)/+$1/:s/^\\+(\\d+)/00$1/"},
|
||||
{"tag":"AnswerTime", "cdr_field_id": "answer_time", "type": "cdrfield", "value": "answer_time", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"Usage", "cdr_field_id": "usage", "type": "cdrfield", "value": "usage"},
|
||||
{"tag":"Cost", "cdr_field_id": "cost", "type": "cdrfield", "value": "cost"},
|
||||
],
|
||||
"trailer_fields": [], // template of the exported trailer fields
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
//"cdrc": {
|
||||
// "*default": {
|
||||
// "enabled": false, // enable CDR client functionality
|
||||
// "cdrs_address": "internal", // address where to reach CDR server. <internal|x.y.z.y:1234>
|
||||
// "cdr_format": "csv", // CDR file format <csv|freeswitch_csv|fwv>
|
||||
// "field_separator": ",", // separator used in case of csv files
|
||||
// "run_delay": 0, // sleep interval in seconds between consecutive runs, 0 to use automation via inotify
|
||||
// "data_usage_multiply_factor": 1024, // conversion factor for data usage
|
||||
// "cdr_in_dir": "/var/log/cgrates/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
// "cdr_out_dir": "/var/log/cgrates/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
// "cdr_source_id": "freeswitch_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
// "cdr_filter": "", // Filter CDR records to import
|
||||
// "cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
// "enabled": false, // enable CDR client functionality
|
||||
// "cdrs_address": "internal", // address where to reach CDR server. <internal|x.y.z.y:1234>
|
||||
// "cdr_format": "csv", // CDR file format <csv|freeswitch_csv|fwv>
|
||||
// "field_separator": ",", // separator used in case of csv files
|
||||
// "run_delay": 0, // sleep interval in seconds between consecutive runs, 0 to use automation via inotify
|
||||
// "data_usage_multiply_factor": 1024, // conversion factor for data usage
|
||||
// "cdr_in_dir": "/var/log/cgrates/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
// "cdr_out_dir": "/var/log/cgrates/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
// "cdr_source_id": "freeswitch_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
// "cdr_filter": "", // Filter CDR records to import
|
||||
// "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": "2", "mandatory": true},
|
||||
// {"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "3", "mandatory": true},
|
||||
// {"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "4", "mandatory": true},
|
||||
@@ -170,7 +196,7 @@
|
||||
// {"tag": "answer_time", "cdr_field_id": "answer_time", "type": "cdrfield", "value": "12", "mandatory": true},
|
||||
// {"tag": "usage", "cdr_field_id": "usage", "type": "cdrfield", "value": "13", "mandatory": true},
|
||||
// ],
|
||||
// }
|
||||
// },
|
||||
//},
|
||||
|
||||
|
||||
|
||||
@@ -7,16 +7,16 @@ event_route[evapi:connection-new] {
|
||||
|
||||
# Called when the connection with CGRateS closes
|
||||
event_route[evapi:connection-closed] {
|
||||
$var(connClosed) = $evapi(srcaddr) + ":" + $evapi(srcport);
|
||||
if $sht(cgrconn=>cgr) == $var(connClosed) {
|
||||
$sht(cgrconn=>cgr) = $null;
|
||||
}
|
||||
$var(connClosed) = $evapi(srcaddr) + ":" + $evapi(srcport);
|
||||
if $sht(cgrconn=>cgr) == $var(connClosed) {
|
||||
$sht(cgrconn=>cgr) = $null;
|
||||
}
|
||||
}
|
||||
|
||||
# Message received from CGRateS, dispatch it to own route
|
||||
event_route[evapi:message-received] {
|
||||
json_get_field("$evapi(msg)", "Event", "$var(Event)");
|
||||
route($(var(Event){s.rm,"})); # String characters are kept by json_get_field, remove them here
|
||||
route($(var(Event){s.rm,"})); # String characters are kept by json_get_field, remove them here
|
||||
}
|
||||
|
||||
# Called by Kamailio on new dialog
|
||||
@@ -56,10 +56,41 @@ route[CGRATES_AUTH_REQUEST] {
|
||||
# Process AUTH_REPLY from CGRateS
|
||||
route[CGR_AUTH_REPLY] {
|
||||
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
|
||||
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
|
||||
json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)");
|
||||
json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)");
|
||||
json_get_field("$evapi(msg)", "Error", "$var(Error)");
|
||||
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
|
||||
json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)");
|
||||
json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)");
|
||||
json_get_field("$evapi(msg)", "Error", "$var(Error)");
|
||||
$var(id_index) = $(var(TransactionIndex){s.int});
|
||||
$var(id_label) = $(var(TransactionLabel){s.int});
|
||||
$var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int});
|
||||
$var(CgrSuppliers) = $(var(Suppliers){s.rm,"});
|
||||
$var(CgrError) = $(var(Error){s.rm,"});
|
||||
t_continue("$var(id_index)", "$var(id_label)", "CGRATES_AUTH_REPLY"); # Unpark the transaction
|
||||
}
|
||||
|
||||
# Send AUTH_REQUEST to CGRateS
|
||||
route[CGRATES_LCR_REQUEST] {
|
||||
# Auth INVITEs with CGRateS
|
||||
if $sht(cgrconn=>cgr) == $null {
|
||||
sl_send_reply("503","Charging controller unreachable");
|
||||
exit;
|
||||
}
|
||||
evapi_async_relay("{\"event\":\"CGR_LCR_REQUEST\",
|
||||
\"tr_index\":\"$T(id_index)\",
|
||||
\"tr_label\":\"$T(id_label)\",
|
||||
\"cgr_tenant\":\"$dlg_var(cgrTenant)\",
|
||||
\"cgr_account\":\"$dlg_var(cgrAccount)\",
|
||||
\"cgr_destination\":\"$dlg_var(cgrDestination)\",
|
||||
\"cgr_setuptime\":\"$TS\"}");
|
||||
}
|
||||
|
||||
# Process LCR_REPLY from CGRateS
|
||||
route[CGR_LCR_REPLY] {
|
||||
json_get_field("$evapi(msg)", "TransactionIndex", "$var(TransactionIndex)");
|
||||
json_get_field("$evapi(msg)", "TransactionLabel", "$var(TransactionLabel)");
|
||||
json_get_field("$evapi(msg)", "MaxSessionTime", "$var(MaxSessionTime)");
|
||||
json_get_field("$evapi(msg)", "Suppliers", "$var(Suppliers)");
|
||||
json_get_field("$evapi(msg)", "Error", "$var(Error)");
|
||||
$var(id_index) = $(var(TransactionIndex){s.int});
|
||||
$var(id_label) = $(var(TransactionLabel){s.int});
|
||||
$var(CgrMaxSessionTime) = $(var(MaxSessionTime){s.int});
|
||||
@@ -71,8 +102,8 @@ route[CGR_AUTH_REPLY] {
|
||||
# CGRateS request for session disconnect
|
||||
route[CGR_SESSION_DISCONNECT] {
|
||||
json_get_field("$evapi(msg)", "HashEntry", "$var(HashEntry)");
|
||||
json_get_field("$evapi(msg)", "HashId", "$var(HashId)");
|
||||
json_get_field("$evapi(msg)", "Reason", "$var(Reason)");
|
||||
json_get_field("$evapi(msg)", "HashId", "$var(HashId)");
|
||||
son_get_field("$evapi(msg)", "Reason", "$var(Reason)");
|
||||
jsonrpc_exec('{"jsonrpc":"2.0","id":1, "method":"dlg.end_dlg","params":[$(var(HashEntry){s.rm,"}),$(var(HashId){s.rm,"})]}');
|
||||
#$jsonrpl($var(reply));
|
||||
}
|
||||
|
||||
@@ -18,6 +18,12 @@ log_facility=LOG_LOCAL0
|
||||
fork=yes
|
||||
children=4
|
||||
tcp_connection_lifetime=3605
|
||||
use_dns_cache=no
|
||||
dns_try_ipv6=no
|
||||
dns_retr_time=1
|
||||
dns_retr_no=1
|
||||
dns_servers_no=1
|
||||
dns_use_search_list=no
|
||||
|
||||
####### Modules Section ########
|
||||
|
||||
@@ -97,6 +103,7 @@ event_route[htable:mod-init] {
|
||||
$sht(users=>1002) = "CGRateS.org";
|
||||
$sht(users=>1003) = "CGRateS.org";
|
||||
$sht(users=>1004) = "CGRateS.org";
|
||||
$sht(users=>1005) = "CGRateS.org";
|
||||
$sht(users=>1006) = "CGRateS.org";
|
||||
$sht(users=>1007) = "CGRateS.org";
|
||||
}
|
||||
@@ -182,6 +189,7 @@ request_route {
|
||||
$dlg_var(cgrAccount) = $fU;
|
||||
$dlg_var(cgrDestination) = $rU;
|
||||
route(CGRATES_AUTH_REQUEST); # Will be answered in CGRATES_AUTH_REPLY
|
||||
#route(CGRATES_LCR_REQUEST);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ func TestTutKamCallsRestartKam(t *testing.T) {
|
||||
if !*testCalls {
|
||||
return
|
||||
}
|
||||
if err := engine.CallScript(path.Join(*dataDir, "tutorials", "kamevapi", "kamailio", "etc", "init.d", "kamailio"), "restart", 1000); err != nil {
|
||||
if err := engine.CallScript(path.Join(*dataDir, "tutorials", "kamevapi", "kamailio", "etc", "init.d", "kamailio"), "restart", 4000); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
@@ -595,6 +595,7 @@ func TestTutKamCallsStopPjsuaListener(t *testing.T) {
|
||||
time.Sleep(time.Duration(1) * time.Second) // Allow pjsua to finish it's tasks, eg un-REGISTER
|
||||
}
|
||||
|
||||
/*
|
||||
func TestTutKamCallsStopCgrEngine(t *testing.T) {
|
||||
if !*testCalls {
|
||||
return
|
||||
@@ -610,3 +611,4 @@ func TestTutKamCallsStopKam(t *testing.T) {
|
||||
}
|
||||
engine.KillProcName("kamailio", 1000)
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -903,6 +903,7 @@ func TestTutLocalCdrStatsAfter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func TestTutLocalStopCgrEngine(t *testing.T) {
|
||||
if !*testLocal {
|
||||
return
|
||||
@@ -911,3 +912,4 @@ func TestTutLocalStopCgrEngine(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user