mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Updating OpenSIPS configs for 2.4
This commit is contained in:
@@ -1,125 +0,0 @@
|
||||
{
|
||||
|
||||
// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"cdrstats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"pubsubs_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"users_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"aliases_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
"stor_db": { // database used to store offline tariff plans and CDRs
|
||||
"db_password": "CGRateS.org", // password to use when connecting to stordb
|
||||
},
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true, // start the CDR Server service: <true|false>
|
||||
"cdrstats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrstats": {
|
||||
"enabled": true, // starts the cdrstats service: <true|false>
|
||||
},
|
||||
|
||||
|
||||
"cdre": {
|
||||
"*default": {
|
||||
"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)
|
||||
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC 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_osipsasync/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", "type": "*composed", "value": "CGRID"},
|
||||
{"tag":"RunId", "type": "*composed", "value": "RunID"},
|
||||
{"tag":"Tor", "type": "*composed", "value": "ToR"},
|
||||
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
|
||||
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
|
||||
{"tag":"Direction", "type": "*composed", "value": "Direction"},
|
||||
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
|
||||
{"tag":"Category", "type": "*composed", "value": "Category"},
|
||||
{"tag":"Account", "type": "*composed", "value": "Account"},
|
||||
{"tag":"Subject", "type": "*composed", "value": "Subject"},
|
||||
{"tag":"Destination", "type": "*composed", "value": "Destination"},
|
||||
{"tag":"SetupTime", "type": "*datetime", "value": "SetupTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"Usage", "type": "*composed", "value": "Usage"},
|
||||
{"tag":"Cost", "type": "*composed", "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)
|
||||
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC 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_directory": "/tmp/cgr_osipsasync/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", "type": "*composed", "value": "CGRID"},
|
||||
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
|
||||
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
|
||||
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
|
||||
{"tag":"Category", "type": "*composed", "value": "Category"},
|
||||
{"tag":"Subject", "type": "*composed", "value": "Account"},
|
||||
{"tag":"Destination", "type": "*datetime", "value": "~Destination:s/^1(\\d+)/+$1/:s/^\\+(\\d+)/00$1/"},
|
||||
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"Usage", "type": "*composed", "value": "Usage"},
|
||||
{"tag":"Cost", "type": "*composed", "value": "Cost"},
|
||||
],
|
||||
"trailer_fields": [],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
"pubsubs": {
|
||||
"enabled": true, // starts PubSub service: <true|false>.
|
||||
},
|
||||
|
||||
|
||||
"aliases": {
|
||||
"enabled": true, // starts PubSub service: <true|false>.
|
||||
},
|
||||
|
||||
|
||||
"users": {
|
||||
"enabled": true, // starts User service: <true|false>.
|
||||
"indexes": ["Uuid"], // user profile field indexes
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
@@ -1,175 +0,0 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS real-time charging system"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorials/fs_evsock/cgrates
|
||||
TMP_DIR=/tmp/cgr_evsock/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_evsock/cgrates/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
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\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
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)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
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 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
@@ -1,175 +0,0 @@
|
||||
#! /bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides: cgrates
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: CGRateS real-time charging system
|
||||
# Description: Control CGRateS - carrier grade real-time charging system
|
||||
### END INIT INFO
|
||||
|
||||
# Author: DanB <danb@cgrates.org>
|
||||
#
|
||||
# Do NOT "set -e"
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="CGRateS real-time charging system"
|
||||
NAME=cgrates
|
||||
DAEMON=/usr/bin/cgr-engine
|
||||
USER=cgrates
|
||||
GROUP=cgrates
|
||||
DAEMON_OPTS=""
|
||||
TUTFOLDER=/usr/share/cgrates/tutorials/osips_async/$NAME
|
||||
TMP_DIR=/tmp/cgr_osipsasync/$NAME
|
||||
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=$TUTFOLDER/etc/cgrates"
|
||||
CDREDIR=$TMP_DIR/cdre
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Load the VERBOSE setting and other rcS variables
|
||||
. /lib/init/vars.sh
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
if [ "$ENABLE" != "true" ]; then
|
||||
echo "$DESC not yet configured. Edit $DEFAULTS first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Install the run folder
|
||||
if [ ! -d $RUNDIR ]; then
|
||||
mkdir -p $RUNDIR
|
||||
touch $STACKTRACE
|
||||
chown -R $USER:$GROUP $RUNDIR
|
||||
fi
|
||||
# Install the cdre folder
|
||||
if [ ! -d $CDREDIR ]; then
|
||||
mkdir -p $CDREDIR
|
||||
chown $USER:$GROUP $CDREDIR
|
||||
fi
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
echo "\n### Started at:" `date`>>$STACKTRACE
|
||||
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\
|
||||
--startas /bin/bash -- -c "exec $DAEMON $DAEMON_OPTS >> $STACKTRACE 2>&1" \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Wait for children to finish too if this is a daemon that forks
|
||||
# and if the daemon is only ever run from this initscript.
|
||||
# If the above conditions are not satisfied then add some other code
|
||||
# that waits for the process to drop all resources that could be
|
||||
# needed by services started subsequently. A last resort is to
|
||||
# sleep for some time.
|
||||
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
|
||||
[ "$?" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
#
|
||||
# Function that sends a SIGHUP to the daemon/service
|
||||
#
|
||||
do_reload() {
|
||||
#
|
||||
# If the daemon can reload its configuration without
|
||||
# restarting (for example, when it is sent a SIGHUP),
|
||||
# then implement that here.
|
||||
#
|
||||
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
|
||||
return 0
|
||||
}
|
||||
|
||||
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)
|
||||
#
|
||||
# If do_reload() is not implemented then leave this commented out
|
||||
# and leave 'force-reload' as an alias for 'restart'.
|
||||
#
|
||||
#log_daemon_msg "Reloading $DESC" "$NAME"
|
||||
#do_reload
|
||||
#log_end_msg $?
|
||||
#;;
|
||||
restart|force-reload)
|
||||
#
|
||||
# If the "reload" option is implemented then remove the
|
||||
# 'force-reload' alias
|
||||
#
|
||||
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 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
|
||||
:
|
||||
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# OpenSIPS startup options
|
||||
#
|
||||
|
||||
# Set to yes to enable opensips, once configured properly.
|
||||
RUN_OPENSIPS=yes
|
||||
|
||||
# User to run as
|
||||
USER=opensips
|
||||
|
||||
# Group to run as
|
||||
GROUP=opensips
|
||||
|
||||
# Amount of shared memory to allocate for the running OpenSIPS server (in Mb)
|
||||
S_MEMORY=64
|
||||
|
||||
# Amount of pkg memory to allocate for the running OpenSIPS server (in Mb)
|
||||
P_MEMORY=4
|
||||
|
||||
# Enable the server to leave a core file when it crashes.
|
||||
# Set this to 'yes' to enable OpenSIPS to leave a core file when it crashes
|
||||
# or 'no' to disable this feature. This option is case sensitive and only
|
||||
# accepts 'yes' and 'no' and only in lowercase letters.
|
||||
# On some systems (e.g. Ubuntu 6.10, Debian 4.0) it is necessary to specify
|
||||
# a directory for the core files to get a dump. Look into the opensips
|
||||
# init file for an example configuration.
|
||||
DUMP_CORE=no
|
||||
@@ -1,199 +0,0 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: opensips
|
||||
# Required-Start: $syslog $network $local_fs $time
|
||||
# Required-Stop: $syslog $network $local_fs
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start the OpenSIPS SIP server
|
||||
# Description: Start the OpenSIPS SIP server
|
||||
### END INIT INFO
|
||||
#
|
||||
# TODO:
|
||||
# The following fields should be added (and completed):
|
||||
# Should-Start: postgresql mysql radius
|
||||
# Should-Stop: postgresql mysql radius
|
||||
|
||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||
DAEMON=/usr/sbin/opensips
|
||||
NAME=opensips
|
||||
DESC=opensips
|
||||
TUTDIR=/usr/share/cgrates/tutorials/osips_async/$NAME
|
||||
SCRIPTNAME=$TUTDIR/etc/init.d/$NAME
|
||||
TMP_DIR=/tmp/cgr_osipsasync/$NAME
|
||||
CFGFILE=$TUTDIR/etc/$NAME/opensips.cfg
|
||||
M4CFGFILE=/etc/opensips/opensips.m4
|
||||
M4ARCHIVEDIR=/etc/opensips/archive
|
||||
HOMEDIR=$TMP_DIR/run/opensips
|
||||
PIDFILE=$HOMEDIR/$NAME.pid
|
||||
DEFAULTS=$TUTDIR/etc/default/opensips
|
||||
RUN_OPENSIPS=no
|
||||
|
||||
if [ ! -d $HOMEDIR ]; then
|
||||
mkdir -p $HOMEDIR
|
||||
chown -R $USER:$GROUP $HOMEDIR
|
||||
fi
|
||||
|
||||
# Do not start opensips if fork=no is set in the config file
|
||||
# otherwise the boot process will just stop
|
||||
check_fork ()
|
||||
{
|
||||
if grep -q "^[[:space:]]*fork[[:space:]]*=[[:space:]]*no.*" $CFGFILE; then
|
||||
echo "Not starting $DESC: fork=no specified in config file; run /etc/init.d/opensips debug instead"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_opensips_config ()
|
||||
{
|
||||
# Check if opensips configuration is valid before starting the server
|
||||
set +e
|
||||
out=$($DAEMON -c 2>&1 > /dev/null)
|
||||
retcode=$?
|
||||
set -e
|
||||
if [ "$retcode" != '0' ]; then
|
||||
echo "Not starting $DESC: invalid configuration file!"
|
||||
echo -e "\n$out\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_radius_seqfile ()
|
||||
{
|
||||
# Create a radius sequence file to be used by the radius client if
|
||||
# radius accounting is enabled. This is needed to avoid any issue
|
||||
# with the file not being writable if opensips first starts as user
|
||||
# root because DUMP_CORE is enabled and creates this file as user
|
||||
# root and then later it switches back to user opensips and cannot
|
||||
# write to the file. If the file exists before opensips starts, it
|
||||
# won't change it's ownership and will be writable for both root
|
||||
# and opensips, no matter what options are chosen at install time
|
||||
RADIUS_SEQ_FILE=/var/run/opensips/opensips_radius.seq
|
||||
if [ -d /var/run/opensips ]; then
|
||||
chown ${USER}:${GROUP} /var/run/opensips
|
||||
|
||||
if [ ! -f $RADIUS_SEQ_FILE ]; then
|
||||
touch $RADIUS_SEQ_FILE
|
||||
fi
|
||||
|
||||
chown ${USER}:${GROUP} $RADIUS_SEQ_FILE
|
||||
chmod 660 $RADIUS_SEQ_FILE
|
||||
fi
|
||||
}
|
||||
|
||||
test -f $DAEMON || exit 0
|
||||
|
||||
# Load startup options if available
|
||||
if [ -f $DEFAULTS ]; then
|
||||
. $DEFAULTS || true
|
||||
fi
|
||||
|
||||
if [ "$RUN_OPENSIPS" != "yes" ]; then
|
||||
echo "OpenSIPS not yet configured. Edit /etc/default/opensips first."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
S_MEMORY=$((`echo $S_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
P_MEMORY=$((`echo $P_MEMORY | sed -e 's/[^0-9]//g'`))
|
||||
[ -z "$USER" ] && USER=opensips
|
||||
[ -z "$GROUP" ] && GROUP=opensips
|
||||
[ $S_MEMORY -le 0 ] && S_MEMORY=32
|
||||
[ $P_MEMORY -le 0 ] && P_MEMORY=32
|
||||
|
||||
if test "$DUMP_CORE" = "yes" ; then
|
||||
# set proper ulimit
|
||||
ulimit -c unlimited
|
||||
|
||||
# directory for the core dump files
|
||||
# COREDIR=/home/corefiles
|
||||
# [ -d $COREDIR ] || mkdir $COREDIR
|
||||
# chmod 777 $COREDIR
|
||||
# echo "$COREDIR/core.%e.sig%s.%p" > /proc/sys/kernel/core_pattern
|
||||
fi
|
||||
|
||||
OPTIONS="-f $CFGFILE -P $PIDFILE -m $S_MEMORY -M $P_MEMORY -u $USER -g $GROUP -w $HOMEDIR"
|
||||
|
||||
case "$1" in
|
||||
start|debug)
|
||||
check_opensips_config
|
||||
create_radius_seqfile
|
||||
|
||||
if [ "$1" != "debug" ]; then
|
||||
check_fork
|
||||
fi
|
||||
|
||||
# dirs under /var/run can go away on reboots.
|
||||
mkdir -p "$HOMEDIR"
|
||||
chmod 775 "$HOMEDIR"
|
||||
chown "$USER:$GROUP" "$HOMEDIR" >/dev/null 2>&1 || true
|
||||
|
||||
# Generate config from M4
|
||||
if [ -f $M4CFGFILE ]; then
|
||||
m4 -Q $M4CFGFILE >$CFGFILE.tmp
|
||||
if [ $? != 0 ]; then
|
||||
echo "Cannot process m4 macro"
|
||||
rm "$CFGFILE.tmp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -e $CFGFILE ] || touch $CFGFILE
|
||||
|
||||
# compare configs
|
||||
if [ `md5sum $CFGFILE|awk '{print $1}'` != `md5sum $CFGFILE.tmp|awk '{print $1}'` ]; then
|
||||
mkdir -p "$M4ARCHIVEDIR"
|
||||
mv "$CFGFILE" "$M4ARCHIVEDIR/$NAME.cfg-`date +%Y%m%d_%H%M%S`"
|
||||
fi
|
||||
|
||||
mv "$CFGFILE.tmp" "$CFGFILE"
|
||||
chown $USER:$GROUP $CFGFILE
|
||||
chmod 640 $CFGFILE
|
||||
fi
|
||||
|
||||
echo -n "Starting $DESC: $NAME"
|
||||
start-stop-daemon --start --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON -- $OPTIONS || echo -n " already running"
|
||||
echo "."
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC: $NAME"
|
||||
start-stop-daemon --oknodo --stop --quiet --pidfile $PIDFILE \
|
||||
--exec $DAEMON
|
||||
echo "."
|
||||
;;
|
||||
restart|force-reload)
|
||||
check_opensips_config
|
||||
create_radius_seqfile
|
||||
|
||||
echo -n "Restarting $DESC: $NAME"
|
||||
start-stop-daemon --oknodo --stop --quiet --pidfile \
|
||||
$PIDFILE --exec $DAEMON
|
||||
sleep 1
|
||||
start-stop-daemon --start --quiet --pidfile \
|
||||
$PIDFILE --exec $DAEMON -- $OPTIONS
|
||||
echo "."
|
||||
;;
|
||||
status)
|
||||
echo -n "Status of $DESC: "
|
||||
if [ ! -r "$PIDFILE" ]; then
|
||||
echo "$NAME is not running."
|
||||
exit 3
|
||||
fi
|
||||
if read pid < "$PIDFILE" && ps -p "$pid" > /dev/null 2>&1; then
|
||||
echo "$NAME is running."
|
||||
exit 0
|
||||
else
|
||||
echo "$NAME is not running but $PIDFILE exists."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
N=/etc/init.d/$NAME
|
||||
echo "Usage: $N {start|stop|restart|force-reload|debug|status}" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -1,369 +0,0 @@
|
||||
|
||||
|
||||
# OpenSIPS residential configuration script
|
||||
# by OpenSIPS Solutions <team@opensips-solutions.com>
|
||||
|
||||
|
||||
####### Global Parameters #########
|
||||
|
||||
log_level=3
|
||||
log_stderror=no
|
||||
log_facility=LOG_LOCAL0
|
||||
|
||||
children=4
|
||||
listen=udp:lo:5060
|
||||
listen=udp:eth0:5060
|
||||
listen=udp:eth1:5060
|
||||
|
||||
auto_aliases=no
|
||||
|
||||
# do not open more than 4096 file descriptors
|
||||
open_files_limit=4096
|
||||
|
||||
####### Modules Section ########
|
||||
|
||||
#set module path
|
||||
mpath="/usr/lib/x86_64-linux-gnu/opensips/modules"
|
||||
|
||||
#### SIGNALING module
|
||||
loadmodule "signaling.so"
|
||||
|
||||
#### StateLess module
|
||||
loadmodule "sl.so"
|
||||
|
||||
#### Transaction Module
|
||||
loadmodule "tm.so"
|
||||
modparam("tm", "fr_timeout", 5)
|
||||
modparam("tm", "fr_inv_timeout", 30)
|
||||
modparam("tm", "restart_fr_on_each_reply", 0)
|
||||
modparam("tm", "onreply_avp_mode", 1)
|
||||
|
||||
#### Record Route Module
|
||||
loadmodule "rr.so"
|
||||
|
||||
|
||||
#### MAX ForWarD module
|
||||
loadmodule "maxfwd.so"
|
||||
|
||||
#### SIP MSG OPerationS module
|
||||
loadmodule "sipmsgops.so"
|
||||
|
||||
#### FIFO Management Interface
|
||||
loadmodule "mi_fifo.so"
|
||||
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
|
||||
modparam("mi_fifo", "fifo_mode", 0666)
|
||||
|
||||
loadmodule "mi_datagram.so"
|
||||
modparam("mi_datagram", "socket_name", "udp:127.0.0.1:8020")
|
||||
|
||||
|
||||
#### Eventdatagram module
|
||||
loadmodule "event_datagram.so"
|
||||
|
||||
|
||||
#### URI module
|
||||
loadmodule "uri.so"
|
||||
modparam("uri", "use_uri_table", 0)
|
||||
|
||||
|
||||
#### USeR LOCation module
|
||||
loadmodule "usrloc.so"
|
||||
modparam("usrloc", "nat_bflag", "NAT")
|
||||
modparam("usrloc", "db_mode", 0)
|
||||
|
||||
#### REGISTRAR module
|
||||
loadmodule "registrar.so"
|
||||
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
|
||||
|
||||
/* uncomment the next line not to allow more than 10 contacts per AOR */
|
||||
#modparam("registrar", "max_contacts", 10)
|
||||
|
||||
#### DIALOG module
|
||||
loadmodule "dialog.so"
|
||||
modparam("dialog", "dlg_extra_hdrs", "Hint: credit expired\r\n")
|
||||
modparam("dialog", "dlg_match_mode", 1)
|
||||
modparam("dialog", "default_timeout", 21600) # 6 hours timeout
|
||||
modparam("dialog", "db_mode", 0)
|
||||
|
||||
#### DbFlatstore module
|
||||
loadmodule "db_flatstore.so"
|
||||
modparam("db_flatstore", "single_file", 1)
|
||||
|
||||
|
||||
#### ACCounting module
|
||||
loadmodule "acc.so"
|
||||
modparam("acc", "detect_direction", 1)
|
||||
modparam("acc", "evi_extra", "cgr_reqtype=$avp(cgr_reqtype);
|
||||
cgr_account=$avp(cgr_account);
|
||||
cgr_destination=$avp(cgr_destination);
|
||||
cgr_supplier=$avp(cgr_supplier);
|
||||
cgr_answertime=$dlg_val(atime);
|
||||
dialog_id=$DLG_did")
|
||||
|
||||
#### CfgUtils module
|
||||
loadmodule "cfgutils.so"
|
||||
|
||||
#### CacheDB Local
|
||||
loadmodule "cachedb_local.so"
|
||||
|
||||
#### UDP protocol
|
||||
loadmodule "proto_udp.so"
|
||||
|
||||
#### Rest client
|
||||
loadmodule "rest_client.so"
|
||||
|
||||
#### JSON parser
|
||||
loadmodule "json.so"
|
||||
|
||||
#### Event route
|
||||
loadmodule "event_route.so"
|
||||
|
||||
|
||||
####### Routing Logic ########
|
||||
|
||||
startup_route {
|
||||
subscribe_event("E_OPENSIPS_START", "udp:127.0.0.1:2020");
|
||||
raise_event("E_OPENSIPS_START");
|
||||
}
|
||||
|
||||
local_route {
|
||||
if (is_method("BYE") ) {
|
||||
# make sure a LOCAL_DISCONNECT event is triggered on local BYEs
|
||||
acc_evi_request("LOCAL_DISCONNECT"); #FixMe
|
||||
}
|
||||
}
|
||||
|
||||
## Send AUTH request to CGRateS engine
|
||||
route[CGR_AUTH_REQ] {
|
||||
# Code to produce the json
|
||||
$json(cgr_auth) := "{}";
|
||||
$json(cgr_auth/id) = "1";
|
||||
$json(cgr_auth/method) = "ApierV1.GetMaxUsage";
|
||||
$json(cgr_auth/params) := "[{}]";
|
||||
$json(cgr_auth/params[0]/RequestType) = $avp(cgr_reqtype);
|
||||
$json(cgr_auth/params[0]/Account) = $avp(cgr_account);
|
||||
$json(cgr_auth/params[0]/Destination) = $avp(cgr_destination);
|
||||
$json(cgr_auth/params[0]/DialogId) = $DLG_did;
|
||||
async(rest_post("http://127.0.0.1:2080/jsonrpc", "$json(cgr_auth)", "application/json", "$avp(cgr_auth_reply)", "$var(ct)", "$var(rcode)"), CGR_AUTH_REPLY);
|
||||
}
|
||||
|
||||
## Process answer received from CGRateS engine
|
||||
route[CGR_AUTH_REPLY] {
|
||||
$json(cgr_auth_reply) := $avp(cgr_auth_reply);
|
||||
if $json(cgr_auth_reply/error) != NULL {
|
||||
xlog("Error received from CGRateS: $json(cgr_auth_reply/error)");
|
||||
sl_send_reply("503","Charging controller error");
|
||||
exit;
|
||||
} else if $json(cgr_auth_reply/result) == 0 {
|
||||
sl_send_reply("403","Payment required");
|
||||
exit;
|
||||
} else if $json(cgr_auth_reply/result) > -1 {
|
||||
$DLG_timeout=$json(cgr_auth_reply/result);
|
||||
}
|
||||
route(CGR_LCR_REQ);
|
||||
}
|
||||
|
||||
## Send LCR request to CGRateS engine
|
||||
route[CGR_LCR_REQ] {
|
||||
#{"method":"ApierV1.GetLcr","params":[{"Direction":"","Tenant":"","Category":"","Account":"dan","Subject":"","Destination":"1001","TimeStart":"","Duration":""}],"id":0}
|
||||
# Code to produce the json
|
||||
$json(cgr_lcr) := "{}";
|
||||
$json(cgr_lcr/id) = "2";
|
||||
$json(cgr_lcr/method) = "ApierV1.GetLcrSuppliers";
|
||||
$json(cgr_lcr/params) := "[{}]";
|
||||
$json(cgr_lcr/params[0]/Account) = $avp(cgr_account);
|
||||
$json(cgr_lcr/params[0]/Destination) = $avp(cgr_destination);
|
||||
async(rest_post("http://127.0.0.1:2080/jsonrpc", "$json(cgr_lcr)", "application/json", "$avp(cgr_lcr_reply)", "$var(ct)", "$var(rcode)"), CGR_LCR_REPLY);
|
||||
}
|
||||
|
||||
## Process LCR reply received from CGRateS engine
|
||||
route[CGR_LCR_REPLY] {
|
||||
$json(cgr_lcr_reply) := $avp(cgr_lcr_reply);
|
||||
if $json(cgr_lcr_reply/error) != NULL {
|
||||
xlog("Error received from CGRateS: $json(cgr_lcr_reply/error)");
|
||||
sl_send_reply("503","Charging controller error");
|
||||
exit;
|
||||
}
|
||||
$avp(cgr_supplier) = $(json(cgr_lcr_reply/result){s.select,0,,});
|
||||
route(location);
|
||||
route(relay);
|
||||
}
|
||||
|
||||
# main request routing logic
|
||||
route{
|
||||
|
||||
|
||||
if (!mf_process_maxfwd_header("10")) {
|
||||
sl_send_reply("483","Too Many Hops");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (has_totag()) {
|
||||
# sequential request withing a dialog should
|
||||
# take the path determined by record-routing
|
||||
if (loose_route()) {
|
||||
if (is_method("BYE")) {
|
||||
do_accounting("evi");
|
||||
} else if (is_method("INVITE")) {
|
||||
# even if in most of the cases is useless, do RR for
|
||||
# re-INVITEs alos, as some buggy clients do change route set
|
||||
# during the dialog.
|
||||
record_route();
|
||||
}
|
||||
# route it out to whatever destination was set by loose_route()
|
||||
# in $du (destination URI).
|
||||
route(relay);
|
||||
} else {
|
||||
|
||||
if ( is_method("ACK") ) {
|
||||
if ( t_check_trans() ) {
|
||||
# non loose-route, but stateful ACK; must be an ACK after
|
||||
# a 487 or e.g. 404 from upstream server
|
||||
t_relay();
|
||||
exit;
|
||||
} else {
|
||||
# ACK without matching transaction ->
|
||||
# ignore and discard
|
||||
exit;
|
||||
}
|
||||
}
|
||||
sl_send_reply("404","Not here");
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
# CANCEL processing
|
||||
if (is_method("CANCEL"))
|
||||
{
|
||||
if (t_check_trans())
|
||||
t_relay();
|
||||
exit;
|
||||
}
|
||||
|
||||
t_check_trans();
|
||||
|
||||
if ( !(is_method("REGISTER") ) ) {
|
||||
|
||||
if (from_uri==myself)
|
||||
|
||||
{
|
||||
|
||||
} else {
|
||||
# if caller is not local, then called number must be local
|
||||
|
||||
if (!uri==myself) {
|
||||
send_reply("403","Relay forbidden");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# preloaded route checking
|
||||
if (loose_route()) {
|
||||
xlog("L_ERR",
|
||||
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
|
||||
if (!is_method("ACK"))
|
||||
sl_send_reply("403","Preload Route denied");
|
||||
exit;
|
||||
}
|
||||
|
||||
# record routing
|
||||
if (!is_method("REGISTER|MESSAGE"))
|
||||
record_route();
|
||||
|
||||
# account only INVITEs
|
||||
if (is_method("INVITE")) {
|
||||
# create dialog with timeout
|
||||
if ( !create_dialog("B") ) {
|
||||
send_reply("500","Internal Server Error");
|
||||
exit;
|
||||
}
|
||||
switch ($fU) {
|
||||
case "1001":
|
||||
case "1006":
|
||||
case "1007":
|
||||
$avp(cgr_reqtype) = "*prepaid";
|
||||
break;
|
||||
case "1002":
|
||||
$avp(cgr_reqtype) = "*postpaid";
|
||||
break;
|
||||
case "1003":
|
||||
$avp(cgr_reqtype) = "*pseudoprepaid";
|
||||
break;
|
||||
default:
|
||||
$avp(cgr_reqtype) = "*rated";
|
||||
}
|
||||
$avp(cgr_account)=$fU;
|
||||
$avp(cgr_destination)=$rU;
|
||||
do_accounting("evi", "missed|failed");
|
||||
route(CGR_AUTH_REQ);
|
||||
#End of processing
|
||||
}
|
||||
|
||||
if (!uri==myself) {
|
||||
route(relay);
|
||||
}
|
||||
|
||||
# requests for my domain
|
||||
|
||||
if (is_method("PUBLISH|SUBSCRIBE"))
|
||||
{
|
||||
sl_send_reply("503", "Service Unavailable");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_method("REGISTER"))
|
||||
{
|
||||
if ( 0 ) setflag(TCP_PERSISTENT);
|
||||
if (!save("location"))
|
||||
sl_reply_error();
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($rU==NULL) {
|
||||
# request with no Username in RURI
|
||||
sl_send_reply("484","Address Incomplete");
|
||||
exit;
|
||||
}
|
||||
|
||||
route(location);
|
||||
route(relay);
|
||||
}
|
||||
|
||||
route[relay] {
|
||||
# for INVITEs enable some additional helper routes
|
||||
if (is_method("INVITE") && !has_totag()) {
|
||||
t_on_reply("MSG_REPLY"); #added for completeness not tested
|
||||
t_on_failure("missed_call");
|
||||
}
|
||||
if (!t_relay()) {
|
||||
send_reply("500","Internal Error");
|
||||
};
|
||||
exit;
|
||||
}
|
||||
|
||||
route[location] {
|
||||
# do lookup with method filtering
|
||||
if (!lookup("location","m")) {
|
||||
t_newtran();
|
||||
t_reply("404", "Not Found");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
failure_route[missed_call] {
|
||||
if (t_was_cancelled()) {
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
onreply_route[MSG_REPLY]{
|
||||
if (t_check_status("200") && !$dlg_val(atime)){#so we set it ONLY ONCE
|
||||
$dlg_val(atime)=$Ts;
|
||||
}
|
||||
if (t_check_status("4..")){#CAPTURE ALL ERROR CODES NEGATIVE ASR record
|
||||
$dlg_val(atime)=NULL;
|
||||
}
|
||||
}
|
||||
@@ -1,135 +1,112 @@
|
||||
{
|
||||
|
||||
// Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
|
||||
// Real-time Charging System for Telecom & ISP environments
|
||||
// Copyright (C) ITsysCOM GmbH
|
||||
//
|
||||
|
||||
"general": {
|
||||
// "default_request_type": "*prepaid",
|
||||
|
||||
"listen": {
|
||||
"rpc_json": ":2012",
|
||||
"rpc_gob": ":2013",
|
||||
"http": ":2080",
|
||||
},
|
||||
|
||||
|
||||
"stor_db": {
|
||||
"db_password": "CGRateS.org",
|
||||
},
|
||||
|
||||
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"cdrstats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"pubsubs_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"users_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"aliases_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"scheduler": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"cdrs": {
|
||||
"enabled": true, // start the CDR Server service: <true|false>
|
||||
"cdrstats_conns": [
|
||||
"rals": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"pubsubs_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"cdrstats": {
|
||||
"enabled": true, // starts the cdrstats service: <true|false>
|
||||
},
|
||||
|
||||
|
||||
"cdre": {
|
||||
"*default": {
|
||||
"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)
|
||||
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC 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_osipsnative/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", "type": "*composed", "value": "CGRID"},
|
||||
{"tag":"RunId", "type": "*composed", "value": "RunID"},
|
||||
{"tag":"Tor", "type": "*composed", "value": "ToR"},
|
||||
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
|
||||
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
|
||||
{"tag":"Direction", "type": "*composed", "value": "Direction"},
|
||||
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
|
||||
{"tag":"Category", "type": "*composed", "value": "Category"},
|
||||
{"tag":"Account", "type": "*composed", "value": "Account"},
|
||||
{"tag":"Subject", "type": "*composed", "value": "Subject"},
|
||||
{"tag":"Destination", "type": "*composed", "value": "Destination"},
|
||||
{"tag":"SetupTime", "type": "*datetime", "value": "SetupTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"Usage", "type": "*composed", "value": "Usage"},
|
||||
{"tag":"Cost", "type": "*composed", "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)
|
||||
"generic_usage_multiply_factor": 1, // multiply data usage before export (eg: convert from GENERIC 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_directory": "/tmp/cgr_osipsnative/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", "type": "*composed", "value": "CGRID"},
|
||||
{"tag":"AccId", "type": "*composed", "value": "OriginID"},
|
||||
{"tag":"ReqType", "type": "*composed", "value": "RequestType"},
|
||||
{"tag":"Tenant", "type": "*composed", "value": "Tenant"},
|
||||
{"tag":"Category", "type": "*composed", "value": "Category"},
|
||||
{"tag":"Subject", "type": "*composed", "value": "Account"},
|
||||
{"tag":"Destination", "type": "*datetime", "value": "~Destination:s/^1(\\d+)/+$1/:s/^\\+(\\d+)/00$1/"},
|
||||
{"tag":"AnswerTime", "type": "*datetime", "value": "AnswerTime", "layout": "2006-01-02T15:04:05Z07:00"},
|
||||
{"tag":"Usage", "type": "*composed", "value": "Usage"},
|
||||
{"tag":"Cost", "type": "*composed", "value": "Cost"},
|
||||
],
|
||||
"trailer_fields": [],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
"pubsubs": {
|
||||
"enabled": true, // starts PubSub service: <true|false>.
|
||||
},
|
||||
|
||||
|
||||
"aliases": {
|
||||
"enabled": true, // starts PubSub service: <true|false>.
|
||||
},
|
||||
|
||||
|
||||
"users": {
|
||||
"enabled": true, // starts User service: <true|false>.
|
||||
"indexes": ["Uuid"], // user profile field indexes
|
||||
"cdrs": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"sessions": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"cdrs_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"suppliers_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"attributes_conns": [
|
||||
{"address": "127.0.0.1:2012", "transport": "*json"}
|
||||
],
|
||||
"debit_interval": "10s",
|
||||
"client_protocol": 0,
|
||||
},
|
||||
|
||||
|
||||
"pubsubs": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"attributes": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"resources": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"stats": {
|
||||
"enabled": true,
|
||||
"thresholds_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
"thresholds": {
|
||||
"enabled": true,
|
||||
},
|
||||
|
||||
|
||||
"suppliers": {
|
||||
"enabled": true,
|
||||
"rals_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"resources_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
"stats_conns": [
|
||||
{"address": "*internal"}
|
||||
],
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# OpenSIPS-CGRateS out of residential configuration script
|
||||
# OpenSIPS residential configuration script
|
||||
# by OpenSIPS Solutions <team@opensips-solutions.com>
|
||||
#
|
||||
# This script was generated via "make menuconfig", from
|
||||
# the "Residential" scenario.
|
||||
# You can enable / disable more features / functionalities by
|
||||
# re-generating the scenario with different options.#
|
||||
#
|
||||
# Please refer to the Core CookBook at:
|
||||
# http://www.opensips.org/Resources/DocsCookbooks
|
||||
@@ -19,8 +21,9 @@ log_facility=LOG_LOCAL0
|
||||
|
||||
children=4
|
||||
|
||||
auto_aliases=yes
|
||||
listen=udp:10.10.10.201:5060
|
||||
auto_aliases=no
|
||||
|
||||
listen=udp:127.0.0.1:5060 ### CUSTOMIZE ME
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +61,6 @@ loadmodule "mi_fifo.so"
|
||||
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
|
||||
modparam("mi_fifo", "fifo_mode", 0666)
|
||||
|
||||
|
||||
#### URI module
|
||||
loadmodule "uri.so"
|
||||
modparam("uri", "use_uri_table", 0)
|
||||
@@ -70,89 +72,93 @@ modparam("usrloc", "db_mode", 0)
|
||||
|
||||
#### REGISTRAR module
|
||||
loadmodule "registrar.so"
|
||||
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
|
||||
|
||||
#### ACCounting module
|
||||
loadmodule "acc.so"
|
||||
modparam("acc", "early_media", 0)
|
||||
modparam("acc", "report_cancels", 0)
|
||||
modparam("acc", "detect_direction", 0)
|
||||
|
||||
loadmodule "proto_udp.so"
|
||||
|
||||
#### Dialog module
|
||||
loadmodule "dialog.so"
|
||||
|
||||
#### CGRateS module
|
||||
loadmodule "dialog.so"
|
||||
loadmodule "cgrates.so"
|
||||
modparam("cgrates", "cgrates_engine", "127.0.0.1:2014")
|
||||
|
||||
|
||||
#### UDP protocol
|
||||
loadmodule "proto_udp.so"
|
||||
|
||||
####### Routing Logic ########
|
||||
|
||||
# main request routing logic
|
||||
|
||||
route{
|
||||
|
||||
if (!mf_process_maxfwd_header("10")) {
|
||||
sl_send_reply("483","Too Many Hops");
|
||||
send_reply("483","Too Many Hops");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (has_totag()) {
|
||||
# sequential requests within a dialog should
|
||||
# take the path determined by record-routing
|
||||
if (loose_route()) {
|
||||
|
||||
if (is_method("INVITE")) {
|
||||
# even if in most of the cases is useless, do RR for
|
||||
# re-INVITEs alos, as some buggy clients do change route set
|
||||
# during the dialog.
|
||||
record_route();
|
||||
}
|
||||
|
||||
# route it out to whatever destination was set by loose_route()
|
||||
# in $du (destination URI).
|
||||
route(relay);
|
||||
} else {
|
||||
|
||||
if ( is_method("ACK") ) {
|
||||
if ( t_check_trans() ) {
|
||||
# non loose-route, but stateful ACK; must be an ACK after
|
||||
# a 487 or e.g. 404 from upstream server
|
||||
t_relay();
|
||||
exit;
|
||||
} else {
|
||||
# ACK without matching transaction ->
|
||||
# ignore and discard
|
||||
exit;
|
||||
}
|
||||
}
|
||||
sl_send_reply("404","Not here");
|
||||
# handle hop-by-hop ACK (no routing required)
|
||||
if ( is_method("ACK") && t_check_trans() ) {
|
||||
t_relay();
|
||||
exit;
|
||||
}
|
||||
|
||||
# sequential request within a dialog should
|
||||
# take the path determined by record-routing
|
||||
if ( !loose_route() ) {
|
||||
# we do record-routing for all our traffic, so we should not
|
||||
# receive any sequential requests without Route hdr.
|
||||
send_reply("404","Not here");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_method("BYE")) {
|
||||
# do accounting even if the transaction fails
|
||||
do_accounting("log","failed");
|
||||
}
|
||||
|
||||
# route it out to whatever destination was set by loose_route()
|
||||
# in $du (destination URI).
|
||||
route(relay);
|
||||
exit;
|
||||
}
|
||||
|
||||
# CANCEL processing
|
||||
if (is_method("CANCEL"))
|
||||
{
|
||||
if (is_method("CANCEL")) {
|
||||
if (t_check_trans())
|
||||
t_relay();
|
||||
exit;
|
||||
}
|
||||
|
||||
# absorb retransmissions, but do not create transaction
|
||||
t_check_trans();
|
||||
|
||||
if ( !(is_method("REGISTER") ) ) {
|
||||
if (from_uri==myself) {
|
||||
|
||||
if (is_myself("$fd")) {
|
||||
|
||||
} else {
|
||||
# if caller is not local, then called number must be local
|
||||
if (!uri==myself) {
|
||||
send_reply("403","Rely forbidden");
|
||||
|
||||
if (!is_myself("$rd")) {
|
||||
send_reply("403","Relay Forbidden");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# preloaded route checking
|
||||
if (loose_route()) {
|
||||
xlog("L_ERR",
|
||||
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
|
||||
"Attempt to route with preloaded Route's [$fu/$tu/$ru/$ci]");
|
||||
if (!is_method("ACK"))
|
||||
sl_send_reply("403","Preload Route denied");
|
||||
send_reply("403","Preload Route denied");
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -160,17 +166,21 @@ route{
|
||||
if (!is_method("REGISTER|MESSAGE"))
|
||||
record_route();
|
||||
|
||||
if (!uri==myself) {
|
||||
if (!is_myself("$rd")) {
|
||||
append_hf("P-hint: outbound\r\n");
|
||||
|
||||
route(relay);
|
||||
}
|
||||
|
||||
# requests for my domain
|
||||
|
||||
if (is_method("PUBLISH|SUBSCRIBE")) {
|
||||
sl_send_reply("503", "Service Unavailable");
|
||||
send_reply("503", "Service Unavailable");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (is_method("REGISTER")) {
|
||||
|
||||
if (!save("location"))
|
||||
sl_reply_error();
|
||||
|
||||
@@ -179,24 +189,37 @@ route{
|
||||
|
||||
if ($rU==NULL) {
|
||||
# request with no Username in RURI
|
||||
sl_send_reply("484","Address Incomplete");
|
||||
send_reply("484","Address Incomplete");
|
||||
exit;
|
||||
}
|
||||
|
||||
# do lookup with method filtering
|
||||
if (!lookup("location","m")) {
|
||||
t_newtran();
|
||||
t_reply("404", "Not Found");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
# check auth with CGRateS
|
||||
#$cgr(Tenant) = $fd;
|
||||
#$cgr(RequestType) = "*prepaid";
|
||||
if (!async(cgrates_auth("$fU", "$rU"), resume_cgr_auth)) {
|
||||
sl_send_reply("503", "Service Unavailable");
|
||||
exit;
|
||||
if (!async(cgrates_auth("$fU", "$rU"), resume_cgr_auth)) {
|
||||
sl_send_reply("503", "Service Unavailable");
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
route [resume_cgr_auth] {
|
||||
if ($rc < 0) {
|
||||
xlog("Call not authorized: code=$cgrret!\n");
|
||||
send_reply("403", "Forbidden");
|
||||
exit;
|
||||
}
|
||||
$var(idx) = 0;
|
||||
while ($(cgr_ret(AttributesDigest){s.select,$var(idx),,}) != NULL) {
|
||||
$avp($(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,0,:}))
|
||||
= $(cgr_ret(AttributesDigest){s.select,$var(idx),,}{s.select,1,:});
|
||||
$var(idx) = $var(idx) + 1;
|
||||
}
|
||||
cgrates_acc("cdr|missed", "$fU", "$rU");
|
||||
route(relay);
|
||||
}
|
||||
|
||||
|
||||
@@ -210,18 +233,8 @@ route[relay] {
|
||||
|
||||
if (!t_relay()) {
|
||||
send_reply("500","Internal Error");
|
||||
};
|
||||
exit;
|
||||
}
|
||||
|
||||
route [resume_cgr_auth] {
|
||||
if ($rc < 0) {
|
||||
xlog("Call not authorized: code=$cgrret!\n");
|
||||
send_reply("403", "Forbidden");
|
||||
exit;
|
||||
}
|
||||
cgrates_acc("cdr|missed", "$fU", "$rU");
|
||||
route(relay);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +246,6 @@ branch_route[per_branch_ops] {
|
||||
|
||||
|
||||
onreply_route[handle_nat] {
|
||||
|
||||
xlog("incoming reply\n");
|
||||
}
|
||||
|
||||
@@ -242,14 +254,4 @@ failure_route[missed_call] {
|
||||
if (t_was_cancelled()) {
|
||||
exit;
|
||||
}
|
||||
|
||||
# block client redirect based on 3xx replies.
|
||||
if (t_check_status("3[0-9][0-9]")) {
|
||||
t_reply("404","Not found");
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user