diff --git a/apier/v1/callsetup.go b/apier/v1/callsetup.go index 9aa10bea3..e12f77e44 100644 --- a/apier/v1/callsetup.go +++ b/apier/v1/callsetup.go @@ -26,7 +26,7 @@ import ( // Returns MaxSessionTime in seconds, -1 for no limit func (self *ApierV1) GetMaxSessionTime(cdr utils.StoredCdr, maxSessionTime *float64) error { var maxDur float64 - if err := self.Responder.GetDerivedMaxSessionTime(&cdr, &maxDur); err != nil { + if err := self.Responder.GetDerivedMaxSessionTime(cdr, &maxDur); err != nil { return err } if maxDur == -1.0 { diff --git a/data/tutorials/fs_csv/README.md b/data/tutorials/fs_csv/README.md deleted file mode 100644 index 1a39ef3ad..000000000 --- a/data/tutorials/fs_csv/README.md +++ /dev/null @@ -1,18 +0,0 @@ -Tutorial FS_CSV -=============== - -Scenario: ---------- - -* FreeSWITCH with default configuration. - - * Modified following users: 1001-prepaid, 1002-postpaid, 1003-pseudoprepaid, 1004-rated. - * Have added inside default dialplan CGR own extensions just before routing towards users. - * FreeSWITCH configured to generate default .csv CDRs, modified example template to add cgr_reqtype from user variables. - -* CGRateS with following components: - - * CGR-SM started as prepaid controller. - * CGR-CDRC component importing CDRs into CGR. - * CGR-CDRE exporting mediated CDRs - diff --git a/data/tutorials/fs_csv/cgrates/etc/cgrates/cgrates.cfg b/data/tutorials/fs_csv/cgrates/etc/cgrates/cgrates.cfg deleted file mode 100644 index ee4126b89..000000000 --- a/data/tutorials/fs_csv/cgrates/etc/cgrates/cgrates.cfg +++ /dev/null @@ -1,119 +0,0 @@ -# CGRateS Configuration file -# -# This file contains the default configuration hardcoded into CGRateS. -# This is what you get when you load CGRateS with an empty configuration file. -# [global] must exist in all files, rest of the configuration is inter-changeable. - -[global] -# ratingdb_type = redis # Rating subsystem database: . -# ratingdb_host = 127.0.0.1 # Rating subsystem database host address. -# ratingdb_port = 6379 # Rating subsystem port to reach the database. -# ratingdb_name = 10 # Rating subsystem database name to connect to. -# ratingdb_user = # Rating subsystem username to use when connecting to database. -# ratingdb_passwd = # Rating subsystem password to use when connecting to database. -# accountdb_type = redis # Accounting subsystem database: . -# accountdb_host = 127.0.0.1 # Accounting subsystem database host address. -# accountdb_port = 6379 # Accounting subsystem port to reach the database. -# accountdb_name = 11 # Accounting subsystem database name to connect to. -# accountdb_user = # Accounting subsystem username to use when connecting to database. -# accountdb_passwd = # Accounting subsystem password to use when connecting to database. -# stordb_type = mysql # Stor database type to use: -# stordb_host = 127.0.0.1 # The host to connect to. Values that start with / are for UNIX domain sockets. -# stordb_port = 3306 # The port to reach the logdb. -# stordb_name = cgrates # The name of the log database to connect to. -# stordb_user = cgrates # Username to use when connecting to stordb. -# stordb_passwd = CGRateS.org # Password to use when connecting to stordb. -# dbdata_encoding = msgpack # The encoding used to store object data in strings: -# rpc_json_listen = 127.0.0.1:2012 # RPC JSON listening address -# rpc_gob_listen = 127.0.0.1:2013 # RPC GOB listening address -# http_listen = 127.0.0.1:2080 # HTTP listening address -# default_reqtype = rated # Default request type to consider when missing from requests: <""|prepaid|postpaid|pseudoprepaid|rated>. -# default_tor = call # Default Type of Record to consider when missing from requests. -# default_tenant = cgrates.org # Default Tenant to consider when missing from requests. -# default_subject = cgrates # Default rating Subject to consider when missing from requests. -# rounding_method = *middle # Rounding method for floats/costs: <*up|*middle|*down> -# rounding_decimals = 4 # Number of decimals to round float/costs at - -[balancer] -# enabled = false # Start Balancer service: . -# listen = 127.0.0.1:2012 # Balancer listen interface: <""|x.y.z.y:1234>. - -[rater] -enabled = true # Enable RaterCDRSExportPath service: . -# balancer = # Register to Balancer as worker: <""|internal|127.0.0.1:2013>. - -[scheduler] -enabled = true # Starts Scheduler service: . - -[cdrs] -enabled = true # Start the CDR Server service: . -# extra_fields = # Extra fields to store in CDRs -mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal> - -[cdre] -# cdr_format = csv # Exported CDRs format -# extra_fields = # List of extra fields to be exported out in CDRs -export_dir = /tmp/cgrates/cdre # Path where the exported CDRs will be placed - -[cdrc] -enabled = true # Enable CDR client functionality -# cdrs = internal # Address where to reach CDR server. -# run_delay = 0 # Sleep interval in seconds between consecutive runs, 0 to use automation via inotify -cdr_type = freeswitch_csv # CDR file format . -cdr_in_dir = /tmp/cgrates/cdr/cdrc/in # Absolute path towards the directory where the CDRs are stored. -cdr_out_dir = /tmp/cgrates/cdr/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 CGRS database. -accid_field = 10 # Accounting id field identifier. Use index number in case of .csv cdrs. -reqtype_field = 16 # Request type field identifier. Use index number in case of .csv cdrs. -direction_field = ^*out # Direction field identifier. Use index numbers in case of .csv cdrs. -tenant_field = ^cgrates.org # Tenant field identifier. Use index numbers in case of .csv cdrs. -tor_field = ^call # Type of Record field identifier. Use index numbers in case of .csv cdrs. -account_field = 1 # Account field identifier. Use index numbers in case of .csv cdrs. -subject_field = 1 # Subject field identifier. Use index numbers in case of .csv CDRs. -destination_field = 2 # Destination field identifier. Use index numbers in case of .csv cdrs. -answer_time_field = 5 # Answer time field identifier. Use index numbers in case of .csv cdrs. -duration_field = 8 # Duration field identifier. Use index numbers in case of .csv cdrs. -extra_fields = read_codec:13,write_codec:14 # Extra fields identifiers. For .csv, format: : - -[mediator] -enabled = true # Starts Mediator service: . -# rater = internal # Address where to reach the Rater: -# rater_reconnects = 3 # Number of reconnects to rater before giving up. -# run_ids = # Identifiers of each extra mediation to run on CDRs -# reqtype_fields = # Name of request type fields to be used during extra mediation. Use index number in case of .csv cdrs. -# direction_fields = # Name of direction fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# tenant_fields = # Name of tenant fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# tor_fields = # Name of tor fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# account_fields = # Name of account fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# subject_fields = # Name of fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# destination_fields = # Name of destination fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# answer_time_fields = # Name of time_answer fields to be used during extra mediation. Use index numbers in case of .csv cdrs. -# duration_fields = # Name of duration fields to be used during extra mediation. Use index numbers in case of .csv cdrs. - -[session_manager] -enabled = true # Starts SessionManager service: . -# switch_type = freeswitch # Defines the type of switch behind: . -# rater = internal # Address where to reach the Rater. -# rater_reconnects = 3 # Number of reconnects to rater before giving up. -# debit_interval = 5 # Interval to perform debits on. - -[freeswitch] -# server = 127.0.0.1:8021 # Adress where to connect to FreeSWITCH socket. -# passwd = ClueCon # FreeSWITCH socket password. -# reconnects = 5 # Number of attempts on connect failure. - -[history_server] -enabled = true # Starts History service: . -history_dir = /tmp/cgrates/history # Location on disk where to store history files. -# save_interval = 1s # Interval to save changed cache into .git archive - -[history_agent] -# enabled = false # Starts History as a client: . -# server = internal # Address where to reach the master history server: - -[mailer] -# server = localhost # The server to use when sending emails out -# auth_user = cgrates # Authenticate to email server using this user -# auth_passwd = CGRateS.org # Authenticate to email server with this password -# from_address = cgr-mailer@localhost.localdomain # From address used when sending emails out - diff --git a/data/tutorials/fs_csv/cgrates/etc/default/cgrates b/data/tutorials/fs_csv/cgrates/etc/default/cgrates deleted file mode 100644 index 4e7add309..000000000 --- a/data/tutorials/fs_csv/cgrates/etc/default/cgrates +++ /dev/null @@ -1,17 +0,0 @@ -# defaults file for CGRateS real-time charging system - -# start CGRateS init.d script? -# starts with "true" -ENABLE=true - -# Start with specific user/group -#USER=cgrates -#GROUP=cgrates - -# what extra options to give cgrates binary? -# See cgr-engine -h for options -#ENGINE_OPTS='' - -# Don't forget to create an appropriate config file, -# else the CGRateS system will not start. - diff --git a/data/tutorials/fs_csv/freeswitch/etc/default/freeswitch b/data/tutorials/fs_csv/freeswitch/etc/default/freeswitch deleted file mode 100755 index 752045062..000000000 --- a/data/tutorials/fs_csv/freeswitch/etc/default/freeswitch +++ /dev/null @@ -1,2 +0,0 @@ -# /etc/default/freeswitch -DAEMON_OPTS="-rp -nonat" diff --git a/data/tutorials/fs_csv/freeswitch/etc/freeswitch_conf.tar.gz b/data/tutorials/fs_csv/freeswitch/etc/freeswitch_conf.tar.gz deleted file mode 100644 index aa3e2f5df..000000000 Binary files a/data/tutorials/fs_csv/freeswitch/etc/freeswitch_conf.tar.gz and /dev/null differ diff --git a/data/tutorials/fs_csv/freeswitch/etc/init.d/freeswitch b/data/tutorials/fs_csv/freeswitch/etc/init.d/freeswitch deleted file mode 100755 index 0763651e2..000000000 --- a/data/tutorials/fs_csv/freeswitch/etc/init.d/freeswitch +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/sh -### -*- mode:shell-script; indent-tabs-mode:nil; sh-basic-offset:2 -*- -### BEGIN INIT INFO -# Provides: freeswitch -# Required-Start: $network $remote_fs $local_fs -# Required-Stop: $network $remote_fs $local_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: FreeSWITCH Softswitch -# Description: FreeSWITCH Softswitch -### END INIT INFO - -# Author: Travis Cross - -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC=freeswitch -NAME=freeswitch -DAEMON=/usr/bin/freeswitch -USER=freeswitch -GROUP=freeswitch -TUTDIR=/usr/share/cgrates/tutorials/fs_csv/freeswitch -CONFDIR=$TUTDIR/etc/$NAME -DEFAULTS=$TUTDIR/etc/default/freeswitch -RUNDIR=/var/run/$NAME -LOGDIR=/var/log/freeswitch -PIDFILE=$RUNDIR/$NAME.pid -SCRIPTNAME=/etc/init.d/$NAME -WORKDIR=/var/lib/$NAME -DBDIR=$WORKDIR/db/ -DAEMON_ARGS="-rp -conf $CONFDIR -db $DBDIR -log $LOGDIR -u $USER -g $GROUP -nonat -nc" - - -[ -x $DAEMON ] || exit 0 -[ -r DEFAULTS ] && . DEFAULTS -. /lib/init/vars.sh -. /lib/lsb/init-functions - -do_start() { - if ! [ -f $CONFDIR/freeswitch.xml ]; then - echo "$NAME is not configured so not starting.">&2 - echo "Please review /usr/share/doc/$NAME/README.Debian">&2 - return 3 - fi - - # Directory in /var/run may disappear on reboot (e.g. when tmpfs used for /var/run). - mkdir -p $RUNDIR - chown -R $USER:$GROUP $RUNDIR - chmod -R ug=rwX,o= $RUNDIR - - start-stop-daemon --start --quiet \ - --pidfile $PIDFILE --exec $DAEMON --name $NAME --user $USER \ - --test > /dev/null \ - || return 1 - ulimit -s 240 - start-stop-daemon --start --quiet \ - --pidfile $PIDFILE --exec $DAEMON --name $NAME --user $USER \ - --chdir $WORKDIR -- $DAEMON_ARGS $DAEMON_OPTS \ - || return 2 - return 0 -} - -stop_fs() { - start-stop-daemon --stop --quiet \ - --pidfile $PIDFILE --name $NAME --user $USER \ - --retry=TERM/30/KILL/5 -} - -stop_fs_children() { - start-stop-daemon --stop --quiet \ - --exec $DAEMON \ - --oknodo --retry=0/30/KILL/5 -} - -do_stop() { - stop_fs - RETVAL="$?" - [ "$RETVAL" -eq 2 ] && return 2 - stop_fs_children - [ "$?" -eq 2 ] && return 2 - rm -f $PIDFILE - return "$RETVAL" -} - -do_reload() { - start-stop-daemon --stop --quiet \ - --pidfile $PIDFILE --name $NAME --user $USER \ - --signal HUP -} - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME" - do_start - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - do_stop - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - status) - status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? - ;; - reload|force-reload) - log_daemon_msg "Reloading $DESC" "$NAME" - do_reload - log_end_msg $? - ;; - restart) - log_daemon_msg "Restarting $DESC" "$NAME" - do_stop - case "$?" in - 0|1) - do_start - case "$?" in - 0) log_end_msg 0 ;; - 1|*) log_end_msg 1 ;; - esac - ;; - *) log_end_msg 1 ;; - esac - ;; - *) - echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 - exit 3 - ;; -esac - -exit 0 diff --git a/data/tutorials/fs_json/README.md b/data/tutorials/fs_evsock/README.md similarity index 65% rename from data/tutorials/fs_json/README.md rename to data/tutorials/fs_evsock/README.md index ba2e4c988..46467eb65 100644 --- a/data/tutorials/fs_json/README.md +++ b/data/tutorials/fs_evsock/README.md @@ -4,15 +4,15 @@ Tutorial FS_JSON Scenario: --------- -- FreeSWITCH with *vanilla* configuration, replacing *mod_cdr_csv* with *mod_json_cdr*. +- FreeSWITCH with minimal custom configuration. - - Modified following users (with configs in *etc/freeswitch/directory/default*): 1001-prepaid, 1002-postpaid, 1003-pseudoprepaid, 1004-rated, 1006-prepaid, 1007-prepaid. + - Added following users (with configs in *etc/freeswitch/directory/default*): 1001-prepaid, 1002-postpaid, 1003-pseudoprepaid, 1004-rated, 1006-prepaid, 1007-prepaid. - Have added inside default dialplan CGR own extensions just before routing towards users (*etc/freeswitch/dialplan/default.xml*). - - FreeSWITCH configured to generate default *http-json* CDRs. - **CGRateS** with following components: - CGR-SM started as prepaid controller, with debits taking place at 5s intervals. - CGR-Mediator component attaching costs to the raw CDRs from FreeSWITCH_ inside CGR StorDB. - CGR-CDRE exporting mediated CDRs from CGR StorDB (export path: */tmp*). + - CGR-CDRStats component building up stats in 5 different queues. - CGR-History component keeping the archive of the rates modifications (path browsable with git client at */tmp/cgr_history*). diff --git a/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json b/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json new file mode 100644 index 000000000..4d7fa8e41 --- /dev/null +++ b/data/tutorials/fs_evsock/cgrates/etc/cgrates/cgrates.json @@ -0,0 +1,253 @@ +{ + +// Real-time Charging System for Telecom & ISP environments +// Copyright (C) ITsysCOM GmbH +// +// This file contains the default configuration hardcoded into CGRateS. +// This is what you get when you load CGRateS with an empty configuration file. + + +//"general": { +// "http_skip_tls_veify": false, // if enabled Http Client will accept any TLS certificate +// "rounding_decimals": 10, // system level precision for floats +// "dbdata_encoding": "msgpack", // encoding used to store object data in strings: +// "tpexport_dir": "/var/log/cgrates/tpe", // path towards export folder for offline Tariff Plans +// "default_reqtype": "rated", // default request type to consider when missing from requests: <""|prepaid|postpaid|pseudoprepaid|rated> +// "default_category": "call", // default Type of Record to consider when missing from requests +// "default_tenant": "cgrates.org", // default Tenant to consider when missing from requests +// "default_subject": "cgrates", // default rating Subject to consider when missing from requests +//}, + + +//"listen": { +// "rpc_json": "127.0.0.1:2012", // RPC JSON listening address +// "rpc_gob": "127.0.0.1:2013", // RPC GOB listening address +// "http": "127.0.0.1:2080", // HTTP listening address +//}, + + +//"rating_db": { +// "db_type": "redis", // rating subsystem database type: +// "db_host": "127.0.0.1", // rating subsystem database host address +// "db_port": 6379, // rating subsystem port to reach the database +// "db_name": "10", // rating subsystem database name to connect to +// "db_user": "", // rating subsystem username to use when connecting to database +// "db_passwd": "", // rating subsystem password to use when connecting to database +//}, + + +//"accounting_db": { +// "db_type": "redis", // accounting subsystem database: +// "db_host": "127.0.0.1", // accounting subsystem database host address +// "db_port": 6379, // accounting subsystem port to reach the database +// "db_name": "11", // accounting subsystem database name to connect to +// "db_user": "", // accounting subsystem username to use when connecting to database +// "db_passwd": "", // accounting subsystem password to use when connecting to database +//}, + + +//"stor_db": { +// "db_type": "mysql", // stor database type to use: +// "db_host": "127.0.0.1", // the host to connect to +// "db_port": 3306, // the port to reach the stordb +// "db_name": "cgrates", // stor database name +// "db_user": "cgrates", // username to use when connecting to stordb +// "db_passwd": "CGRateS.org", // password to use when connecting to stordb +// "max_open_conns": 0, // maximum database connections opened +// "max_idle_conns": -1, // maximum database connections idle +//}, + + +//"balancer": { +// "enabled": false, // start Balancer service: +//}, + + +"rater": { + "enabled": true, // enable Rater service: +// "balancer": "", // register to Balancer as worker: <""|internal|x.y.z.y:1234> +}, + + +"scheduler": { + "enabled": true, // start Scheduler service: +}, + + +"cdrs": { + "enabled": true, // start the CDR Server service: +// "extra_fields": [], // extra fields to store in CDRs for non-generic CDRs + "mediator": "internal", // address where to reach the Mediator. Empty for disabling mediation. <""|internal> + "cdrstats": "internal", // address where to reach the cdrstats service. Empty to disable stats gathering from raw CDRs <""|internal|x.y.z.y:1234> +// "store_disable": false, // when true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario +}, + + +"mediator": { + "enabled": true, // starts Mediator service: . +// "reconnects": 3, // number of reconnects to rater/cdrs before giving up. + "rater": "internal", // address where to reach the Rater: + "cdrstats": "internal", // address where to reach the cdrstats service. Empty to disable stats gathering out of mediated CDRs <""|internal|x.y.z.y:1234> +// "store_disable": false, // when true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario +}, + + +"cdrstats": { + "enabled": true, // starts the cdrstats service: +// "queue_length": 50, // number of items in the stats buffer +// "time_window": "1h", // will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow +// "metrics": ["ASR", "ACD", "ACC"], // stat metric ids to build +// "setup_interval": [], // filter on CDR SetupTime +// "tors": [], // filter on CDR TOR fields +// "cdr_hosts": [], // filter on CDR CdrHost fields +// "cdr_sources": [], // filter on CDR CdrSource fields +// "req_types": [], // filter on CDR ReqType fields +// "directions": [], // filter on CDR Direction fields +// "tenants": [], // filter on CDR Tenant fields +// "categories": [], // filter on CDR Category fields +// "accounts": [], // filter on CDR Account fields +// "subjects": [], // filter on CDR Subject fields +// "destination_prefixes": [], // filter on CDR Destination prefixes +// "usage_interval": [], // filter on CDR Usage +// "mediation_run_ids": [], // filter on CDR MediationRunId fields +// "rated_accounts": [], // filter on CDR RatedAccount fields +// "rated_subjects": [], // filter on CDR RatedSubject fields +// "cost_interval": [], // filter on CDR Cost +}, + + +"cdre": { + "*default": { + "cdr_format": "csv", // exported CDRs format + "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_fsevsock/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":"RunId", "cdr_field_id": "mediation_runid", "type": "cdrfield", "value": "mediation_runid"}, + {"tag":"Tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "tor"}, + {"tag":"AccId", "cdr_field_id": "accid", "type": "cdrfield", "value": "accid"}, + {"tag":"ReqType", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "reqtype"}, + {"tag":"Direction", "cdr_field_id": "direction", "type": "cdrfield", "value": "direction"}, + {"tag":"Tenant", "cdr_field_id": "tenant", "type": "cdrfield", "value": "tenant"}, + {"tag":"Category", "cdr_field_id": "category", "type": "cdrfield", "value": "category"}, + {"tag":"Account", "cdr_field_id": "account", "type": "cdrfield", "value": "account"}, + {"tag":"Subject", "cdr_field_id": "subject", "type": "cdrfield", "value": "subject"}, + {"tag":"Destination", "cdr_field_id": "destination", "type": "cdrfield", "value": "destination"}, + {"tag":"SetupTime", "cdr_field_id": "setup_time", "type": "cdrfield", "value": "setup_time", "layout": "2006-01-02T15:04:05Z07:00"}, + {"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. +// "cdr_format": "csv", // CDR file format +// "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}, +// {"tag": "direction", "cdr_field_id": "direction", "type": "cdrfield", "value": "5", "mandatory": true}, +// {"tag": "tenant", "cdr_field_id": "tenant", "type": "cdrfield", "value": "6", "mandatory": true}, +// {"tag": "category", "cdr_field_id": "category", "type": "cdrfield", "value": "7", "mandatory": true}, +// {"tag": "account", "cdr_field_id": "account", "type": "cdrfield", "value": "8", "mandatory": true}, +// {"tag": "subject", "cdr_field_id": "subject", "type": "cdrfield", "value": "9", "mandatory": true}, +// {"tag": "destination", "cdr_field_id": "destination", "type": "cdrfield", "value": "10", "mandatory": true}, +// {"tag": "setup_time", "cdr_field_id": "setup_time", "type": "cdrfield", "value": "11", "mandatory": true}, +// {"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}, +// ], +// } +//}, + + +"sm_freeswitch": { + "enabled": true, // starts SessionManager service: + "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013> + "cdrs": "internal", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234> +// "reconnects": 5, // number of reconnect attempts to rater or cdrs +// "cdr_extra_fields": [], // extra fields to store in CDRs in case of processing them + "debit_interval": "5s", // interval to perform debits on. +// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this +// "max_call_duration": "3h", // maximum call duration a prepaid call can last +// "min_dur_low_balance": "5s", // threshold which will trigger low balance warnings for prepaid calls (needs to be lower than debit_interval) +// "low_balance_ann_file": "", // file to be played when low balance is reached for prepaid calls +// "empty_balance_context": "", // if defined, prepaid calls will be transfered to this context on empty balance +// "empty_balance_ann_file": "", // file to be played before disconnecting prepaid calls on empty balance (applies only if no context defined) +// "connections":[ // instantiate connections to multiple FreeSWITCH servers +// {"server": "127.0.0.1:8021", "password": "ClueCon", "reconnects": -1} // reconnects -1 to indefinitely connect +// ], +}, + + +//"sm_kamailio": { +// "enabled": false, // starts SessionManager service: +// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013> +// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234> +// "reconnects": 5, // number of reconnect attempts to rater or cdrs +// "debit_interval": "10s", // interval to perform debits on. +// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this +// "max_call_duration": "3h", // maximum call duration a prepaid call can last +// "connections":[ // instantiate connections to multiple Kamailio servers +// {"evapi_addr": "127.0.0.1:8448", "reconnects": -1} // reconnects -1 to indefinitely connect +// ], +//}, + + +//"sm_opensips": { +// "enabled": false, // starts SessionManager service: +// "listen_udp": "127.0.0.1:2020", // address where to listen for datagram events coming from OpenSIPS +// "rater": "internal", // address where to reach the Rater <""|internal|127.0.0.1:2013> +// "cdrs": "", // address where to reach CDR Server, empty to disable CDR capturing <""|internal|x.y.z.y:1234> +// "debit_interval": "10s", // interval to perform debits on. +// "min_call_duration": "0s", // only authorize calls with allowed duration higher than this +// "max_call_duration": "3h", // maximum call duration a prepaid call can last +// "events_subscribe_interval": "60s", // automatic events subscription to OpenSIPS, 0 to disable it +// "mi_addr": "127.0.0.1:8020", // address where to reach OpenSIPS MI to send session disconnects +// "reconnects": -1, // reconnects -1 to indefinitely connect +//}, + + + +"history_server": { + "enabled": true, // starts History service: . + "history_dir": "/tmp/cgr_fsevsock/cgrates/history", // location on disk where to store history files. +// "save_interval": "1s", // interval to save changed cache into .git archive +}, + + +"history_agent": { + "enabled": true, // starts History as a client: . +// "server": "internal", // address where to reach the master history server: +}, + + +//"mailer": { +// "server": "localhost", // the server to use when sending emails out +// "auth_user": "cgrates", // authenticate to email server using this user +// "auth_passwd": "CGRateS.org", // authenticate to email server with this password +// "from_address": "cgr-mailer@localhost.localdomain" // from address used when sending emails out +//}, + +} + diff --git a/data/tutorials/fs_csv/cgrates/etc/init.d/cgrates b/data/tutorials/fs_evsock/cgrates/etc/init.d/.fuse_hidden0000001700000001 similarity index 82% rename from data/tutorials/fs_csv/cgrates/etc/init.d/cgrates rename to data/tutorials/fs_evsock/cgrates/etc/init.d/.fuse_hidden0000001700000001 index 730a8c17a..8011a04a5 100755 --- a/data/tutorials/fs_csv/cgrates/etc/init.d/cgrates +++ b/data/tutorials/fs_evsock/cgrates/etc/init.d/.fuse_hidden0000001700000001 @@ -14,31 +14,27 @@ # Do NOT "set -e" # PATH should only include /usr/* if it runs after the mountnfs.sh script -RUNDIR=/tmp/$NAME/run -PIDFILE=$RUNDIR/cgr-engine.pid PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="CGRateS real-time charging system" NAME=cgrates DAEMON=/usr/bin/cgr-engine USER=cgrates GROUP=cgrates -TUTFOLDER=/usr/share/cgrates/tutorials/fs_json/cgrates -ENGINE_OPTS=-config=$TUTFOLDER/etc/cgrates/cgrates.cfg -PIDFILE=/tmp/cgr-engine_tutfsjson.pid +DAEMON_OPTS="" +TUTFOLDER=/usr/share/cgrates/tutorials/fs_evsock/cgrates +TMP_DIR=/tmp/cgr_evsock/cgrates SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME -DEFAULTS=$TUTFOLDER/etc/default/$NAME -ENABLE=false -HISTDIR=/tmp/$NAME/history -CDREDIR=/tmp/$NAME/cdre -CDRCINDIR=/tmp/$NAME/cdr/cdrc/in -CDRCOUTDIR=/tmp/cgrates/cdr/cdrc/out +RUNDIR=$TMP_DIR/run +PIDFILE=$RUNDIR/cgr-engine.pid +STACKTRACE=$RUNDIR/$NAME.strace +ENABLE=true +DAEMON_OPTS="-config_dir=/usr/share/cgrates/tutorials/fs_evsock/cgrates/etc/cgrates" +HISTDIR=$TMP_DIR/history +CDREDIR=$TMP_DIR/cdre # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 -# Read configuration variable file if it is present -[ -r $DEFAULTS ] && . $DEFAULTS - # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh @@ -55,7 +51,8 @@ fi # Install the run folder if [ ! -d $RUNDIR ]; then mkdir -p $RUNDIR - chown $USER:$GROUP $RUNDIR + touch $STACKTRACE + chown -R $USER:$GROUP $RUNDIR fi # Install the cdre folder if [ ! -d $CDREDIR ]; then @@ -67,15 +64,6 @@ if [ ! -d $HISTDIR ]; then mkdir -p $HISTDIR chown $USER:$GROUP $HISTDIR fi -if [ ! -d $CDRCINDIR ]; then - mkdir -p $CDRCINDIR - chown $USER:$GROUP $CDRCINDIR -fi -if [ ! -d $CDRCOUTDIR ]; then - mkdir -p $CDRCOUTDIR - chown $USER:$GROUP $CDRCOUTDIR -fi - # # Function that starts the daemon/service @@ -86,11 +74,12 @@ do_start() # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + echo "\n### Started at:" `date`>>$STACKTRACE + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\ || return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --exec $DAEMON --chuid $USER:$GROUP --background -- \ - $ENGINE_OPTS \ - || return 2 + start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\ + --startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \ + || return 2 } # diff --git a/data/tutorials/fs_json/cgrates/etc/init.d/cgrates b/data/tutorials/fs_evsock/cgrates/etc/init.d/cgrates similarity index 95% rename from data/tutorials/fs_json/cgrates/etc/init.d/cgrates rename to data/tutorials/fs_evsock/cgrates/etc/init.d/cgrates index b55f21683..5f13fdf76 100755 --- a/data/tutorials/fs_json/cgrates/etc/init.d/cgrates +++ b/data/tutorials/fs_evsock/cgrates/etc/init.d/cgrates @@ -21,14 +21,14 @@ DAEMON=/usr/bin/cgr-engine USER=cgrates GROUP=cgrates DAEMON_OPTS="" -TUTFOLDER=/usr/share/cgrates/tutorials/fs_json/cgrates -TMP_DIR=/tmp/cgr_fsjson/cgrates +TUTFOLDER=/usr/share/cgrates/tutorials/fs_evsock/cgrates +TMP_DIR=/tmp/cgr_fsevsock/cgrates SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME RUNDIR=$TMP_DIR/run PIDFILE=$RUNDIR/cgr-engine.pid STACKTRACE=$RUNDIR/$NAME.strace ENABLE=true -DAEMON_OPTS="-config_dir=/usr/share/cgrates/tutorials/fs_json/cgrates/etc/cgrates" +DAEMON_OPTS="-config_dir=$TUTFOLDER/etc/cgrates" HISTDIR=$TMP_DIR/history CDREDIR=$TMP_DIR/cdre @@ -75,7 +75,6 @@ do_start() # 1 if daemon was already running # 2 if daemon could not be started echo "\n### Started at:" `date`>>$STACKTRACE - echo $DAEMON $DAEMON_OPTS $PIDFILE start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test\ || return 1 start-stop-daemon --start --quiet --chuid $USER:$GROUP --make-pidfile --pidfile $PIDFILE --background\ diff --git a/data/tutorials/fs_evsock/freeswitch/etc/freeswitch_conf.tar.gz b/data/tutorials/fs_evsock/freeswitch/etc/freeswitch_conf.tar.gz new file mode 100644 index 000000000..9d4637798 Binary files /dev/null and b/data/tutorials/fs_evsock/freeswitch/etc/freeswitch_conf.tar.gz differ diff --git a/data/tutorials/fs_json/freeswitch/etc/init.d/freeswitch b/data/tutorials/fs_evsock/freeswitch/etc/init.d/freeswitch similarity index 97% rename from data/tutorials/fs_json/freeswitch/etc/init.d/freeswitch rename to data/tutorials/fs_evsock/freeswitch/etc/init.d/freeswitch index fc15fbbea..a1deb52d6 100755 --- a/data/tutorials/fs_json/freeswitch/etc/init.d/freeswitch +++ b/data/tutorials/fs_evsock/freeswitch/etc/init.d/freeswitch @@ -18,9 +18,9 @@ NAME=freeswitch DAEMON=/usr/bin/freeswitch USER=freeswitch GROUP=freeswitch -TUTDIR=/usr/share/cgrates/tutorials/fs_json/freeswitch +TUTDIR=/usr/share/cgrates/tutorials/fs_evsock/freeswitch SCRIPTNAME=$TUTDIR/etc/init.d/$NAME -TMP_DIR=/tmp/cgr_fsjson/freeswitch +TMP_DIR=/tmp/cgr_fsevsock/freeswitch CONFDIR=$TUTDIR/etc/$NAME RUNDIR=$TMP_DIR//run LOGDIR=$TMP_DIR/log diff --git a/data/tutorials/fs_json/freeswitch/etc/freeswitch_conf.tar.gz b/data/tutorials/fs_json/freeswitch/etc/freeswitch_conf.tar.gz deleted file mode 100644 index d05fdfe96..000000000 Binary files a/data/tutorials/fs_json/freeswitch/etc/freeswitch_conf.tar.gz and /dev/null differ diff --git a/engine/responder.go b/engine/responder.go index 5372b2827..4d9c56a74 100644 --- a/engine/responder.go +++ b/engine/responder.go @@ -126,7 +126,7 @@ func (rs *Responder) GetMaxSessionTime(arg CallDescriptor, reply *float64) (err } // Returns MaxSessionTime for an event received in SessionManager, considering DerivedCharging for it -func (rs *Responder) GetDerivedMaxSessionTime(ev utils.Event, reply *float64) error { +func (rs *Responder) GetDerivedMaxSessionTime(ev utils.StoredCdr, reply *float64) error { if rs.Bal != nil { return errors.New("Unsupported method on the balancer") } @@ -184,7 +184,7 @@ func (rs *Responder) GetDerivedMaxSessionTime(ev utils.Event, reply *float64) er } // Used by SM to get all the prepaid CallDescriptors attached to a session -func (rs *Responder) GetSessionRuns(ev utils.Event, sRuns *[]*SessionRun) error { +func (rs *Responder) GetSessionRuns(ev utils.StoredCdr, sRuns *[]*SessionRun) error { if rs.Bal != nil { return errors.New("Unsupported method on the balancer") } @@ -397,8 +397,8 @@ type Connector interface { RefundIncrements(CallDescriptor, *float64) error GetMaxSessionTime(CallDescriptor, *float64) error GetDerivedChargers(utils.AttrDerivedChargers, *utils.DerivedChargers) error - GetDerivedMaxSessionTime(utils.Event, *float64) error - GetSessionRuns(utils.Event, *[]*SessionRun) error + GetDerivedMaxSessionTime(utils.StoredCdr, *float64) error + GetSessionRuns(utils.StoredCdr, *[]*SessionRun) error ProcessCdr(*utils.StoredCdr, *string) error } @@ -426,11 +426,11 @@ func (rcc *RPCClientConnector) GetMaxSessionTime(cd CallDescriptor, resp *float6 return rcc.Client.Call("Responder.GetMaxSessionTime", cd, resp) } -func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev utils.Event, reply *float64) error { +func (rcc *RPCClientConnector) GetDerivedMaxSessionTime(ev utils.StoredCdr, reply *float64) error { return rcc.Client.Call("Responder.GetDerivedMaxSessionTime", ev, reply) } -func (rcc *RPCClientConnector) GetSessionRuns(ev utils.Event, sRuns *[]*SessionRun) error { +func (rcc *RPCClientConnector) GetSessionRuns(ev utils.StoredCdr, sRuns *[]*SessionRun) error { return rcc.Client.Call("Responder.GetSessionRuns", ev, sRuns) } diff --git a/sessionmanager/fssessionmanager.go b/sessionmanager/fssessionmanager.go index 4374ce48f..074440547 100644 --- a/sessionmanager/fssessionmanager.go +++ b/sessionmanager/fssessionmanager.go @@ -158,7 +158,7 @@ func (sm *FSSessionManager) unparkCall(uuid, connId, call_dest_nb, notify string func (sm *FSSessionManager) onChannelPark(ev utils.Event, connId string) { var maxCallDuration float64 // This will be the maximum duration this channel will be allowed to last - if err := sm.rater.GetDerivedMaxSessionTime(ev, &maxCallDuration); err != nil { + if err := sm.rater.GetDerivedMaxSessionTime(*ev.AsStoredCdr(), &maxCallDuration); err != nil { engine.Logger.Err(fmt.Sprintf(" Could not get max session time for %s, error: %s", ev.GetUUID(), err.Error())) } maxCallDur := time.Duration(maxCallDuration) diff --git a/sessionmanager/kamailiosm.go b/sessionmanager/kamailiosm.go index c61109d8c..bf65e277d 100644 --- a/sessionmanager/kamailiosm.go +++ b/sessionmanager/kamailiosm.go @@ -58,7 +58,7 @@ func (self *KamailioSessionManager) onCgrAuth(evData []byte, connId string) { return } var remainingDuration float64 - if err = self.rater.GetDerivedMaxSessionTime(kev.AsEvent(""), &remainingDuration); err != nil { + if err = self.rater.GetDerivedMaxSessionTime(*kev.AsStoredCdr(), &remainingDuration); err != nil { engine.Logger.Err(fmt.Sprintf(" Could not get max session time for %s, error: %s", kev.GetUUID(), err.Error())) } if kar, err := kev.AsKamAuthReply(remainingDuration, err); err != nil { diff --git a/sessionmanager/kamevent.go b/sessionmanager/kamevent.go index 4c2272005..01a12be5e 100644 --- a/sessionmanager/kamevent.go +++ b/sessionmanager/kamevent.go @@ -262,6 +262,7 @@ func (kev KamEvent) ParseEventValue(rsrFld *utils.RSRField) string { func (kev KamEvent) PassesFieldFilter(*utils.RSRField) (bool, string) { return false, "" } + func (kev KamEvent) AsStoredCdr() *utils.StoredCdr { storCdr := new(utils.StoredCdr) storCdr.CgrId = kev.GetCgrId() diff --git a/sessionmanager/session.go b/sessionmanager/session.go index 12f782c0c..5a4fcb111 100644 --- a/sessionmanager/session.go +++ b/sessionmanager/session.go @@ -58,7 +58,7 @@ func NewSession(ev utils.Event, connId string, sm SessionManager) *Session { sessionManager: sm, connId: connId, } - if err := sm.Rater().GetSessionRuns(ev, &s.sessionRuns); err != nil || len(s.sessionRuns) == 0 { + if err := sm.Rater().GetSessionRuns(*ev.AsStoredCdr(), &s.sessionRuns); err != nil || len(s.sessionRuns) == 0 { return nil } for runIdx := range s.sessionRuns {