diff --git a/data/tutorials/osips_event/cgrates/etc/cgrates/cgrates.cfg b/data/tutorials/osips_event/cgrates/etc/cgrates/cgrates.cfg new file mode 100644 index 000000000..5925ca203 --- /dev/null +++ b/data/tutorials/osips_event/cgrates/etc/cgrates/cgrates.cfg @@ -0,0 +1,173 @@ +# 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. + +[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_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. +# rounding_decimals = 10 # System level precision for floats +# http_skip_tls_veify = false # If enabled Http Client will accept any TLS certificate +# xmlcfg_path = # Path towards additional config defined in xml file + +[balancer] +# enabled = false # Start Balancer service: . + +[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 for non-generic CDRs +mediator = internal # Address where to reach the Mediator. Empty for disabling mediation. <""|internal> +# cdrstats = # Address where to reach the cdrstats service: +# store_disable = false # When true, CDRs will not longer be saved in stordb, useful for cdrstats only scenario + + +[cdre] +# cdr_format = csv # Exported CDRs format +# data_usage_multiply_factor = 0.0 # Multiply data usage before export (eg: convert from KBytes to Bytes) +# cost_multiply_factor = 0.0 # Multiply cost before export (0.0 to disable), 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 = # Destination id containing called addresses to be masked on export +# mask_length = 0 # Length of the destination suffix to be masked +# export_dir = /var/log/cgrates/cdre # Path where the exported CDRs will be placed +# export_template = cgrid,mediation_runid,tor,accid,reqtype,direction,tenant,category,account,subject,destination,setup_time,answer_time,usage,cost + # Exported fields template <""|fld1,fld2|*xml:instance_name> +[cdrc] +# enabled = false # 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 = csv # CDR file format . +# csv_separator = , # Separator used in case of csv files. One character only supported and needs to be right after equal sign +# 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 = csv # Free form field, tag identifying the source of the CDRs within CGRS database. +# tor_field = 2 # TypeOfRecord field identifier. Use index number in case of .csv cdrs. +# accid_field = 3 # Accounting id field identifier. Use index number in case of .csv cdrs. +# reqtype_field = 4 # Request type field identifier. Use index number in case of .csv cdrs. +# direction_field = 5 # Direction field identifier. Use index numbers in case of .csv cdrs. +# tenant_field = 6 # Tenant field identifier. Use index numbers in case of .csv cdrs. +# category_field = 7 # Type of Record field identifier. Use index numbers in case of .csv cdrs. +# account_field = 8 # Account field identifier. Use index numbers in case of .csv cdrs. +# subject_field = 9 # Subject field identifier. Use index numbers in case of .csv CDRs. +# destination_field = 10 # Destination field identifier. Use index numbers in case of .csv cdrs. +# setup_time_field = 11 # Setup time field identifier. Use index numbers in case of .csv cdrs. +# answer_time_field = 12 # Answer time field identifier. Use index numbers in case of .csv cdrs. +# usage_field = 13 # Usage field identifier. Use index numbers in case of .csv cdrs. +# extra_fields = # Extra fields identifiers. For .csv, format: :[...,:] + +[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: +# 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 = 5 # Number of items in the stats buffer +time_window = 5m # 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_intervals = # Filter on CDR Cost + +[session_manager] +enabled = true # Starts SessionManager service: +switch_type = opensips # Defines the type of switch behind: +# rater = internal # Address where to reach the Rater +# reconnects = 3 # Number of reconnects to rater/cdrs before giving up. +# debit_interval = 10 # Interval to perform debits on. +# min_call_duration = 0s # Only authorize calls with allowed duration bigger than this +# max_call_duration = 3h # Maximum call duration a prepaid call can last + +[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. +# 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) + +[opensips] +# listen_udp = 127.0.0.1:2020 # Address where to listen for datagram events coming from OpenSIPS +# mi_addr = 127.0.0.1:8020 # Adress where to reach OpenSIPS mi_datagram module +# events_subscribe_interval = 60s # Automatic events subscription to OpenSIPS, 0 to disable it +# cdrs = internal # Address where to reach CDR Server, empty to disable CDR processing <""|internal|127.0.0.1:2013> +# reconnects = 3 # Number of attempts on connect failure. + +[derived_charging] +# run_ids = # Identifiers of additional sessions control. +# run_filters = # List of cdr field filters for each run. +# reqtype_fields = # Name of request type fields to be used during additional sessions control <""|*default|field_name>. +# direction_fields = # Name of direction fields to be used during additional sessions control <""|*default|field_name>. +# tenant_fields = # Name of tenant fields to be used during additional sessions control <""|*default|field_name>. +# category_fields = # Name of tor fields to be used during additional sessions control <""|*default|field_name>. +# account_fields = # Name of account fields to be used during additional sessions control <""|*default|field_name>. +# subject_fields = # Name of fields to be used during additional sessions control <""|*default|field_name>. +# destination_fields = # Name of destination fields to be used during additional sessions control <""|*default|field_name>. +# setup_time_fields = # Name of setup_time fields to be used during additional sessions control <""|*default|field_name>. +# answer_time_fields = # Name of answer_time fields to be used during additional sessions control <""|*default|field_name>. +# usage_fields = # Name of usage fields to be used during additional sessions control <""|*default|field_name>. +# combined_chargers = true # Combine accounts specific derived_chargers with server configured ones . + +[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 = 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/osips_event/cgrates/etc/default/cgrates b/data/tutorials/osips_event/cgrates/etc/default/cgrates new file mode 100644 index 000000000..4e7add309 --- /dev/null +++ b/data/tutorials/osips_event/cgrates/etc/default/cgrates @@ -0,0 +1,17 @@ +# 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/osips_event/cgrates/etc/init.d/cgrates b/data/tutorials/osips_event/cgrates/etc/init.d/cgrates new file mode 100755 index 000000000..237ab9b7a --- /dev/null +++ b/data/tutorials/osips_event/cgrates/etc/init.d/cgrates @@ -0,0 +1,182 @@ +#! /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 +# +# 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 +SCRIPTNAME=$TUTFOLDER/etc/init.d/$NAME +DEFAULTS=$TUTFOLDER/etc/default/$NAME +ENABLE=false +HISTDIR=/tmp/$NAME/history +CDREDIR=/tmp/$NAME/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 + +# 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 + chown $USER:$GROUP $RUNDIR +fi +# Install the cdre folder +if [ ! -d $CDREDIR ]; then + mkdir -p $CDREDIR + chown $USER:$GROUP $CDREDIR +fi +# Install the history folder +if [ ! -d $HISTDIR ]; then + mkdir -p $HISTDIR + chown $USER:$GROUP $HISTDIR +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 + start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ + || return 1 + start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --exec $DAEMON --chuid $USER:$GROUP --background -- \ + $ENGINE_OPTS \ + || 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 + +: diff --git a/data/tutorials/osips_event/opensips/etc/opensips/opensips.cfg b/data/tutorials/osips_event/opensips/etc/opensips/opensips.cfg new file mode 100644 index 000000000..51578751e --- /dev/null +++ b/data/tutorials/osips_event/opensips/etc/opensips/opensips.cfg @@ -0,0 +1,361 @@ +# +# $Id$ +# +# OpenSIPS residential configuration script +# by OpenSIPS Solutions +# +# 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 +# for a explanation of possible statements, functions and parameters. +# + + +####### Global Parameters ######### + +debug=3 +log_stderror=no +log_facility=LOG_LOCAL0 + +fork=yes +children=4 + +auto_aliases=no + +disable_tcp=yes +disable_tls=yes + + +####### Modules Section ######## + +#set module path +mpath="/usr/lib/opensips/modules" + +#### SIGNALING module +loadmodule "signaling.so" + +#### StateLess module +loadmodule "sl.so" + +#### Transaction Module +loadmodule "tm.so" +modparam("tm", "fr_timer", 5) +modparam("tm", "fr_inv_timer", 30) +modparam("tm", "restart_fr_on_each_reply", 0) +modparam("tm", "onreply_avp_mode", 1) + +#### Record Route Module +loadmodule "rr.so" +/* do not append from tag to the RR (no need for this script) */ +modparam("rr", "append_fromtag", 0) + +#### 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_match_mode", 1) +modparam("dialog", "default_timeout", 21600) # 6 hours timeout +modparam("dialog", "db_mode", 0) + + +#### ACCounting module +loadmodule "acc.so" +/* what special events should be accounted ? */ +modparam("acc", "early_media", 0) +modparam("acc", "report_cancels", 1) +modparam("acc", "cdr_flag", "CDR") +modparam("acc", "evi_flag", "CDR") +modparam("acc", "evi_missed_flag", "CDR") +modparam("acc", "evi_extra", + "cgr_reqtype=$avp(cgr_reqtype); + cgr_account=$avp(cgr_account); + cgr_subject=$avp(cgr_subject); + cgr_destination=$avp(cgr_destination); + originalUri=$ou") + +#### CfgUtils module +loadmodule "cfgutils.so" + +#### CacheDB Local +loadmodule "cachedb_local.so" + + +####### Routing Logic ######## + +startup_route { + subscribe_event("E_OPENSIPS_START", "udp:127.0.0.1:2020"); + raise_event("E_OPENSIPS_START"); +} + +# 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")) { + #setflag(CDR); # do accounting ... + } 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","Rely 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; + } + setflag(CDR); + route(CGR_HANDLER); + } + + if (!uri==myself) { + append_hf("P-hint: outbound\r\n"); + + 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; + } + + + # do lookup with method filtering + if (!lookup("location","m")) { + t_newtran(); + t_reply("404", "Not Found"); + exit; + } + + route(relay); +} + + +route[relay] { + # for INVITEs enable some additional helper routes + if (is_method("INVITE")) { + + + + #t_on_branch("per_branch_ops"); + #t_on_reply("handle_nat"); + t_on_failure("missed_call"); + } + + + + if (!t_relay()) { + send_reply("500","Internal Error"); + }; + exit; +} + +route[CGR_HANDLER] { + # These variables should be populated by script admin by need + $avp(cgr_reqtype)="rated"; + $avp(cgr_account)=$fU; + $avp(cgr_subject)=$fU; + $avp(cgr_destination)=$rU; + switch ($avp(cgr_account)) { + case "1002": + $avp(cgr_reqtype)="postpaid"; + break; + case "1003": + $avp(cgr_reqtype)="pseudoprepaid"; + break; + } + + + # End of variables population + + if $avp(cgr_reqtype)=="pseudoprepaid" || $avp(cgr_reqtype)=="prepaid" { #Make sure we got enough balance for the call + + $avp(auth_keys) = "cgr_reqtype"; + $avp(auth_vals) = $avp(cgr_reqtype); + $avp(auth_keys) = "callid"; + $avp(auth_vals) = $ci; + $avp(auth_keys) = "from_tag"; + $avp(auth_vals) = $ft; + $avp(auth_keys) = "cgr_account"; + $avp(auth_vals) = $avp(cgr_account); + $avp(auth_keys) = "cgr_subject"; + $avp(auth_vals) = $avp(cgr_subject); + $avp(auth_keys) = "cgr_destination"; + $avp(auth_vals) = $avp(cgr_destination); + $avp(auth_keys) = "created"; + $avp(auth_vals) = $Ts; + raise_event("E_CGR_AUTHORIZE", $avp(auth_keys), $avp(auth_vals)); + + $var(accid) = $ci+";"+$ft+";"; + $var(rply_cgr_notify) = $var(accid)+"/"+"cgr_notify"; #Key in localcache for cgr_notify + $var(rply_cgr_maxdur) = $var(accid)+"/"+"cgr_maxdur"; #Key in localcache for cgr_maxdur + $var(ms) = 0; + while($var(ms) < 2000) { # Check for values set every 10 ms for maximum 2 seconds + if cache_fetch("local", "$var(rply_cgr_notify)", $avp(cgr_notify) ) $var(ms) = 2000; # Break out + $var(ms) = $var(ms) + 10; + usleep("10"); + } + if $avp(cgr_notify) == NULL { # Cannot check it in switch + sl_send_reply("503","Prepaid controller error on notify"); + exit; + } + switch ($avp(cgr_notify)) { + case "SERVER_ERROR": + sl_send_reply("503","Prepaid controller error"); + exit; + case "INSUFFICIENT_FUNDS": + sl_send_reply("403", "Payment required"); + exit; + } + if !cache_fetch("local", "$var(rply_cgr_maxdur)", $avp(cgr_maxdur) ) { + sl_send_reply("503","Prepaid controller error on maxdur"); + exit; + } + $DLG_timeout=$avp(cgr_maxdur); + + } + +} + + + +failure_route[missed_call] { + if (t_was_cancelled()) { + exit; + } + +} + + + diff --git a/sessionmanager/osipsevent.go b/sessionmanager/osipsevent.go index 1ff94ab8e..67c80d4cb 100644 --- a/sessionmanager/osipsevent.go +++ b/sessionmanager/osipsevent.go @@ -31,20 +31,21 @@ import ( // sip_reason:OK time:1406312795 cgr_reqtype:prepaid cgr_destination:dan cgr_subject:dan sip_code:200 duration:7 from_tag:a5716471] Values:[]}*/ const ( - FROM_TAG = "from_tag" - TO_TAG = "to_tag" - CALLID = "callid" - CGR_CATEGORY = "cgr_category" - CGR_REQTYPE = "cgr_reqtype" - CGR_TENANT = "cgr_tenant" - CGR_SUBJECT = "cgr_subject" - CGR_ACCOUNT = "cgr_account" - CGR_DESTINATION = "cgr_destination" - TIME = "time" - SETUP_DURATION = "setuptime" - OSIPS__SETUP_TIME = "created" - OSIPS_DURATION = "duration" - OSIPS_AUTH_OK = "AUTH_OK" + FROM_TAG = "from_tag" + TO_TAG = "to_tag" + CALLID = "callid" + CGR_CATEGORY = "cgr_category" + CGR_REQTYPE = "cgr_reqtype" + CGR_TENANT = "cgr_tenant" + CGR_SUBJECT = "cgr_subject" + CGR_ACCOUNT = "cgr_account" + CGR_DESTINATION = "cgr_destination" + TIME = "time" + SETUP_DURATION = "setuptime" + OSIPS__SETUP_TIME = "created" + OSIPS_DURATION = "duration" + OSIPS_AUTH_OK = "AUTH_OK" + OSIPS_INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS" ) func NewOsipsEvent(osipsDagramEvent *osipsdagram.OsipsEvent) (*OsipsEvent, error) { diff --git a/sessionmanager/osipssm.go b/sessionmanager/osipssm.go index 384fe79fe..dc16eed47 100644 --- a/sessionmanager/osipssm.go +++ b/sessionmanager/osipssm.go @@ -220,7 +220,7 @@ func (osm *OsipsSessionManager) OnAuthorize(osipsDagram *osipsdagram.OsipsEvent) } } if maxCallDuration <= osm.cgrCfg.SMMinCallDuration { - cmdNotify := fmt.Sprintf(":cache_store:\nlocal\n%s/cgr_notify\n%s\n2\n\n", ev.GetUUID(), INSUFFICIENT_FUNDS) + cmdNotify := fmt.Sprintf(":cache_store:\nlocal\n%s/cgr_notify\n%s\n2\n\n", ev.GetUUID(), OSIPS_INSUFFICIENT_FUNDS) if reply, err := osm.miConn.SendCommand([]byte(cmdNotify)); err != nil || !bytes.HasPrefix(reply, []byte("200 OK")) { engine.Logger.Err(fmt.Sprintf("Failed setting cgr_notify variable for accid: %s, err: %v, reply: %s", ev.GetUUID(), err, string(reply))) }